svf-tools 1.0.604 → 1.0.605
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/SVF-doxygen/html/html/AndersenSFR_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/Andersen_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CFLGraphBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CFLStat_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CHGBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CPPUtil_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CSC_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CallGraphBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/Casting_8h.html +3 -0
- package/SVF-doxygen/html/html/Casting_8h_source.html +22 -22
- package/SVF-doxygen/html/html/ConsG_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/ContextDDA_8cpp_source.html +15 -15
- package/SVF-doxygen/html/html/ContextDDA_8h_source.html +3 -3
- package/SVF-doxygen/html/html/DCHG_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/DCHG_8h_source.html +1 -1
- package/SVF-doxygen/html/html/DDAStat_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/DDAVFSolver_8h_source.html +82 -74
- package/SVF-doxygen/html/html/FSMPTA_8cpp_source.html +14 -14
- package/SVF-doxygen/html/html/FlowDDA_8h_source.html +9 -9
- package/SVF-doxygen/html/html/FlowSensitiveStat_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/FlowSensitive_8cpp_source.html +27 -21
- package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +18 -18
- package/SVF-doxygen/html/html/IRAnnotator_8h_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMModule_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/LLVMUtil_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/LLVMUtil_8h_source.html +1 -1
- package/SVF-doxygen/html/html/LocationSet_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/LockAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/LockResultValidator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MHP_8cpp_source.html +33 -38
- package/SVF-doxygen/html/html/MHP_8h_source.html +22 -22
- package/SVF-doxygen/html/html/MTAResultValidator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MTAStat_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8h_source.html +1 -1
- package/SVF-doxygen/html/html/PointerAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SVFGOPT_8cpp_source.html +12 -11
- package/SVF-doxygen/html/html/SVFGOPT_8h_source.html +11 -11
- package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/SVFValue_8h_source.html +1 -1
- package/SVF-doxygen/html/html/SaberSVFGBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +8 -1
- package/SVF-doxygen/html/html/SymbolTableBuilder_8cpp_source.html +11 -11
- package/SVF-doxygen/html/html/SymbolTableBuilder_8h_source.html +8 -8
- package/SVF-doxygen/html/html/SymbolTableInfo_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/ThreadCallGraph_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/TypeAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1AliasCFLGraphBuilder.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1CFLStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1CHGBuilder.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CSC.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ConstraintGraph.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ContextDDA.html +19 -19
- package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +11 -11
- package/SVF-doxygen/html/html/classSVF_1_1DDAStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1DDAVFSolver.html +228 -220
- package/SVF-doxygen/html/html/classSVF_1_1FSMPTA.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1FlowDDA.html +17 -17
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +64 -58
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ForkJoinAnalysis.html +30 -38
- package/SVF-doxygen/html/html/classSVF_1_1IRAnnotator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1LLVMModuleSet.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1LocationSet.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1LockAnalysis.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1LockResultValidator.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1MHP.html +67 -83
- package/SVF-doxygen/html/html/classSVF_1_1MHPValidator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MTAResultValidator.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1MTASVFGBuilder.html +53 -53
- package/SVF-doxygen/html/html/classSVF_1_1MTAStat.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1ObjTypeInfo.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1RaceResultValidator.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1SVFCallInst.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1SVFGOPT.html +46 -33
- package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1SaberSVFGBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +8 -1
- package/SVF-doxygen/html/html/classSVF_1_1SymbolTableBuilder.html +32 -32
- package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraph.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraphBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1VFCFLGraphBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive_1_1SCC.html +1 -1
- package/SVF-doxygen/html/html/include_2MTA_2MTAResultValidator_8h_source.html +2 -2
- package/SVF-doxygen/html/html/namespaceSVF_1_1LLVMUtil.html +7 -7
- package/SVF-doxygen/html/html/namespaceSVF_1_1SVFUtil.html +50 -17
- package/SVF-doxygen/html/html/namespaceSVF_1_1cppUtil.html +2 -2
- package/SVF-doxygen/html/html/namespacemembers_func_i.html +7 -7
- package/SVF-doxygen/html/html/namespacemembers_i.html +8 -8
- package/SVF-doxygen/html/html/search/all_9.js +1 -1
- package/SVF-doxygen/html/html/search/functions_8.js +1 -1
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__convert__val.html +3 -3
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__convert__val_3_01To_00_01FromTy_00_01FromTy_01_4.html +3 -3
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01From_01_5_01_4.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01const_01From_01_4.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01const_01From_01_5_01_4.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01const_01From_01_5const_01_4.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01std_1_1unique__ptr_3_01From_01_4_01_4.html +4 -4
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__wrap.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1cast__retty__wrap_3_01To_00_01FromTy_00_01FromTy_01_4.html +2 -2
- package/SVF-doxygen/html/html/structSVF_1_1SVFUtil_1_1is__simple__type.html +2 -2
- package/SVF-doxygen/html/html/tools_2MTA_2MTAResultValidator_8h_source.html +1 -1
- package/include/DDA/DDAVFSolver.h +4 -8
- package/include/Graphs/SVFGOPT.h +2 -2
- package/include/MTA/MTAResultValidator.h +1 -1
- package/include/Util/Casting.h +7 -0
- package/lib/CFL/CFLStat.cpp +1 -1
- package/lib/DDA/ContextDDA.cpp +1 -1
- package/lib/Graphs/ConsG.cpp +2 -2
- package/lib/Graphs/SVFGOPT.cpp +15 -17
- package/lib/MTA/FSMPTA.cpp +7 -6
- package/lib/MTA/LockAnalysis.cpp +1 -1
- package/lib/MTA/MHP.cpp +215 -227
- package/lib/MemoryModel/LocationSet.cpp +1 -1
- package/lib/MemoryModel/PointerAnalysis.cpp +1 -1
- package/lib/SABER/SaberSVFGBuilder.cpp +1 -1
- package/lib/SABER/SrcSnkDDA.cpp +3 -3
- package/lib/SVF-LLVM/LLVMModule.cpp +1 -1
- package/lib/SVF-LLVM/LLVMUtil.cpp +1 -1
- package/lib/SVF-LLVM/SVFIRBuilder.cpp +4 -4
- package/lib/SVF-LLVM/SymbolTableBuilder.cpp +3 -2
- package/lib/SVFIR/SymbolTableInfo.cpp +1 -1
- package/lib/WPA/AndersenSFR.cpp +1 -1
- package/lib/WPA/FlowSensitive.cpp +23 -22
- package/package.json +1 -1
package/lib/MTA/MHP.cpp
CHANGED
|
@@ -41,8 +41,8 @@ using namespace SVFUtil;
|
|
|
41
41
|
/*!
|
|
42
42
|
* Constructor
|
|
43
43
|
*/
|
|
44
|
-
MHP::MHP(TCT* t) :tcg(t->getThreadCallGraph()),tct(t),numOfTotalQueries(0),numOfMHPQueries(0),
|
|
45
|
-
interleavingTime(0),interleavingQueriesTime(0)
|
|
44
|
+
MHP::MHP(TCT* t) : tcg(t->getThreadCallGraph()), tct(t), numOfTotalQueries(0), numOfMHPQueries(0),
|
|
45
|
+
interleavingTime(0), interleavingQueriesTime(0)
|
|
46
46
|
{
|
|
47
47
|
fja = new ForkJoinAnalysis(tct);
|
|
48
48
|
fja->analyzeForkJoinPair();
|
|
@@ -61,14 +61,12 @@ MHP::~MHP()
|
|
|
61
61
|
*/
|
|
62
62
|
void MHP::analyze()
|
|
63
63
|
{
|
|
64
|
-
|
|
65
64
|
DBOUT(DGENERAL, outs() << pasMsg("MHP interleaving analysis\n"));
|
|
66
65
|
DBOUT(DMTA, outs() << pasMsg("MHP interleaving analysis\n"));
|
|
67
66
|
DOTIMESTAT(double interleavingStart = PTAStat::getClk(true));
|
|
68
67
|
analyzeInterleaving();
|
|
69
68
|
DOTIMESTAT(double interleavingEnd = PTAStat::getClk(true));
|
|
70
69
|
DOTIMESTAT(interleavingTime += (interleavingEnd - interleavingStart) / TIMEINTERVAL);
|
|
71
|
-
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
/*!
|
|
@@ -76,27 +74,27 @@ void MHP::analyze()
|
|
|
76
74
|
*/
|
|
77
75
|
void MHP::analyzeInterleaving()
|
|
78
76
|
{
|
|
79
|
-
for(
|
|
77
|
+
for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
|
|
80
78
|
{
|
|
81
|
-
const CxtThread& ct =
|
|
82
|
-
NodeID rootTid =
|
|
79
|
+
const CxtThread& ct = tpair.second->getCxtThread();
|
|
80
|
+
NodeID rootTid = tpair.first;
|
|
83
81
|
const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct);
|
|
84
82
|
const SVFInstruction* svfInst = routine->getEntryBlock()->front();
|
|
85
|
-
CxtThreadStmt rootcts(rootTid,ct.getContext(),svfInst);
|
|
83
|
+
CxtThreadStmt rootcts(rootTid, ct.getContext(), svfInst);
|
|
86
84
|
|
|
87
|
-
addInterleavingThread(rootcts,rootTid);
|
|
85
|
+
addInterleavingThread(rootcts, rootTid);
|
|
88
86
|
updateAncestorThreads(rootTid);
|
|
89
87
|
updateSiblingThreads(rootTid);
|
|
90
88
|
|
|
91
|
-
while(!cxtStmtList.empty())
|
|
89
|
+
while (!cxtStmtList.empty())
|
|
92
90
|
{
|
|
93
91
|
CxtThreadStmt cts = popFromCTSWorkList();
|
|
94
92
|
const SVFInstruction* curInst = cts.getStmt();
|
|
95
|
-
DBOUT(DMTA,outs() << "-----\nMHP analysis root thread: " << rootTid << " ");
|
|
96
|
-
DBOUT(DMTA,cts.dump());
|
|
97
|
-
DBOUT(DMTA,outs() << "current thread interleaving: < ");
|
|
98
|
-
DBOUT(DMTA,dumpSet(getInterleavingThreads(cts)));
|
|
99
|
-
DBOUT(DMTA,outs() << " >\n-----\n");
|
|
93
|
+
DBOUT(DMTA, outs() << "-----\nMHP analysis root thread: " << rootTid << " ");
|
|
94
|
+
DBOUT(DMTA, cts.dump());
|
|
95
|
+
DBOUT(DMTA, outs() << "current thread interleaving: < ");
|
|
96
|
+
DBOUT(DMTA, dumpSet(getInterleavingThreads(cts)));
|
|
97
|
+
DBOUT(DMTA, outs() << " >\n-----\n");
|
|
100
98
|
|
|
101
99
|
/// handle non-candidate function
|
|
102
100
|
if (!tct->isCandidateFun(curInst->getParent()->getParent()))
|
|
@@ -106,22 +104,22 @@ void MHP::analyzeInterleaving()
|
|
|
106
104
|
/// handle candidate function
|
|
107
105
|
else
|
|
108
106
|
{
|
|
109
|
-
if(isTDFork(curInst))
|
|
107
|
+
if (isTDFork(curInst))
|
|
110
108
|
{
|
|
111
|
-
handleFork(cts,rootTid);
|
|
109
|
+
handleFork(cts, rootTid);
|
|
112
110
|
}
|
|
113
|
-
else if(isTDJoin(curInst))
|
|
111
|
+
else if (isTDJoin(curInst))
|
|
114
112
|
{
|
|
115
|
-
handleJoin(cts,rootTid);
|
|
113
|
+
handleJoin(cts, rootTid);
|
|
116
114
|
}
|
|
117
|
-
else if(SVFUtil::isCallSite(curInst) && !isExtCall(curInst))
|
|
115
|
+
else if (SVFUtil::isCallSite(curInst) && !isExtCall(curInst))
|
|
118
116
|
{
|
|
119
|
-
handleCall(cts,rootTid);
|
|
117
|
+
handleCall(cts, rootTid);
|
|
120
118
|
PTACallGraph::FunctionSet callees;
|
|
121
|
-
if(!tct->isCandidateFun(getCallee(curInst, callees)))
|
|
119
|
+
if (!tct->isCandidateFun(getCallee(curInst, callees)))
|
|
122
120
|
handleIntra(cts);
|
|
123
121
|
}
|
|
124
|
-
else if(curInst->isRetInst())
|
|
122
|
+
else if (curInst->isRetInst())
|
|
125
123
|
{
|
|
126
124
|
handleRet(cts);
|
|
127
125
|
}
|
|
@@ -136,8 +134,7 @@ void MHP::analyzeInterleaving()
|
|
|
136
134
|
/// update non-candidate functions' interleaving
|
|
137
135
|
updateNonCandidateFunInterleaving();
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
if(Options::PrintInterLev)
|
|
137
|
+
if (Options::PrintInterLev)
|
|
141
138
|
printInterleaving();
|
|
142
139
|
}
|
|
143
140
|
|
|
@@ -157,9 +154,8 @@ void MHP::updateNonCandidateFunInterleaving()
|
|
|
157
154
|
|
|
158
155
|
const CxtThreadStmtSet& tsSet = getThreadStmtSet(entryinst);
|
|
159
156
|
|
|
160
|
-
for (
|
|
157
|
+
for (const CxtThreadStmt& cts : tsSet)
|
|
161
158
|
{
|
|
162
|
-
const CxtThreadStmt& cts = *it1;
|
|
163
159
|
const CallStrCxt& curCxt = cts.getContext();
|
|
164
160
|
|
|
165
161
|
for (const SVFBasicBlock* svfbb : fun->getBasicBlockList())
|
|
@@ -212,19 +208,20 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
212
208
|
|
|
213
209
|
assert(isTDFork(call));
|
|
214
210
|
CallICFGNode* cbn = getCBN(call);
|
|
215
|
-
if(tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
211
|
+
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
216
212
|
{
|
|
217
213
|
|
|
218
214
|
for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(cbn),
|
|
219
|
-
ecgIt = tcg->getForkEdgeEnd(cbn);
|
|
215
|
+
ecgIt = tcg->getForkEdgeEnd(cbn);
|
|
216
|
+
cgIt != ecgIt; ++cgIt)
|
|
220
217
|
{
|
|
221
218
|
const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction();
|
|
222
219
|
CallStrCxt newCxt = curCxt;
|
|
223
|
-
pushCxt(newCxt,call,svfroutine);
|
|
220
|
+
pushCxt(newCxt, call, svfroutine);
|
|
224
221
|
const SVFInstruction* stmt = svfroutine->getEntryBlock()->front();
|
|
225
|
-
CxtThread ct(newCxt,call);
|
|
226
|
-
CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(),ct.getContext(),stmt);
|
|
227
|
-
addInterleavingThread(newcts,cts);
|
|
222
|
+
CxtThread ct(newCxt, call);
|
|
223
|
+
CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
|
|
224
|
+
addInterleavingThread(newcts, cts);
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
227
|
handleIntra(cts);
|
|
@@ -241,45 +238,45 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
241
238
|
|
|
242
239
|
assert(isTDJoin(call));
|
|
243
240
|
|
|
244
|
-
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt,call);
|
|
245
|
-
if(!joinedTids.empty())
|
|
241
|
+
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt, call);
|
|
242
|
+
if (!joinedTids.empty())
|
|
246
243
|
{
|
|
247
|
-
if(fja->hasJoinLoop(call))
|
|
244
|
+
if (fja->hasJoinLoop(call))
|
|
248
245
|
{
|
|
249
|
-
std::vector<const SVFBasicBlock*>
|
|
250
|
-
call->getFunction()->getExitBlocksOfLoop(call->getParent(),exitbbs);
|
|
251
|
-
while(!exitbbs.empty())
|
|
246
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
247
|
+
call->getFunction()->getExitBlocksOfLoop(call->getParent(), exitbbs);
|
|
248
|
+
while (!exitbbs.empty())
|
|
252
249
|
{
|
|
253
250
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
254
251
|
exitbbs.pop_back();
|
|
255
252
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
256
|
-
CxtThreadStmt newCts(cts.getTid(),curCxt,svfEntryInst);
|
|
257
|
-
addInterleavingThread(newCts,cts);
|
|
258
|
-
if(hasJoinInSymmetricLoop(curCxt,call))
|
|
259
|
-
rmInterleavingThread(newCts,joinedTids,call);
|
|
253
|
+
CxtThreadStmt newCts(cts.getTid(), curCxt, svfEntryInst);
|
|
254
|
+
addInterleavingThread(newCts, cts);
|
|
255
|
+
if (hasJoinInSymmetricLoop(curCxt, call))
|
|
256
|
+
rmInterleavingThread(newCts, joinedTids, call);
|
|
260
257
|
}
|
|
261
258
|
}
|
|
262
259
|
else
|
|
263
260
|
{
|
|
264
|
-
rmInterleavingThread(cts,joinedTids,call);
|
|
265
|
-
DBOUT(DMTA,outs() << "\n\t match join site " << call->toString() <<
|
|
261
|
+
rmInterleavingThread(cts, joinedTids, call);
|
|
262
|
+
DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << " for thread " << rootTid << "\n");
|
|
266
263
|
}
|
|
267
264
|
}
|
|
268
265
|
/// for the join site in a loop loop which does not join the current thread
|
|
269
266
|
/// we process the loop exit
|
|
270
267
|
else
|
|
271
268
|
{
|
|
272
|
-
if(fja->hasJoinLoop(call))
|
|
269
|
+
if (fja->hasJoinLoop(call))
|
|
273
270
|
{
|
|
274
|
-
std::vector<const SVFBasicBlock*>
|
|
275
|
-
call->getFunction()->getExitBlocksOfLoop(call->getParent(),exitbbs);
|
|
276
|
-
while(!exitbbs.empty())
|
|
271
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
272
|
+
call->getFunction()->getExitBlocksOfLoop(call->getParent(), exitbbs);
|
|
273
|
+
while (!exitbbs.empty())
|
|
277
274
|
{
|
|
278
275
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
279
276
|
exitbbs.pop_back();
|
|
280
277
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
281
|
-
CxtThreadStmt newCts(cts.getTid(),cts.getContext(),svfEntryInst);
|
|
282
|
-
addInterleavingThread(newCts,cts);
|
|
278
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), svfEntryInst);
|
|
279
|
+
addInterleavingThread(newCts, cts);
|
|
283
280
|
}
|
|
284
281
|
}
|
|
285
282
|
}
|
|
@@ -295,20 +292,21 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
295
292
|
const SVFInstruction* call = cts.getStmt();
|
|
296
293
|
const CallStrCxt& curCxt = cts.getContext();
|
|
297
294
|
CallICFGNode* cbn = getCBN(call);
|
|
298
|
-
if(tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
295
|
+
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
299
296
|
{
|
|
300
297
|
for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn),
|
|
301
|
-
ecgIt = tcg->getCallEdgeEnd(cbn);
|
|
298
|
+
ecgIt = tcg->getCallEdgeEnd(cbn);
|
|
299
|
+
cgIt != ecgIt; ++cgIt)
|
|
302
300
|
{
|
|
303
301
|
|
|
304
302
|
const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
|
|
305
303
|
if (isExtCall(svfcallee))
|
|
306
304
|
continue;
|
|
307
305
|
CallStrCxt newCxt = curCxt;
|
|
308
|
-
pushCxt(newCxt,call,svfcallee);
|
|
306
|
+
pushCxt(newCxt, call, svfcallee);
|
|
309
307
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
310
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt,svfEntryInst);
|
|
311
|
-
addInterleavingThread(newCts,cts);
|
|
308
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, svfEntryInst);
|
|
309
|
+
addInterleavingThread(newCts, cts);
|
|
312
310
|
}
|
|
313
311
|
}
|
|
314
312
|
}
|
|
@@ -318,38 +316,38 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
318
316
|
*/
|
|
319
317
|
void MHP::handleRet(const CxtThreadStmt& cts)
|
|
320
318
|
{
|
|
321
|
-
|
|
322
319
|
PTACallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getParent()->getParent());
|
|
323
|
-
for
|
|
320
|
+
for (PTACallGraphEdge* edge : curFunNode->getInEdges())
|
|
324
321
|
{
|
|
325
|
-
|
|
326
|
-
if(SVFUtil::isa<ThreadForkEdge>(edge) || SVFUtil::isa<ThreadJoinEdge>(edge))
|
|
322
|
+
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
327
323
|
continue;
|
|
328
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
|
|
329
|
-
ecit = (edge)->directCallsEnd();
|
|
324
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
|
|
325
|
+
ecit = (edge)->directCallsEnd();
|
|
326
|
+
cit != ecit; ++cit)
|
|
330
327
|
{
|
|
331
328
|
CallStrCxt newCxt = cts.getContext();
|
|
332
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
329
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
333
330
|
{
|
|
334
331
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
335
|
-
for(
|
|
332
|
+
for (const auto& ni : nextInsts)
|
|
336
333
|
{
|
|
337
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt
|
|
338
|
-
addInterleavingThread(newCts,cts);
|
|
334
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, ni);
|
|
335
|
+
addInterleavingThread(newCts, cts);
|
|
339
336
|
}
|
|
340
337
|
}
|
|
341
338
|
}
|
|
342
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
|
|
343
|
-
ecit = (edge)->indirectCallsEnd();
|
|
339
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
|
|
340
|
+
ecit = (edge)->indirectCallsEnd();
|
|
341
|
+
cit != ecit; ++cit)
|
|
344
342
|
{
|
|
345
343
|
CallStrCxt newCxt = cts.getContext();
|
|
346
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
344
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
347
345
|
{
|
|
348
346
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
349
|
-
for
|
|
347
|
+
for (const auto& ni: nextInsts)
|
|
350
348
|
{
|
|
351
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt
|
|
352
|
-
addInterleavingThread(newCts,cts);
|
|
349
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, ni);
|
|
350
|
+
addInterleavingThread(newCts, cts);
|
|
353
351
|
}
|
|
354
352
|
}
|
|
355
353
|
}
|
|
@@ -363,36 +361,35 @@ void MHP::handleIntra(const CxtThreadStmt& cts)
|
|
|
363
361
|
{
|
|
364
362
|
|
|
365
363
|
const InstVec& nextInsts = cts.getStmt()->getSuccInstructions();
|
|
366
|
-
for
|
|
364
|
+
for (const auto& ni: nextInsts)
|
|
367
365
|
{
|
|
368
|
-
CxtThreadStmt newCts(cts.getTid(),cts.getContext()
|
|
369
|
-
addInterleavingThread(newCts,cts);
|
|
366
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), ni);
|
|
367
|
+
addInterleavingThread(newCts, cts);
|
|
370
368
|
}
|
|
371
369
|
}
|
|
372
370
|
|
|
373
|
-
|
|
374
371
|
/*!
|
|
375
372
|
* Update interleavings of ancestor threads according to TCT
|
|
376
373
|
*/
|
|
377
374
|
void MHP::updateAncestorThreads(NodeID curTid)
|
|
378
375
|
{
|
|
379
376
|
NodeBS tds = tct->getAncestorThread(curTid);
|
|
380
|
-
DBOUT(DMTA,outs() << "##Ancestor thread of " << curTid << " is : ");
|
|
381
|
-
DBOUT(DMTA,dumpSet(tds));
|
|
382
|
-
DBOUT(DMTA,outs() << "\n");
|
|
377
|
+
DBOUT(DMTA, outs() << "##Ancestor thread of " << curTid << " is : ");
|
|
378
|
+
DBOUT(DMTA, dumpSet(tds));
|
|
379
|
+
DBOUT(DMTA, outs() << "\n");
|
|
383
380
|
tds.set(curTid);
|
|
384
381
|
|
|
385
|
-
for(
|
|
382
|
+
for (const unsigned i : tds)
|
|
386
383
|
{
|
|
387
|
-
const CxtThread& ct = tct->getTCTNode(
|
|
388
|
-
if(const SVFInstruction* forkInst = ct.getThread())
|
|
384
|
+
const CxtThread& ct = tct->getTCTNode(i)->getCxtThread();
|
|
385
|
+
if (const SVFInstruction* forkInst = ct.getThread())
|
|
389
386
|
{
|
|
390
387
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
391
388
|
const InstVec& nextInsts = forkInst->getSuccInstructions();
|
|
392
|
-
for
|
|
389
|
+
for (const auto& ni: nextInsts)
|
|
393
390
|
{
|
|
394
|
-
CxtThreadStmt cts(tct->getParentThread(
|
|
395
|
-
addInterleavingThread(cts,curTid);
|
|
391
|
+
CxtThreadStmt cts(tct->getParentThread(i), forkSiteCxt, ni);
|
|
392
|
+
addInterleavingThread(cts, curTid);
|
|
396
393
|
}
|
|
397
394
|
}
|
|
398
395
|
}
|
|
@@ -412,25 +409,24 @@ void MHP::updateSiblingThreads(NodeID curTid)
|
|
|
412
409
|
{
|
|
413
410
|
NodeBS tds = tct->getAncestorThread(curTid);
|
|
414
411
|
tds.set(curTid);
|
|
415
|
-
for(
|
|
412
|
+
for (const unsigned tid : tds)
|
|
416
413
|
{
|
|
417
|
-
NodeBS
|
|
418
|
-
for(
|
|
414
|
+
NodeBS siblingTds = tct->getSiblingThread(tid);
|
|
415
|
+
for (const unsigned stid : siblingTds)
|
|
419
416
|
{
|
|
420
|
-
|
|
421
|
-
if((isHBPair(*cit,*it) && isRecurFullJoin(*cit,curTid)) || isHBPair(*it,*cit) )
|
|
417
|
+
if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid))
|
|
422
418
|
continue;
|
|
423
419
|
|
|
424
|
-
const CxtThread& ct = tct->getTCTNode(
|
|
420
|
+
const CxtThread& ct = tct->getTCTNode(stid)->getCxtThread();
|
|
425
421
|
const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct);
|
|
426
422
|
const SVFInstruction* stmt = routine->getEntryBlock()->front();
|
|
427
|
-
CxtThreadStmt cts(
|
|
428
|
-
addInterleavingThread(cts,curTid);
|
|
423
|
+
CxtThreadStmt cts(stid, ct.getContext(), stmt);
|
|
424
|
+
addInterleavingThread(cts, curTid);
|
|
429
425
|
}
|
|
430
426
|
|
|
431
|
-
DBOUT(DMTA,outs() << "##Sibling thread of " << curTid << " is : ");
|
|
432
|
-
DBOUT(DMTA,dumpSet(siblingTds));
|
|
433
|
-
DBOUT(DMTA,outs() << "\n");
|
|
427
|
+
DBOUT(DMTA, outs() << "##Sibling thread of " << curTid << " is : ");
|
|
428
|
+
DBOUT(DMTA, dumpSet(siblingTds));
|
|
429
|
+
DBOUT(DMTA, outs() << "\n");
|
|
434
430
|
}
|
|
435
431
|
}
|
|
436
432
|
|
|
@@ -439,24 +435,24 @@ void MHP::updateSiblingThreads(NodeID curTid)
|
|
|
439
435
|
*/
|
|
440
436
|
bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
441
437
|
{
|
|
442
|
-
if(parentTid==curTid)
|
|
438
|
+
if (parentTid == curTid)
|
|
443
439
|
return true;
|
|
444
440
|
|
|
445
441
|
const TCTNode* curNode = tct->getTCTNode(curTid);
|
|
446
442
|
FIFOWorkList<const TCTNode*> worklist;
|
|
447
443
|
worklist.push(curNode);
|
|
448
|
-
while(!worklist.empty())
|
|
444
|
+
while (!worklist.empty())
|
|
449
445
|
{
|
|
450
446
|
const TCTNode* node = worklist.pop();
|
|
451
|
-
for
|
|
447
|
+
for (TCTEdge* edge : node->getInEdges())
|
|
452
448
|
{
|
|
453
|
-
NodeID srcID =
|
|
454
|
-
if(fja->isFullJoin(srcID,node->getId()))
|
|
449
|
+
NodeID srcID = edge->getSrcID();
|
|
450
|
+
if (fja->isFullJoin(srcID, node->getId()))
|
|
455
451
|
{
|
|
456
|
-
if(srcID == parentTid)
|
|
452
|
+
if (srcID == parentTid)
|
|
457
453
|
return true;
|
|
458
454
|
else
|
|
459
|
-
worklist.push(
|
|
455
|
+
worklist.push(edge->getSrcNode());
|
|
460
456
|
}
|
|
461
457
|
else
|
|
462
458
|
{
|
|
@@ -467,7 +463,6 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
|
467
463
|
return false;
|
|
468
464
|
}
|
|
469
465
|
|
|
470
|
-
|
|
471
466
|
/*!
|
|
472
467
|
* A join site must join t if
|
|
473
468
|
* (1) t is not a multiforked thread
|
|
@@ -484,7 +479,7 @@ bool MHP::isMustJoin(NodeID curTid, const SVFInstruction* joinsite)
|
|
|
484
479
|
*/
|
|
485
480
|
NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* call)
|
|
486
481
|
{
|
|
487
|
-
CxtStmt cs(cxt,call);
|
|
482
|
+
CxtStmt cs(cxt, call);
|
|
488
483
|
return fja->getDirAndIndJoinedTid(cs);
|
|
489
484
|
}
|
|
490
485
|
|
|
@@ -493,29 +488,25 @@ NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* c
|
|
|
493
488
|
*/
|
|
494
489
|
bool MHP::hasJoinInSymmetricLoop(const CallStrCxt& cxt, const SVFInstruction* call) const
|
|
495
490
|
{
|
|
496
|
-
CxtStmt cs(cxt,call);
|
|
491
|
+
CxtStmt cs(cxt, call);
|
|
497
492
|
return fja->hasJoinInSymmetricLoop(cs);
|
|
498
493
|
}
|
|
499
494
|
|
|
500
|
-
|
|
501
495
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
502
496
|
const MHP::LoopBBs& MHP::getJoinInSymmetricLoop(const CallStrCxt& cxt, const SVFInstruction* call) const
|
|
503
497
|
{
|
|
504
|
-
CxtStmt cs(cxt,call);
|
|
498
|
+
CxtStmt cs(cxt, call);
|
|
505
499
|
return fja->getJoinInSymmetricLoop(cs);
|
|
506
500
|
}
|
|
507
501
|
|
|
508
|
-
|
|
509
502
|
/*!
|
|
510
503
|
* Whether two thread t1 happens-fore t2
|
|
511
504
|
*/
|
|
512
505
|
bool MHP::isHBPair(NodeID tid1, NodeID tid2)
|
|
513
506
|
{
|
|
514
|
-
return fja->isHBPair(tid1,tid2);
|
|
507
|
+
return fja->isHBPair(tid1, tid2);
|
|
515
508
|
}
|
|
516
509
|
|
|
517
|
-
|
|
518
|
-
|
|
519
510
|
bool MHP::isConnectedfromMain(const SVFFunction* fun)
|
|
520
511
|
{
|
|
521
512
|
PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun);
|
|
@@ -526,7 +517,7 @@ bool MHP::isConnectedfromMain(const SVFFunction* fun)
|
|
|
526
517
|
while (!worklist.empty())
|
|
527
518
|
{
|
|
528
519
|
const PTACallGraphNode* node = worklist.pop();
|
|
529
|
-
if("main" == node->getFunction()->getName())
|
|
520
|
+
if ("main" == node->getFunction()->getName())
|
|
530
521
|
return true;
|
|
531
522
|
for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
|
|
532
523
|
{
|
|
@@ -555,22 +546,20 @@ bool MHP::mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction
|
|
|
555
546
|
{
|
|
556
547
|
|
|
557
548
|
/// TODO: Any instruction in dead function is assumed no MHP with others
|
|
558
|
-
if(!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
549
|
+
if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
559
550
|
return false;
|
|
560
551
|
|
|
561
552
|
const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1);
|
|
562
553
|
const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2);
|
|
563
|
-
for(
|
|
554
|
+
for (const CxtThreadStmt& ts1 : tsSet1)
|
|
564
555
|
{
|
|
565
|
-
const CxtThreadStmt& ts1 = *it1;
|
|
566
556
|
NodeBS l1 = getInterleavingThreads(ts1);
|
|
567
|
-
for(
|
|
557
|
+
for (const CxtThreadStmt& ts2 : tsSet2)
|
|
568
558
|
{
|
|
569
|
-
const CxtThreadStmt& ts2 = *it2;
|
|
570
559
|
NodeBS l2 = getInterleavingThreads(ts2);
|
|
571
|
-
if(ts1.getTid()!=ts2.getTid())
|
|
560
|
+
if (ts1.getTid() != ts2.getTid())
|
|
572
561
|
{
|
|
573
|
-
if(l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
|
|
562
|
+
if (l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
|
|
574
563
|
{
|
|
575
564
|
numOfMHPQueries++;
|
|
576
565
|
return true;
|
|
@@ -591,11 +580,11 @@ bool MHP::mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction
|
|
|
591
580
|
|
|
592
581
|
bool MHP::mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
593
582
|
{
|
|
594
|
-
if(!tct->isCandidateFun(i1->getParent()->getParent())
|
|
583
|
+
if (!tct->isCandidateFun(i1->getParent()->getParent()) && !tct->isCandidateFun(i2->getParent()->getParent()))
|
|
595
584
|
{
|
|
596
585
|
FuncPair funpair = std::make_pair(i1->getFunction(), i2->getFunction());
|
|
597
586
|
FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
|
|
598
|
-
if (it==nonCandidateFuncMHPRelMap.end())
|
|
587
|
+
if (it == nonCandidateFuncMHPRelMap.end())
|
|
599
588
|
{
|
|
600
589
|
bool mhp = mayHappenInParallelInst(i1, i2);
|
|
601
590
|
nonCandidateFuncMHPRelMap[funpair] = mhp;
|
|
@@ -603,12 +592,12 @@ bool MHP::mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstructio
|
|
|
603
592
|
}
|
|
604
593
|
else
|
|
605
594
|
{
|
|
606
|
-
if(it->second)
|
|
595
|
+
if (it->second)
|
|
607
596
|
numOfMHPQueries++;
|
|
608
597
|
return it->second;
|
|
609
598
|
}
|
|
610
599
|
}
|
|
611
|
-
return mayHappenInParallelInst(i1,i2);
|
|
600
|
+
return mayHappenInParallelInst(i1, i2);
|
|
612
601
|
}
|
|
613
602
|
|
|
614
603
|
bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
@@ -616,7 +605,7 @@ bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2
|
|
|
616
605
|
numOfTotalQueries++;
|
|
617
606
|
|
|
618
607
|
DOTIMESTAT(double queryStart = PTAStat::getClk(true));
|
|
619
|
-
bool mhp=mayHappenInParallelCache(i1,i2);
|
|
608
|
+
bool mhp = mayHappenInParallelCache(i1, i2);
|
|
620
609
|
DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
|
|
621
610
|
DOTIMESTAT(interleavingQueriesTime += (queryEnd - queryStart) / TIMEINTERVAL);
|
|
622
611
|
|
|
@@ -625,45 +614,40 @@ bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2
|
|
|
625
614
|
|
|
626
615
|
bool MHP::executedByTheSameThread(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
627
616
|
{
|
|
628
|
-
if(!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
617
|
+
if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
629
618
|
return true;
|
|
630
619
|
|
|
631
620
|
const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1);
|
|
632
621
|
const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2);
|
|
633
|
-
for
|
|
622
|
+
for (const CxtThreadStmt&ts1 : tsSet1)
|
|
634
623
|
{
|
|
635
|
-
const CxtThreadStmt&
|
|
636
|
-
for(CxtThreadStmtSet::const_iterator it2 = tsSet2.begin(), eit2 = tsSet2.end(); it2!=eit2; ++it2)
|
|
624
|
+
for (const CxtThreadStmt& ts2 : tsSet2)
|
|
637
625
|
{
|
|
638
|
-
|
|
639
|
-
if(ts1.getTid()!=ts2.getTid())
|
|
640
|
-
return false;
|
|
641
|
-
else if (isMultiForkedThread(ts1.getTid()))
|
|
626
|
+
if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid()))
|
|
642
627
|
return false;
|
|
643
628
|
}
|
|
644
629
|
}
|
|
645
630
|
return true;
|
|
646
631
|
}
|
|
647
632
|
|
|
648
|
-
|
|
649
633
|
/*!
|
|
650
634
|
* Print interleaving results
|
|
651
635
|
*/
|
|
652
636
|
void MHP::printInterleaving()
|
|
653
637
|
{
|
|
654
|
-
for(
|
|
638
|
+
for (const auto& pair : threadStmtToTheadInterLeav)
|
|
655
639
|
{
|
|
656
|
-
outs() << "( t" <<
|
|
657
|
-
|
|
658
|
-
|
|
640
|
+
outs() << "( t" << pair.first.getTid()
|
|
641
|
+
<< " , $" << pair.first.getStmt()->getSourceLoc()
|
|
642
|
+
<< "$" << pair.first.getStmt()->toString() << " ) ==> [";
|
|
643
|
+
for (unsigned i : pair.second)
|
|
659
644
|
{
|
|
660
|
-
outs() << " " <<
|
|
645
|
+
outs() << " " << i << " ";
|
|
661
646
|
}
|
|
662
647
|
outs() << "]\n";
|
|
663
648
|
}
|
|
664
649
|
}
|
|
665
650
|
|
|
666
|
-
|
|
667
651
|
/*!
|
|
668
652
|
* Collect SCEV pass information for pointers at fork/join sites
|
|
669
653
|
* Because ScalarEvolution is a function pass, previous knowledge of a function
|
|
@@ -673,18 +657,20 @@ void MHP::printInterleaving()
|
|
|
673
657
|
void ForkJoinAnalysis::collectSCEVInfo()
|
|
674
658
|
{
|
|
675
659
|
typedef Set<const SVFInstruction*> CallInstSet;
|
|
676
|
-
typedef Map<const SVFFunction*, CallInstSet
|
|
660
|
+
typedef Map<const SVFFunction*, CallInstSet> FunToFJSites;
|
|
677
661
|
FunToFJSites funToFJSites;
|
|
678
662
|
|
|
679
|
-
for(ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
680
|
-
eit = tct->getThreadCallGraph()->forksitesEnd();
|
|
663
|
+
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
664
|
+
eit = tct->getThreadCallGraph()->forksitesEnd();
|
|
665
|
+
it != eit; ++it)
|
|
681
666
|
{
|
|
682
667
|
const SVFInstruction* fork = (*it)->getCallSite();
|
|
683
668
|
funToFJSites[fork->getFunction()].insert(fork);
|
|
684
669
|
}
|
|
685
670
|
|
|
686
|
-
for(ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
687
|
-
eit = tct->getThreadCallGraph()->joinsitesEnd();
|
|
671
|
+
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
672
|
+
eit = tct->getThreadCallGraph()->joinsitesEnd();
|
|
673
|
+
it != eit; ++it)
|
|
688
674
|
{
|
|
689
675
|
const SVFInstruction* join = (*it)->getCallSite();
|
|
690
676
|
funToFJSites[join->getFunction()].insert(join);
|
|
@@ -724,45 +710,45 @@ void ForkJoinAnalysis::collectSCEVInfo()
|
|
|
724
710
|
*/
|
|
725
711
|
void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
726
712
|
{
|
|
727
|
-
for(
|
|
713
|
+
for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
|
|
728
714
|
{
|
|
729
|
-
const CxtThread& ct =
|
|
730
|
-
const NodeID rootTid =
|
|
715
|
+
const CxtThread& ct = tpair.second->getCxtThread();
|
|
716
|
+
const NodeID rootTid = tpair.first;
|
|
731
717
|
clearFlagMap();
|
|
732
|
-
if(const SVFInstruction* forkInst = ct.getThread())
|
|
718
|
+
if (const SVFInstruction* forkInst = ct.getThread())
|
|
733
719
|
{
|
|
734
720
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
735
721
|
const SVFInstruction* exitInst = getExitInstOfParentRoutineFun(rootTid);
|
|
736
722
|
|
|
737
723
|
const InstVec& nextInsts = forkInst->getSuccInstructions();
|
|
738
|
-
for(
|
|
724
|
+
for (const SVFInstruction* ni : nextInsts)
|
|
739
725
|
{
|
|
740
|
-
CxtStmt cs(forkSiteCxt
|
|
741
|
-
markCxtStmtFlag(cs,TDAlive);
|
|
726
|
+
CxtStmt cs(forkSiteCxt, ni);
|
|
727
|
+
markCxtStmtFlag(cs, TDAlive);
|
|
742
728
|
}
|
|
743
729
|
|
|
744
|
-
while(!cxtStmtList.empty())
|
|
730
|
+
while (!cxtStmtList.empty())
|
|
745
731
|
{
|
|
746
732
|
CxtStmt cts = popFromCTSWorkList();
|
|
747
733
|
const SVFInstruction* curInst = cts.getStmt();
|
|
748
|
-
DBOUT(DMTA,outs() << "-----\nForkJoinAnalysis root thread: " <<
|
|
749
|
-
DBOUT(DMTA,cts.dump());
|
|
750
|
-
DBOUT(DMTA,outs() << "-----\n");
|
|
734
|
+
DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
|
|
735
|
+
DBOUT(DMTA, cts.dump());
|
|
736
|
+
DBOUT(DMTA, outs() << "-----\n");
|
|
751
737
|
PTACallGraph::FunctionSet callees;
|
|
752
|
-
if(isTDFork(curInst))
|
|
738
|
+
if (isTDFork(curInst))
|
|
753
739
|
{
|
|
754
|
-
handleFork(cts,rootTid);
|
|
740
|
+
handleFork(cts, rootTid);
|
|
755
741
|
}
|
|
756
|
-
else if(isTDJoin(curInst))
|
|
742
|
+
else if (isTDJoin(curInst))
|
|
757
743
|
{
|
|
758
|
-
handleJoin(cts,rootTid);
|
|
744
|
+
handleJoin(cts, rootTid);
|
|
759
745
|
}
|
|
760
|
-
else if(SVFUtil::isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
|
|
746
|
+
else if (SVFUtil::isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
|
|
761
747
|
{
|
|
762
748
|
|
|
763
|
-
handleCall(cts,rootTid);
|
|
749
|
+
handleCall(cts, rootTid);
|
|
764
750
|
}
|
|
765
|
-
else if(curInst->isRetInst())
|
|
751
|
+
else if (curInst->isRetInst())
|
|
766
752
|
{
|
|
767
753
|
handleRet(cts);
|
|
768
754
|
}
|
|
@@ -771,15 +757,14 @@ void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
|
771
757
|
handleIntra(cts);
|
|
772
758
|
}
|
|
773
759
|
|
|
774
|
-
if(curInst==exitInst)
|
|
760
|
+
if (curInst == exitInst)
|
|
775
761
|
{
|
|
776
|
-
if(getMarkedFlag(cts)!=TDAlive)
|
|
777
|
-
addToFullJoin(tct->getParentThread(rootTid),rootTid);
|
|
762
|
+
if (getMarkedFlag(cts) != TDAlive)
|
|
763
|
+
addToFullJoin(tct->getParentThread(rootTid), rootTid);
|
|
778
764
|
else
|
|
779
|
-
addToPartial(tct->getParentThread(rootTid),rootTid);
|
|
765
|
+
addToPartial(tct->getParentThread(rootTid), rootTid);
|
|
780
766
|
}
|
|
781
767
|
}
|
|
782
|
-
|
|
783
768
|
}
|
|
784
769
|
}
|
|
785
770
|
}
|
|
@@ -792,19 +777,20 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid)
|
|
|
792
777
|
|
|
793
778
|
assert(isTDFork(call));
|
|
794
779
|
CallICFGNode* cbn = getCBN(call);
|
|
795
|
-
if(getTCG()->hasThreadForkEdge(cbn))
|
|
780
|
+
if (getTCG()->hasThreadForkEdge(cbn))
|
|
796
781
|
{
|
|
797
782
|
for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
|
|
798
|
-
ecgIt = getTCG()->getForkEdgeEnd(cbn);
|
|
783
|
+
ecgIt = getTCG()->getForkEdgeEnd(cbn);
|
|
784
|
+
cgIt != ecgIt; ++cgIt)
|
|
799
785
|
{
|
|
800
786
|
const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction();
|
|
801
787
|
CallStrCxt newCxt = curCxt;
|
|
802
|
-
pushCxt(newCxt,call,callee);
|
|
803
|
-
CxtThread ct(newCxt,call);
|
|
804
|
-
if(getMarkedFlag(cts)!=TDAlive)
|
|
805
|
-
addToHBPair(rootTid,tct->getTCTNode(ct)->getId());
|
|
788
|
+
pushCxt(newCxt, call, callee);
|
|
789
|
+
CxtThread ct(newCxt, call);
|
|
790
|
+
if (getMarkedFlag(cts) != TDAlive)
|
|
791
|
+
addToHBPair(rootTid, tct->getTCTNode(ct)->getId());
|
|
806
792
|
else
|
|
807
|
-
addToHPPair(rootTid,tct->getTCTNode(ct)->getId());
|
|
793
|
+
addToHPPair(rootTid, tct->getTCTNode(ct)->getId());
|
|
808
794
|
}
|
|
809
795
|
}
|
|
810
796
|
handleIntra(cts);
|
|
@@ -818,56 +804,56 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
818
804
|
|
|
819
805
|
assert(isTDJoin(call));
|
|
820
806
|
CallICFGNode* cbn = getCBN(call);
|
|
821
|
-
if(getTCG()->hasCallGraphEdge(cbn))
|
|
807
|
+
if (getTCG()->hasCallGraphEdge(cbn))
|
|
822
808
|
{
|
|
823
809
|
const SVFInstruction* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
|
|
824
810
|
const SVFInstruction* joinSite = cts.getStmt();
|
|
825
811
|
|
|
826
|
-
if(isAliasedForkJoin(forkSite, joinSite))
|
|
812
|
+
if (isAliasedForkJoin(forkSite, joinSite))
|
|
827
813
|
{
|
|
828
|
-
if(hasJoinLoop(joinSite))
|
|
814
|
+
if (hasJoinLoop(joinSite))
|
|
829
815
|
{
|
|
830
816
|
LoopBBs& joinLoop = getJoinLoop(joinSite);
|
|
831
|
-
std::vector<const SVFBasicBlock*>
|
|
832
|
-
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(),exitbbs);
|
|
833
|
-
while(!exitbbs.empty())
|
|
817
|
+
std::vector<const SVFBasicBlock *> exitbbs;
|
|
818
|
+
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(), exitbbs);
|
|
819
|
+
while (!exitbbs.empty())
|
|
834
820
|
{
|
|
835
821
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
836
822
|
exitbbs.pop_back();
|
|
837
823
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
838
|
-
CxtStmt newCts(curCxt,svfEntryInst);
|
|
839
|
-
addDirectlyJoinTID(cts,rootTid);
|
|
840
|
-
if(isSameSCEV(forkSite,joinSite))
|
|
824
|
+
CxtStmt newCts(curCxt, svfEntryInst);
|
|
825
|
+
addDirectlyJoinTID(cts, rootTid);
|
|
826
|
+
if (isSameSCEV(forkSite, joinSite))
|
|
841
827
|
{
|
|
842
|
-
markCxtStmtFlag(newCts,TDDead);
|
|
843
|
-
addSymmetricLoopJoin(cts,joinLoop);
|
|
828
|
+
markCxtStmtFlag(newCts, TDDead);
|
|
829
|
+
addSymmetricLoopJoin(cts, joinLoop);
|
|
844
830
|
}
|
|
845
831
|
else
|
|
846
|
-
markCxtStmtFlag(cts,TDAlive);
|
|
832
|
+
markCxtStmtFlag(cts, TDAlive);
|
|
847
833
|
}
|
|
848
834
|
}
|
|
849
835
|
else
|
|
850
836
|
{
|
|
851
|
-
markCxtStmtFlag(cts,TDDead);
|
|
852
|
-
addDirectlyJoinTID(cts,rootTid);
|
|
853
|
-
DBOUT(DMTA,outs() << "\n\t match join site " << call->toString() <<
|
|
837
|
+
markCxtStmtFlag(cts, TDDead);
|
|
838
|
+
addDirectlyJoinTID(cts, rootTid);
|
|
839
|
+
DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
|
|
854
840
|
}
|
|
855
841
|
}
|
|
856
842
|
/// for the join site in a loop loop which does not join the current thread
|
|
857
843
|
/// we process the loop exit
|
|
858
844
|
else
|
|
859
845
|
{
|
|
860
|
-
if(hasJoinLoop(joinSite))
|
|
846
|
+
if (hasJoinLoop(joinSite))
|
|
861
847
|
{
|
|
862
|
-
std::vector<const SVFBasicBlock*>
|
|
863
|
-
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(),exitbbs);
|
|
864
|
-
while(!exitbbs.empty())
|
|
848
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
849
|
+
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(), exitbbs);
|
|
850
|
+
while (!exitbbs.empty())
|
|
865
851
|
{
|
|
866
852
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
867
853
|
exitbbs.pop_back();
|
|
868
854
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
869
|
-
CxtStmt newCts(curCxt,svfEntryInst);
|
|
870
|
-
markCxtStmtFlag(newCts,cts);
|
|
855
|
+
CxtStmt newCts(curCxt, svfEntryInst);
|
|
856
|
+
markCxtStmtFlag(newCts, cts);
|
|
871
857
|
}
|
|
872
858
|
}
|
|
873
859
|
}
|
|
@@ -882,19 +868,20 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid)
|
|
|
882
868
|
const SVFInstruction* call = cts.getStmt();
|
|
883
869
|
const CallStrCxt& curCxt = cts.getContext();
|
|
884
870
|
CallICFGNode* cbn = getCBN(call);
|
|
885
|
-
if(getTCG()->hasCallGraphEdge(cbn))
|
|
871
|
+
if (getTCG()->hasCallGraphEdge(cbn))
|
|
886
872
|
{
|
|
887
873
|
for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
|
|
888
|
-
ecgIt = getTCG()->getCallEdgeEnd(cbn);
|
|
874
|
+
ecgIt = getTCG()->getCallEdgeEnd(cbn);
|
|
875
|
+
cgIt != ecgIt; ++cgIt)
|
|
889
876
|
{
|
|
890
877
|
const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
|
|
891
878
|
if (isExtCall(svfcallee))
|
|
892
879
|
continue;
|
|
893
880
|
CallStrCxt newCxt = curCxt;
|
|
894
|
-
pushCxt(newCxt,call,svfcallee);
|
|
881
|
+
pushCxt(newCxt, call, svfcallee);
|
|
895
882
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
896
|
-
CxtStmt newCts(newCxt,svfEntryInst);
|
|
897
|
-
markCxtStmtFlag(newCts,cts);
|
|
883
|
+
CxtStmt newCts(newCxt, svfEntryInst);
|
|
884
|
+
markCxtStmtFlag(newCts, cts);
|
|
898
885
|
}
|
|
899
886
|
}
|
|
900
887
|
}
|
|
@@ -907,36 +894,37 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
|
907
894
|
const CallStrCxt& curCxt = cts.getContext();
|
|
908
895
|
|
|
909
896
|
PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFunction());
|
|
910
|
-
for
|
|
897
|
+
for (PTACallGraphEdge* edge : curFunNode->getInEdges())
|
|
911
898
|
{
|
|
912
|
-
|
|
913
|
-
if(SVFUtil::isa<ThreadForkEdge>(edge) || SVFUtil::isa<ThreadJoinEdge>(edge))
|
|
899
|
+
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
914
900
|
continue;
|
|
915
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit =
|
|
916
|
-
ecit =
|
|
901
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(),
|
|
902
|
+
ecit = edge->directCallsEnd();
|
|
903
|
+
cit != ecit; ++cit)
|
|
917
904
|
{
|
|
918
905
|
CallStrCxt newCxt = curCxt;
|
|
919
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
906
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
920
907
|
{
|
|
921
908
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
922
|
-
for(
|
|
909
|
+
for (const auto& ni : nextInsts)
|
|
923
910
|
{
|
|
924
|
-
CxtStmt newCts(newCxt
|
|
925
|
-
markCxtStmtFlag(newCts,cts);
|
|
911
|
+
CxtStmt newCts(newCxt, ni);
|
|
912
|
+
markCxtStmtFlag(newCts, cts);
|
|
926
913
|
}
|
|
927
914
|
}
|
|
928
915
|
}
|
|
929
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit =
|
|
930
|
-
ecit =
|
|
916
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
|
|
917
|
+
ecit = edge->indirectCallsEnd();
|
|
918
|
+
cit != ecit; ++cit)
|
|
931
919
|
{
|
|
932
920
|
CallStrCxt newCxt = curCxt;
|
|
933
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
921
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
934
922
|
{
|
|
935
923
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
936
|
-
for(
|
|
924
|
+
for (const auto& ni : nextInsts)
|
|
937
925
|
{
|
|
938
|
-
CxtStmt newCts(newCxt
|
|
939
|
-
markCxtStmtFlag(newCts,cts);
|
|
926
|
+
CxtStmt newCts(newCxt, ni);
|
|
927
|
+
markCxtStmtFlag(newCts, cts);
|
|
940
928
|
}
|
|
941
929
|
}
|
|
942
930
|
}
|
|
@@ -951,10 +939,10 @@ void ForkJoinAnalysis::handleIntra(const CxtStmt& cts)
|
|
|
951
939
|
const CallStrCxt& curCxt = cts.getContext();
|
|
952
940
|
|
|
953
941
|
const InstVec& nextInsts = curInst->getSuccInstructions();
|
|
954
|
-
for
|
|
942
|
+
for (const auto& ni: nextInsts)
|
|
955
943
|
{
|
|
956
|
-
CxtStmt newCts(curCxt
|
|
957
|
-
markCxtStmtFlag(newCts,cts);
|
|
944
|
+
CxtStmt newCts(curCxt, ni);
|
|
945
|
+
markCxtStmtFlag(newCts, cts);
|
|
958
946
|
}
|
|
959
947
|
}
|
|
960
948
|
|
|
@@ -967,26 +955,26 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs)
|
|
|
967
955
|
{
|
|
968
956
|
|
|
969
957
|
CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
|
|
970
|
-
if(it!=dirAndIndJoinMap.end())
|
|
958
|
+
if (it != dirAndIndJoinMap.end())
|
|
971
959
|
return it->second;
|
|
972
960
|
|
|
973
|
-
const NodeBS& directJoinTids =
|
|
961
|
+
const NodeBS& directJoinTids = getDirectlyJoinedTid(cs);
|
|
974
962
|
NodeBS allJoinTids = directJoinTids;
|
|
975
963
|
|
|
976
964
|
FIFOWorkList<NodeID> worklist;
|
|
977
|
-
for
|
|
965
|
+
for (unsigned id : directJoinTids)
|
|
978
966
|
{
|
|
979
|
-
worklist.push(
|
|
967
|
+
worklist.push(id);
|
|
980
968
|
}
|
|
981
969
|
|
|
982
|
-
while(!worklist.empty())
|
|
970
|
+
while (!worklist.empty())
|
|
983
971
|
{
|
|
984
972
|
NodeID tid = worklist.pop();
|
|
985
973
|
TCTNode* node = tct->getTCTNode(tid);
|
|
986
|
-
for(TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it!=eit; ++it)
|
|
974
|
+
for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
|
|
987
975
|
{
|
|
988
976
|
NodeID childTid = (*it)->getDstID();
|
|
989
|
-
if(isFullJoin(tid,childTid))
|
|
977
|
+
if (isFullJoin(tid, childTid))
|
|
990
978
|
{
|
|
991
979
|
allJoinTids.set(childTid);
|
|
992
980
|
worklist.push(childTid);
|
|
@@ -1051,7 +1039,7 @@ bool ForkJoinAnalysis::isSameSCEV(const SVFInstruction* forkSite, const SVFInstr
|
|
|
1051
1039
|
// return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
|
|
1052
1040
|
// else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
|
|
1053
1041
|
// return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
|
|
1054
|
-
// else if(SVFUtil::isa<GetElementPtrInst
|
|
1042
|
+
// else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
|
|
1055
1043
|
// return false;
|
|
1056
1044
|
// else
|
|
1057
1045
|
// return true;
|