svf-tools 1.0.976 → 1.0.978
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/Graphs/ThreadCallGraph.h +0 -6
- package/svf/include/MTA/LockAnalysis.h +41 -31
- package/svf/include/MTA/MHP.h +34 -54
- package/svf/include/MTA/MTAStat.h +1 -2
- package/svf/include/MTA/TCT.h +36 -18
- package/svf/include/Util/CxtStmt.h +13 -12
- package/svf/include/Util/Options.h +1 -20
- package/svf/include/Util/SVFUtil.h +8 -43
- package/svf/include/Util/ThreadAPI.h +42 -85
- package/svf/lib/Graphs/ThreadCallGraph.cpp +1 -73
- package/svf/lib/MTA/LockAnalysis.cpp +83 -75
- package/svf/lib/MTA/MHP.cpp +142 -121
- package/svf/lib/MTA/MTA.cpp +2 -40
- package/svf/lib/MTA/MTAStat.cpp +7 -33
- package/svf/lib/MTA/TCT.cpp +30 -30
- package/svf/lib/Util/CallGraphBuilder.cpp +0 -15
- package/svf/lib/Util/Options.cpp +0 -62
- package/svf/lib/Util/ThreadAPI.cpp +27 -6
- package/svf-llvm/lib/SVFIRExtAPI.cpp +0 -26
- package/svf-llvm/tools/MTA/CMakeLists.txt +1 -1
- package/svf-llvm/tools/MTA/mta.cpp +0 -8
- package/svf/include/MTA/FSMPTA.h +0 -270
- package/svf/include/MTA/MTAResultValidator.h +0 -448
- package/svf/include/MTA/PCG.h +0 -229
- package/svf/lib/MTA/FSMPTA.cpp +0 -792
- package/svf/lib/MTA/PCG.cpp +0 -364
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +0 -251
- package/svf-llvm/tools/MTA/LockResultValidator.h +0 -84
- package/svf-llvm/tools/MTA/MTAAnnotator.cpp +0 -293
- package/svf-llvm/tools/MTA/MTAAnnotator.h +0 -120
- package/svf-llvm/tools/MTA/MTAResultValidator.cpp +0 -716
- package/svf-llvm/tools/MTA/MTAResultValidator.h +0 -337
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.978",
|
|
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": {
|
|
@@ -356,12 +356,6 @@ public:
|
|
|
356
356
|
void addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forksite);
|
|
357
357
|
//@}
|
|
358
358
|
|
|
359
|
-
/// Add direct/indirect parallel for edges
|
|
360
|
-
//@{
|
|
361
|
-
void addDirectParForEdge(const CallICFGNode* cs);
|
|
362
|
-
void addIndirectParForEdge(const CallICFGNode* cs, const SVFFunction* callee);
|
|
363
|
-
//@}
|
|
364
|
-
|
|
365
359
|
|
|
366
360
|
/// map call instruction to its CallGraphEdge map
|
|
367
361
|
inline void addThreadForkEdgeSetMap(const CallICFGNode* cs, ThreadForkEdge* edge)
|
|
@@ -58,11 +58,11 @@ public:
|
|
|
58
58
|
|
|
59
59
|
typedef NodeBS LockSet;
|
|
60
60
|
typedef TCT::InstVec InstVec;
|
|
61
|
-
typedef Set<const
|
|
61
|
+
typedef Set<const ICFGNode*> InstSet;
|
|
62
62
|
typedef InstSet CISpan;
|
|
63
|
-
typedef Map<const
|
|
63
|
+
typedef Map<const ICFGNode*, CISpan>CILockToSpan;
|
|
64
64
|
typedef Set<const SVFFunction*> FunSet;
|
|
65
|
-
typedef Map<const
|
|
65
|
+
typedef Map<const ICFGNode*, InstSet> InstToInstSetMap;
|
|
66
66
|
typedef Map<CxtStmt, ValDomain> CxtStmtToLockFlagMap;
|
|
67
67
|
typedef FIFOWorkList<CxtStmt> CxtStmtWorkList;
|
|
68
68
|
typedef Set<CxtStmt> LockSpan;
|
|
@@ -71,13 +71,13 @@ public:
|
|
|
71
71
|
|
|
72
72
|
typedef Map<CxtLock, LockSpan> CxtLockToSpan;
|
|
73
73
|
typedef Map<CxtLock, NodeBS> CxtLockToLockSet;
|
|
74
|
-
typedef Map<const
|
|
75
|
-
typedef Map<const
|
|
74
|
+
typedef Map<const ICFGNode*, NodeBS> LockSiteToLockSet;
|
|
75
|
+
typedef Map<const ICFGNode*, LockSpan> InstToCxtStmtSet;
|
|
76
76
|
typedef Map<CxtStmt, CxtLockSet> CxtStmtToCxtLockSet;
|
|
77
77
|
typedef FIFOWorkList<CxtLockProc> CxtLockProcVec;
|
|
78
78
|
typedef Set<CxtLockProc> CxtLockProcSet;
|
|
79
79
|
|
|
80
|
-
typedef Map<const
|
|
80
|
+
typedef Map<const ICFGNode*, CxtStmtSet> InstToCxtStmt;
|
|
81
81
|
|
|
82
82
|
LockAnalysis(TCT* t) : tct(t), lockTime(0),numOfTotalQueries(0), numOfLockedQueries(0), lockQueriesTime(0)
|
|
83
83
|
{
|
|
@@ -88,7 +88,7 @@ public:
|
|
|
88
88
|
/// (2) maps a context-sensitive lock site to its corresponding lock span.
|
|
89
89
|
void analyze();
|
|
90
90
|
void analyzeIntraProcedualLock();
|
|
91
|
-
bool intraForwardTraverse(const
|
|
91
|
+
bool intraForwardTraverse(const ICFGNode* lock, InstSet& unlockset, InstSet& forwardInsts);
|
|
92
92
|
bool intraBackwardTraverse(const InstSet& unlockset, InstSet& backwardInsts);
|
|
93
93
|
|
|
94
94
|
void collectCxtLock();
|
|
@@ -100,14 +100,14 @@ public:
|
|
|
100
100
|
/// Intraprocedural locks
|
|
101
101
|
//@{
|
|
102
102
|
/// Return true if the lock is an intra-procedural lock
|
|
103
|
-
inline bool isIntraLock(const
|
|
103
|
+
inline bool isIntraLock(const ICFGNode* lock) const
|
|
104
104
|
{
|
|
105
105
|
assert(locksites.find(lock)!=locksites.end() && "not a lock site?");
|
|
106
106
|
return ciLocktoSpan.find(lock)!=ciLocktoSpan.end();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/// Add intra-procedural lock
|
|
110
|
-
inline void addIntraLock(const
|
|
110
|
+
inline void addIntraLock(const ICFGNode* lockSite, const InstSet& stmts)
|
|
111
111
|
{
|
|
112
112
|
for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
|
|
113
113
|
{
|
|
@@ -117,7 +117,7 @@ public:
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/// Add intra-procedural lock
|
|
120
|
-
inline void addCondIntraLock(const
|
|
120
|
+
inline void addCondIntraLock(const ICFGNode* lockSite, const InstSet& stmts)
|
|
121
121
|
{
|
|
122
122
|
for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
|
|
123
123
|
{
|
|
@@ -126,18 +126,18 @@ public:
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
/// Return true if a statement is inside an intra-procedural lock
|
|
129
|
-
inline bool isInsideIntraLock(const
|
|
129
|
+
inline bool isInsideIntraLock(const ICFGNode* stmt) const
|
|
130
130
|
{
|
|
131
131
|
return instCILocksMap.find(stmt)!=instCILocksMap.end() || isInsideCondIntraLock(stmt);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/// Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional unlock)
|
|
135
|
-
inline bool isInsideCondIntraLock(const
|
|
135
|
+
inline bool isInsideCondIntraLock(const ICFGNode* stmt) const
|
|
136
136
|
{
|
|
137
137
|
return instTocondCILocksMap.find(stmt)!=instTocondCILocksMap.end();
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
inline const InstSet& getIntraLockSet(const
|
|
140
|
+
inline const InstSet& getIntraLockSet(const ICFGNode* stmt) const
|
|
141
141
|
{
|
|
142
142
|
InstToInstSetMap::const_iterator it = instCILocksMap.find(stmt);
|
|
143
143
|
assert(it!=instCILocksMap.end() && "intralock not found!");
|
|
@@ -148,7 +148,7 @@ public:
|
|
|
148
148
|
/// Context-sensitive locks
|
|
149
149
|
//@{
|
|
150
150
|
/// Add inter-procedural context-sensitive lock
|
|
151
|
-
inline void addCxtLock(const CallStrCxt& cxt,const
|
|
151
|
+
inline void addCxtLock(const CallStrCxt& cxt,const ICFGNode* inst)
|
|
152
152
|
{
|
|
153
153
|
CxtLock cxtlock(cxt,inst);
|
|
154
154
|
cxtLockset.insert(cxtlock);
|
|
@@ -200,12 +200,12 @@ public:
|
|
|
200
200
|
/// Context-sensitive statement and lock spans
|
|
201
201
|
//@{
|
|
202
202
|
/// Get LockSet and LockSpan
|
|
203
|
-
inline bool hasCxtStmtfromInst(const
|
|
203
|
+
inline bool hasCxtStmtfromInst(const ICFGNode* inst) const
|
|
204
204
|
{
|
|
205
205
|
InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
|
|
206
206
|
return (it != instToCxtStmtSet.end());
|
|
207
207
|
}
|
|
208
|
-
inline const CxtStmtSet& getCxtStmtfromInst(const
|
|
208
|
+
inline const CxtStmtSet& getCxtStmtfromInst(const ICFGNode* inst) const
|
|
209
209
|
{
|
|
210
210
|
InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
|
|
211
211
|
assert(it != instToCxtStmtSet.end());
|
|
@@ -269,7 +269,7 @@ public:
|
|
|
269
269
|
|
|
270
270
|
|
|
271
271
|
/// Check if one instruction's context stmt is in a lock span
|
|
272
|
-
inline bool hasOneCxtInLockSpan(const
|
|
272
|
+
inline bool hasOneCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
|
|
273
273
|
{
|
|
274
274
|
if(!hasCxtStmtfromInst(I))
|
|
275
275
|
return false;
|
|
@@ -284,7 +284,7 @@ public:
|
|
|
284
284
|
return false;
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
inline bool hasAllCxtInLockSpan(const
|
|
287
|
+
inline bool hasAllCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
|
|
288
288
|
{
|
|
289
289
|
if(!hasCxtStmtfromInst(I))
|
|
290
290
|
return false;
|
|
@@ -303,15 +303,15 @@ public:
|
|
|
303
303
|
/// Check if two Instructions are protected by common locks
|
|
304
304
|
/// echo inst may have multiple cxt stmt
|
|
305
305
|
/// we check whether every cxt stmt of instructions is protected by a common lock.
|
|
306
|
-
bool isProtectedByCommonLock(const
|
|
307
|
-
bool isProtectedByCommonCxtLock(const
|
|
306
|
+
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2);
|
|
307
|
+
bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2);
|
|
308
308
|
bool isProtectedByCommonCxtLock(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2);
|
|
309
|
-
bool isProtectedByCommonCILock(const
|
|
309
|
+
bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2);
|
|
310
310
|
|
|
311
|
-
bool isInSameSpan(const
|
|
312
|
-
bool isInSameCSSpan(const
|
|
311
|
+
bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2);
|
|
312
|
+
bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const;
|
|
313
313
|
bool isInSameCSSpan(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) const;
|
|
314
|
-
bool isInSameCISpan(const
|
|
314
|
+
bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const;
|
|
315
315
|
|
|
316
316
|
inline u32_t getNumOfCxtLocks()
|
|
317
317
|
{
|
|
@@ -346,7 +346,7 @@ private:
|
|
|
346
346
|
{
|
|
347
347
|
return isAliasedLocks(cl1.getStmt(), cl2.getStmt());
|
|
348
348
|
}
|
|
349
|
-
bool isAliasedLocks(const
|
|
349
|
+
bool isAliasedLocks(const ICFGNode* i1, const ICFGNode* i2)
|
|
350
350
|
{
|
|
351
351
|
/// todo: must alias
|
|
352
352
|
return tct->getPTA()->alias(getLockVal(i1), getLockVal(i2));
|
|
@@ -430,27 +430,37 @@ private:
|
|
|
430
430
|
//@}
|
|
431
431
|
|
|
432
432
|
/// Push calling context
|
|
433
|
-
void pushCxt(CallStrCxt& cxt, const
|
|
433
|
+
void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee);
|
|
434
434
|
/// Match context
|
|
435
|
-
bool matchCxt(CallStrCxt& cxt, const
|
|
435
|
+
bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee);
|
|
436
436
|
|
|
437
437
|
/// Whether it is a lock site
|
|
438
|
-
inline bool isTDFork(const
|
|
438
|
+
inline bool isTDFork(const ICFGNode* call)
|
|
439
439
|
{
|
|
440
440
|
return getTCG()->getThreadAPI()->isTDFork(call);
|
|
441
441
|
}
|
|
442
442
|
/// Whether it is a lock site
|
|
443
|
-
inline bool isTDAcquire(const
|
|
443
|
+
inline bool isTDAcquire(const ICFGNode* call)
|
|
444
444
|
{
|
|
445
445
|
return getTCG()->getThreadAPI()->isTDAcquire(call);
|
|
446
446
|
}
|
|
447
447
|
/// Whether it is a unlock site
|
|
448
|
-
inline bool isTDRelease(const
|
|
448
|
+
inline bool isTDRelease(const ICFGNode* call)
|
|
449
449
|
{
|
|
450
450
|
return getTCG()->getThreadAPI()->isTDRelease(call);
|
|
451
451
|
}
|
|
452
|
+
/// Whether it is a callsite
|
|
453
|
+
inline bool isCallSite(const ICFGNode* inst)
|
|
454
|
+
{
|
|
455
|
+
return tct->isCallSite(inst);
|
|
456
|
+
}
|
|
457
|
+
/// Whether it is calling an external function
|
|
458
|
+
inline bool isExtCall(const ICFGNode* inst)
|
|
459
|
+
{
|
|
460
|
+
return tct->isExtCall(inst);
|
|
461
|
+
}
|
|
452
462
|
/// Get lock value
|
|
453
|
-
inline const SVFValue* getLockVal(const
|
|
463
|
+
inline const SVFValue* getLockVal(const ICFGNode* call)
|
|
454
464
|
{
|
|
455
465
|
return getTCG()->getThreadAPI()->getLockVal(call);
|
|
456
466
|
}
|
package/svf/include/MTA/MHP.h
CHANGED
|
@@ -48,11 +48,11 @@ class MHP
|
|
|
48
48
|
public:
|
|
49
49
|
typedef Set<const SVFFunction*> FunSet;
|
|
50
50
|
typedef Set<const SVFInstruction*> InstSet;
|
|
51
|
-
typedef
|
|
51
|
+
typedef std::vector<const SVFInstruction*> InstVec;
|
|
52
52
|
typedef FIFOWorkList<CxtThreadStmt> CxtThreadStmtWorkList;
|
|
53
53
|
typedef Set<CxtThreadStmt> CxtThreadStmtSet;
|
|
54
54
|
typedef Map<CxtThreadStmt,NodeBS> ThreadStmtToThreadInterleav;
|
|
55
|
-
typedef Map<const
|
|
55
|
+
typedef Map<const ICFGNode*,CxtThreadStmtSet> InstToThreadStmtSetMap;
|
|
56
56
|
typedef SVFLoopAndDomInfo::LoopBBs LoopBBs;
|
|
57
57
|
|
|
58
58
|
typedef Set<CxtStmt> LockSpan;
|
|
@@ -84,30 +84,15 @@ public:
|
|
|
84
84
|
return tct;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
// Get CallICFGNode
|
|
88
|
-
inline CallICFGNode* getCBN(const SVFInstruction* inst)
|
|
89
|
-
{
|
|
90
|
-
return tct->getCallICFGNode(inst);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
87
|
/// Whether the function is connected from main function in thread call graph
|
|
94
88
|
bool isConnectedfromMain(const SVFFunction* fun);
|
|
95
89
|
|
|
96
|
-
// /// Interface to query whether two instructions are protected by common locks
|
|
97
|
-
// virtual bool isProtectedByACommonLock(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
98
|
-
// virtual bool isAllCxtInSameLockSpan(const SVFInstruction *I1, const SVFInstruction *I2);
|
|
99
|
-
// virtual bool isOneCxtInSameLockSpan(const SVFInstruction *I1, const SVFInstruction *I2);
|
|
100
|
-
//
|
|
101
|
-
// bool hasOneCxtInLockSpan(const SVFInstruction *I, LockSpan lspan);
|
|
102
|
-
// bool hasAllCxtInLockSpan(const SVFInstruction *I, LockSpan lspan);
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
90
|
// LockSpan getSpanfromCxtLock(NodeID l);
|
|
106
91
|
/// Interface to query whether two instructions may happen-in-parallel
|
|
107
|
-
virtual bool mayHappenInParallel(const
|
|
108
|
-
virtual bool mayHappenInParallelCache(const
|
|
109
|
-
virtual bool mayHappenInParallelInst(const
|
|
110
|
-
virtual bool executedByTheSameThread(const
|
|
92
|
+
virtual bool mayHappenInParallel(const ICFGNode* i1, const ICFGNode* i2);
|
|
93
|
+
virtual bool mayHappenInParallelCache(const ICFGNode* i1, const ICFGNode* i2);
|
|
94
|
+
virtual bool mayHappenInParallelInst(const ICFGNode* i1, const ICFGNode* i2);
|
|
95
|
+
virtual bool executedByTheSameThread(const ICFGNode* i1, const ICFGNode* i2);
|
|
111
96
|
|
|
112
97
|
/// Get interleaving thread for statement inst
|
|
113
98
|
//@{
|
|
@@ -123,13 +108,13 @@ public:
|
|
|
123
108
|
|
|
124
109
|
/// Get/has ThreadStmt
|
|
125
110
|
//@{
|
|
126
|
-
inline const CxtThreadStmtSet& getThreadStmtSet(const
|
|
111
|
+
inline const CxtThreadStmtSet& getThreadStmtSet(const ICFGNode* inst) const
|
|
127
112
|
{
|
|
128
113
|
InstToThreadStmtSetMap::const_iterator it = instToTSMap.find(inst);
|
|
129
114
|
assert(it!=instToTSMap.end() && "no thread access the instruction?");
|
|
130
115
|
return it->second;
|
|
131
116
|
}
|
|
132
|
-
inline bool hasThreadStmtSet(const
|
|
117
|
+
inline bool hasThreadStmtSet(const ICFGNode* inst) const
|
|
133
118
|
{
|
|
134
119
|
return instToTSMap.find(inst)!=instToTSMap.end();
|
|
135
120
|
}
|
|
@@ -140,9 +125,9 @@ public:
|
|
|
140
125
|
|
|
141
126
|
private:
|
|
142
127
|
|
|
143
|
-
inline const CallGraph::FunctionSet& getCallee(const
|
|
128
|
+
inline const CallGraph::FunctionSet& getCallee(const CallICFGNode* inst, CallGraph::FunctionSet& callees)
|
|
144
129
|
{
|
|
145
|
-
tcg->getCallees(
|
|
130
|
+
tcg->getCallees(inst, callees);
|
|
146
131
|
return callees;
|
|
147
132
|
}
|
|
148
133
|
/// Update non-candidate functions' interleaving.
|
|
@@ -186,7 +171,7 @@ private:
|
|
|
186
171
|
pushToCTSWorkList(tgr);
|
|
187
172
|
}
|
|
188
173
|
}
|
|
189
|
-
inline void rmInterleavingThread(const CxtThreadStmt& tgr, const NodeBS& tids, const
|
|
174
|
+
inline void rmInterleavingThread(const CxtThreadStmt& tgr, const NodeBS& tids, const ICFGNode* joinsite)
|
|
190
175
|
{
|
|
191
176
|
NodeBS joinedTids;
|
|
192
177
|
for(NodeBS::iterator it = tids.begin(), eit = tids.end(); it!=eit; ++it)
|
|
@@ -211,7 +196,7 @@ private:
|
|
|
211
196
|
bool isRecurFullJoin(NodeID parentTid, NodeID curTid);
|
|
212
197
|
|
|
213
198
|
/// Whether a join site must join a thread t
|
|
214
|
-
bool isMustJoin(const NodeID curTid, const
|
|
199
|
+
bool isMustJoin(const NodeID curTid, const ICFGNode* joinsite);
|
|
215
200
|
|
|
216
201
|
/// A thread is a multiForked thread if it is in a loop or recursion
|
|
217
202
|
inline bool isMultiForkedThread(NodeID curTid)
|
|
@@ -219,12 +204,12 @@ private:
|
|
|
219
204
|
return tct->getTCTNode(curTid)->isMultiforked();
|
|
220
205
|
}
|
|
221
206
|
/// Push calling context
|
|
222
|
-
inline void pushCxt(CallStrCxt& cxt, const
|
|
207
|
+
inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
223
208
|
{
|
|
224
209
|
tct->pushCxt(cxt,call,callee);
|
|
225
210
|
}
|
|
226
211
|
/// Match context
|
|
227
|
-
inline bool matchCxt(CallStrCxt& cxt, const
|
|
212
|
+
inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
228
213
|
{
|
|
229
214
|
return tct->matchCxt(cxt,call,callee);
|
|
230
215
|
}
|
|
@@ -242,24 +227,24 @@ private:
|
|
|
242
227
|
}
|
|
243
228
|
|
|
244
229
|
/// Whether it is a fork site
|
|
245
|
-
inline bool isTDFork(const
|
|
230
|
+
inline bool isTDFork(const ICFGNode* call)
|
|
246
231
|
{
|
|
247
232
|
return tcg->getThreadAPI()->isTDFork(call);
|
|
248
233
|
}
|
|
249
234
|
/// Whether it is a join site
|
|
250
|
-
inline bool isTDJoin(const
|
|
235
|
+
inline bool isTDJoin(const ICFGNode* call)
|
|
251
236
|
{
|
|
252
237
|
return tcg->getThreadAPI()->isTDJoin(call);
|
|
253
238
|
}
|
|
254
239
|
|
|
255
240
|
/// Return thread id(s) which are directly or indirectly joined at this join site
|
|
256
|
-
NodeBS getDirAndIndJoinedTid(const CallStrCxt& cxt, const
|
|
241
|
+
NodeBS getDirAndIndJoinedTid(const CallStrCxt& cxt, const ICFGNode* call);
|
|
257
242
|
|
|
258
243
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
259
|
-
bool hasJoinInSymmetricLoop(const CallStrCxt& cxt, const
|
|
244
|
+
bool hasJoinInSymmetricLoop(const CallStrCxt& cxt, const ICFGNode* call) const;
|
|
260
245
|
|
|
261
246
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
262
|
-
const LoopBBs& getJoinInSymmetricLoop(const CallStrCxt& cxt, const
|
|
247
|
+
const LoopBBs& getJoinInSymmetricLoop(const CallStrCxt& cxt, const ICFGNode* call) const;
|
|
263
248
|
|
|
264
249
|
/// Whether thread t1 happens before t2 based on ForkJoin Analysis
|
|
265
250
|
bool isHBPair(NodeID tid1, NodeID tid2);
|
|
@@ -353,21 +338,21 @@ public:
|
|
|
353
338
|
}
|
|
354
339
|
|
|
355
340
|
/// Get exit instruction of the start routine function of tid's parent thread
|
|
356
|
-
inline const
|
|
341
|
+
inline const ICFGNode* getExitInstOfParentRoutineFun(NodeID tid) const
|
|
357
342
|
{
|
|
358
343
|
NodeID parentTid = tct->getParentThread(tid);
|
|
359
344
|
const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
|
|
360
345
|
const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
|
|
361
346
|
const SVFInstruction* inst = parentRoutine->getExitBB()->back();
|
|
362
|
-
return inst;
|
|
347
|
+
return tct->getICFGNode(inst);
|
|
363
348
|
}
|
|
364
349
|
|
|
365
350
|
/// Get loop for join site
|
|
366
|
-
inline LoopBBs& getJoinLoop(const
|
|
351
|
+
inline LoopBBs& getJoinLoop(const ICFGNode* inst)
|
|
367
352
|
{
|
|
368
353
|
return tct->getJoinLoop(inst);
|
|
369
354
|
}
|
|
370
|
-
inline bool hasJoinLoop(const
|
|
355
|
+
inline bool hasJoinLoop(const ICFGNode* inst)
|
|
371
356
|
{
|
|
372
357
|
return tct->hasJoinLoop(inst);
|
|
373
358
|
}
|
|
@@ -389,21 +374,16 @@ private:
|
|
|
389
374
|
void handleIntra(const CxtStmt& cts);
|
|
390
375
|
|
|
391
376
|
/// Return true if the fork and join have the same SCEV
|
|
392
|
-
bool isSameSCEV(const
|
|
377
|
+
bool isSameSCEV(const ICFGNode* forkSite, const ICFGNode* joinSite);
|
|
393
378
|
|
|
394
379
|
/// Same loop trip count
|
|
395
|
-
bool sameLoopTripCount(const
|
|
380
|
+
bool sameLoopTripCount(const ICFGNode* forkSite, const ICFGNode* joinSite);
|
|
396
381
|
|
|
397
382
|
/// Whether it is a matched fork join pair
|
|
398
|
-
bool isAliasedForkJoin(const
|
|
383
|
+
bool isAliasedForkJoin(const ICFGNode* forkSite, const ICFGNode* joinSite)
|
|
399
384
|
{
|
|
400
385
|
return tct->getPTA()->alias(getForkedThread(forkSite), getJoinedThread(joinSite)) && isSameSCEV(forkSite,joinSite);
|
|
401
386
|
}
|
|
402
|
-
// Get CallICFGNode
|
|
403
|
-
inline CallICFGNode* getCBN(const SVFInstruction* inst)
|
|
404
|
-
{
|
|
405
|
-
return tct->getCallICFGNode(inst);
|
|
406
|
-
}
|
|
407
387
|
/// Mark thread flags for cxtStmt
|
|
408
388
|
//@{
|
|
409
389
|
/// Get the flag for a cxtStmt
|
|
@@ -471,39 +451,39 @@ private:
|
|
|
471
451
|
//@}
|
|
472
452
|
|
|
473
453
|
/// Push calling context
|
|
474
|
-
inline void pushCxt(CallStrCxt& cxt, const
|
|
454
|
+
inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
475
455
|
{
|
|
476
456
|
tct->pushCxt(cxt,call,callee);
|
|
477
457
|
}
|
|
478
458
|
/// Match context
|
|
479
|
-
inline bool matchCxt(CallStrCxt& cxt, const
|
|
459
|
+
inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
480
460
|
{
|
|
481
461
|
return tct->matchCxt(cxt,call,callee);
|
|
482
462
|
}
|
|
483
463
|
|
|
484
464
|
/// Whether it is a fork site
|
|
485
|
-
inline bool isTDFork(const
|
|
465
|
+
inline bool isTDFork(const ICFGNode* call)
|
|
486
466
|
{
|
|
487
467
|
return getTCG()->getThreadAPI()->isTDFork(call);
|
|
488
468
|
}
|
|
489
469
|
/// Whether it is a join site
|
|
490
|
-
inline bool isTDJoin(const
|
|
470
|
+
inline bool isTDJoin(const ICFGNode* call)
|
|
491
471
|
{
|
|
492
472
|
return getTCG()->getThreadAPI()->isTDJoin(call);
|
|
493
473
|
}
|
|
494
474
|
/// Get forked thread
|
|
495
|
-
inline const SVFValue* getForkedThread(const
|
|
475
|
+
inline const SVFValue* getForkedThread(const ICFGNode* call)
|
|
496
476
|
{
|
|
497
477
|
return getTCG()->getThreadAPI()->getForkedThread(call);
|
|
498
478
|
}
|
|
499
479
|
/// Get joined thread
|
|
500
|
-
inline const SVFValue* getJoinedThread(const
|
|
480
|
+
inline const SVFValue* getJoinedThread(const ICFGNode* call)
|
|
501
481
|
{
|
|
502
482
|
return getTCG()->getThreadAPI()->getJoinedThread(call);
|
|
503
483
|
}
|
|
504
|
-
inline const CallGraph::FunctionSet& getCallee(const
|
|
484
|
+
inline const CallGraph::FunctionSet& getCallee(const ICFGNode* inst, CallGraph::FunctionSet& callees)
|
|
505
485
|
{
|
|
506
|
-
getTCG()->getCallees(
|
|
486
|
+
getTCG()->getCallees(SVFUtil::cast<CallICFGNode>(inst), callees);
|
|
507
487
|
return callees;
|
|
508
488
|
}
|
|
509
489
|
/// ThreadCallGraph
|
|
@@ -51,7 +51,7 @@ public:
|
|
|
51
51
|
typedef Set<const Instruction*> InstSet;
|
|
52
52
|
|
|
53
53
|
/// Constructor
|
|
54
|
-
MTAStat():PTAStat(nullptr),TCTTime(0),MHPTime(0),
|
|
54
|
+
MTAStat():PTAStat(nullptr),TCTTime(0),MHPTime(0),AnnotationTime(0)
|
|
55
55
|
{
|
|
56
56
|
}
|
|
57
57
|
/// Statistics for thread call graph
|
|
@@ -65,7 +65,6 @@ public:
|
|
|
65
65
|
|
|
66
66
|
double TCTTime;
|
|
67
67
|
double MHPTime;
|
|
68
|
-
double FSMPTATime;
|
|
69
68
|
double AnnotationTime;
|
|
70
69
|
};
|
|
71
70
|
|
package/svf/include/MTA/TCT.h
CHANGED
|
@@ -140,13 +140,13 @@ public:
|
|
|
140
140
|
typedef TCTEdge::ThreadCreateEdgeSet ThreadCreateEdgeSet;
|
|
141
141
|
typedef ThreadCreateEdgeSet::iterator TCTNodeIter;
|
|
142
142
|
typedef Set<const SVFFunction*> FunSet;
|
|
143
|
-
typedef std::vector<const
|
|
144
|
-
typedef Set<const
|
|
143
|
+
typedef std::vector<const ICFGNode*> InstVec;
|
|
144
|
+
typedef Set<const ICFGNode*> InstSet;
|
|
145
145
|
typedef Set<const CallGraphNode*> PTACGNodeSet;
|
|
146
146
|
typedef Map<CxtThread,TCTNode*> CxtThreadToNodeMap;
|
|
147
147
|
typedef Map<CxtThread,CallStrCxt> CxtThreadToForkCxt;
|
|
148
148
|
typedef Map<CxtThread,const SVFFunction*> CxtThreadToFun;
|
|
149
|
-
typedef Map<const
|
|
149
|
+
typedef Map<const ICFGNode*, LoopBBs> InstToLoopMap;
|
|
150
150
|
typedef FIFOWorkList<CxtThreadProc> CxtThreadProcVec;
|
|
151
151
|
typedef Set<CxtThreadProc> CxtThreadProcSet;
|
|
152
152
|
typedef SCCDetection<CallGraph*> ThreadCallGraphSCC;
|
|
@@ -172,6 +172,11 @@ public:
|
|
|
172
172
|
{
|
|
173
173
|
return pta->getICFG()->getCallICFGNode(inst);
|
|
174
174
|
}
|
|
175
|
+
const ICFGNode* getICFGNode(const SVFInstruction* inst)
|
|
176
|
+
{
|
|
177
|
+
return pta->getICFG()->getICFGNode(inst);
|
|
178
|
+
}
|
|
179
|
+
|
|
175
180
|
/// Get SVFFModule
|
|
176
181
|
SVFModule* getSVFModule() const
|
|
177
182
|
{
|
|
@@ -246,6 +251,19 @@ public:
|
|
|
246
251
|
}
|
|
247
252
|
//@}
|
|
248
253
|
|
|
254
|
+
/// Whether it is calling an external function
|
|
255
|
+
inline bool isExtCall(const ICFGNode* inst)
|
|
256
|
+
{
|
|
257
|
+
if(const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
|
|
258
|
+
return SVFUtil::isExtCall(call->getCallSite());
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
/// Whether it is a callsite
|
|
262
|
+
inline bool isCallSite(const ICFGNode* inst)
|
|
263
|
+
{
|
|
264
|
+
return SVFUtil::isa<CallICFGNode>(inst);
|
|
265
|
+
}
|
|
266
|
+
|
|
249
267
|
/// Find/Get TCT node
|
|
250
268
|
//@{
|
|
251
269
|
inline bool hasTCTNode(const CxtThread& ct) const
|
|
@@ -355,7 +373,7 @@ public:
|
|
|
355
373
|
}
|
|
356
374
|
|
|
357
375
|
/// Get loop for join site
|
|
358
|
-
inline LoopBBs& getJoinLoop(const
|
|
376
|
+
inline LoopBBs& getJoinLoop(const ICFGNode* join)
|
|
359
377
|
{
|
|
360
378
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
361
379
|
InstToLoopMap::iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -363,7 +381,7 @@ public:
|
|
|
363
381
|
return it->second;
|
|
364
382
|
}
|
|
365
383
|
|
|
366
|
-
inline bool hasJoinLoop(const
|
|
384
|
+
inline bool hasJoinLoop(const ICFGNode* join) const
|
|
367
385
|
{
|
|
368
386
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
369
387
|
InstToLoopMap::const_iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -372,24 +390,24 @@ public:
|
|
|
372
390
|
|
|
373
391
|
bool hasLoop(const SVFBasicBlock* bb) const
|
|
374
392
|
{
|
|
375
|
-
const SVFFunction* fun = bb->
|
|
393
|
+
const SVFFunction* fun = bb->getFunction();
|
|
376
394
|
return fun->hasLoopInfo(bb);
|
|
377
395
|
}
|
|
378
|
-
bool hasLoop(const
|
|
396
|
+
bool hasLoop(const ICFGNode* inst) const
|
|
379
397
|
{
|
|
380
|
-
return hasLoop(inst->
|
|
398
|
+
return hasLoop(inst->getBB());
|
|
381
399
|
}
|
|
382
400
|
/// Return true if a join instruction must be executed inside a loop
|
|
383
|
-
bool isJoinMustExecutedInLoop(const LoopBBs& lp,const
|
|
401
|
+
bool isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join);
|
|
384
402
|
/// Get loop for an instruction
|
|
385
|
-
const LoopBBs& getLoop(const
|
|
403
|
+
const LoopBBs& getLoop(const ICFGNode* inst);
|
|
386
404
|
/// Get loop for fork/join site
|
|
387
405
|
const LoopBBs& getLoop(const SVFBasicBlock* bb);
|
|
388
406
|
|
|
389
407
|
/// Push calling context
|
|
390
|
-
void pushCxt(CallStrCxt& cxt, const
|
|
408
|
+
void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee);
|
|
391
409
|
/// Match context
|
|
392
|
-
bool matchCxt(CallStrCxt& cxt, const
|
|
410
|
+
bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee);
|
|
393
411
|
|
|
394
412
|
inline void pushCxt(CallStrCxt& cxt, CallSiteID csId)
|
|
395
413
|
{
|
|
@@ -398,7 +416,7 @@ public:
|
|
|
398
416
|
MaxCxtSize = cxt.size();
|
|
399
417
|
}
|
|
400
418
|
/// Whether a join site is in recursion
|
|
401
|
-
inline bool isJoinSiteInRecursion(const
|
|
419
|
+
inline bool isJoinSiteInRecursion(const ICFGNode* join) const
|
|
402
420
|
{
|
|
403
421
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
404
422
|
return inRecurJoinSites.find(join)!=inRecurJoinSites.end();
|
|
@@ -473,9 +491,9 @@ private:
|
|
|
473
491
|
/// Multi-forked threads
|
|
474
492
|
//@{
|
|
475
493
|
/// Whether an instruction is in a loop
|
|
476
|
-
bool isInLoopInstruction(const
|
|
494
|
+
bool isInLoopInstruction(const ICFGNode* inst);
|
|
477
495
|
/// Whether an instruction is in a recursion
|
|
478
|
-
bool isInRecursion(const
|
|
496
|
+
bool isInRecursion(const ICFGNode* inst) const;
|
|
479
497
|
//@}
|
|
480
498
|
|
|
481
499
|
/// Handle call relations
|
|
@@ -483,7 +501,7 @@ private:
|
|
|
483
501
|
|
|
484
502
|
/// Get or create a tct node based on CxtThread
|
|
485
503
|
//@{
|
|
486
|
-
inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const
|
|
504
|
+
inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork,const CallStrCxt& oldCxt, const SVFFunction* routine)
|
|
487
505
|
{
|
|
488
506
|
CxtThread ct(cxt,fork);
|
|
489
507
|
CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct);
|
|
@@ -506,7 +524,7 @@ private:
|
|
|
506
524
|
/// non-main thread
|
|
507
525
|
if(ct.getThread() != nullptr)
|
|
508
526
|
{
|
|
509
|
-
const
|
|
527
|
+
const ICFGNode* svfInst = ct.getThread();
|
|
510
528
|
ct.setInloop(isInLoopInstruction(svfInst));
|
|
511
529
|
ct.setIncycle(isInRecursion(svfInst));
|
|
512
530
|
}
|
|
@@ -567,7 +585,7 @@ private:
|
|
|
567
585
|
CxtThreadToForkCxt ctToForkCxtMap; /// Map a CxtThread to the context at its spawning site (fork site).
|
|
568
586
|
CxtThreadToFun ctToRoutineFunMap; /// Map a CxtThread to its start routine function.
|
|
569
587
|
InstToLoopMap joinSiteToLoopMap; ///< map an inloop join to its loop class
|
|
570
|
-
|
|
588
|
+
Set<const ICFGNode*> inRecurJoinSites; ///< Fork or Join sites in recursions
|
|
571
589
|
};
|
|
572
590
|
|
|
573
591
|
} // End namespace SVF
|