svf-tools 1.0.976 → 1.0.978
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/Graphs/ThreadCallGraph.h +0 -6
- package/svf/include/MTA/LockAnalysis.h +41 -31
- package/svf/include/MTA/MHP.h +34 -54
- package/svf/include/MTA/MTAStat.h +1 -2
- package/svf/include/MTA/TCT.h +36 -18
- package/svf/include/Util/CxtStmt.h +13 -12
- package/svf/include/Util/Options.h +1 -20
- package/svf/include/Util/SVFUtil.h +8 -43
- package/svf/include/Util/ThreadAPI.h +42 -85
- package/svf/lib/Graphs/ThreadCallGraph.cpp +1 -73
- package/svf/lib/MTA/LockAnalysis.cpp +83 -75
- package/svf/lib/MTA/MHP.cpp +142 -121
- package/svf/lib/MTA/MTA.cpp +2 -40
- package/svf/lib/MTA/MTAStat.cpp +7 -33
- package/svf/lib/MTA/TCT.cpp +30 -30
- package/svf/lib/Util/CallGraphBuilder.cpp +0 -15
- package/svf/lib/Util/Options.cpp +0 -62
- package/svf/lib/Util/ThreadAPI.cpp +27 -6
- package/svf-llvm/lib/SVFIRExtAPI.cpp +0 -26
- package/svf-llvm/tools/MTA/CMakeLists.txt +1 -1
- package/svf-llvm/tools/MTA/mta.cpp +0 -8
- package/svf/include/MTA/FSMPTA.h +0 -270
- package/svf/include/MTA/MTAResultValidator.h +0 -448
- package/svf/include/MTA/PCG.h +0 -229
- package/svf/lib/MTA/FSMPTA.cpp +0 -792
- package/svf/lib/MTA/PCG.cpp +0 -364
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +0 -251
- package/svf-llvm/tools/MTA/LockResultValidator.h +0 -84
- package/svf-llvm/tools/MTA/MTAAnnotator.cpp +0 -293
- package/svf-llvm/tools/MTA/MTAAnnotator.h +0 -120
- package/svf-llvm/tools/MTA/MTAResultValidator.cpp +0 -716
- package/svf-llvm/tools/MTA/MTAResultValidator.h +0 -337
package/svf/lib/MTA/MHP.cpp
CHANGED
|
@@ -80,7 +80,7 @@ void MHP::analyzeInterleaving()
|
|
|
80
80
|
NodeID rootTid = tpair.first;
|
|
81
81
|
const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct);
|
|
82
82
|
const SVFInstruction* svfInst = routine->getEntryBlock()->front();
|
|
83
|
-
CxtThreadStmt rootcts(rootTid, ct.getContext(), svfInst);
|
|
83
|
+
CxtThreadStmt rootcts(rootTid, ct.getContext(), tct->getICFGNode(svfInst));
|
|
84
84
|
|
|
85
85
|
addInterleavingThread(rootcts, rootTid);
|
|
86
86
|
updateAncestorThreads(rootTid);
|
|
@@ -89,7 +89,7 @@ void MHP::analyzeInterleaving()
|
|
|
89
89
|
while (!cxtStmtList.empty())
|
|
90
90
|
{
|
|
91
91
|
CxtThreadStmt cts = popFromCTSWorkList();
|
|
92
|
-
const
|
|
92
|
+
const ICFGNode* curInst = cts.getStmt();
|
|
93
93
|
DBOUT(DMTA, outs() << "-----\nMHP analysis root thread: " << rootTid << " ");
|
|
94
94
|
DBOUT(DMTA, cts.dump());
|
|
95
95
|
DBOUT(DMTA, outs() << "current thread interleaving: < ");
|
|
@@ -97,7 +97,7 @@ void MHP::analyzeInterleaving()
|
|
|
97
97
|
DBOUT(DMTA, outs() << " >\n-----\n");
|
|
98
98
|
|
|
99
99
|
/// handle non-candidate function
|
|
100
|
-
if (!tct->isCandidateFun(curInst->
|
|
100
|
+
if (!tct->isCandidateFun(curInst->getFun()))
|
|
101
101
|
{
|
|
102
102
|
handleNonCandidateFun(cts);
|
|
103
103
|
}
|
|
@@ -112,14 +112,14 @@ void MHP::analyzeInterleaving()
|
|
|
112
112
|
{
|
|
113
113
|
handleJoin(cts, rootTid);
|
|
114
114
|
}
|
|
115
|
-
else if (
|
|
115
|
+
else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
|
|
116
116
|
{
|
|
117
117
|
handleCall(cts, rootTid);
|
|
118
118
|
CallGraph::FunctionSet callees;
|
|
119
|
-
if (!tct->isCandidateFun(getCallee(curInst, callees)))
|
|
119
|
+
if (!tct->isCandidateFun(getCallee(SVFUtil::cast<CallICFGNode>(curInst), callees)))
|
|
120
120
|
handleIntra(cts);
|
|
121
121
|
}
|
|
122
|
-
else if (curInst->isRetInst())
|
|
122
|
+
else if (isa<IntraICFGNode>(curInst) && cast<IntraICFGNode>(curInst)->getInst()->isRetInst())
|
|
123
123
|
{
|
|
124
124
|
handleRet(cts);
|
|
125
125
|
}
|
|
@@ -149,10 +149,12 @@ void MHP::updateNonCandidateFunInterleaving()
|
|
|
149
149
|
if (!tct->isCandidateFun(fun) && !isExtCall(fun))
|
|
150
150
|
{
|
|
151
151
|
const SVFInstruction* entryinst = fun->getEntryBlock()->front();
|
|
152
|
-
|
|
152
|
+
const ICFGNode* entryNode = tct->getICFGNode(entryinst);
|
|
153
|
+
|
|
154
|
+
if (!hasThreadStmtSet(entryNode))
|
|
153
155
|
continue;
|
|
154
156
|
|
|
155
|
-
const CxtThreadStmtSet& tsSet = getThreadStmtSet(
|
|
157
|
+
const CxtThreadStmtSet& tsSet = getThreadStmtSet(entryNode);
|
|
156
158
|
|
|
157
159
|
for (const CxtThreadStmt& cts : tsSet)
|
|
158
160
|
{
|
|
@@ -164,9 +166,10 @@ void MHP::updateNonCandidateFunInterleaving()
|
|
|
164
166
|
{
|
|
165
167
|
if (svfInst == entryinst)
|
|
166
168
|
continue;
|
|
167
|
-
|
|
169
|
+
const ICFGNode* curNode = tct->getICFGNode(svfInst);
|
|
170
|
+
CxtThreadStmt newCts(cts.getTid(), curCxt, curNode);
|
|
168
171
|
threadStmtToTheadInterLeav[newCts] |= threadStmtToTheadInterLeav[cts];
|
|
169
|
-
instToTSMap[
|
|
172
|
+
instToTSMap[curNode].insert(newCts);
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
}
|
|
@@ -179,9 +182,9 @@ void MHP::updateNonCandidateFunInterleaving()
|
|
|
179
182
|
*/
|
|
180
183
|
void MHP::handleNonCandidateFun(const CxtThreadStmt& cts)
|
|
181
184
|
{
|
|
182
|
-
const
|
|
183
|
-
const SVFFunction* curfun = curInst->
|
|
184
|
-
assert((curInst == curfun->getEntryBlock()->front()) && "curInst is not the entry of non candidate function.");
|
|
185
|
+
const ICFGNode* curInst = cts.getStmt();
|
|
186
|
+
const SVFFunction* curfun = curInst->getFun();
|
|
187
|
+
assert((curInst == tct->getICFGNode(curfun->getEntryBlock()->front())) && "curInst is not the entry of non candidate function.");
|
|
185
188
|
const CallStrCxt& curCxt = cts.getContext();
|
|
186
189
|
CallGraphNode* node = tcg->getCallGraphNode(curfun);
|
|
187
190
|
for (CallGraphNode::const_iterator nit = node->OutEdgeBegin(), neit = node->OutEdgeEnd(); nit != neit; nit++)
|
|
@@ -190,7 +193,7 @@ void MHP::handleNonCandidateFun(const CxtThreadStmt& cts)
|
|
|
190
193
|
if (!isExtCall(callee))
|
|
191
194
|
{
|
|
192
195
|
const SVFInstruction* calleeInst = callee->getEntryBlock()->front();
|
|
193
|
-
CxtThreadStmt newCts(cts.getTid(), curCxt, calleeInst);
|
|
196
|
+
CxtThreadStmt newCts(cts.getTid(), curCxt, tct->getICFGNode(calleeInst));
|
|
194
197
|
addInterleavingThread(newCts, cts);
|
|
195
198
|
}
|
|
196
199
|
}
|
|
@@ -202,11 +205,11 @@ void MHP::handleNonCandidateFun(const CxtThreadStmt& cts)
|
|
|
202
205
|
void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
203
206
|
{
|
|
204
207
|
|
|
205
|
-
const
|
|
208
|
+
const ICFGNode* call = cts.getStmt();
|
|
206
209
|
const CallStrCxt& curCxt = cts.getContext();
|
|
207
210
|
|
|
208
211
|
assert(isTDFork(call));
|
|
209
|
-
CallICFGNode* cbn =
|
|
212
|
+
const CallICFGNode* cbn = cast<CallICFGNode>(call);
|
|
210
213
|
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
211
214
|
{
|
|
212
215
|
|
|
@@ -216,10 +219,10 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
216
219
|
{
|
|
217
220
|
const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction();
|
|
218
221
|
CallStrCxt newCxt = curCxt;
|
|
219
|
-
pushCxt(newCxt,
|
|
222
|
+
pushCxt(newCxt, cbn, svfroutine);
|
|
220
223
|
const SVFInstruction* stmt = svfroutine->getEntryBlock()->front();
|
|
221
224
|
CxtThread ct(newCxt, call);
|
|
222
|
-
CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
|
|
225
|
+
CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), tct->getICFGNode(stmt));
|
|
223
226
|
addInterleavingThread(newcts, cts);
|
|
224
227
|
}
|
|
225
228
|
}
|
|
@@ -232,7 +235,7 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
232
235
|
void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
233
236
|
{
|
|
234
237
|
|
|
235
|
-
const
|
|
238
|
+
const ICFGNode* call = cts.getStmt();
|
|
236
239
|
const CallStrCxt& curCxt = cts.getContext();
|
|
237
240
|
|
|
238
241
|
assert(isTDJoin(call));
|
|
@@ -243,13 +246,13 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
243
246
|
if (fja->hasJoinLoop(call))
|
|
244
247
|
{
|
|
245
248
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
246
|
-
call->
|
|
249
|
+
call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
|
|
247
250
|
while (!exitbbs.empty())
|
|
248
251
|
{
|
|
249
252
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
250
253
|
exitbbs.pop_back();
|
|
251
254
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
252
|
-
CxtThreadStmt newCts(cts.getTid(), curCxt, svfEntryInst);
|
|
255
|
+
CxtThreadStmt newCts(cts.getTid(), curCxt, tct->getICFGNode(svfEntryInst));
|
|
253
256
|
addInterleavingThread(newCts, cts);
|
|
254
257
|
if (hasJoinInSymmetricLoop(curCxt, call))
|
|
255
258
|
rmInterleavingThread(newCts, joinedTids, call);
|
|
@@ -268,13 +271,13 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
268
271
|
if (fja->hasJoinLoop(call))
|
|
269
272
|
{
|
|
270
273
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
271
|
-
call->
|
|
274
|
+
call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
|
|
272
275
|
while (!exitbbs.empty())
|
|
273
276
|
{
|
|
274
277
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
275
278
|
exitbbs.pop_back();
|
|
276
279
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
277
|
-
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), svfEntryInst);
|
|
280
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), tct->getICFGNode(svfEntryInst));
|
|
278
281
|
addInterleavingThread(newCts, cts);
|
|
279
282
|
}
|
|
280
283
|
}
|
|
@@ -288,9 +291,9 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
288
291
|
void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
289
292
|
{
|
|
290
293
|
|
|
291
|
-
const
|
|
294
|
+
const ICFGNode* call = cts.getStmt();
|
|
292
295
|
const CallStrCxt& curCxt = cts.getContext();
|
|
293
|
-
CallICFGNode* cbn =
|
|
296
|
+
const CallICFGNode* cbn = cast<CallICFGNode>(call);
|
|
294
297
|
if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn))
|
|
295
298
|
{
|
|
296
299
|
for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn),
|
|
@@ -302,9 +305,10 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
302
305
|
if (isExtCall(svfcallee))
|
|
303
306
|
continue;
|
|
304
307
|
CallStrCxt newCxt = curCxt;
|
|
305
|
-
|
|
308
|
+
const CallICFGNode* callicfgnode = SVFUtil::cast<CallICFGNode>(call);
|
|
309
|
+
pushCxt(newCxt, callicfgnode, svfcallee);
|
|
306
310
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
307
|
-
CxtThreadStmt newCts(cts.getTid(), newCxt, svfEntryInst);
|
|
311
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, tct->getICFGNode(svfEntryInst));
|
|
308
312
|
addInterleavingThread(newCts, cts);
|
|
309
313
|
}
|
|
310
314
|
}
|
|
@@ -315,7 +319,7 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
315
319
|
*/
|
|
316
320
|
void MHP::handleRet(const CxtThreadStmt& cts)
|
|
317
321
|
{
|
|
318
|
-
CallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->
|
|
322
|
+
CallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun());
|
|
319
323
|
for (CallGraphEdge* edge : curFunNode->getInEdges())
|
|
320
324
|
{
|
|
321
325
|
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
@@ -325,13 +329,15 @@ void MHP::handleRet(const CxtThreadStmt& cts)
|
|
|
325
329
|
cit != ecit; ++cit)
|
|
326
330
|
{
|
|
327
331
|
CallStrCxt newCxt = cts.getContext();
|
|
328
|
-
if (matchCxt(newCxt,
|
|
332
|
+
if (matchCxt(newCxt, *cit, curFunNode->getFunction()))
|
|
329
333
|
{
|
|
330
|
-
const
|
|
331
|
-
for (const auto& ni : nextInsts)
|
|
334
|
+
for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
|
|
332
335
|
{
|
|
333
|
-
|
|
334
|
-
|
|
336
|
+
if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
|
|
337
|
+
{
|
|
338
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode());
|
|
339
|
+
addInterleavingThread(newCts, cts);
|
|
340
|
+
}
|
|
335
341
|
}
|
|
336
342
|
}
|
|
337
343
|
}
|
|
@@ -340,13 +346,15 @@ void MHP::handleRet(const CxtThreadStmt& cts)
|
|
|
340
346
|
cit != ecit; ++cit)
|
|
341
347
|
{
|
|
342
348
|
CallStrCxt newCxt = cts.getContext();
|
|
343
|
-
if (matchCxt(newCxt,
|
|
349
|
+
if (matchCxt(newCxt, *cit, curFunNode->getFunction()))
|
|
344
350
|
{
|
|
345
|
-
const
|
|
346
|
-
for (const auto& ni: nextInsts)
|
|
351
|
+
for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
|
|
347
352
|
{
|
|
348
|
-
|
|
349
|
-
|
|
353
|
+
if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
|
|
354
|
+
{
|
|
355
|
+
CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode());
|
|
356
|
+
addInterleavingThread(newCts, cts);
|
|
357
|
+
}
|
|
350
358
|
}
|
|
351
359
|
}
|
|
352
360
|
}
|
|
@@ -359,11 +367,13 @@ void MHP::handleRet(const CxtThreadStmt& cts)
|
|
|
359
367
|
void MHP::handleIntra(const CxtThreadStmt& cts)
|
|
360
368
|
{
|
|
361
369
|
|
|
362
|
-
const
|
|
363
|
-
for (const auto& ni: nextInsts)
|
|
370
|
+
for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
|
|
364
371
|
{
|
|
365
|
-
|
|
366
|
-
|
|
372
|
+
if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
|
|
373
|
+
{
|
|
374
|
+
CxtThreadStmt newCts(cts.getTid(), cts.getContext(), outEdge->getDstNode());
|
|
375
|
+
addInterleavingThread(newCts, cts);
|
|
376
|
+
}
|
|
367
377
|
}
|
|
368
378
|
}
|
|
369
379
|
|
|
@@ -381,14 +391,16 @@ void MHP::updateAncestorThreads(NodeID curTid)
|
|
|
381
391
|
for (const unsigned i : tds)
|
|
382
392
|
{
|
|
383
393
|
const CxtThread& ct = tct->getTCTNode(i)->getCxtThread();
|
|
384
|
-
if (const
|
|
394
|
+
if (const ICFGNode* forkInst = ct.getThread())
|
|
385
395
|
{
|
|
386
396
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
387
|
-
const
|
|
388
|
-
for (const auto& ni: nextInsts)
|
|
397
|
+
for(const ICFGEdge* outEdge : forkInst->getOutEdges())
|
|
389
398
|
{
|
|
390
|
-
|
|
391
|
-
|
|
399
|
+
if(outEdge->getDstNode()->getFun() == forkInst->getFun())
|
|
400
|
+
{
|
|
401
|
+
CxtThreadStmt cts(tct->getParentThread(i), forkSiteCxt, outEdge->getDstNode());
|
|
402
|
+
addInterleavingThread(cts, curTid);
|
|
403
|
+
}
|
|
392
404
|
}
|
|
393
405
|
}
|
|
394
406
|
}
|
|
@@ -419,7 +431,7 @@ void MHP::updateSiblingThreads(NodeID curTid)
|
|
|
419
431
|
const CxtThread& ct = tct->getTCTNode(stid)->getCxtThread();
|
|
420
432
|
const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct);
|
|
421
433
|
const SVFInstruction* stmt = routine->getEntryBlock()->front();
|
|
422
|
-
CxtThreadStmt cts(stid, ct.getContext(), stmt);
|
|
434
|
+
CxtThreadStmt cts(stid, ct.getContext(), tct->getICFGNode(stmt));
|
|
423
435
|
addInterleavingThread(cts, curTid);
|
|
424
436
|
}
|
|
425
437
|
|
|
@@ -467,7 +479,7 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
|
467
479
|
* (1) t is not a multiforked thread
|
|
468
480
|
* (2) the join site of t is not in recursion
|
|
469
481
|
*/
|
|
470
|
-
bool MHP::isMustJoin(NodeID curTid, const
|
|
482
|
+
bool MHP::isMustJoin(NodeID curTid, const ICFGNode* joinsite)
|
|
471
483
|
{
|
|
472
484
|
assert(isTDJoin(joinsite) && "not a join site!");
|
|
473
485
|
return !isMultiForkedThread(curTid) && !tct->isJoinSiteInRecursion(joinsite);
|
|
@@ -476,7 +488,7 @@ bool MHP::isMustJoin(NodeID curTid, const SVFInstruction* joinsite)
|
|
|
476
488
|
/*!
|
|
477
489
|
* Return thread id(s) which are directly or indirectly joined at this join site
|
|
478
490
|
*/
|
|
479
|
-
NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const
|
|
491
|
+
NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const ICFGNode* call)
|
|
480
492
|
{
|
|
481
493
|
CxtStmt cs(cxt, call);
|
|
482
494
|
return fja->getDirAndIndJoinedTid(cs);
|
|
@@ -485,14 +497,14 @@ NodeBS MHP::getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* c
|
|
|
485
497
|
/*!
|
|
486
498
|
* Whether a context-sensitive join satisfies symmetric loop pattern
|
|
487
499
|
*/
|
|
488
|
-
bool MHP::hasJoinInSymmetricLoop(const CallStrCxt& cxt, const
|
|
500
|
+
bool MHP::hasJoinInSymmetricLoop(const CallStrCxt& cxt, const ICFGNode* call) const
|
|
489
501
|
{
|
|
490
502
|
CxtStmt cs(cxt, call);
|
|
491
503
|
return fja->hasJoinInSymmetricLoop(cs);
|
|
492
504
|
}
|
|
493
505
|
|
|
494
506
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
495
|
-
const MHP::LoopBBs& MHP::getJoinInSymmetricLoop(const CallStrCxt& cxt, const
|
|
507
|
+
const MHP::LoopBBs& MHP::getJoinInSymmetricLoop(const CallStrCxt& cxt, const ICFGNode* call) const
|
|
496
508
|
{
|
|
497
509
|
CxtStmt cs(cxt, call);
|
|
498
510
|
return fja->getJoinInSymmetricLoop(cs);
|
|
@@ -541,7 +553,7 @@ bool MHP::isConnectedfromMain(const SVFFunction* fun)
|
|
|
541
553
|
* (2) t1!=t2 and t1 \in l2 and t2 \in l1
|
|
542
554
|
*/
|
|
543
555
|
|
|
544
|
-
bool MHP::mayHappenInParallelInst(const
|
|
556
|
+
bool MHP::mayHappenInParallelInst(const ICFGNode* i1, const ICFGNode* i2)
|
|
545
557
|
{
|
|
546
558
|
|
|
547
559
|
/// TODO: Any instruction in dead function is assumed no MHP with others
|
|
@@ -577,11 +589,11 @@ bool MHP::mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction
|
|
|
577
589
|
return false;
|
|
578
590
|
}
|
|
579
591
|
|
|
580
|
-
bool MHP::mayHappenInParallelCache(const
|
|
592
|
+
bool MHP::mayHappenInParallelCache(const ICFGNode* i1, const ICFGNode* i2)
|
|
581
593
|
{
|
|
582
|
-
if (!tct->isCandidateFun(i1->
|
|
594
|
+
if (!tct->isCandidateFun(i1->getFun()) && !tct->isCandidateFun(i2->getFun()))
|
|
583
595
|
{
|
|
584
|
-
FuncPair funpair = std::make_pair(i1->
|
|
596
|
+
FuncPair funpair = std::make_pair(i1->getFun(), i2->getFun());
|
|
585
597
|
FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
|
|
586
598
|
if (it == nonCandidateFuncMHPRelMap.end())
|
|
587
599
|
{
|
|
@@ -599,7 +611,7 @@ bool MHP::mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstructio
|
|
|
599
611
|
return mayHappenInParallelInst(i1, i2);
|
|
600
612
|
}
|
|
601
613
|
|
|
602
|
-
bool MHP::mayHappenInParallel(const
|
|
614
|
+
bool MHP::mayHappenInParallel(const ICFGNode* i1, const ICFGNode* i2)
|
|
603
615
|
{
|
|
604
616
|
numOfTotalQueries++;
|
|
605
617
|
|
|
@@ -611,7 +623,7 @@ bool MHP::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2
|
|
|
611
623
|
return mhp;
|
|
612
624
|
}
|
|
613
625
|
|
|
614
|
-
bool MHP::executedByTheSameThread(const
|
|
626
|
+
bool MHP::executedByTheSameThread(const ICFGNode* i1, const ICFGNode* i2)
|
|
615
627
|
{
|
|
616
628
|
if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2))
|
|
617
629
|
return true;
|
|
@@ -637,8 +649,7 @@ void MHP::printInterleaving()
|
|
|
637
649
|
for (const auto& pair : threadStmtToTheadInterLeav)
|
|
638
650
|
{
|
|
639
651
|
outs() << "( t" << pair.first.getTid()
|
|
640
|
-
<<
|
|
641
|
-
<< "$" << pair.first.getStmt()->toString() << " ) ==> [";
|
|
652
|
+
<< pair.first.getStmt()->toString() << " ) ==> [";
|
|
642
653
|
for (unsigned i : pair.second)
|
|
643
654
|
{
|
|
644
655
|
outs() << " " << i << " ";
|
|
@@ -655,25 +666,25 @@ void MHP::printInterleaving()
|
|
|
655
666
|
*/
|
|
656
667
|
void ForkJoinAnalysis::collectSCEVInfo()
|
|
657
668
|
{
|
|
658
|
-
typedef Set<const
|
|
659
|
-
typedef Map<const SVFFunction*, CallInstSet> FunToFJSites;
|
|
660
|
-
FunToFJSites funToFJSites;
|
|
669
|
+
// typedef Set<const ICFGNode*> CallInstSet;
|
|
670
|
+
// typedef Map<const SVFFunction*, CallInstSet> FunToFJSites;
|
|
671
|
+
// FunToFJSites funToFJSites;
|
|
661
672
|
|
|
662
|
-
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
{
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
}
|
|
673
|
+
// for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
|
|
674
|
+
// eit = tct->getThreadCallGraph()->forksitesEnd();
|
|
675
|
+
// it != eit; ++it)
|
|
676
|
+
// {
|
|
677
|
+
// const ICFGNode* fork = *it;
|
|
678
|
+
// funToFJSites[fork->getFun()].insert(fork);
|
|
679
|
+
// }
|
|
669
680
|
|
|
670
|
-
for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
{
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
}
|
|
681
|
+
// for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
|
|
682
|
+
// eit = tct->getThreadCallGraph()->joinsitesEnd();
|
|
683
|
+
// it != eit; ++it)
|
|
684
|
+
// {
|
|
685
|
+
// const ICFGNode* join = *it;
|
|
686
|
+
// funToFJSites[join->getFun()].insert(join);
|
|
687
|
+
// }
|
|
677
688
|
|
|
678
689
|
// for(FunToFJSites::const_iterator it = funToFJSites.begin(), eit = funToFJSites.end(); it!=eit; ++it)
|
|
679
690
|
// {
|
|
@@ -714,22 +725,24 @@ void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
|
714
725
|
const CxtThread& ct = tpair.second->getCxtThread();
|
|
715
726
|
const NodeID rootTid = tpair.first;
|
|
716
727
|
clearFlagMap();
|
|
717
|
-
if (const
|
|
728
|
+
if (const ICFGNode* forkInst = ct.getThread())
|
|
718
729
|
{
|
|
719
730
|
CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
|
|
720
|
-
const
|
|
731
|
+
const ICFGNode* exitInst = getExitInstOfParentRoutineFun(rootTid);
|
|
721
732
|
|
|
722
|
-
const
|
|
723
|
-
for (const SVFInstruction* ni : nextInsts)
|
|
733
|
+
for(const ICFGEdge* outEdge : forkInst->getOutEdges())
|
|
724
734
|
{
|
|
725
|
-
|
|
726
|
-
|
|
735
|
+
if(outEdge->getDstNode()->getFun() == forkInst->getFun())
|
|
736
|
+
{
|
|
737
|
+
CxtStmt newCts(forkSiteCxt, outEdge->getDstNode());
|
|
738
|
+
markCxtStmtFlag(newCts, TDAlive);
|
|
739
|
+
}
|
|
727
740
|
}
|
|
728
741
|
|
|
729
742
|
while (!cxtStmtList.empty())
|
|
730
743
|
{
|
|
731
744
|
CxtStmt cts = popFromCTSWorkList();
|
|
732
|
-
const
|
|
745
|
+
const ICFGNode* curInst = cts.getStmt();
|
|
733
746
|
DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
|
|
734
747
|
DBOUT(DMTA, cts.dump());
|
|
735
748
|
DBOUT(DMTA, outs() << "-----\n");
|
|
@@ -742,12 +755,12 @@ void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
|
742
755
|
{
|
|
743
756
|
handleJoin(cts, rootTid);
|
|
744
757
|
}
|
|
745
|
-
else if (
|
|
758
|
+
else if (tct->isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
|
|
746
759
|
{
|
|
747
760
|
|
|
748
761
|
handleCall(cts, rootTid);
|
|
749
762
|
}
|
|
750
|
-
else if (curInst->isRetInst())
|
|
763
|
+
else if (isa<IntraICFGNode>(curInst) && cast<IntraICFGNode>(curInst)->getInst()->isRetInst())
|
|
751
764
|
{
|
|
752
765
|
handleRet(cts);
|
|
753
766
|
}
|
|
@@ -771,11 +784,11 @@ void ForkJoinAnalysis::analyzeForkJoinPair()
|
|
|
771
784
|
/// Handle fork
|
|
772
785
|
void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid)
|
|
773
786
|
{
|
|
774
|
-
const
|
|
787
|
+
const ICFGNode* call = cts.getStmt();
|
|
775
788
|
const CallStrCxt& curCxt = cts.getContext();
|
|
776
789
|
|
|
777
790
|
assert(isTDFork(call));
|
|
778
|
-
CallICFGNode* cbn =
|
|
791
|
+
const CallICFGNode* cbn = cast<CallICFGNode>(call);
|
|
779
792
|
if (getTCG()->hasThreadForkEdge(cbn))
|
|
780
793
|
{
|
|
781
794
|
for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
|
|
@@ -784,7 +797,7 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid)
|
|
|
784
797
|
{
|
|
785
798
|
const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction();
|
|
786
799
|
CallStrCxt newCxt = curCxt;
|
|
787
|
-
pushCxt(newCxt,
|
|
800
|
+
pushCxt(newCxt, cbn, callee);
|
|
788
801
|
CxtThread ct(newCxt, call);
|
|
789
802
|
if (getMarkedFlag(cts) != TDAlive)
|
|
790
803
|
addToHBPair(rootTid, tct->getTCTNode(ct)->getId());
|
|
@@ -798,15 +811,15 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid)
|
|
|
798
811
|
/// Handle join
|
|
799
812
|
void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
800
813
|
{
|
|
801
|
-
const
|
|
814
|
+
const ICFGNode* call = cts.getStmt();
|
|
802
815
|
const CallStrCxt& curCxt = cts.getContext();
|
|
803
816
|
|
|
804
817
|
assert(isTDJoin(call));
|
|
805
|
-
CallICFGNode* cbn =
|
|
818
|
+
const CallICFGNode* cbn = cast<CallICFGNode>(call);
|
|
806
819
|
if (getTCG()->hasCallGraphEdge(cbn))
|
|
807
820
|
{
|
|
808
|
-
const
|
|
809
|
-
const
|
|
821
|
+
const ICFGNode* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
|
|
822
|
+
const ICFGNode* joinSite = cts.getStmt();
|
|
810
823
|
|
|
811
824
|
if (isAliasedForkJoin(forkSite, joinSite))
|
|
812
825
|
{
|
|
@@ -814,13 +827,13 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
814
827
|
{
|
|
815
828
|
LoopBBs& joinLoop = getJoinLoop(joinSite);
|
|
816
829
|
std::vector<const SVFBasicBlock *> exitbbs;
|
|
817
|
-
joinSite->
|
|
830
|
+
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|
|
818
831
|
while (!exitbbs.empty())
|
|
819
832
|
{
|
|
820
833
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
821
834
|
exitbbs.pop_back();
|
|
822
835
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
823
|
-
CxtStmt newCts(curCxt, svfEntryInst);
|
|
836
|
+
CxtStmt newCts(curCxt, tct->getICFGNode(svfEntryInst));
|
|
824
837
|
addDirectlyJoinTID(cts, rootTid);
|
|
825
838
|
if (isSameSCEV(forkSite, joinSite))
|
|
826
839
|
{
|
|
@@ -845,13 +858,13 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
845
858
|
if (hasJoinLoop(joinSite))
|
|
846
859
|
{
|
|
847
860
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
848
|
-
joinSite->
|
|
861
|
+
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|
|
849
862
|
while (!exitbbs.empty())
|
|
850
863
|
{
|
|
851
864
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
852
865
|
exitbbs.pop_back();
|
|
853
866
|
const SVFInstruction* svfEntryInst = eb->front();
|
|
854
|
-
CxtStmt newCts(curCxt, svfEntryInst);
|
|
867
|
+
CxtStmt newCts(curCxt, tct->getICFGNode(svfEntryInst));
|
|
855
868
|
markCxtStmtFlag(newCts, cts);
|
|
856
869
|
}
|
|
857
870
|
}
|
|
@@ -864,9 +877,9 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
864
877
|
void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid)
|
|
865
878
|
{
|
|
866
879
|
|
|
867
|
-
const
|
|
880
|
+
const ICFGNode* call = cts.getStmt();
|
|
868
881
|
const CallStrCxt& curCxt = cts.getContext();
|
|
869
|
-
CallICFGNode* cbn =
|
|
882
|
+
const CallICFGNode* cbn = SVFUtil::cast<CallICFGNode>(call);
|
|
870
883
|
if (getTCG()->hasCallGraphEdge(cbn))
|
|
871
884
|
{
|
|
872
885
|
for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
|
|
@@ -877,9 +890,9 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid)
|
|
|
877
890
|
if (isExtCall(svfcallee))
|
|
878
891
|
continue;
|
|
879
892
|
CallStrCxt newCxt = curCxt;
|
|
880
|
-
pushCxt(newCxt,
|
|
893
|
+
pushCxt(newCxt, cbn, svfcallee);
|
|
881
894
|
const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front();
|
|
882
|
-
CxtStmt newCts(newCxt, svfEntryInst);
|
|
895
|
+
CxtStmt newCts(newCxt, tct->getICFGNode(svfEntryInst));
|
|
883
896
|
markCxtStmtFlag(newCts, cts);
|
|
884
897
|
}
|
|
885
898
|
}
|
|
@@ -888,11 +901,10 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid)
|
|
|
888
901
|
/// Handle return
|
|
889
902
|
void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
890
903
|
{
|
|
891
|
-
|
|
892
|
-
const SVFInstruction* curInst = cts.getStmt();
|
|
904
|
+
const ICFGNode* curInst = cts.getStmt();
|
|
893
905
|
const CallStrCxt& curCxt = cts.getContext();
|
|
894
906
|
|
|
895
|
-
CallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->
|
|
907
|
+
CallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFun());
|
|
896
908
|
for (CallGraphEdge* edge : curFunNode->getInEdges())
|
|
897
909
|
{
|
|
898
910
|
if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
|
|
@@ -902,13 +914,16 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
|
902
914
|
cit != ecit; ++cit)
|
|
903
915
|
{
|
|
904
916
|
CallStrCxt newCxt = curCxt;
|
|
905
|
-
|
|
917
|
+
const ICFGNode* curNode = tct->getICFGNode((*cit)->getCallSite());
|
|
918
|
+
if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
|
|
906
919
|
{
|
|
907
|
-
const
|
|
908
|
-
for (const auto& ni : nextInsts)
|
|
920
|
+
for(const ICFGEdge* outEdge : curNode->getOutEdges())
|
|
909
921
|
{
|
|
910
|
-
|
|
911
|
-
|
|
922
|
+
if(outEdge->getDstNode()->getFun() == curNode->getFun())
|
|
923
|
+
{
|
|
924
|
+
CxtStmt newCts(newCxt, outEdge->getDstNode());
|
|
925
|
+
markCxtStmtFlag(newCts, cts);
|
|
926
|
+
}
|
|
912
927
|
}
|
|
913
928
|
}
|
|
914
929
|
}
|
|
@@ -917,13 +932,17 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
|
917
932
|
cit != ecit; ++cit)
|
|
918
933
|
{
|
|
919
934
|
CallStrCxt newCxt = curCxt;
|
|
920
|
-
|
|
935
|
+
const ICFGNode* curNode = tct->getICFGNode((*cit)->getCallSite());
|
|
936
|
+
|
|
937
|
+
if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
|
|
921
938
|
{
|
|
922
|
-
const
|
|
923
|
-
for (const auto& ni : nextInsts)
|
|
939
|
+
for(const ICFGEdge* outEdge : curNode->getOutEdges())
|
|
924
940
|
{
|
|
925
|
-
|
|
926
|
-
|
|
941
|
+
if(outEdge->getDstNode()->getFun() == curNode->getFun())
|
|
942
|
+
{
|
|
943
|
+
CxtStmt newCts(newCxt, outEdge->getDstNode());
|
|
944
|
+
markCxtStmtFlag(newCts, cts);
|
|
945
|
+
}
|
|
927
946
|
}
|
|
928
947
|
}
|
|
929
948
|
}
|
|
@@ -934,14 +953,16 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts)
|
|
|
934
953
|
void ForkJoinAnalysis::handleIntra(const CxtStmt& cts)
|
|
935
954
|
{
|
|
936
955
|
|
|
937
|
-
const
|
|
956
|
+
const ICFGNode* curInst = cts.getStmt();
|
|
938
957
|
const CallStrCxt& curCxt = cts.getContext();
|
|
939
958
|
|
|
940
|
-
const
|
|
941
|
-
for (const auto& ni: nextInsts)
|
|
959
|
+
for(const ICFGEdge* outEdge : curInst->getOutEdges())
|
|
942
960
|
{
|
|
943
|
-
|
|
944
|
-
|
|
961
|
+
if(outEdge->getDstNode()->getFun() == curInst->getFun())
|
|
962
|
+
{
|
|
963
|
+
CxtStmt newCts(curCxt, outEdge->getDstNode());
|
|
964
|
+
markCxtStmtFlag(newCts, cts);
|
|
965
|
+
}
|
|
945
966
|
}
|
|
946
967
|
}
|
|
947
968
|
|
|
@@ -1025,7 +1046,7 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs)
|
|
|
1025
1046
|
* pointers of fork thread and join thread should have same scev start and step.
|
|
1026
1047
|
* and should have same loop trip count
|
|
1027
1048
|
*/
|
|
1028
|
-
bool ForkJoinAnalysis::isSameSCEV(const
|
|
1049
|
+
bool ForkJoinAnalysis::isSameSCEV(const ICFGNode* forkSite, const ICFGNode* joinSite)
|
|
1029
1050
|
{
|
|
1030
1051
|
|
|
1031
1052
|
// const PTASCEV& forkse = fkjnToPTASCEVMap[forkSite];
|
|
@@ -1049,7 +1070,7 @@ bool ForkJoinAnalysis::isSameSCEV(const SVFInstruction* forkSite, const SVFInstr
|
|
|
1049
1070
|
/*!
|
|
1050
1071
|
* The fork and join have same loop trip count
|
|
1051
1072
|
*/
|
|
1052
|
-
bool ForkJoinAnalysis::sameLoopTripCount(const
|
|
1073
|
+
bool ForkJoinAnalysis::sameLoopTripCount(const ICFGNode* forkSite, const ICFGNode* joinSite)
|
|
1053
1074
|
{
|
|
1054
1075
|
|
|
1055
1076
|
// ScalarEvolution* forkSE = getSE(forkSite);
|