Skip to content

Commit 4727c83

Browse files
authored
Merge pull request #93 from ddiepo-pjr/OptimizePtUsers
Optimize calls to get the Users for a a points-to vertex.
2 parents 3756f52 + 348a619 commit 4727c83

2 files changed

Lines changed: 43 additions & 43 deletions

File tree

include/phasar/PhasarLLVM/Pointer/LLVMPointsToGraph.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ class PointsToGraph {
7777
VertexProperties() = default;
7878
VertexProperties(const llvm::Value *v);
7979
std::string getValueAsString() const;
80+
81+
// Fetching the users for V is expensive, so we cache the result.
82+
mutable std::vector<const llvm::User*> users;
83+
std::vector<const llvm::User*> getUsers() const;
8084
};
8185

8286
/**
@@ -91,7 +95,7 @@ class PointsToGraph {
9195
};
9296

9397
/// Data structure for holding the points-to graph.
94-
typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS,
98+
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
9599
VertexProperties, EdgeProperties>
96100
graph_t;
97101

lib/PhasarLLVM/Pointer/LLVMPointsToGraph.cpp

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,16 @@ std::string PointsToGraph::VertexProperties::getValueAsString() const {
123123
return llvmIRToString(V);
124124
}
125125

126+
std::vector<const llvm::User*>
127+
PointsToGraph::VertexProperties::getUsers() const {
128+
if (!users.empty() || V == nullptr) {
129+
return users;
130+
}
131+
auto allUsers = V->users();
132+
users.insert(users.end(), allUsers.begin(), allUsers.end());
133+
return users;
134+
}
135+
126136
PointsToGraph::EdgeProperties::EdgeProperties(const llvm::Value *V) : V(V) {}
127137

128138
std::string PointsToGraph::EdgeProperties::getValueAsString() const {
@@ -189,43 +199,31 @@ PointsToGraph::PointsToGraph(llvm::Function *F, llvm::AAResults &AA) {
189199
INC_COUNTER("GS Pointer", Pointers.size(), PAMM_SEVERITY_LEVEL::Core);
190200

191201
// make vertices for all pointers
192-
for (auto Pointer : Pointers) {
193-
ValueVertexMap[Pointer] = boost::add_vertex(VertexProperties(Pointer), PAG);
202+
for (auto P : Pointers) {
203+
ValueVertexMap[P] = boost::add_vertex(VertexProperties(P), PAG);
194204
}
195205
// iterate over the worklist, and run the full (n^2)/2 disambiguations
196-
for (llvm::SetVector<llvm::Value *>::iterator I1 = Pointers.begin(),
197-
E = Pointers.end();
198-
I1 != E; ++I1) {
199-
uint64_t I1Size = llvm::MemoryLocation::UnknownSize;
206+
const auto mapEnd = ValueVertexMap.end();
207+
for (auto I1 = ValueVertexMap.begin(); I1 != mapEnd; ++I1) {
200208
llvm::Type *I1ElTy =
201-
llvm::cast<llvm::PointerType>((*I1)->getType())->getElementType();
202-
if (I1ElTy->isSized()) {
203-
I1Size = DL.getTypeStoreSize(I1ElTy);
204-
}
205-
for (llvm::SetVector<llvm::Value *>::iterator I2 = Pointers.begin();
206-
I2 != I1; ++I2) {
207-
uint64_t I2Size = llvm::MemoryLocation::UnknownSize;
209+
llvm::cast<llvm::PointerType>(I1->first->getType())->getElementType();
210+
const uint64_t I1Size = I1ElTy->isSized() ? DL.getTypeStoreSize(I1ElTy)
211+
: llvm::MemoryLocation::UnknownSize;
212+
for (auto I2 = std::next(I1); I2 != mapEnd; ++I2) {
208213
llvm::Type *I2ElTy =
209-
llvm::cast<llvm::PointerType>((*I2)->getType())->getElementType();
210-
if (I2ElTy->isSized()) {
211-
I2Size = DL.getTypeStoreSize(I2ElTy);
212-
}
213-
switch (AA.alias(llvm::MemoryLocation(*I1, I1Size),
214-
llvm::MemoryLocation(*I2, I2Size))) {
214+
llvm::cast<llvm::PointerType>(I2->first->getType())->getElementType();
215+
const uint64_t I2Size = I2ElTy->isSized() ? DL.getTypeStoreSize(I2ElTy)
216+
: llvm::MemoryLocation::UnknownSize;
217+
218+
switch (AA.alias(I1->first, I1Size, I2->first, I2Size)) {
215219
case llvm::NoAlias:
216-
// NoAlias
217-
break;
218-
case llvm::MayAlias:
219-
boost::add_edge(ValueVertexMap[*I1], ValueVertexMap[*I2], PAG);
220-
break;
221-
case llvm::PartialAlias:
222-
boost::add_edge(ValueVertexMap[*I1], ValueVertexMap[*I2], PAG);
223220
break;
221+
case llvm::MayAlias: // no break
222+
case llvm::PartialAlias: // no break
224223
case llvm::MustAlias:
225-
boost::add_edge(ValueVertexMap[*I1], ValueVertexMap[*I2], PAG);
224+
boost::add_edge(I1->second, I2->second, PAG);
226225
break;
227226
default:
228-
// do nothing
229227
break;
230228
}
231229
}
@@ -235,10 +233,9 @@ PointsToGraph::PointsToGraph(llvm::Function *F, llvm::AAResults &AA) {
235233
vector<pair<unsigned, const llvm::Value *>>
236234
PointsToGraph::getPointersEscapingThroughParams() {
237235
vector<pair<unsigned, const llvm::Value *>> escaping_pointers;
238-
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
239-
vp.first != vp.second; ++vp.first) {
236+
for (auto vertexIter : boost::make_iterator_range(boost::vertices(PAG))) {
240237
if (const llvm::Argument *arg =
241-
llvm::dyn_cast<llvm::Argument>(PAG[*vp.first].V)) {
238+
llvm::dyn_cast<llvm::Argument>(PAG[vertexIter].V)) {
242239
escaping_pointers.push_back(make_pair(arg->getArgNo(), arg));
243240
}
244241
}
@@ -248,11 +245,11 @@ PointsToGraph::getPointersEscapingThroughParams() {
248245
vector<const llvm::Value *>
249246
PointsToGraph::getPointersEscapingThroughReturns() const {
250247
vector<const llvm::Value *> escaping_pointers;
251-
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
252-
vp.first != vp.second; ++vp.first) {
253-
for (auto user : PAG[*vp.first].V->users()) {
248+
for (auto vertexIter : boost::make_iterator_range(boost::vertices(PAG))) {
249+
auto& vertex = PAG[vertexIter];
250+
for (const auto user : vertex.getUsers()) {
254251
if (llvm::isa<llvm::ReturnInst>(user)) {
255-
escaping_pointers.push_back(PAG[*vp.first].V);
252+
escaping_pointers.push_back(vertex.V);
256253
}
257254
}
258255
}
@@ -263,12 +260,12 @@ vector<const llvm::Value *>
263260
PointsToGraph::getPointersEscapingThroughReturnsForFunction(
264261
const llvm::Function *F) const {
265262
vector<const llvm::Value *> escaping_pointers;
266-
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
267-
vp.first != vp.second; ++vp.first) {
268-
for (auto user : PAG[*vp.first].V->users()) {
263+
for (auto vertexIter : boost::make_iterator_range(boost::vertices(PAG))) {
264+
auto& vertex = PAG[vertexIter];
265+
for (const auto user : vertex.getUsers()) {
269266
if (auto R = llvm::dyn_cast<llvm::ReturnInst>(user)) {
270267
if (R->getFunction() == F)
271-
escaping_pointers.push_back(PAG[*vp.first].V);
268+
escaping_pointers.push_back(vertex.V);
272269
}
273270
}
274271
}
@@ -289,9 +286,8 @@ set<const llvm::Value *> PointsToGraph::getReachableAllocationSites(
289286
}
290287

291288
bool PointsToGraph::containsValue(llvm::Value *V) {
292-
pair<vertex_iterator, vertex_iterator> vp;
293-
for (vp = boost::vertices(PAG); vp.first != vp.second; ++vp.first)
294-
if (PAG[*vp.first].V == V)
289+
for (auto vertexIter : boost::make_iterator_range(boost::vertices(PAG)))
290+
if (PAG[vertexIter].V == V)
295291
return true;
296292
return false;
297293
}

0 commit comments

Comments
 (0)