svf-tools 1.0.604 → 1.0.606
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 +216 -229
- 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())
|
|
@@ -185,8 +181,7 @@ void MHP::handleNonCandidateFun(const CxtThreadStmt& cts)
|
|
|
185
181
|
{
|
|
186
182
|
const SVFInstruction* curInst = cts.getStmt();
|
|
187
183
|
const SVFFunction* curfun = curInst->getParent()->getParent();
|
|
188
|
-
|
|
189
|
-
assert((curInst == svfInst) && "curInst is not the entry of non candidate function.");
|
|
184
|
+
assert((curInst == curfun->getEntryBlock()->front()) && "curInst is not the entry of non candidate function.");
|
|
190
185
|
const CallStrCxt& curCxt = cts.getContext();
|
|
191
186
|
PTACallGraphNode* node = tcg->getCallGraphNode(curfun);
|
|
192
187
|
for (PTACallGraphNode::const_iterator nit = node->OutEdgeBegin(), neit = node->OutEdgeEnd(); nit != neit; nit++)
|
|
@@ -212,19 +207,20 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
212
207
|
|
|
213
208
|
assert(isTDFork(call));
|
|
214
209
|
CallICFGNode* cbn = getCBN(call);
|
|
215
|
-
if(tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
210
|
+
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
216
211
|
{
|
|
217
212
|
|
|
218
213
|
for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(cbn),
|
|
219
|
-
ecgIt = tcg->getForkEdgeEnd(cbn);
|
|
214
|
+
ecgIt = tcg->getForkEdgeEnd(cbn);
|
|
215
|
+
cgIt != ecgIt; ++cgIt)
|
|
220
216
|
{
|
|
221
217
|
const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction();
|
|
222
218
|
CallStrCxt newCxt = curCxt;
|
|
223
|
-
pushCxt(newCxt,call,svfroutine);
|
|
219
|
+
pushCxt(newCxt, call, svfroutine);
|
|
224
220
|
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);
|
|
221
|
+
CxtThread ct(newCxt, call);
|
|
222
|
+
CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
|
|
223
|
+
addInterleavingThread(newcts, cts);
|
|
228
224
|
}
|
|
229
225
|
}
|
|
230
226
|
handleIntra(cts);
|
|
@@ -241,45 +237,45 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
241
237
|
|
|
242
238
|
assert(isTDJoin(call));
|
|
243
239
|
|
|
244
|
-
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt,call);
|
|
245
|
-
if(!joinedTids.empty())
|
|
240
|
+
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt, call);
|
|
241
|
+
if (!joinedTids.empty())
|
|
246
242
|
{
|
|
247
|
-
if(fja->hasJoinLoop(call))
|
|
243
|
+
if (fja->hasJoinLoop(call))
|
|
248
244
|
{
|
|
249
|
-
std::vector<const SVFBasicBlock*>
|
|
250
|
-
call->getFunction()->getExitBlocksOfLoop(call->getParent(),exitbbs);
|
|
251
|
-
while(!exitbbs.empty())
|
|
245
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
246
|
+
call->getFunction()->getExitBlocksOfLoop(call->getParent(), exitbbs);
|
|
247
|
+
while (!exitbbs.empty())
|
|
252
248
|
{
|
|
253
249
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
254
250
|
exitbbs.pop_back();
|
|
255
251
|
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);
|
|
252
|
+
CxtThreadStmt newCts(cts.getTid(), curCxt, svfEntryInst);
|
|
253
|
+
addInterleavingThread(newCts, cts);
|
|
254
|
+
if (hasJoinInSymmetricLoop(curCxt, call))
|
|
255
|
+
rmInterleavingThread(newCts, joinedTids, call);
|
|
260
256
|
}
|
|
261
257
|
}
|
|
262
258
|
else
|
|
263
259
|
{
|
|
264
|
-
rmInterleavingThread(cts,joinedTids,call);
|
|
265
|
-
DBOUT(DMTA,outs() << "\n\t match join site " << call->toString() <<
|
|
260
|
+
rmInterleavingThread(cts, joinedTids, call);
|
|
261
|
+
DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << " for thread " << rootTid << "\n");
|
|
266
262
|
}
|
|
267
263
|
}
|
|
268
264
|
/// for the join site in a loop loop which does not join the current thread
|
|
269
265
|
/// we process the loop exit
|
|
270
266
|
else
|
|
271
267
|
{
|
|
272
|
-
if(fja->hasJoinLoop(call))
|
|
268
|
+
if (fja->hasJoinLoop(call))
|
|
273
269
|
{
|
|
274
|
-
std::vector<const SVFBasicBlock*>
|
|
275
|
-
call->getFunction()->getExitBlocksOfLoop(call->getParent(),exitbbs);
|
|
276
|
-
while(!exitbbs.empty())
|
|
270
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
271
|
+
call->getFunction()->getExitBlocksOfLoop(call->getParent(), exitbbs);
|
|
272
|
+
while (!exitbbs.empty())
|
|
277
273
|
{
|
|
278
274
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
279
275
|
exitbbs.pop_back();
|
|
280
276
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
281
|
-
CxtThreadStmt newCts(cts.getTid(),cts.getContext(),svfEntryInst);
|
|
282
|
-
addInterleavingThread(newCts,cts);
|
|
277
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), svfEntryInst);
|
|
278
|
+
addInterleavingThread(newCts, cts);
|
|
283
279
|
}
|
|
284
280
|
}
|
|
285
281
|
}
|
|
@@ -295,20 +291,21 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
295
291
|
const SVFInstruction* call = cts.getStmt();
|
|
296
292
|
const CallStrCxt& curCxt = cts.getContext();
|
|
297
293
|
CallICFGNode* cbn = getCBN(call);
|
|
298
|
-
if(tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
294
|
+
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
299
295
|
{
|
|
300
296
|
for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn),
|
|
301
|
-
ecgIt = tcg->getCallEdgeEnd(cbn);
|
|
297
|
+
ecgIt = tcg->getCallEdgeEnd(cbn);
|
|
298
|
+
cgIt != ecgIt; ++cgIt)
|
|
302
299
|
{
|
|
303
300
|
|
|
304
301
|
const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
|
|
305
302
|
if (isExtCall(svfcallee))
|
|
306
303
|
continue;
|
|
307
304
|
CallStrCxt newCxt = curCxt;
|
|
308
|
-
pushCxt(newCxt,call,svfcallee);
|
|
305
|
+
pushCxt(newCxt, call, svfcallee);
|
|
309
306
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
310
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt,svfEntryInst);
|
|
311
|
-
addInterleavingThread(newCts,cts);
|
|
307
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, svfEntryInst);
|
|
308
|
+
addInterleavingThread(newCts, cts);
|
|
312
309
|
}
|
|
313
310
|
}
|
|
314
311
|
}
|
|
@@ -318,38 +315,38 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
318
315
|
*/
|
|
319
316
|
void MHP::handleRet(const CxtThreadStmt& cts)
|
|
320
317
|
{
|
|
321
|
-
|
|
322
318
|
PTACallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getParent()->getParent());
|
|
323
|
-
for
|
|
319
|
+
for (PTACallGraphEdge* edge : curFunNode->getInEdges())
|
|
324
320
|
{
|
|
325
|
-
|
|
326
|
-
if(SVFUtil::isa<ThreadForkEdge>(edge) || SVFUtil::isa<ThreadJoinEdge>(edge))
|
|
321
|
+
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
327
322
|
continue;
|
|
328
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
|
|
329
|
-
ecit = (edge)->directCallsEnd();
|
|
323
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
|
|
324
|
+
ecit = (edge)->directCallsEnd();
|
|
325
|
+
cit != ecit; ++cit)
|
|
330
326
|
{
|
|
331
327
|
CallStrCxt newCxt = cts.getContext();
|
|
332
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
328
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
333
329
|
{
|
|
334
330
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
335
|
-
for(
|
|
331
|
+
for (const auto& ni : nextInsts)
|
|
336
332
|
{
|
|
337
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt
|
|
338
|
-
addInterleavingThread(newCts,cts);
|
|
333
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, ni);
|
|
334
|
+
addInterleavingThread(newCts, cts);
|
|
339
335
|
}
|
|
340
336
|
}
|
|
341
337
|
}
|
|
342
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
|
|
343
|
-
ecit = (edge)->indirectCallsEnd();
|
|
338
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
|
|
339
|
+
ecit = (edge)->indirectCallsEnd();
|
|
340
|
+
cit != ecit; ++cit)
|
|
344
341
|
{
|
|
345
342
|
CallStrCxt newCxt = cts.getContext();
|
|
346
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
343
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
347
344
|
{
|
|
348
345
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
349
|
-
for
|
|
346
|
+
for (const auto& ni: nextInsts)
|
|
350
347
|
{
|
|
351
|
-
CxtThreadStmt newCts(cts.getTid(),newCxt
|
|
352
|
-
addInterleavingThread(newCts,cts);
|
|
348
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, ni);
|
|
349
|
+
addInterleavingThread(newCts, cts);
|
|
353
350
|
}
|
|
354
351
|
}
|
|
355
352
|
}
|
|
@@ -363,36 +360,35 @@ void MHP::handleIntra(const CxtThreadStmt& cts)
|
|
|
363
360
|
{
|
|
364
361
|
|
|
365
362
|
const InstVec& nextInsts = cts.getStmt()->getSuccInstructions();
|
|
366
|
-
for
|
|
363
|
+
for (const auto& ni: nextInsts)
|
|
367
364
|
{
|
|
368
|
-
CxtThreadStmt newCts(cts.getTid(),cts.getContext()
|
|
369
|
-
addInterleavingThread(newCts,cts);
|
|
365
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), ni);
|
|
366
|
+
addInterleavingThread(newCts, cts);
|
|
370
367
|
}
|
|
371
368
|
}
|
|
372
369
|
|
|
373
|
-
|
|
374
370
|
/*!
|
|
375
371
|
* Update interleavings of ancestor threads according to TCT
|
|
376
372
|
*/
|
|
377
373
|
void MHP::updateAncestorThreads(NodeID curTid)
|
|
378
374
|
{
|
|
379
375
|
NodeBS tds = tct->getAncestorThread(curTid);
|
|
380
|
-
DBOUT(DMTA,outs() << "##Ancestor thread of " << curTid << " is : ");
|
|
381
|
-
DBOUT(DMTA,dumpSet(tds));
|
|
382
|
-
DBOUT(DMTA,outs() << "\n");
|
|
376
|
+
DBOUT(DMTA, outs() << "##Ancestor thread of " << curTid << " is : ");
|
|
377
|
+
DBOUT(DMTA, dumpSet(tds));
|
|
378
|
+
DBOUT(DMTA, outs() << "\n");
|
|
383
379
|
tds.set(curTid);
|
|
384
380
|
|
|
385
|
-
for(
|
|
381
|
+
for (const unsigned i : tds)
|
|
386
382
|
{
|
|
387
|
-
const CxtThread& ct = tct->getTCTNode(
|
|
388
|
-
if(const SVFInstruction* forkInst = ct.getThread())
|
|
383
|
+
const CxtThread& ct = tct->getTCTNode(i)->getCxtThread();
|
|
384
|
+
if (const SVFInstruction* forkInst = ct.getThread())
|
|
389
385
|
{
|
|
390
386
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
391
387
|
const InstVec& nextInsts = forkInst->getSuccInstructions();
|
|
392
|
-
for
|
|
388
|
+
for (const auto& ni: nextInsts)
|
|
393
389
|
{
|
|
394
|
-
CxtThreadStmt cts(tct->getParentThread(
|
|
395
|
-
addInterleavingThread(cts,curTid);
|
|
390
|
+
CxtThreadStmt cts(tct->getParentThread(i), forkSiteCxt, ni);
|
|
391
|
+
addInterleavingThread(cts, curTid);
|
|
396
392
|
}
|
|
397
393
|
}
|
|
398
394
|
}
|
|
@@ -412,25 +408,24 @@ void MHP::updateSiblingThreads(NodeID curTid)
|
|
|
412
408
|
{
|
|
413
409
|
NodeBS tds = tct->getAncestorThread(curTid);
|
|
414
410
|
tds.set(curTid);
|
|
415
|
-
for(
|
|
411
|
+
for (const unsigned tid : tds)
|
|
416
412
|
{
|
|
417
|
-
NodeBS
|
|
418
|
-
for(
|
|
413
|
+
NodeBS siblingTds = tct->getSiblingThread(tid);
|
|
414
|
+
for (const unsigned stid : siblingTds)
|
|
419
415
|
{
|
|
420
|
-
|
|
421
|
-
if((isHBPair(*cit,*it) && isRecurFullJoin(*cit,curTid)) || isHBPair(*it,*cit) )
|
|
416
|
+
if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid))
|
|
422
417
|
continue;
|
|
423
418
|
|
|
424
|
-
const CxtThread& ct = tct->getTCTNode(
|
|
419
|
+
const CxtThread& ct = tct->getTCTNode(stid)->getCxtThread();
|
|
425
420
|
const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct);
|
|
426
421
|
const SVFInstruction* stmt = routine->getEntryBlock()->front();
|
|
427
|
-
CxtThreadStmt cts(
|
|
428
|
-
addInterleavingThread(cts,curTid);
|
|
422
|
+
CxtThreadStmt cts(stid, ct.getContext(), stmt);
|
|
423
|
+
addInterleavingThread(cts, curTid);
|
|
429
424
|
}
|
|
430
425
|
|
|
431
|
-
DBOUT(DMTA,outs() << "##Sibling thread of " << curTid << " is : ");
|
|
432
|
-
DBOUT(DMTA,dumpSet(siblingTds));
|
|
433
|
-
DBOUT(DMTA,outs() << "\n");
|
|
426
|
+
DBOUT(DMTA, outs() << "##Sibling thread of " << curTid << " is : ");
|
|
427
|
+
DBOUT(DMTA, dumpSet(siblingTds));
|
|
428
|
+
DBOUT(DMTA, outs() << "\n");
|
|
434
429
|
}
|
|
435
430
|
}
|
|
436
431
|
|
|
@@ -439,24 +434,24 @@ void MHP::updateSiblingThreads(NodeID curTid)
|
|
|
439
434
|
*/
|
|
440
435
|
bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
441
436
|
{
|
|
442
|
-
if(parentTid==curTid)
|
|
437
|
+
if (parentTid == curTid)
|
|
443
438
|
return true;
|
|
444
439
|
|
|
445
440
|
const TCTNode* curNode = tct->getTCTNode(curTid);
|
|
446
441
|
FIFOWorkList<const TCTNode*> worklist;
|
|
447
442
|
worklist.push(curNode);
|
|
448
|
-
while(!worklist.empty())
|
|
443
|
+
while (!worklist.empty())
|
|
449
444
|
{
|
|
450
445
|
const TCTNode* node = worklist.pop();
|
|
451
|
-
for
|
|
446
|
+
for (TCTEdge* edge : node->getInEdges())
|
|
452
447
|
{
|
|
453
|
-
NodeID srcID =
|
|
454
|
-
if(fja->isFullJoin(srcID,node->getId()))
|
|
448
|
+
NodeID srcID = edge->getSrcID();
|
|
449
|
+
if (fja->isFullJoin(srcID, node->getId()))
|
|
455
450
|
{
|
|
456
|
-
if(srcID == parentTid)
|
|
451
|
+
if (srcID == parentTid)
|
|
457
452
|
return true;
|
|
458
453
|
else
|
|
459
|
-
worklist.push(
|
|
454
|
+
worklist.push(edge->getSrcNode());
|
|
460
455
|
}
|
|
461
456
|
else
|
|
462
457
|
{
|
|
@@ -467,7 +462,6 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
|
467
462
|
return false;
|
|
468
463
|
}
|
|
469
464
|
|
|
470
|
-
|
|
471
465
|
/*!
|
|
472
466
|
* A join site must join t if
|
|
473
467
|
* (1) t is not a multiforked thread
|
|
@@ -484,7 +478,7 @@ bool MHP::isMustJoin(NodeID curTid, const SVFInstruction* joinsite)
|
|
|
484
478
|
*/
|
|
485
479
|
NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* call)
|
|
486
480
|
{
|
|
487
|
-
CxtStmt cs(cxt,call);
|
|
481
|
+
CxtStmt cs(cxt, call);
|
|
488
482
|
return fja->getDirAndIndJoinedTid(cs);
|
|
489
483
|
}
|
|
490
484
|
|
|
@@ -493,29 +487,25 @@ NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* c
|
|
|
493
487
|
*/
|
|
494
488
|
bool MHP::hasJoinInSymmetricLoop(const CallStrCxt& cxt, const SVFInstruction* call) const
|
|
495
489
|
{
|
|
496
|
-
CxtStmt cs(cxt,call);
|
|
490
|
+
CxtStmt cs(cxt, call);
|
|
497
491
|
return fja->hasJoinInSymmetricLoop(cs);
|
|
498
492
|
}
|
|
499
493
|
|
|
500
|
-
|
|
501
494
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
502
495
|
const MHP::LoopBBs& MHP::getJoinInSymmetricLoop(const CallStrCxt& cxt, const SVFInstruction* call) const
|
|
503
496
|
{
|
|
504
|
-
CxtStmt cs(cxt,call);
|
|
497
|
+
CxtStmt cs(cxt, call);
|
|
505
498
|
return fja->getJoinInSymmetricLoop(cs);
|
|
506
499
|
}
|
|
507
500
|
|
|
508
|
-
|
|
509
501
|
/*!
|
|
510
502
|
* Whether two thread t1 happens-fore t2
|
|
511
503
|
*/
|
|
512
504
|
bool MHP::isHBPair(NodeID tid1, NodeID tid2)
|
|
513
505
|
{
|
|
514
|
-
return fja->isHBPair(tid1,tid2);
|
|
506
|
+
return fja->isHBPair(tid1, tid2);
|
|
515
507
|
}
|
|
516
508
|
|
|
517
|
-
|
|
518
|
-
|
|
519
509
|
bool MHP::isConnectedfromMain(const SVFFunction* fun)
|
|
520
510
|
{
|
|
521
511
|
PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun);
|
|
@@ -526,7 +516,7 @@ bool MHP::isConnectedfromMain(const SVFFunction* fun)
|
|
|
526
516
|
while (!worklist.empty())
|
|
527
517
|
{
|
|
528
518
|
const PTACallGraphNode* node = worklist.pop();
|
|
529
|
-
if("main" == node->getFunction()->getName())
|
|
519
|
+
if ("main" == node->getFunction()->getName())
|
|
530
520
|
return true;
|
|
531
521
|
for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
|
|
532
522
|
{
|
|
@@ -555,22 +545,20 @@ bool MHP::mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction
|
|
|
555
545
|
{
|
|
556
546
|
|
|
557
547
|
/// TODO: Any instruction in dead function is assumed no MHP with others
|
|
558
|
-
if(!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
548
|
+
if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
559
549
|
return false;
|
|
560
550
|
|
|
561
551
|
const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1);
|
|
562
552
|
const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2);
|
|
563
|
-
for(
|
|
553
|
+
for (const CxtThreadStmt& ts1 : tsSet1)
|
|
564
554
|
{
|
|
565
|
-
const CxtThreadStmt& ts1 = *it1;
|
|
566
555
|
NodeBS l1 = getInterleavingThreads(ts1);
|
|
567
|
-
for(
|
|
556
|
+
for (const CxtThreadStmt& ts2 : tsSet2)
|
|
568
557
|
{
|
|
569
|
-
const CxtThreadStmt& ts2 = *it2;
|
|
570
558
|
NodeBS l2 = getInterleavingThreads(ts2);
|
|
571
|
-
if(ts1.getTid()!=ts2.getTid())
|
|
559
|
+
if (ts1.getTid() != ts2.getTid())
|
|
572
560
|
{
|
|
573
|
-
if(l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
|
|
561
|
+
if (l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
|
|
574
562
|
{
|
|
575
563
|
numOfMHPQueries++;
|
|
576
564
|
return true;
|
|
@@ -591,11 +579,11 @@ bool MHP::mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction
|
|
|
591
579
|
|
|
592
580
|
bool MHP::mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
593
581
|
{
|
|
594
|
-
if(!tct->isCandidateFun(i1->getParent()->getParent())
|
|
582
|
+
if (!tct->isCandidateFun(i1->getParent()->getParent()) && !tct->isCandidateFun(i2->getParent()->getParent()))
|
|
595
583
|
{
|
|
596
584
|
FuncPair funpair = std::make_pair(i1->getFunction(), i2->getFunction());
|
|
597
585
|
FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
|
|
598
|
-
if (it==nonCandidateFuncMHPRelMap.end())
|
|
586
|
+
if (it == nonCandidateFuncMHPRelMap.end())
|
|
599
587
|
{
|
|
600
588
|
bool mhp = mayHappenInParallelInst(i1, i2);
|
|
601
589
|
nonCandidateFuncMHPRelMap[funpair] = mhp;
|
|
@@ -603,12 +591,12 @@ bool MHP::mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstructio
|
|
|
603
591
|
}
|
|
604
592
|
else
|
|
605
593
|
{
|
|
606
|
-
if(it->second)
|
|
594
|
+
if (it->second)
|
|
607
595
|
numOfMHPQueries++;
|
|
608
596
|
return it->second;
|
|
609
597
|
}
|
|
610
598
|
}
|
|
611
|
-
return mayHappenInParallelInst(i1,i2);
|
|
599
|
+
return mayHappenInParallelInst(i1, i2);
|
|
612
600
|
}
|
|
613
601
|
|
|
614
602
|
bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
@@ -616,7 +604,7 @@ bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2
|
|
|
616
604
|
numOfTotalQueries++;
|
|
617
605
|
|
|
618
606
|
DOTIMESTAT(double queryStart = PTAStat::getClk(true));
|
|
619
|
-
bool mhp=mayHappenInParallelCache(i1,i2);
|
|
607
|
+
bool mhp = mayHappenInParallelCache(i1, i2);
|
|
620
608
|
DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
|
|
621
609
|
DOTIMESTAT(interleavingQueriesTime += (queryEnd - queryStart) / TIMEINTERVAL);
|
|
622
610
|
|
|
@@ -625,45 +613,40 @@ bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2
|
|
|
625
613
|
|
|
626
614
|
bool MHP::executedByTheSameThread(const SVFInstruction* i1, const SVFInstruction* i2)
|
|
627
615
|
{
|
|
628
|
-
if(!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
616
|
+
if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
629
617
|
return true;
|
|
630
618
|
|
|
631
619
|
const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1);
|
|
632
620
|
const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2);
|
|
633
|
-
for
|
|
621
|
+
for (const CxtThreadStmt&ts1 : tsSet1)
|
|
634
622
|
{
|
|
635
|
-
const CxtThreadStmt&
|
|
636
|
-
for(CxtThreadStmtSet::const_iterator it2 = tsSet2.begin(), eit2 = tsSet2.end(); it2!=eit2; ++it2)
|
|
623
|
+
for (const CxtThreadStmt& ts2 : tsSet2)
|
|
637
624
|
{
|
|
638
|
-
|
|
639
|
-
if(ts1.getTid()!=ts2.getTid())
|
|
640
|
-
return false;
|
|
641
|
-
else if (isMultiForkedThread(ts1.getTid()))
|
|
625
|
+
if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid()))
|
|
642
626
|
return false;
|
|
643
627
|
}
|
|
644
628
|
}
|
|
645
629
|
return true;
|
|
646
630
|
}
|
|
647
631
|
|
|
648
|
-
|
|
649
632
|
/*!
|
|
650
633
|
* Print interleaving results
|
|
651
634
|
*/
|
|
652
635
|
void MHP::printInterleaving()
|
|
653
636
|
{
|
|
654
|
-
for(
|
|
637
|
+
for (const auto& pair : threadStmtToTheadInterLeav)
|
|
655
638
|
{
|
|
656
|
-
outs() << "( t" <<
|
|
657
|
-
|
|
658
|
-
|
|
639
|
+
outs() << "( t" << pair.first.getTid()
|
|
640
|
+
<< " , $" << pair.first.getStmt()->getSourceLoc()
|
|
641
|
+
<< "$" << pair.first.getStmt()->toString() << " ) ==> [";
|
|
642
|
+
for (unsigned i : pair.second)
|
|
659
643
|
{
|
|
660
|
-
outs() << " " <<
|
|
644
|
+
outs() << " " << i << " ";
|
|
661
645
|
}
|
|
662
646
|
outs() << "]\n";
|
|
663
647
|
}
|
|
664
648
|
}
|
|
665
649
|
|
|
666
|
-
|
|
667
650
|
/*!
|
|
668
651
|
* Collect SCEV pass information for pointers at fork/join sites
|
|
669
652
|
* Because ScalarEvolution is a function pass, previous knowledge of a function
|
|
@@ -673,18 +656,20 @@ void MHP::printInterleaving()
|
|
|
673
656
|
void ForkJoinAnalysis::collectSCEVInfo()
|
|
674
657
|
{
|
|
675
658
|
typedef Set<const SVFInstruction*> CallInstSet;
|
|
676
|
-
typedef Map<const SVFFunction*, CallInstSet
|
|
659
|
+
typedef Map<const SVFFunction*, CallInstSet> FunToFJSites;
|
|
677
660
|
FunToFJSites funToFJSites;
|
|
678
661
|
|
|
679
|
-
for(ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
680
|
-
eit = tct->getThreadCallGraph()->forksitesEnd();
|
|
662
|
+
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
663
|
+
eit = tct->getThreadCallGraph()->forksitesEnd();
|
|
664
|
+
it != eit; ++it)
|
|
681
665
|
{
|
|
682
666
|
const SVFInstruction* fork = (*it)->getCallSite();
|
|
683
667
|
funToFJSites[fork->getFunction()].insert(fork);
|
|
684
668
|
}
|
|
685
669
|
|
|
686
|
-
for(ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
687
|
-
eit = tct->getThreadCallGraph()->joinsitesEnd();
|
|
670
|
+
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
671
|
+
eit = tct->getThreadCallGraph()->joinsitesEnd();
|
|
672
|
+
it != eit; ++it)
|
|
688
673
|
{
|
|
689
674
|
const SVFInstruction* join = (*it)->getCallSite();
|
|
690
675
|
funToFJSites[join->getFunction()].insert(join);
|
|
@@ -724,45 +709,45 @@ void ForkJoinAnalysis::collectSCEVInfo()
|
|
|
724
709
|
*/
|
|
725
710
|
void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
726
711
|
{
|
|
727
|
-
for(
|
|
712
|
+
for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
|
|
728
713
|
{
|
|
729
|
-
const CxtThread& ct =
|
|
730
|
-
const NodeID rootTid =
|
|
714
|
+
const CxtThread& ct = tpair.second->getCxtThread();
|
|
715
|
+
const NodeID rootTid = tpair.first;
|
|
731
716
|
clearFlagMap();
|
|
732
|
-
if(const SVFInstruction* forkInst = ct.getThread())
|
|
717
|
+
if (const SVFInstruction* forkInst = ct.getThread())
|
|
733
718
|
{
|
|
734
719
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
735
720
|
const SVFInstruction* exitInst = getExitInstOfParentRoutineFun(rootTid);
|
|
736
721
|
|
|
737
722
|
const InstVec& nextInsts = forkInst->getSuccInstructions();
|
|
738
|
-
for(
|
|
723
|
+
for (const SVFInstruction* ni : nextInsts)
|
|
739
724
|
{
|
|
740
|
-
CxtStmt cs(forkSiteCxt
|
|
741
|
-
markCxtStmtFlag(cs,TDAlive);
|
|
725
|
+
CxtStmt cs(forkSiteCxt, ni);
|
|
726
|
+
markCxtStmtFlag(cs, TDAlive);
|
|
742
727
|
}
|
|
743
728
|
|
|
744
|
-
while(!cxtStmtList.empty())
|
|
729
|
+
while (!cxtStmtList.empty())
|
|
745
730
|
{
|
|
746
731
|
CxtStmt cts = popFromCTSWorkList();
|
|
747
732
|
const SVFInstruction* curInst = cts.getStmt();
|
|
748
|
-
DBOUT(DMTA,outs() << "-----\nForkJoinAnalysis root thread: " <<
|
|
749
|
-
DBOUT(DMTA,cts.dump());
|
|
750
|
-
DBOUT(DMTA,outs() << "-----\n");
|
|
733
|
+
DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
|
|
734
|
+
DBOUT(DMTA, cts.dump());
|
|
735
|
+
DBOUT(DMTA, outs() << "-----\n");
|
|
751
736
|
PTACallGraph::FunctionSet callees;
|
|
752
|
-
if(isTDFork(curInst))
|
|
737
|
+
if (isTDFork(curInst))
|
|
753
738
|
{
|
|
754
|
-
handleFork(cts,rootTid);
|
|
739
|
+
handleFork(cts, rootTid);
|
|
755
740
|
}
|
|
756
|
-
else if(isTDJoin(curInst))
|
|
741
|
+
else if (isTDJoin(curInst))
|
|
757
742
|
{
|
|
758
|
-
handleJoin(cts,rootTid);
|
|
743
|
+
handleJoin(cts, rootTid);
|
|
759
744
|
}
|
|
760
|
-
else if(SVFUtil::isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
|
|
745
|
+
else if (SVFUtil::isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
|
|
761
746
|
{
|
|
762
747
|
|
|
763
|
-
handleCall(cts,rootTid);
|
|
748
|
+
handleCall(cts, rootTid);
|
|
764
749
|
}
|
|
765
|
-
else if(curInst->isRetInst())
|
|
750
|
+
else if (curInst->isRetInst())
|
|
766
751
|
{
|
|
767
752
|
handleRet(cts);
|
|
768
753
|
}
|
|
@@ -771,15 +756,14 @@ void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
|
771
756
|
handleIntra(cts);
|
|
772
757
|
}
|
|
773
758
|
|
|
774
|
-
if(curInst==exitInst)
|
|
759
|
+
if (curInst == exitInst)
|
|
775
760
|
{
|
|
776
|
-
if(getMarkedFlag(cts)!=TDAlive)
|
|
777
|
-
addToFullJoin(tct->getParentThread(rootTid),rootTid);
|
|
761
|
+
if (getMarkedFlag(cts) != TDAlive)
|
|
762
|
+
addToFullJoin(tct->getParentThread(rootTid), rootTid);
|
|
778
763
|
else
|
|
779
|
-
addToPartial(tct->getParentThread(rootTid),rootTid);
|
|
764
|
+
addToPartial(tct->getParentThread(rootTid), rootTid);
|
|
780
765
|
}
|
|
781
766
|
}
|
|
782
|
-
|
|
783
767
|
}
|
|
784
768
|
}
|
|
785
769
|
}
|
|
@@ -792,19 +776,20 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid)
|
|
|
792
776
|
|
|
793
777
|
assert(isTDFork(call));
|
|
794
778
|
CallICFGNode* cbn = getCBN(call);
|
|
795
|
-
if(getTCG()->hasThreadForkEdge(cbn))
|
|
779
|
+
if (getTCG()->hasThreadForkEdge(cbn))
|
|
796
780
|
{
|
|
797
781
|
for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
|
|
798
|
-
ecgIt = getTCG()->getForkEdgeEnd(cbn);
|
|
782
|
+
ecgIt = getTCG()->getForkEdgeEnd(cbn);
|
|
783
|
+
cgIt != ecgIt; ++cgIt)
|
|
799
784
|
{
|
|
800
785
|
const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction();
|
|
801
786
|
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());
|
|
787
|
+
pushCxt(newCxt, call, callee);
|
|
788
|
+
CxtThread ct(newCxt, call);
|
|
789
|
+
if (getMarkedFlag(cts) != TDAlive)
|
|
790
|
+
addToHBPair(rootTid, tct->getTCTNode(ct)->getId());
|
|
806
791
|
else
|
|
807
|
-
addToHPPair(rootTid,tct->getTCTNode(ct)->getId());
|
|
792
|
+
addToHPPair(rootTid, tct->getTCTNode(ct)->getId());
|
|
808
793
|
}
|
|
809
794
|
}
|
|
810
795
|
handleIntra(cts);
|
|
@@ -818,56 +803,56 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
818
803
|
|
|
819
804
|
assert(isTDJoin(call));
|
|
820
805
|
CallICFGNode* cbn = getCBN(call);
|
|
821
|
-
if(getTCG()->hasCallGraphEdge(cbn))
|
|
806
|
+
if (getTCG()->hasCallGraphEdge(cbn))
|
|
822
807
|
{
|
|
823
808
|
const SVFInstruction* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
|
|
824
809
|
const SVFInstruction* joinSite = cts.getStmt();
|
|
825
810
|
|
|
826
|
-
if(isAliasedForkJoin(forkSite, joinSite))
|
|
811
|
+
if (isAliasedForkJoin(forkSite, joinSite))
|
|
827
812
|
{
|
|
828
|
-
if(hasJoinLoop(joinSite))
|
|
813
|
+
if (hasJoinLoop(joinSite))
|
|
829
814
|
{
|
|
830
815
|
LoopBBs& joinLoop = getJoinLoop(joinSite);
|
|
831
|
-
std::vector<const SVFBasicBlock*>
|
|
832
|
-
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(),exitbbs);
|
|
833
|
-
while(!exitbbs.empty())
|
|
816
|
+
std::vector<const SVFBasicBlock *> exitbbs;
|
|
817
|
+
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(), exitbbs);
|
|
818
|
+
while (!exitbbs.empty())
|
|
834
819
|
{
|
|
835
820
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
836
821
|
exitbbs.pop_back();
|
|
837
822
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
838
|
-
CxtStmt newCts(curCxt,svfEntryInst);
|
|
839
|
-
addDirectlyJoinTID(cts,rootTid);
|
|
840
|
-
if(isSameSCEV(forkSite,joinSite))
|
|
823
|
+
CxtStmt newCts(curCxt, svfEntryInst);
|
|
824
|
+
addDirectlyJoinTID(cts, rootTid);
|
|
825
|
+
if (isSameSCEV(forkSite, joinSite))
|
|
841
826
|
{
|
|
842
|
-
markCxtStmtFlag(newCts,TDDead);
|
|
843
|
-
addSymmetricLoopJoin(cts,joinLoop);
|
|
827
|
+
markCxtStmtFlag(newCts, TDDead);
|
|
828
|
+
addSymmetricLoopJoin(cts, joinLoop);
|
|
844
829
|
}
|
|
845
830
|
else
|
|
846
|
-
markCxtStmtFlag(cts,TDAlive);
|
|
831
|
+
markCxtStmtFlag(cts, TDAlive);
|
|
847
832
|
}
|
|
848
833
|
}
|
|
849
834
|
else
|
|
850
835
|
{
|
|
851
|
-
markCxtStmtFlag(cts,TDDead);
|
|
852
|
-
addDirectlyJoinTID(cts,rootTid);
|
|
853
|
-
DBOUT(DMTA,outs() << "\n\t match join site " << call->toString() <<
|
|
836
|
+
markCxtStmtFlag(cts, TDDead);
|
|
837
|
+
addDirectlyJoinTID(cts, rootTid);
|
|
838
|
+
DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
|
|
854
839
|
}
|
|
855
840
|
}
|
|
856
841
|
/// for the join site in a loop loop which does not join the current thread
|
|
857
842
|
/// we process the loop exit
|
|
858
843
|
else
|
|
859
844
|
{
|
|
860
|
-
if(hasJoinLoop(joinSite))
|
|
845
|
+
if (hasJoinLoop(joinSite))
|
|
861
846
|
{
|
|
862
|
-
std::vector<const SVFBasicBlock*>
|
|
863
|
-
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(),exitbbs);
|
|
864
|
-
while(!exitbbs.empty())
|
|
847
|
+
std::vector<const SVFBasicBlock*> exitbbs;
|
|
848
|
+
joinSite->getFunction()->getExitBlocksOfLoop(joinSite->getParent(), exitbbs);
|
|
849
|
+
while (!exitbbs.empty())
|
|
865
850
|
{
|
|
866
851
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
867
852
|
exitbbs.pop_back();
|
|
868
853
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
869
|
-
CxtStmt newCts(curCxt,svfEntryInst);
|
|
870
|
-
markCxtStmtFlag(newCts,cts);
|
|
854
|
+
CxtStmt newCts(curCxt, svfEntryInst);
|
|
855
|
+
markCxtStmtFlag(newCts, cts);
|
|
871
856
|
}
|
|
872
857
|
}
|
|
873
858
|
}
|
|
@@ -882,19 +867,20 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid)
|
|
|
882
867
|
const SVFInstruction* call = cts.getStmt();
|
|
883
868
|
const CallStrCxt& curCxt = cts.getContext();
|
|
884
869
|
CallICFGNode* cbn = getCBN(call);
|
|
885
|
-
if(getTCG()->hasCallGraphEdge(cbn))
|
|
870
|
+
if (getTCG()->hasCallGraphEdge(cbn))
|
|
886
871
|
{
|
|
887
872
|
for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
|
|
888
|
-
ecgIt = getTCG()->getCallEdgeEnd(cbn);
|
|
873
|
+
ecgIt = getTCG()->getCallEdgeEnd(cbn);
|
|
874
|
+
cgIt != ecgIt; ++cgIt)
|
|
889
875
|
{
|
|
890
876
|
const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
|
|
891
877
|
if (isExtCall(svfcallee))
|
|
892
878
|
continue;
|
|
893
879
|
CallStrCxt newCxt = curCxt;
|
|
894
|
-
pushCxt(newCxt,call,svfcallee);
|
|
880
|
+
pushCxt(newCxt, call, svfcallee);
|
|
895
881
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
896
|
-
CxtStmt newCts(newCxt,svfEntryInst);
|
|
897
|
-
markCxtStmtFlag(newCts,cts);
|
|
882
|
+
CxtStmt newCts(newCxt, svfEntryInst);
|
|
883
|
+
markCxtStmtFlag(newCts, cts);
|
|
898
884
|
}
|
|
899
885
|
}
|
|
900
886
|
}
|
|
@@ -907,36 +893,37 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
|
907
893
|
const CallStrCxt& curCxt = cts.getContext();
|
|
908
894
|
|
|
909
895
|
PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFunction());
|
|
910
|
-
for
|
|
896
|
+
for (PTACallGraphEdge* edge : curFunNode->getInEdges())
|
|
911
897
|
{
|
|
912
|
-
|
|
913
|
-
if(SVFUtil::isa<ThreadForkEdge>(edge) || SVFUtil::isa<ThreadJoinEdge>(edge))
|
|
898
|
+
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
914
899
|
continue;
|
|
915
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit =
|
|
916
|
-
ecit =
|
|
900
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(),
|
|
901
|
+
ecit = edge->directCallsEnd();
|
|
902
|
+
cit != ecit; ++cit)
|
|
917
903
|
{
|
|
918
904
|
CallStrCxt newCxt = curCxt;
|
|
919
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
905
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
920
906
|
{
|
|
921
907
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
922
|
-
for(
|
|
908
|
+
for (const auto& ni : nextInsts)
|
|
923
909
|
{
|
|
924
|
-
CxtStmt newCts(newCxt
|
|
925
|
-
markCxtStmtFlag(newCts,cts);
|
|
910
|
+
CxtStmt newCts(newCxt, ni);
|
|
911
|
+
markCxtStmtFlag(newCts, cts);
|
|
926
912
|
}
|
|
927
913
|
}
|
|
928
914
|
}
|
|
929
|
-
for(PTACallGraphEdge::CallInstSet::const_iterator cit =
|
|
930
|
-
ecit =
|
|
915
|
+
for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
|
|
916
|
+
ecit = edge->indirectCallsEnd();
|
|
917
|
+
cit != ecit; ++cit)
|
|
931
918
|
{
|
|
932
919
|
CallStrCxt newCxt = curCxt;
|
|
933
|
-
if(matchCxt(newCxt,(*cit)->getCallSite(),curFunNode->getFunction()))
|
|
920
|
+
if (matchCxt(newCxt, (*cit)->getCallSite(), curFunNode->getFunction()))
|
|
934
921
|
{
|
|
935
922
|
const InstVec& nextInsts = (*cit)->getCallSite()->getSuccInstructions();
|
|
936
|
-
for(
|
|
923
|
+
for (const auto& ni : nextInsts)
|
|
937
924
|
{
|
|
938
|
-
CxtStmt newCts(newCxt
|
|
939
|
-
markCxtStmtFlag(newCts,cts);
|
|
925
|
+
CxtStmt newCts(newCxt, ni);
|
|
926
|
+
markCxtStmtFlag(newCts, cts);
|
|
940
927
|
}
|
|
941
928
|
}
|
|
942
929
|
}
|
|
@@ -951,10 +938,10 @@ void ForkJoinAnalysis::handleIntra(const CxtStmt& cts)
|
|
|
951
938
|
const CallStrCxt& curCxt = cts.getContext();
|
|
952
939
|
|
|
953
940
|
const InstVec& nextInsts = curInst->getSuccInstructions();
|
|
954
|
-
for
|
|
941
|
+
for (const auto& ni: nextInsts)
|
|
955
942
|
{
|
|
956
|
-
CxtStmt newCts(curCxt
|
|
957
|
-
markCxtStmtFlag(newCts,cts);
|
|
943
|
+
CxtStmt newCts(curCxt, ni);
|
|
944
|
+
markCxtStmtFlag(newCts, cts);
|
|
958
945
|
}
|
|
959
946
|
}
|
|
960
947
|
|
|
@@ -967,26 +954,26 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs)
|
|
|
967
954
|
{
|
|
968
955
|
|
|
969
956
|
CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
|
|
970
|
-
if(it!=dirAndIndJoinMap.end())
|
|
957
|
+
if (it != dirAndIndJoinMap.end())
|
|
971
958
|
return it->second;
|
|
972
959
|
|
|
973
|
-
const NodeBS& directJoinTids =
|
|
960
|
+
const NodeBS& directJoinTids = getDirectlyJoinedTid(cs);
|
|
974
961
|
NodeBS allJoinTids = directJoinTids;
|
|
975
962
|
|
|
976
963
|
FIFOWorkList<NodeID> worklist;
|
|
977
|
-
for
|
|
964
|
+
for (unsigned id : directJoinTids)
|
|
978
965
|
{
|
|
979
|
-
worklist.push(
|
|
966
|
+
worklist.push(id);
|
|
980
967
|
}
|
|
981
968
|
|
|
982
|
-
while(!worklist.empty())
|
|
969
|
+
while (!worklist.empty())
|
|
983
970
|
{
|
|
984
971
|
NodeID tid = worklist.pop();
|
|
985
972
|
TCTNode* node = tct->getTCTNode(tid);
|
|
986
|
-
for(TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it!=eit; ++it)
|
|
973
|
+
for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
|
|
987
974
|
{
|
|
988
975
|
NodeID childTid = (*it)->getDstID();
|
|
989
|
-
if(isFullJoin(tid,childTid))
|
|
976
|
+
if (isFullJoin(tid, childTid))
|
|
990
977
|
{
|
|
991
978
|
allJoinTids.set(childTid);
|
|
992
979
|
worklist.push(childTid);
|
|
@@ -1051,7 +1038,7 @@ bool ForkJoinAnalysis::isSameSCEV(const SVFInstruction* forkSite, const SVFInstr
|
|
|
1051
1038
|
// return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
|
|
1052
1039
|
// else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
|
|
1053
1040
|
// return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
|
|
1054
|
-
// else if(SVFUtil::isa<GetElementPtrInst
|
|
1041
|
+
// else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
|
|
1055
1042
|
// return false;
|
|
1056
1043
|
// else
|
|
1057
1044
|
// return true;
|