Skip to content

Commit 96b29fe

Browse files
committed
Initial version with unique_ptr PointsToSets (a bit slower than before)
1 parent 08abd7a commit 96b29fe

10 files changed

Lines changed: 114 additions & 30 deletions

File tree

include/phasar/DB/ProjectIRDB.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class ProjectIRDB {
172172
return IDInstructionMapping.size();
173173
}
174174

175+
[[nodiscard]] std::size_t getNumGlobals() const;
176+
175177
[[nodiscard]] llvm::Instruction *getInstruction(std::size_t Id);
176178

177179
[[nodiscard]] static std::size_t getInstructionID(const llvm::Instruction *I);

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEInstInteractionAnalysis.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class IDEInstInteractionAnalysisT
255255
//
256256
struct IIAFlowFunction : FlowFunction<d_t, container_type> {
257257
const llvm::LoadInst *Load;
258-
LLVMPointsToInfo::PointsToSetPtrTy PTS;
258+
LLVMPointsToInfo::AllocationSiteSetPtrTy PTS;
259259

260260
IIAFlowFunction(IDEInstInteractionAnalysisT &Problem,
261261
const llvm::LoadInst *Load)
@@ -300,8 +300,8 @@ class IDEInstInteractionAnalysisT
300300
//
301301
struct IIAFlowFunction : FlowFunction<d_t, container_type> {
302302
const llvm::StoreInst *Store;
303-
LLVMPointsToInfo::PointsToSetPtrTy ValuePTS;
304-
LLVMPointsToInfo::PointsToSetPtrTy PointerPTS;
303+
LLVMPointsToInfo::AllocationSiteSetPtrTy ValuePTS;
304+
LLVMPointsToInfo::AllocationSiteSetPtrTy PointerPTS;
305305

306306
IIAFlowFunction(IDEInstInteractionAnalysisT &Problem,
307307
const llvm::StoreInst *Store)
@@ -311,7 +311,7 @@ class IDEInstInteractionAnalysisT
311311
Store->getValueOperand(),
312312
Problem.OnlyConsiderLocalAliases);
313313
} else {
314-
return std::make_shared<LLVMPointsToInfo::PointsToSetTy>(
314+
return std::make_unique<LLVMPointsToInfo::PointsToSetTy>(
315315
LLVMPointsToInfo::PointsToSetTy{
316316
Store->getValueOperand()});
317317
}

include/phasar/PhasarLLVM/Pointer/LLVMPointsToGraph.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "phasar/Config/Configuration.h"
2525
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
2626
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
27+
#include "phasar/PhasarLLVM/Pointer/PointsToSetOwner.h"
2728

2829
namespace llvm {
2930
class Value;
@@ -106,6 +107,8 @@ class LLVMPointsToGraph : public LLVMPointsToInfo {
106107
/// Keep track of what has already been merged into this points-to graph.
107108
std::unordered_set<const llvm::Function *> AnalyzedFunctions;
108109
LLVMBasedPointsToAnalysis PTA;
110+
PointsToSetOwner<PointsToSetTy> Owner;
111+
std::unordered_map<const llvm::Value *, PointsToSetTy *> Cache;
109112

110113
// void mergeGraph(const LLVMPointsToGraph &Other);
111114

@@ -140,7 +143,7 @@ class LLVMPointsToGraph : public LLVMPointsToInfo {
140143
getPointsToSet(const llvm::Value *V,
141144
const llvm::Instruction *I = nullptr) override;
142145

143-
PointsToSetPtrTy
146+
AllocationSiteSetPtrTy
144147
getReachableAllocationSites(const llvm::Value *V, bool IntraProcOnly = false,
145148
const llvm::Instruction *I = nullptr) override;
146149

include/phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace psr {
2323
class LLVMPointsToInfo
2424
: public PointsToInfo<const llvm::Value *, const llvm::Instruction *> {
2525
public:
26+
using PointsToInfo::AllocationSiteSetPtrTy;
2627
using PointsToInfo::PointsToSetPtrTy;
2728
using PointsToInfo::PointsToSetTy;
2829

include/phasar/PhasarLLVM/Pointer/LLVMPointsToSet.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
2323
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
24+
#include "phasar/PhasarLLVM/Pointer/PointsToSetOwner.h"
2425

2526
#include "llvm/ADT/DenseSet.h"
2627
#include "llvm/Support/FormatVariadic.h"
@@ -39,12 +40,12 @@ namespace psr {
3940

4041
class LLVMPointsToSet : public LLVMPointsToInfo {
4142
private:
42-
using PointsToSetMap =
43-
std::unordered_map<const llvm::Value *, PointsToSetPtrTy>;
43+
using PointsToSetMap = llvm::DenseMap<const llvm::Value *, PointsToSetTy *>;
4444

4545
LLVMBasedPointsToAnalysis PTA;
4646
llvm::DenseSet<const llvm::Function *> AnalyzedFunctions;
4747

48+
PointsToSetOwner<PointsToSetTy> Owner;
4849
PointsToSetMap PointsToSets;
4950

5051
void computeValuesPointsToSet(const llvm::Value *V);
@@ -55,8 +56,7 @@ class LLVMPointsToSet : public LLVMPointsToInfo {
5556

5657
void mergePointsToSets(const llvm::Value *V1, const llvm::Value *V2);
5758

58-
PointsToSetPtrTy mergePointsToSets(const PointsToSetPtrTy &PTS1,
59-
const PointsToSetPtrTy &PTS2);
59+
PointsToSetTy *mergePointsToSets(PointsToSetTy *PTS1, PointsToSetTy *PTS2);
6060

6161
bool interIsReachableAllocationSiteTy(const llvm::Value *V,
6262
const llvm::Value *P);
@@ -104,7 +104,7 @@ class LLVMPointsToSet : public LLVMPointsToInfo {
104104
getPointsToSet(const llvm::Value *V,
105105
const llvm::Instruction *I = nullptr) override;
106106

107-
[[nodiscard]] PointsToSetPtrTy
107+
[[nodiscard]] AllocationSiteSetPtrTy
108108
getReachableAllocationSites(const llvm::Value *V, bool IntraProcOnly = false,
109109
const llvm::Instruction *I = nullptr) override;
110110

include/phasar/PhasarLLVM/Pointer/PointsToInfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ std::ostream &operator<<(std::ostream &os, const PointerAnalysisType &PA);
4343
template <typename V, typename N> class PointsToInfo {
4444
public:
4545
using PointsToSetTy = llvm::DenseSet<V>;
46-
using PointsToSetPtrTy = std::shared_ptr<PointsToSetTy>;
46+
using PointsToSetPtrTy = const PointsToSetTy *;
47+
using AllocationSiteSetPtrTy = std::unique_ptr<PointsToSetTy>;
4748

4849
virtual ~PointsToInfo() = default;
4950

@@ -55,7 +56,7 @@ template <typename V, typename N> class PointsToInfo {
5556

5657
virtual PointsToSetPtrTy getPointsToSet(V V1, N I = N{}) = 0;
5758

58-
virtual PointsToSetPtrTy
59+
virtual AllocationSiteSetPtrTy
5960
getReachableAllocationSites(V V1, bool IntraProcOnly = false, N I = N{}) = 0;
6061

6162
// Checks if V2 is a reachable allocation in the points to set of V1.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/******************************************************************************
2+
* Copyright (c) 2021 Philipp Schubert.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel, Philipp Schubert and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H_
11+
#define PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H_
12+
13+
#include "llvm/ADT/DenseMap.h"
14+
#include <memory>
15+
#include <vector>
16+
17+
namespace psr {
18+
template <typename PointsToSetTy> class PointsToSetOwner {
19+
public:
20+
explicit PointsToSetOwner() = default;
21+
explicit PointsToSetOwner(size_t InitialCapacity) {
22+
Owner.reserve(InitialCapacity);
23+
OwnedPTS.reserve(InitialCapacity);
24+
}
25+
26+
PointsToSetTy *acquire() {
27+
Owner.push_back(std::make_unique<PointsToSetTy>());
28+
OwnedPTS[Owner.back().get()] = Owner.size() - 1;
29+
return Owner.back().get();
30+
}
31+
void release(PointsToSetTy *PTS) {
32+
if (Owner.empty()) {
33+
return;
34+
}
35+
36+
assert(Owner.size() == OwnedPTS.size());
37+
38+
if (auto It = OwnedPTS.find(PTS); It != OwnedPTS.end()) {
39+
auto Idx = It->second;
40+
41+
OwnedPTS[Owner.back().get()] = Idx;
42+
OwnedPTS.erase(PTS);
43+
44+
std::swap(Owner[Idx], Owner.back());
45+
Owner.pop_back();
46+
}
47+
}
48+
49+
private:
50+
std::vector<std::unique_ptr<PointsToSetTy>> Owner;
51+
llvm::DenseMap<PointsToSetTy *, size_t> OwnedPTS;
52+
};
53+
} // namespace psr
54+
55+
#endif // PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H_

lib/DB/ProjectIRDB.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ llvm::Module *ProjectIRDB::getModule(const std::string &ModuleName) {
231231
return nullptr;
232232
}
233233

234+
std::size_t ProjectIRDB::getNumGlobals() const {
235+
std::size_t Ret = 0;
236+
for (const auto &[File, Module] : Modules) {
237+
Ret += Module->global_size();
238+
}
239+
return Ret;
240+
}
241+
234242
llvm::Instruction *ProjectIRDB::getInstruction(std::size_t Id) {
235243
if (IDInstructionMapping.count(Id)) {
236244
return IDInstructionMapping[Id];

lib/PhasarLLVM/Pointer/LLVMPointsToGraph.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ AliasResult LLVMPointsToGraph::alias(const llvm::Value *V1,
267267
auto LLVMPointsToGraph::getReachableAllocationSites(const llvm::Value *V,
268268
bool IntraProcOnly,
269269
const llvm::Instruction *I)
270-
-> PointsToSetPtrTy {
270+
-> AllocationSiteSetPtrTy {
271271
computePointsToGraph(V);
272-
auto AllocSites = std::make_shared<PointsToSetTy>();
272+
auto AllocSites = std::make_unique<PointsToSetTy>();
273273
AllocationSiteDFSVisitor AllocVis(*AllocSites, {});
274274
vector<boost::default_color_type> ColorMap(boost::num_vertices(PAG));
275275
boost::depth_first_visit(
@@ -378,7 +378,7 @@ auto LLVMPointsToGraph::getPointsToSet(const llvm::Value *V,
378378
PAMM_GET_INSTANCE;
379379
INC_COUNTER("[Calls] getPointsToSet", 1, PAMM_SEVERITY_LEVEL::Full);
380380
START_TIMER("PointsTo-Set Computation", PAMM_SEVERITY_LEVEL::Full);
381-
auto *VF = retrieveFunction(V);
381+
const auto *VF = retrieveFunction(V);
382382
computePointsToGraph(VF);
383383
// check if the graph contains a corresponding vertex
384384
set<vertex_t> ReachableVertices;
@@ -388,7 +388,16 @@ auto LLVMPointsToGraph::getPointsToSet(const llvm::Value *V,
388388
PAG, ValueVertexMap.at(V), Vis,
389389
boost::make_iterator_property_map(
390390
ColorMap.begin(), boost::get(boost::vertex_index, PAG), ColorMap[0]));
391-
auto ResultSet = std::make_shared<PointsToSetTy>();
391+
auto *ResultSet = [this, V] {
392+
auto &Ret = Cache[V];
393+
394+
if (!Ret) {
395+
Ret = Owner.acquire();
396+
}
397+
398+
return Ret;
399+
}();
400+
392401
for (auto Vertex : ReachableVertices) {
393402
ResultSet->insert(PAG[Vertex].V);
394403
}

lib/PhasarLLVM/Pointer/LLVMPointsToSet.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace psr {
5151

5252
LLVMPointsToSet::LLVMPointsToSet(ProjectIRDB &IRDB, bool UseLazyEvaluation,
5353
PointerAnalysisType PATy)
54-
: PTA(IRDB, UseLazyEvaluation, PATy) {
54+
: PTA(IRDB, UseLazyEvaluation, PATy), Owner(IRDB.getNumGlobals()) {
5555
for (llvm::Module *M : IRDB.getAllModules()) {
5656
// compute points-to information for all globals
5757

@@ -122,7 +122,8 @@ auto LLVMPointsToSet::addSingletonPointsToSet(const llvm::Value *V)
122122
auto &PTS = PointsToSets[V];
123123

124124
if (!PTS) {
125-
PTS = std::make_shared<PointsToSetTy>(PointsToSetTy{V});
125+
PTS = Owner.acquire();
126+
PTS->insert(V);
126127
}
127128

128129
assert(PTS->count(V));
@@ -144,9 +145,9 @@ void LLVMPointsToSet::mergePointsToSets(const llvm::Value *V1,
144145
mergePointsToSets(SearchV1->second, SearchV2->second);
145146
}
146147

147-
auto LLVMPointsToSet::mergePointsToSets(const PointsToSetPtrTy &PTS1,
148-
const PointsToSetPtrTy &PTS2)
149-
-> PointsToSetPtrTy {
148+
auto LLVMPointsToSet::mergePointsToSets(PointsToSetTy *PTS1,
149+
PointsToSetTy *PTS2)
150+
-> PointsToSetTy * {
150151
if (PTS1 == PTS2) {
151152
return PTS1;
152153
}
@@ -167,12 +168,11 @@ auto LLVMPointsToSet::mergePointsToSets(const PointsToSetPtrTy &PTS1,
167168
}
168169

169170
// add smaller set to larger one and get rid of the smaller set
170-
// LargerSet->merge(*SmallerSet);
171171
LargerSet->reserve(LargerSet->size() + SmallerSet->size());
172172
LargerSet->insert(SmallerSet->begin(), SmallerSet->end());
173-
SmallerSet->clear();
174173

175-
// assert(SmallerSet->empty() && "Expect the points-to-sets to be disjoint");
174+
SmallerSet->clear();
175+
Owner.release(SmallerSet);
176176

177177
return LargerSet;
178178
}
@@ -474,8 +474,8 @@ LLVMPointsToSet::alias(const llvm::Value *V1, const llvm::Value *V2,
474474
}
475475

476476
auto LLVMPointsToSet::getEmptyPointsToSet() -> PointsToSetPtrTy {
477-
static auto EmptySet = std::make_shared<PointsToSetTy>();
478-
return EmptySet;
477+
static PointsToSetTy EmptySet{};
478+
return &EmptySet;
479479
}
480480

481481
auto LLVMPointsToSet::getPointsToSet(
@@ -497,13 +497,16 @@ auto LLVMPointsToSet::getPointsToSet(
497497

498498
auto LLVMPointsToSet::getReachableAllocationSites(
499499
const llvm::Value *V, bool IntraProcOnly,
500-
[[maybe_unused]] const llvm::Instruction *I) -> PointsToSetPtrTy {
500+
[[maybe_unused]] const llvm::Instruction *I) -> AllocationSiteSetPtrTy {
501+
502+
auto AllocSites = std::make_unique<PointsToSetTy>();
503+
501504
// if V is not a (interesting) pointer we can return an empty set
502505
if (!isInterestingPointer(V)) {
503-
return getEmptyPointsToSet();
506+
return AllocSites;
504507
}
505508
computeValuesPointsToSet(V);
506-
auto AllocSites = std::make_shared<PointsToSetTy>();
509+
507510
const auto PTS = PointsToSets[V];
508511
// consider the full inter-procedural points-to/alias information
509512
if (!IntraProcOnly) {
@@ -587,7 +590,9 @@ void LLVMPointsToSet::mergeWith(const PointsToInfo &PTI) {
587590
// if none of the pointers of a set of other is known in this, we need to
588591
// perform a copy
589592
if (!FoundElemPtr) {
590-
PointsToSets.insert({KeyPtr, std::make_shared<PointsToSetTy>(*Set)});
593+
auto *PTS = Owner.acquire();
594+
*PTS = *Set;
595+
PointsToSets.try_emplace(KeyPtr, PTS);
591596
}
592597
}
593598
}

0 commit comments

Comments
 (0)