/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/andersen/Andersen.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "parcoach/andersen/Andersen.h" |
2 | | |
3 | | #include "llvm/ADT/Statistic.h" |
4 | | #include "llvm/IR/Module.h" |
5 | | #include "llvm/Support/CommandLine.h" |
6 | | #include "llvm/Support/raw_ostream.h" |
7 | | #define DEBUG_TYPE "andersen" |
8 | | |
9 | | using namespace llvm; |
10 | | |
11 | | #ifndef NDEBUG |
12 | | cl::opt<bool> DumpDebugInfo("dump-debug", |
13 | | cl::desc("Dump debug info into stderr"), |
14 | | cl::init(false), cl::Hidden); |
15 | | cl::opt<bool> DumpResultInfo("dump-result", |
16 | | cl::desc("Dump result info into stderr"), |
17 | | cl::init(false), cl::Hidden); |
18 | | cl::opt<bool> DumpConstraintInfo("dump-cons", |
19 | | cl::desc("Dump constraint info into stderr"), |
20 | | cl::init(false), cl::Hidden); |
21 | | #endif |
22 | | |
23 | | AnalysisKey AndersenAA::Key; |
24 | | |
25 | 1.76k | Andersen AndersenAA::run(Module &M, ModuleAnalysisManager &) { |
26 | 1.76k | TimeTraceScope TTS("parcoach::Andersen"); |
27 | 1.76k | Andersen AA; |
28 | 1.76k | LLVM_DEBUG(dbgs() << "Running Andersen\n"); |
29 | 1.76k | AA.runOnModule(M); |
30 | 1.76k | return AA; |
31 | 1.76k | } |
32 | | |
33 | | void Andersen::getAllAllocationSites( |
34 | 3.52k | std::vector<llvm::Value const *> &allocSites) const { |
35 | 3.52k | nodeFactory.getAllocSites(allocSites); |
36 | 3.52k | } |
37 | | |
38 | | bool Andersen::getPointsToSet(llvm::Value const *v, |
39 | 256k | std::vector<llvm::Value const *> &ptsSet) const { |
40 | 256k | NodeIndex ptrIndex = nodeFactory.getValueNodeFor(v); |
41 | | // We have no idea what v is... |
42 | 256k | if (ptrIndex == AndersNodeFactory::InvalidIndex || |
43 | 256k | ptrIndex == nodeFactory.getUniversalPtrNode()) |
44 | 0 | return false; |
45 | | |
46 | 256k | NodeIndex ptrTgt = nodeFactory.getMergeTarget(ptrIndex); |
47 | 256k | ptsSet.clear(); |
48 | | |
49 | 256k | auto ptsItr = ptsGraph.find(ptrTgt); |
50 | 256k | if (ptsItr == ptsGraph.end()) { |
51 | | // Can't find ptrTgt. The reason might be that ptrTgt is an undefined |
52 | | // pointer. Dereferencing it is undefined behavior anyway, so we might just |
53 | | // want to treat it as a nullptr pointer |
54 | 10 | return true; |
55 | 10 | } |
56 | 394k | for (auto v : ptsItr->second) { |
57 | 394k | if (v == nodeFactory.getNullObjectNode()) |
58 | 562 | continue; |
59 | | |
60 | 394k | llvm::Value const *val = nodeFactory.getValueForNode(v); |
61 | 394k | if (val != nullptr) |
62 | 255k | ptsSet.push_back(val); |
63 | 394k | } |
64 | 256k | return true; |
65 | 256k | } |
66 | | |
67 | 1.76k | bool Andersen::runOnModule(Module const &M) { |
68 | 1.76k | collectConstraints(M); |
69 | | |
70 | | #ifndef NDEBUG |
71 | | if (DumpDebugInfo) |
72 | | dumpConstraintsPlainVanilla(); |
73 | | #endif |
74 | | |
75 | | #ifdef ANDERSEN_ENABLE_OPTIMIZATIONS |
76 | | optimizeConstraints(); |
77 | | #endif |
78 | | |
79 | | #ifndef NDEBUG |
80 | | if (DumpConstraintInfo) |
81 | | dumpConstraints(); |
82 | | #endif |
83 | | |
84 | 1.76k | solveConstraints(); |
85 | | |
86 | | #ifndef NDEBUG |
87 | | if (DumpDebugInfo) { |
88 | | errs() << "\n"; |
89 | | dumpPtsGraphPlainVanilla(); |
90 | | } |
91 | | |
92 | | if (DumpResultInfo) { |
93 | | nodeFactory.dumpNodeInfo(); |
94 | | errs() << "\n"; |
95 | | dumpPtsGraphPlainVanilla(); |
96 | | } |
97 | | #endif |
98 | | |
99 | 1.76k | return false; |
100 | 1.76k | } |
101 | | |
102 | | #ifndef NDEBUG |
103 | | void Andersen::dumpConstraint(AndersConstraint const &item) const { |
104 | | NodeIndex dest = item.getDest(); |
105 | | NodeIndex src = item.getSrc(); |
106 | | |
107 | | switch (item.getType()) { |
108 | | case AndersConstraint::COPY: { |
109 | | nodeFactory.dumpNode(dest); |
110 | | errs() << " = "; |
111 | | nodeFactory.dumpNode(src); |
112 | | break; |
113 | | } |
114 | | case AndersConstraint::LOAD: { |
115 | | nodeFactory.dumpNode(dest); |
116 | | errs() << " = *"; |
117 | | nodeFactory.dumpNode(src); |
118 | | break; |
119 | | } |
120 | | case AndersConstraint::STORE: { |
121 | | errs() << "*"; |
122 | | nodeFactory.dumpNode(dest); |
123 | | errs() << " = "; |
124 | | nodeFactory.dumpNode(src); |
125 | | break; |
126 | | } |
127 | | case AndersConstraint::ADDR_OF: { |
128 | | nodeFactory.dumpNode(dest); |
129 | | errs() << " = &"; |
130 | | nodeFactory.dumpNode(src); |
131 | | } |
132 | | } |
133 | | |
134 | | errs() << "\n"; |
135 | | } |
136 | | |
137 | | void Andersen::dumpConstraints() const { |
138 | | errs() << "\n----- Constraints -----\n"; |
139 | | for (auto const &item : constraints) |
140 | | dumpConstraint(item); |
141 | | errs() << "----- End of Print -----\n"; |
142 | | } |
143 | | |
144 | | void Andersen::dumpConstraintsPlainVanilla() const { |
145 | | for (auto const &item : constraints) { |
146 | | errs() << item.getType() << " " << item.getDest() << " " << item.getSrc() |
147 | | << " 0\n"; |
148 | | } |
149 | | } |
150 | | |
151 | | void Andersen::dumpPtsGraphPlainVanilla() const { |
152 | | for (unsigned i = 0, e = nodeFactory.getNumNodes(); i < e; ++i) { |
153 | | NodeIndex rep = nodeFactory.getMergeTarget(i); |
154 | | auto ptsItr = ptsGraph.find(rep); |
155 | | if (ptsItr != ptsGraph.end()) { |
156 | | errs() << i << " "; |
157 | | for (auto v : ptsItr->second) |
158 | | errs() << v << " "; |
159 | | errs() << "\n"; |
160 | | } |
161 | | } |
162 | | } |
163 | | #endif |