svf-tools 1.0.657 → 1.0.658
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/CFL/CFLAlias.h +16 -2
- package/svf/include/CFL/CFLGrammar.txt +1 -1
- package/svf/include/CFL/CFLSolver.h +86 -106
- package/svf/include/Util/Options.h +1 -0
- package/svf/lib/CFL/CFLAlias.cpp +11 -13
- package/svf/lib/CFL/CFLSolver.cpp +168 -4
- package/svf/lib/Util/Options.cpp +7 -1
- package/svf-llvm/tools/CFL/cfl.cpp +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.658",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -51,6 +51,10 @@ public:
|
|
|
51
51
|
/// Initialize the grammar, graph, solver
|
|
52
52
|
virtual void initialize();
|
|
53
53
|
|
|
54
|
+
/// Initialize Solver
|
|
55
|
+
virtual void initializeSolver();
|
|
56
|
+
|
|
57
|
+
|
|
54
58
|
/// Print grammar and graph
|
|
55
59
|
virtual void finalize();
|
|
56
60
|
|
|
@@ -143,9 +147,19 @@ public:
|
|
|
143
147
|
POCRAlias(SVFIR* ir) : CFLAlias(ir)
|
|
144
148
|
{
|
|
145
149
|
}
|
|
150
|
+
/// Initialize POCR Solver
|
|
151
|
+
virtual void initializeSolver();
|
|
152
|
+
};
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
class POCRHybrid : public CFLAlias
|
|
155
|
+
{
|
|
156
|
+
public:
|
|
157
|
+
POCRHybrid(SVFIR* ir) : CFLAlias(ir)
|
|
158
|
+
{
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// Initialize POCRHybrid Solver
|
|
162
|
+
virtual void initializeSolver();
|
|
149
163
|
};
|
|
150
164
|
} // End namespace SVF
|
|
151
165
|
|
|
@@ -3,7 +3,7 @@ Start:
|
|
|
3
3
|
Terminal:
|
|
4
4
|
addr copy store load gep vgep
|
|
5
5
|
Productions:
|
|
6
|
-
F -> epsilon | F copy | addr Memflow | F store V load | store Memflow load;
|
|
6
|
+
F -> epsilon | F copy | addr Memflow | F store V load | store Memflow load | F F;
|
|
7
7
|
Fbar -> epsilon | copybar Fbar | Memflowbar addrbar | loadbar V storebar Fbar | loadbar Memflowbar storebar;
|
|
8
8
|
V -> Fbar V F | addrbar addr | gepbar_i V gep_i | gepbarpath V gep_0 | gepbar_i F gep_i | gepbar_i Fbar gep_i;
|
|
9
9
|
copy -> vgep;
|
|
@@ -40,112 +40,6 @@ namespace SVF
|
|
|
40
40
|
{
|
|
41
41
|
typedef GrammarBase::Symbol Label;
|
|
42
42
|
|
|
43
|
-
/*!
|
|
44
|
-
* Hybrid graph representation for transitive relations
|
|
45
|
-
* The implementation is based on
|
|
46
|
-
* Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
|
|
47
|
-
* Taming Transitive Redundancy for Context-Free Language Reachability.
|
|
48
|
-
* ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
|
|
49
|
-
*/
|
|
50
|
-
class HybridData
|
|
51
|
-
{
|
|
52
|
-
public:
|
|
53
|
-
struct TreeNode
|
|
54
|
-
{
|
|
55
|
-
NodeID id;
|
|
56
|
-
std::unordered_set<TreeNode*> children;
|
|
57
|
-
|
|
58
|
-
TreeNode(NodeID nId) : id(nId)
|
|
59
|
-
{}
|
|
60
|
-
|
|
61
|
-
~TreeNode()
|
|
62
|
-
{
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
inline bool operator==(const TreeNode& rhs) const
|
|
66
|
-
{
|
|
67
|
-
return id == rhs.id;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
inline bool operator<(const TreeNode& rhs) const
|
|
71
|
-
{
|
|
72
|
-
return id < rhs.id;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
public:
|
|
78
|
-
Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
|
|
79
|
-
|
|
80
|
-
HybridData()
|
|
81
|
-
{}
|
|
82
|
-
|
|
83
|
-
~HybridData()
|
|
84
|
-
{
|
|
85
|
-
for (auto iter1: indMap)
|
|
86
|
-
{
|
|
87
|
-
for (auto iter2: iter1.second)
|
|
88
|
-
{
|
|
89
|
-
delete iter2.second;
|
|
90
|
-
iter2.second = NULL;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
bool hasInd(NodeID src, NodeID dst)
|
|
96
|
-
{
|
|
97
|
-
auto it = indMap.find(dst);
|
|
98
|
-
if (it == indMap.end())
|
|
99
|
-
return false;
|
|
100
|
-
return (it->second.find(src) != it->second.end());
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/// Add a node dst to tree(src)
|
|
104
|
-
TreeNode* addInd(NodeID src, NodeID dst)
|
|
105
|
-
{
|
|
106
|
-
auto resIns = indMap[dst].insert(std::make_pair(src, new TreeNode(dst)));
|
|
107
|
-
if (resIns.second)
|
|
108
|
-
return resIns.first->second;
|
|
109
|
-
return nullptr;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/// Get the node dst in tree(src)
|
|
113
|
-
TreeNode* getNode(NodeID src, NodeID dst)
|
|
114
|
-
{
|
|
115
|
-
return indMap[dst][src];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/// add v into desc(x) as a child of u
|
|
119
|
-
void insertEdge(TreeNode* u, TreeNode* v)
|
|
120
|
-
{
|
|
121
|
-
u->children.insert(v);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
void addArc(NodeID src, NodeID dst)
|
|
125
|
-
{
|
|
126
|
-
if (!hasInd(src, dst))
|
|
127
|
-
{
|
|
128
|
-
for (auto iter: indMap[src])
|
|
129
|
-
{
|
|
130
|
-
meld(iter.first, getNode(iter.first, src), getNode(dst, dst));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
void meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
|
|
136
|
-
{
|
|
137
|
-
TreeNode* newVNode = addInd(x, vNode->id);
|
|
138
|
-
if (!newVNode)
|
|
139
|
-
return;
|
|
140
|
-
|
|
141
|
-
insertEdge(uNode, newVNode);
|
|
142
|
-
for (TreeNode* vChild: vNode->children)
|
|
143
|
-
{
|
|
144
|
-
meld(x, newVNode, vChild);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
43
|
class CFLSolver
|
|
150
44
|
{
|
|
151
45
|
|
|
@@ -389,6 +283,92 @@ public:
|
|
|
389
283
|
|
|
390
284
|
virtual void initialize();
|
|
391
285
|
};
|
|
286
|
+
/*!
|
|
287
|
+
* Hybrid graph representation for transitive relations
|
|
288
|
+
* The implementation is based on
|
|
289
|
+
* Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
|
|
290
|
+
* Taming Transitive Redundancy for Context-Free Language Reachability.
|
|
291
|
+
* ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
|
|
292
|
+
*/
|
|
293
|
+
/// Solver Utilize Hybrid Representation of Graph
|
|
294
|
+
class POCRHybridSolver : public POCRSolver
|
|
295
|
+
{
|
|
296
|
+
//Hybrid
|
|
297
|
+
//{@
|
|
298
|
+
public:
|
|
299
|
+
struct TreeNode
|
|
300
|
+
{
|
|
301
|
+
NodeID id;
|
|
302
|
+
std::unordered_set<TreeNode*> children;
|
|
303
|
+
|
|
304
|
+
TreeNode(NodeID nId) : id(nId)
|
|
305
|
+
{}
|
|
306
|
+
|
|
307
|
+
~TreeNode()
|
|
308
|
+
{
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
inline bool operator==(const TreeNode& rhs) const
|
|
312
|
+
{
|
|
313
|
+
return id == rhs.id;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
inline bool operator<(const TreeNode& rhs) const
|
|
317
|
+
{
|
|
318
|
+
return id < rhs.id;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
public:
|
|
323
|
+
Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
|
|
324
|
+
|
|
325
|
+
bool hasInd_h(NodeID src, NodeID dst);
|
|
326
|
+
|
|
327
|
+
/// Add a node dst to tree(src)
|
|
328
|
+
TreeNode* addInd_h(NodeID src, NodeID dst);
|
|
329
|
+
|
|
330
|
+
/// Get the node dst in tree(src)
|
|
331
|
+
TreeNode* getNode_h(NodeID src, NodeID dst)
|
|
332
|
+
{
|
|
333
|
+
return indMap[dst][src];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/// add v into desc(x) as a child of u
|
|
337
|
+
void insertEdge_h(TreeNode* u, TreeNode* v)
|
|
338
|
+
{
|
|
339
|
+
u->children.insert(v);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
void addArc_h(NodeID src, NodeID dst);
|
|
343
|
+
|
|
344
|
+
void meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode);
|
|
345
|
+
//@}
|
|
346
|
+
public:
|
|
347
|
+
POCRHybridSolver(CFLGraph* _graph, CFLGrammar* _grammar) : POCRSolver(_graph, _grammar)
|
|
348
|
+
{
|
|
349
|
+
}
|
|
350
|
+
/// Destructor
|
|
351
|
+
virtual ~POCRHybridSolver()
|
|
352
|
+
{
|
|
353
|
+
for (auto iter1: indMap)
|
|
354
|
+
{
|
|
355
|
+
for (auto iter2: iter1.second)
|
|
356
|
+
{
|
|
357
|
+
delete iter2.second;
|
|
358
|
+
iter2.second = NULL;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/// Process CFLEdge
|
|
364
|
+
virtual void processCFLEdge(const CFLEdge* Y_edge);
|
|
365
|
+
|
|
366
|
+
virtual void initialize();
|
|
367
|
+
|
|
368
|
+
public:
|
|
369
|
+
void addArc(NodeID src, NodeID dst);
|
|
370
|
+
void meld(NodeID x, TreeNode* uNode, TreeNode* vNode);
|
|
371
|
+
};
|
|
392
372
|
}
|
|
393
373
|
|
|
394
374
|
#endif /* INCLUDE_CFL_CFLSolver_H_*/
|
package/svf/lib/CFL/CFLAlias.cpp
CHANGED
|
@@ -201,6 +201,11 @@ void CFLAlias::initialize()
|
|
|
201
201
|
normalizeCFLGrammar();
|
|
202
202
|
|
|
203
203
|
// Initialize sovler
|
|
204
|
+
initializeSolver();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void CFLAlias::initializeSolver()
|
|
208
|
+
{
|
|
204
209
|
solver = new CFLSolver(graph, grammar);
|
|
205
210
|
}
|
|
206
211
|
|
|
@@ -238,19 +243,12 @@ void CFLAlias::solve()
|
|
|
238
243
|
timeOfSolving += (end - start) / TIMEINTERVAL;
|
|
239
244
|
}
|
|
240
245
|
|
|
241
|
-
void POCRAlias::
|
|
246
|
+
void POCRAlias::initializeSolver()
|
|
242
247
|
{
|
|
243
|
-
stat = new CFLStat(this);
|
|
244
|
-
|
|
245
|
-
// Build CFL Grammar
|
|
246
|
-
buildCFLGrammar();
|
|
247
|
-
|
|
248
|
-
// Build CFL Graph
|
|
249
|
-
buildCFLGraph();
|
|
250
|
-
|
|
251
|
-
// Normalize CFL Grammar
|
|
252
|
-
normalizeCFLGrammar();
|
|
253
|
-
|
|
254
|
-
// Initialize POCRSolver
|
|
255
248
|
solver = new POCRSolver(graph, grammar);
|
|
256
249
|
}
|
|
250
|
+
|
|
251
|
+
void POCRHybrid::initializeSolver()
|
|
252
|
+
{
|
|
253
|
+
solver = new POCRHybridSolver(graph, grammar);
|
|
254
|
+
}
|
|
@@ -191,15 +191,110 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
|
|
|
191
191
|
|
|
192
192
|
void POCRSolver::initialize()
|
|
193
193
|
{
|
|
194
|
-
for(auto
|
|
194
|
+
for(auto edge : graph->getCFLEdges())
|
|
195
195
|
{
|
|
196
|
-
|
|
196
|
+
pushIntoWorklist(edge);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/// Foreach production X -> epsilon
|
|
200
|
+
/// add X(i,i) if not exist to E and to worklist
|
|
201
|
+
for(const Production& prod : grammar->getEpsilonProds())
|
|
202
|
+
{
|
|
203
|
+
for(auto IDMap : getSuccMap())
|
|
197
204
|
{
|
|
198
|
-
|
|
205
|
+
Symbol X = grammar->getLHSSymbol(prod);
|
|
206
|
+
if (addEdge(IDMap.first, IDMap.first, X))
|
|
207
|
+
{
|
|
208
|
+
CFLNode* i = graph->getGNode(IDMap.first);
|
|
209
|
+
const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
|
|
210
|
+
pushIntoWorklist(newEdge);
|
|
211
|
+
}
|
|
199
212
|
}
|
|
200
213
|
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge)
|
|
217
|
+
{
|
|
218
|
+
CFLNode* i = Y_edge->getSrcNode();
|
|
219
|
+
CFLNode* j = Y_edge->getDstNode();
|
|
220
|
+
|
|
221
|
+
/// For each production X -> Y
|
|
222
|
+
/// add X(i,j) if not exist to E and to worklist
|
|
223
|
+
Symbol Y = Y_edge->getEdgeKind();
|
|
224
|
+
if (grammar->hasProdsFromSingleRHS(Y))
|
|
225
|
+
for(const Production& prod : grammar->getProdsFromSingleRHS(Y))
|
|
226
|
+
{
|
|
227
|
+
Symbol X = grammar->getLHSSymbol(prod);
|
|
228
|
+
numOfChecks++;
|
|
229
|
+
if (addEdge(i->getId(), j->getId(), X))
|
|
230
|
+
{
|
|
231
|
+
const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X);
|
|
232
|
+
pushIntoWorklist(newEdge);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/// For each production X -> Y Z
|
|
238
|
+
/// Foreach outgoing edge Z(j,k) from node j do
|
|
239
|
+
/// add X(i,k) if not exist to E and to worklist
|
|
240
|
+
if (grammar->hasProdsFromFirstRHS(Y))
|
|
241
|
+
for(const Production& prod : grammar->getProdsFromFirstRHS(Y))
|
|
242
|
+
{
|
|
243
|
+
if ((grammar->getLHSSymbol(prod) == grammar->str2Symbol("F")) && (Y == grammar->str2Symbol("F")) && (grammar->getSecondRHSSymbol(prod) == grammar->str2Symbol("F")))
|
|
244
|
+
{
|
|
245
|
+
addArc(i->getId(), j->getId());
|
|
246
|
+
}
|
|
247
|
+
else
|
|
248
|
+
{
|
|
249
|
+
Symbol X = grammar->getLHSSymbol(prod);
|
|
250
|
+
NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
|
|
251
|
+
numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
|
|
252
|
+
for (NodeID diffDst: diffDsts)
|
|
253
|
+
{
|
|
254
|
+
const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X);
|
|
255
|
+
pushIntoWorklist(newEdge);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/// For each production X -> Z Y
|
|
261
|
+
/// Foreach incoming edge Z(k,i) to node i do
|
|
262
|
+
/// add X(k,j) if not exist to E and to worklist
|
|
263
|
+
if(grammar->hasProdsFromSecondRHS(Y))
|
|
264
|
+
for(const Production& prod : grammar->getProdsFromSecondRHS(Y))
|
|
265
|
+
{
|
|
266
|
+
if ((grammar->getLHSSymbol(prod) == grammar->str2Symbol("F")) && (Y == grammar->str2Symbol("F")) && (grammar->getFirstRHSSymbol(prod) == grammar->str2Symbol("F")))
|
|
267
|
+
{
|
|
268
|
+
addArc(i->getId(), j->getId());
|
|
269
|
+
}
|
|
270
|
+
else
|
|
271
|
+
{
|
|
272
|
+
Symbol X = grammar->getLHSSymbol(prod);
|
|
273
|
+
NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
|
|
274
|
+
numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
|
|
275
|
+
for (NodeID diffSrc: diffSrcs)
|
|
276
|
+
{
|
|
277
|
+
const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X);
|
|
278
|
+
pushIntoWorklist(newEdge);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
void POCRHybridSolver::initialize()
|
|
285
|
+
{
|
|
286
|
+
for(auto edge : graph->getCFLEdges())
|
|
287
|
+
{
|
|
288
|
+
pushIntoWorklist(edge);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// init hybrid dataset
|
|
292
|
+
for (auto it = graph->begin(); it != graph->end(); ++it)
|
|
293
|
+
{
|
|
294
|
+
NodeID nId = it->first;
|
|
295
|
+
addInd_h(nId, nId);
|
|
296
|
+
}
|
|
201
297
|
|
|
202
|
-
/// Foreach production X -> epsilon
|
|
203
298
|
/// add X(i,i) if not exist to E and to worklist
|
|
204
299
|
for(const Production& prod : grammar->getEpsilonProds())
|
|
205
300
|
{
|
|
@@ -214,4 +309,73 @@ void POCRSolver::initialize()
|
|
|
214
309
|
}
|
|
215
310
|
}
|
|
216
311
|
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
void POCRHybridSolver::addArc(NodeID src, NodeID dst)
|
|
315
|
+
{
|
|
316
|
+
if(hasEdge(src, dst, grammar->str2Symbol("F")))
|
|
317
|
+
return;
|
|
318
|
+
|
|
319
|
+
for (auto& iter: indMap[src])
|
|
320
|
+
{
|
|
321
|
+
meld(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
void POCRHybridSolver::meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
|
|
327
|
+
{
|
|
328
|
+
numOfChecks++;
|
|
329
|
+
|
|
330
|
+
TreeNode* newVNode = addInd_h(x, vNode->id);
|
|
331
|
+
if (!newVNode)
|
|
332
|
+
return;
|
|
333
|
+
|
|
334
|
+
insertEdge_h(uNode, newVNode);
|
|
335
|
+
for (TreeNode* vChild: vNode->children)
|
|
336
|
+
{
|
|
337
|
+
meld_h(x, newVNode, vChild);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
bool POCRHybridSolver::hasInd_h(NodeID src, NodeID dst)
|
|
342
|
+
{
|
|
343
|
+
auto it = indMap.find(dst);
|
|
344
|
+
if (it == indMap.end())
|
|
345
|
+
return false;
|
|
346
|
+
return (it->second.find(src) != it->second.end());
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
POCRHybridSolver::TreeNode* POCRHybridSolver::addInd_h(NodeID src, NodeID dst)
|
|
350
|
+
{
|
|
351
|
+
TreeNode* newNode = new TreeNode(dst);
|
|
352
|
+
auto resIns = indMap[dst].insert(std::make_pair(src, newNode));
|
|
353
|
+
if (resIns.second)
|
|
354
|
+
return resIns.first->second;
|
|
355
|
+
delete newNode;
|
|
356
|
+
return nullptr;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
void POCRHybridSolver::addArc_h(NodeID src, NodeID dst)
|
|
360
|
+
{
|
|
361
|
+
if (!hasInd_h(src, dst))
|
|
362
|
+
{
|
|
363
|
+
for (auto iter: indMap[src])
|
|
364
|
+
{
|
|
365
|
+
meld_h(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
void POCRHybridSolver::meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode)
|
|
371
|
+
{
|
|
372
|
+
TreeNode* newVNode = addInd_h(x, vNode->id);
|
|
373
|
+
if (!newVNode)
|
|
374
|
+
return;
|
|
375
|
+
|
|
376
|
+
insertEdge_h(uNode, newVNode);
|
|
377
|
+
for (TreeNode* vChild: vNode->children)
|
|
378
|
+
{
|
|
379
|
+
meld_h(x, newVNode, vChild);
|
|
380
|
+
}
|
|
217
381
|
}
|
package/svf/lib/Util/Options.cpp
CHANGED
|
@@ -829,6 +829,12 @@ const Option<bool> Options::POCRAlias(
|
|
|
829
829
|
false
|
|
830
830
|
);
|
|
831
831
|
|
|
832
|
+
const Option<bool> Options::POCRHybrid(
|
|
833
|
+
"pocr-hybrid",
|
|
834
|
+
"When explicit to true, POCRHybridSolver transfer CFL graph to internal hybird graph representation.",
|
|
835
|
+
false
|
|
836
|
+
);
|
|
837
|
+
|
|
832
838
|
const Option<bool> Options::LoopAnalysis(
|
|
833
839
|
"loop-analysis",
|
|
834
840
|
"Analyze every func and get loop info and loop bounds.",
|
|
@@ -841,4 +847,4 @@ const Option<u32_t> Options::LoopBound(
|
|
|
841
847
|
1
|
|
842
848
|
);
|
|
843
849
|
|
|
844
|
-
} // namespace SVF.
|
|
850
|
+
} // namespace SVF.
|
|
@@ -59,6 +59,8 @@ int main(int argc, char ** argv)
|
|
|
59
59
|
std::unique_ptr<CFLBase> cfl;
|
|
60
60
|
if (Options::CFLSVFG())
|
|
61
61
|
cfl = std::make_unique<CFLVF>(svfir);
|
|
62
|
+
else if (Options::POCRHybrid())
|
|
63
|
+
cfl = std::make_unique<POCRHybrid>(svfir);
|
|
62
64
|
else if (Options::POCRAlias())
|
|
63
65
|
cfl = std::make_unique<POCRAlias>(svfir);
|
|
64
66
|
else
|