Static Value-Flow Analysis
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 
37 using namespace SVF;
38 using namespace SVFUtil;
39 
40 
42 {
43 
44  collectLockUnlocksites();
45  buildCandidateFuncSetforLock();
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");
51  analyzeIntraProcedualLock();
52 
53  DBOUT(DGENERAL, outs() << "\tCollect context-sensitive locks\n");
54  DBOUT(DMTA, outs() << "\tCollect context-sensitive locks\n");
55  collectCxtLock();
56 
57  DBOUT(DGENERAL, outs() << "\tInter-procedural LockAnalysis\n");
58  DBOUT(DMTA, outs() << "\tInter-procedural LockAnalysis\n");
59  analyzeLockSpanCxtStmt();
60 
61  DOTIMESTAT(double lockEnd = PTAStat::getClk(true));
62  DOTIMESTAT(lockTime += (lockEnd - lockStart) / TIMEINTERVAL);
63 }
64 
65 
70 {
71  ThreadCallGraph* tcg=tct->getThreadCallGraph();
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 
98  ThreadCallGraph* tcg=tct->getThreadCallGraph();
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();
106  PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun);
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();
116  PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun);
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
153  InstSet forwardInsts;
154  InstSet backwardInsts;
155  InstSet unlockSet;
156 
157  bool forward = intraForwardTraverse(lockSite,unlockSet,forwardInsts);
158  bool backward = intraBackwardTraverse(unlockSet,backwardInsts);
159 
161  if(forward && backward)
162  addIntraLock(lockSite,forwardInsts);
163  else if(forward && !backward)
164  addCondIntraLock(lockSite,forwardInsts);
165  }
166 }
167 
171 bool LockAnalysis::intraForwardTraverse(const ICFGNode* lockSite, InstSet& unlockSet, InstSet& forwardInsts)
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 
215 bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& backwardInsts)
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;
222  const ICFGNode* entryInst = unlockSite->getFun()->getEntryBlock()->back();
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 
238  if (isTDAcquire(I) && isAliasedLocks(unlockSite, I))
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);
268  pushToCTPWorkList(t);
269  }
270 
271  while (!clpList.empty())
272  {
273  CxtLockProc clp = popFromCTPWorkList();
274  PTACallGraphNode* cgNode = getTCG()->getCallGraphNode(clp.getProc());
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");
289  handleCallRelation(clp, cgEdge, *cit);
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");
298  handleCallRelation(clp, cgEdge, *ind);
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 
321  CxtLockProc newclp(cxt, svfcallee);
322  if (pushToCTPWorkList(newclp))
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();
340  CxtStmt cxtstmt(cxt, frontInst);
341  pushToCTSWorkList(cxtstmt);
342  }
343 
344  while (!cxtStmtList.empty())
345  {
346  CxtStmt cts = popFromCTSWorkList();
347 
348  touchCxtStmt(cts);
349  const ICFGNode* curInst = cts.getStmt();
350  instToCxtStmtSet[curInst].insert(cts);
351 
352  DBOUT(DMTA, outs() << "\nVisit cxtStmt: ");
353  DBOUT(DMTA, cts.dump());
354 
355  DBOUT(DMTA, outs() << "\nIts cxt lock sets: ");
356  DBOUT(DMTA, printLocks(cts));
357 
358  if (isTDFork(curInst))
359  {
360  handleFork(cts);
361  }
362  else if (isTDAcquire(curInst))
363  {
364  assert(hasCxtLock(cts) && "context-sensitive lock not found!!");
365  if(addCxtStmtToSpan(cts,cts))
366  handleIntra(cts);
367  }
368  else if (isTDRelease(curInst))
369  {
370  if(removeCxtStmtToSpan(cts,cts))
371  handleIntra(cts);
372  }
373  else if (isCallSite(curInst) && !isExtCall(curInst))
374  {
375  handleCall(cts);
376  }
377  else if (isRetInstNode(curInst))
378  {
379  handleRet(cts);
380  }
381  else
382  {
383  handleIntra(cts);
384  }
385 
386  }
387 
388 }
389 
390 
395 {
396  const CxtLockSet & lockset = getCxtLockfromCxtStmt(cts);
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();
417  CallStrCxt newCxt = curCxt;
418  pushCxt(newCxt,call,svfcallee);
419  const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
420  CxtStmt newCts(newCxt, svfInst);
421  markCxtStmtFlag(newCts, cts);
422  }
423  }
424  handleIntra(cts);
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();
439  if (SVFUtil::isExtCall(svfcallee))
440  continue;
441  CallStrCxt newCxt = curCxt;
442  pushCxt(newCxt, call, svfcallee);
443  const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
444  CxtStmt newCts(newCxt, svfInst);
445  markCxtStmtFlag(newCts, cts);
446  }
447  }
448 }
449 
452 {
453 
454  const ICFGNode* curInst = cts.getStmt();
455  const CallStrCxt& curCxt = cts.getContext();
456  const SVFFunction* svffun = curInst->getFun();
457  PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(svffun);
458 
459  for (PTACallGraphNode::const_iterator it = curFunNode->getInEdges().begin(), eit = curFunNode->getInEdges().end(); it != eit; ++it)
460  {
461  PTACallGraphEdge* edge = *it;
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  {
467  CallStrCxt newCxt = curCxt;
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());
476  markCxtStmtFlag(newCts, cts);
477  }
478  }
479  }
480  }
481  for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(), ecit = (edge)->indirectCallsEnd();
482  cit != ecit; ++cit)
483  {
484  CallStrCxt newCxt = curCxt;
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());
493  markCxtStmtFlag(newCts, cts);
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());
513  markCxtStmtFlag(newCts, cts);
514  }
515  }
516 }
517 
518 
519 void LockAnalysis::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
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 
535 bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
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 
564 {
565  numOfTotalQueries++;
566  bool commonlock = false;
567  DOTIMESTAT(double queryStart = PTAStat::getClk(true));
568  if (isInsideIntraLock(i1) && isInsideIntraLock(i2))
569  commonlock = isProtectedByCommonCILock(i1,i2) ;
570  else
571  commonlock = isProtectedByCommonCxtLock(i1,i2);
572  DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
573  DOTIMESTAT(lockQueriesTime += (queryEnd - queryStart) / TIMEINTERVAL);
574  return commonlock;
575 }
576 
581 {
582 
583  if(!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2))
584  {
585  const InstSet& lockset1 = getIntraLockSet(i1);
586  const InstSet& lockset2 = getIntraLockSet(i2);
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 
602 bool LockAnalysis::isProtectedByCommonCxtLock(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2)
603 {
604  if(!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2))
605  return true;
606  const CxtLockSet& lockset1 = getCxtLockfromCxtStmt(cxtStmt1);
607  const CxtLockSet& lockset2 = getCxtLockfromCxtStmt(cxtStmt2);
608  return alias(lockset1,lockset2);
609 }
610 
615 {
616  if(!hasCxtStmtfromInst(i1) || !hasCxtStmtfromInst(i2))
617  return false;
618  const CxtStmtSet& ctsset1 = getCxtStmtfromInst(i1);
619  const CxtStmtSet& ctsset2 = getCxtStmtfromInst(i2);
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;
627  if(isProtectedByCommonCxtLock(cxtStmt1,cxtStmt2)==false)
628  return false;
629  }
630  }
631  return true;
632 }
633 
634 
638 bool LockAnalysis::isInSameSpan(const ICFGNode *i1, const ICFGNode *i2)
639 {
640  DOTIMESTAT(double queryStart = PTAStat::getClk(true));
641 
642  bool sameSpan = false;
643  if (isInsideIntraLock(i1) && isInsideIntraLock(i2))
644  sameSpan = isInSameCISpan(i1, i2);
645  else
646  sameSpan = isInSameCSSpan(i1, i2);
647 
648  DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
649  DOTIMESTAT(lockQueriesTime += (queryEnd - queryStart) / TIMEINTERVAL);
650  return sameSpan;
651 }
652 
656 bool LockAnalysis::isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const
657 {
658  if(!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2))
659  {
660  const InstSet& lockset1 = getIntraLockSet(i1);
661  const InstSet& lockset2 = getIntraLockSet(i2);
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 
677 bool LockAnalysis::isInSameCSSpan(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) const
678 {
679  if(!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2))
680  return true;
681  const CxtLockSet& lockset1 = getCxtLockfromCxtStmt(cxtStmt1);
682  const CxtLockSet& lockset2 = getCxtLockfromCxtStmt(cxtStmt2);
683  return intersects(lockset1,lockset2);
684 }
688 bool LockAnalysis::isInSameCSSpan(const ICFGNode *I1, const ICFGNode *I2) const
689 {
690  if(!hasCxtStmtfromInst(I1) || !hasCxtStmtfromInst(I2))
691  return false;
692  const CxtStmtSet& ctsset1 = getCxtStmtfromInst(I1);
693  const CxtStmtSet& ctsset2 = getCxtStmtfromInst(I2);
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;
702  if(isInSameCSSpan(cxtStmt1,cxtStmt2)==false)
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
void dump() const
Dump CxtProc.
Definition: CxtStmt.h:379
const CallStrCxt & getContext() const
Return current context.
Definition: CxtStmt.h:332
const SVFFunction * getProc() const
Return current procedure.
Definition: CxtStmt.h:327
const CallStrCxt & getContext() const
Return current context.
Definition: CxtStmt.h:58
void dump() const
Dump CxtStmt.
Definition: CxtStmt.h:110
const ICFGNode * getStmt() const
Return current statement.
Definition: CxtStmt.h:63
bool push(const Data &data)
Definition: WorkList.h:165
bool empty() const
Definition: WorkList.h:146
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeType * getDstNode() const
Definition: GenericGraph.h:101
iterator OutEdgeEnd()
Definition: GenericGraph.h:458
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:454
iterator InEdgeBegin()
Definition: GenericGraph.h:462
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
iterator InEdgeEnd()
Definition: GenericGraph.h:466
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition: ICFGNode.h:76
void analyzeLockSpanCxtStmt()
Set< CxtLock > CxtLockSet
Definition: LockAnalysis.h:70
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()
Set< CxtStmt > CxtStmtSet
Definition: LockAnalysis.h:69
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
void handleFork(const CxtStmt &cts)
Handle fork.
bool intraBackwardTraverse(const InstSet &unlockset, InstSet &backwardInsts)
void handleIntra(const CxtStmt &cts)
Handle intra.
bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2)
void analyzeIntraProcedualLock()
void handleCall(const CxtStmt &cts)
Handle call.
void collectLockUnlocksites()
Set< const ICFGNode * > InstSet
Definition: LockAnalysis.h:61
Set< const SVFFunction * > FunSet
Definition: LockAnalysis.h:64
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.
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
TCT::InstVec InstVec
Definition: LockAnalysis.h:60
CallInstSet::const_iterator indirectCallsEnd() const
Definition: PTACallGraph.h:135
CallInstSet::const_iterator directCallsBegin() const
Iterators for direct and indirect callsites.
Definition: PTACallGraph.h:122
CallInstSet::const_iterator directCallsEnd() const
Definition: PTACallGraph.h:126
CallInstSet::const_iterator indirectCallsBegin() const
Definition: PTACallGraph.h:131
const SVFFunction * getFunction() const
Get function of this call node.
Definition: PTACallGraph.h:198
PTACallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator
Definition: PTACallGraph.h:180
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
Definition: PTACallGraph.h:339
virtual const std::string getSourceLoc() const
Definition: GenericGraph.h:281
const ICFGNode * front() const
Definition: SVFValue.h:594
const ICFGNode * back() const
Definition: SVFValue.h:600
const SVFBasicBlock * getEntryBlock() const
Definition: SVFValue.h:409
const SVFBasicBlock * getExitBB() const
Definition: SVFValue.cpp:186
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
Set< const PTACallGraphNode * > PTACGNodeSet
Definition: TCT.h:163
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
Definition: ThreadAPI.cpp:153
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
Definition: ThreadAPI.cpp:148
ThreadAPI * getThreadAPI() const
Thread API.
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
bool isCallSite(const SVFValue *val)
Whether an instruction is a call or invoke instruction.
Definition: SVFUtil.h:175
bool isRetInstNode(const ICFGNode *node)
Definition: SVFUtil.cpp:388
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned CallSiteID
Definition: GeneralType.h:58
std::vector< u32_t > CallStrCxt
Definition: GeneralType.h:122