Static Value-Flow Analysis
Loading...
Searching...
No Matches
LockAnalysis.cpp
Go to the documentation of this file.
1//===- LockAnalysis.cpp -- Analysis of locksets-------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * LocksetAnalysis.cpp
25 *
26 * Created on: 26 Aug 2015
27 * Author: pengd
28 */
29
30#include "Util/Options.h"
31#include "MTA/LockAnalysis.h"
32#include "MTA/MTA.h"
33#include "Util/SVFUtil.h"
34#include "Util/PTAStat.h"
35
36
37using namespace SVF;
38using namespace SVFUtil;
39
40
42{
43
46
47 DOTIMESTAT(double lockStart = PTAStat::getClk(true));
48
49 DBOUT(DGENERAL, outs() << "\tIntra-procedural LockAnalysis\n");
50 DBOUT(DMTA, outs() << "\tIntra-procedural LockAnalysis\n");
52
53 DBOUT(DGENERAL, outs() << "\tCollect context-sensitive locks\n");
54 DBOUT(DMTA, outs() << "\tCollect context-sensitive locks\n");
56
57 DBOUT(DGENERAL, outs() << "\tInter-procedural LockAnalysis\n");
58 DBOUT(DMTA, outs() << "\tInter-procedural LockAnalysis\n");
60
61 DOTIMESTAT(double lockEnd = PTAStat::getClk(true));
63}
64
65
70{
72
73 for (const SVFFunction* F : tct->getSVFModule()->getFunctionSet())
74 {
75 for (const SVFBasicBlock* bb : F->getBasicBlockList())
76 {
77 for (const ICFGNode* icfgNode : bb->getICFGNodeList())
78 {
79 if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDRelease(cast<CallICFGNode>(icfgNode)))
80 {
81 unlocksites.insert(icfgNode);
82 }
83 if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDAcquire(cast<CallICFGNode>(icfgNode)))
84 {
85 locksites.insert(icfgNode);
86 }
87 }
88 }
89 }
90}
91
96{
97
99
100 TCT::PTACGNodeSet visited;
102
103 for (InstSet::iterator it = locksites.begin(), eit = locksites.end(); it != eit; ++it)
104 {
105 const SVFFunction* fun=(*it)->getFun();
107 if (visited.find(cgnode) == visited.end())
108 {
109 worklist.push(cgnode);
110 visited.insert(cgnode);
111 }
112 }
113 for (InstSet::iterator it = unlocksites.begin(), eit = unlocksites.end(); it != eit; ++it)
114 {
115 const SVFFunction* fun = (*it)->getFun();
117 if (visited.find(cgnode) == visited.end())
118 {
119 worklist.push(cgnode);
120 visited.insert(cgnode);
121 }
122 }
123 while (!worklist.empty())
124 {
125 const PTACallGraphNode* node = worklist.pop();
126 lockcandidateFuncSet.insert(node->getFunction());
127 for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
128 {
129 const PTACallGraphNode* srcNode = (*nit)->getSrcNode();
130 if (visited.find(srcNode) == visited.end())
131 {
132 visited.insert(srcNode);
133 worklist.push(srcNode);
134 }
135 }
136 }
137}
138
144{
145
146 // Identify the protected Instructions.
147 for (InstSet::const_iterator it = locksites.begin(), ie = locksites.end(); it != ie; ++it)
148 {
149 const ICFGNode* lockSite = *it;
150 assert(isCallSite(lockSite) && "Lock acquire instruction must be a CallSite");
151
152 // Perform forward traversal
156
159
161 if(forward && backward)
163 else if(forward && !backward)
165 }
166}
167
172{
173
174 const SVFFunction* svfFun = lockSite->getFun();
175
176 InstVec worklist;
177 worklist.push_back(lockSite);
178 while (!worklist.empty())
179 {
180 const ICFGNode *I = worklist.back();
181 worklist.pop_back();
182 const ICFGNode* exitInst = svfFun->getExitBB()->back();
183 if(exitInst == I)
184 return false;
185
186 // Skip the visited Instructions.
187 if (forwardInsts.find(I)!=forwardInsts.end())
188 continue;
189 forwardInsts.insert(I);
190
191 if (isTDRelease(I) && isAliasedLocks(lockSite, I))
192 {
193 unlockSet.insert(I);
194 DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << lockSite->getSourceLoc()<<"\n");
195 DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << I->getSourceLoc()<<"\n");
196 continue;
197 }
198
199 for(const ICFGEdge* outEdge : I->getOutEdges())
200 {
201 if(outEdge->getDstNode()->getFun() == I->getFun())
202 {
203 worklist.push_back(outEdge->getDstNode());
204 }
205 }
206 }
207
208 return true;
209}
210
211
216{
217
218 InstVec worklist;
219 for(InstSet::const_iterator it = unlockSet.begin(), eit = unlockSet.end(); it!=eit; ++it)
220 {
221 const ICFGNode* unlockSite = *it;
223 worklist.push_back(*it);
224
225 while (!worklist.empty())
226 {
227 const ICFGNode *I = worklist.back();
228 worklist.pop_back();
229
230 if(entryInst == I)
231 return false;
232
233 // Skip the visited Instructions.
234 if (backwardInsts.find(I)!=backwardInsts.end())
235 continue;
236 backwardInsts.insert(I);
237
239 {
240 DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << I->getSourceLoc()<<"\n");
241 DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << unlockSite->getSourceLoc()<<"\n");
242 continue;
243 }
244
245 for(const ICFGEdge* inEdge : I->getInEdges())
246 {
247 if(inEdge->getSrcNode()->getFun() == I->getFun())
248 {
249 worklist.push_back(inEdge->getSrcNode());
250 }
251 }
252 }
253 }
254
255 return true;
256}
257
258
260{
261 FunSet entryFuncSet = tct->getEntryProcs();
262 for (FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it)
263 {
264 if (!isLockCandidateFun(*it))
265 continue;
266 CallStrCxt cxt;
267 CxtLockProc t(cxt, *it);
269 }
270
271 while (!clpList.empty())
272 {
275 // lzh TODO.
276 if (!isLockCandidateFun(cgNode->getFunction()))
277 continue;
278
279 for (PTACallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit != neit; nit++)
280 {
281 const PTACallGraphEdge* cgEdge = (*nit);
282
283 for (PTACallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(), ecit = cgEdge->directCallsEnd();
284 cit != ecit; ++cit)
285 {
286 DBOUT(DMTA,
287 outs() << "\nCollecting CxtLocks: handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName()
288 << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
290 }
291 for (PTACallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(), eind = cgEdge->indirectCallsEnd();
292 ind != eind; ++ind)
293 {
294 DBOUT(DMTA,
295 outs() << "\nCollecting CxtLocks: handling indirect call:" << **ind << "\t"
296 << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName()
297 << "\n");
299 }
300 }
301 }
302}
303
304
309{
310
311 CallStrCxt cxt(clp.getContext());
312 const ICFGNode* curNode = cs;
313 if (isTDAcquire(curNode))
314 {
315 addCxtLock(cxt,curNode);
316 return;
317 }
318 const SVFFunction* svfcallee = cgEdge->getDstNode()->getFunction();
319 pushCxt(cxt, SVFUtil::cast<CallICFGNode>(curNode), svfcallee);
320
323 {
324 DBOUT(DMTA, outs() << "LockAnalysis Process CallRet old clp --"; clp.dump());
325 DBOUT(DMTA, outs() << "LockAnalysis Process CallRet new clp --"; newclp.dump());
326 }
327
328}
329
331{
332
333 FunSet entryFuncSet = tct->getEntryProcs();
334 for (FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it)
335 {
336 if (!isLockCandidateFun(*it))
337 continue;
338 CallStrCxt cxt;
339 const ICFGNode* frontInst = (*it)->getEntryBlock()->front();
342 }
343
344 while (!cxtStmtList.empty())
345 {
347
349 const ICFGNode* curInst = cts.getStmt();
351
352 DBOUT(DMTA, outs() << "\nVisit cxtStmt: ");
353 DBOUT(DMTA, cts.dump());
354
355 DBOUT(DMTA, outs() << "\nIts cxt lock sets: ");
357
358 if (isTDFork(curInst))
359 {
361 }
362 else if (isTDAcquire(curInst))
363 {
364 assert(hasCxtLock(cts) && "context-sensitive lock not found!!");
367 }
368 else if (isTDRelease(curInst))
369 {
372 }
373 else if (isCallSite(curInst) && !isExtCall(curInst))
374 {
376 }
377 else if (isRetInstNode(curInst))
378 {
379 handleRet(cts);
380 }
381 else
382 {
384 }
385
386 }
387
388}
389
390
395{
397 outs() << "\nlock sets size = " << lockset.size() << "\n";
398 for (CxtLockSet::const_iterator it = lockset.begin(), eit = lockset.end(); it != eit; ++it)
399 {
400 (*it).dump();
401 }
402}
403
404
405
408{
409 const CallStrCxt& curCxt = cts.getContext();
410 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cts.getStmt());
411 if(getTCG()->hasThreadForkEdge(call))
412 {
413 for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(call),
414 ecgIt = getTCG()->getForkEdgeEnd(call); cgIt != ecgIt; ++cgIt)
415 {
416 const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
419 const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
422 }
423 }
425}
426
429{
430
431 const CallStrCxt& curCxt = cts.getContext();
432 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cts.getStmt());
433 if (getTCG()->hasCallGraphEdge(call))
434 {
435 for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(call), ecgIt = getTCG()->getCallEdgeEnd(call);
436 cgIt != ecgIt; ++cgIt)
437 {
438 const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
440 continue;
442 pushCxt(newCxt, call, svfcallee);
443 const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
446 }
447 }
448}
449
452{
453
454 const ICFGNode* curInst = cts.getStmt();
455 const CallStrCxt& curCxt = cts.getContext();
456 const SVFFunction* svffun = curInst->getFun();
458
459 for (PTACallGraphNode::const_iterator it = curFunNode->getInEdges().begin(), eit = curFunNode->getInEdges().end(); it != eit; ++it)
460 {
462 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
463 continue;
464 for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(), ecit = (edge)->directCallsEnd(); cit != ecit;
465 ++cit)
466 {
468 const ICFGNode* inst = *cit;
469 if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(inst), curFunNode->getFunction()))
470 {
471 for(const ICFGEdge* outEdge : curInst->getOutEdges())
472 {
473 if(outEdge->getDstNode()->getFun() == curInst->getFun())
474 {
475 CxtStmt newCts(newCxt, outEdge->getDstNode());
477 }
478 }
479 }
480 }
481 for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(), ecit = (edge)->indirectCallsEnd();
482 cit != ecit; ++cit)
483 {
485 const ICFGNode* inst = *cit;
486 if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(inst), curFunNode->getFunction()))
487 {
488 for(const ICFGEdge* outEdge : curInst->getOutEdges())
489 {
490 if(outEdge->getDstNode()->getFun() == curInst->getFun())
491 {
492 CxtStmt newCts(newCxt, outEdge->getDstNode());
494 }
495 }
496 }
497 }
498 }
499}
500
503{
504
505 const ICFGNode* curInst = cts.getStmt();
506 const CallStrCxt& curCxt = cts.getContext();
507
508 for(const ICFGEdge* outEdge : curInst->getOutEdges())
509 {
510 if(outEdge->getDstNode()->getFun() == curInst->getFun())
511 {
512 CxtStmt newCts(curCxt, outEdge->getDstNode());
514 }
515 }
516}
517
518
520{
521 const SVFFunction* svfcaller = call->getFun();
522 CallSiteID csId = getTCG()->getCallSiteID(call, callee);
523
524// /// handle calling context for candidate functions only
525// if (isLockCandidateFun(caller) == false)
526// return;
527
528 if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false)
529 {
530 tct->pushCxt(cxt,csId);
531 DBOUT(DMTA, tct->dumpCxt(cxt));
532 }
533}
534
536{
537 const SVFFunction* svfcaller = call->getFun();
538 CallSiteID csId = getTCG()->getCallSiteID(call, callee);
539
540// /// handle calling context for candidate functions only
541// if (isLockCandidateFun(caller) == false)
542// return true;
543
545 if (cxt.empty())
546 return true;
547
548 if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false)
549 {
550 if (cxt.back() == csId)
551 cxt.pop_back();
552 else
553 return false;
554 DBOUT(DMTA, tct->dumpCxt(cxt));
555 }
556 return true;
557}
558
559
576
581{
582
584 {
587 for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1)
588 {
589 for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2)
590 {
591 if (isAliasedLocks(*cil1, *cil2))
592 return true;
593 }
594 }
595 }
596 return false;
597}
598
610
615{
617 return false;
620 for (CxtStmtSet::const_iterator cts1 = ctsset1.begin(), ects1 = ctsset1.end(); cts1 != ects1; cts1++)
621 {
622 const CxtStmt& cxtStmt1 = *cts1;
623 for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++)
624 {
625 const CxtStmt& cxtStmt2 = *cts2;
626 if(cxtStmt1==cxtStmt2) continue;
628 return false;
629 }
630 }
631 return true;
632}
633
634
639{
640 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
641
642 bool sameSpan = false;
645 else
647
648 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
650 return sameSpan;
651}
652
657{
659 {
662 for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1)
663 {
664 for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2)
665 {
666 if (*cil1==*cil2)
667 return true;
668 }
669 }
670 }
671 return false;
672}
673
689{
691 return false;
694
695 for (CxtStmtSet::const_iterator cts1 = ctsset1.begin(), ects1 = ctsset1.end(); cts1 != ects1; cts1++)
696 {
697 const CxtStmt& cxtStmt1 = *cts1;
698 for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++)
699 {
700 const CxtStmt& cxtStmt2 = *cts2;
701 if(cxtStmt1==cxtStmt2) continue;
703 return false;
704 }
705 }
706 return true;
707}
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DMTA
Definition SVFType.h:505
#define DGENERAL
Definition SVFType.h:490
#define DOTIMESTAT(X)
Definition SVFType.h:486
bool push(const Data &data)
Definition WorkList.h:165
bool empty() const
Definition WorkList.h:146
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
GEdgeSetTy::const_iterator const_iterator
iterator InEdgeBegin()
iterator InEdgeEnd()
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:76
Set< CxtLock > CxtLockSet
bool removeCxtStmtToSpan(CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2)
bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2)
void buildCandidateFuncSetforLock()
void markCxtStmtFlag(const CxtStmt &tgr, const CxtStmt &src)
Mark thread flags for cxtStmt.
bool hasCxtLockfromCxtStmt(const CxtStmt &cts) const
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Set< CxtStmt > CxtStmtSet
bool alias(const CxtLockSet &lockset1, const CxtLockSet &lockset2)
Return true if two locksets has at least one alias lock.
CxtStmt popFromCTSWorkList()
FunSet lockcandidateFuncSet
Candidate functions which relevant to locks/unlocks.
bool isInsideIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside an intra-procedural lock.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
ThreadCallGraph * getTCG() const
ThreadCallGraph.
void handleFork(const CxtStmt &cts)
Handle fork.
bool isInsideCondIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional ...
bool intraBackwardTraverse(const InstSet &unlockset, InstSet &backwardInsts)
void addCondIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
bool hasCxtLock(const CxtLock &cxtLock) const
Get context-sensitive lock.
void handleIntra(const CxtStmt &cts)
Handle intra.
bool isTDRelease(const ICFGNode *call)
Whether it is a unlock site.
const CxtStmtSet & getCxtStmtfromInst(const ICFGNode *inst) const
bool addCxtStmtToSpan(const CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
bool isTDFork(const ICFGNode *call)
Whether it is a lock site.
InstSet locksites
Record all visited clps.
bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2)
void analyzeIntraProcedualLock()
bool pushToCTPWorkList(const CxtLockProc &clp)
WorkList helper functions.
const InstSet & getIntraLockSet(const ICFGNode *stmt) const
void handleCall(const CxtStmt &cts)
Handle call.
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
void addIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
void collectLockUnlocksites()
void touchCxtStmt(CxtStmt &cts)
Touch this context statement.
Set< const ICFGNode * > InstSet
Set< const SVFFunction * > FunSet
bool intraForwardTraverse(const ICFGNode *lock, InstSet &unlockset, InstSet &forwardInsts)
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
void printLocks(const CxtStmt &cts)
Print locks and spans.
CxtLockProc popFromCTPWorkList()
void handleRet(const CxtStmt &cts)
Handle return.
void handleCallRelation(CxtLockProc &clp, const PTACallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const
bool hasCxtStmtfromInst(const ICFGNode *inst) const
Context-sensitive statement and lock spans.
bool isAliasedLocks(const CxtLock &cl1, const CxtLock &cl2)
Return true it a lock matches an unlock.
bool isLockCandidateFun(const SVFFunction *fun) const
Return true if it is a candidate function.
InstToCxtStmtSet instToCxtStmtSet
Map a statement to all its context-sensitive statements.
TCT::InstVec InstVec
const CxtLockSet & getCxtLockfromCxtStmt(const CxtStmt &cts) const
void addCxtLock(const CallStrCxt &cxt, const ICFGNode *inst)
Context-sensitive locks.
bool intersects(const CxtLockSet &lockset1, const CxtLockSet &lockset2) const
Return true if the intersection of two locksets is not empty.
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
CxtLockProcVec clpList
Following data structures are used for collecting context-sensitive locks.
bool isTDAcquire(const ICFGNode *call)
Whether it is a lock site.
const SVFFunction * getFunction() const
Get function of this call node.
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *callee) const
Get CallSiteID.
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
virtual const std::string getSourceLoc() const
const ICFGNode * back() const
Definition SVFValue.h:611
const SVFBasicBlock * getEntryBlock() const
Definition SVFValue.h:420
const FunctionSetType & getFunctionSet() const
Definition SVFModule.h:199
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition TCT.cpp:445
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:196
SVFModule * getSVFModule() const
Get SVFFModule.
Definition TCT.h:190
bool inSameCallGraphSCC(const PTACallGraphNode *src, const PTACallGraphNode *dst)
Whether two functions in the same callgraph scc.
Definition TCT.h:306
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
Definition TCT.cpp:496
const FunSet & getEntryProcs() const
Get marked candidate functions.
Definition TCT.h:242
Set< const PTACallGraphNode * > PTACGNodeSet
Definition TCT.h:163
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
ThreadAPI * getThreadAPI() const
Thread API.
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:389
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
std::vector< u32_t > CallStrCxt