Static Value-Flow Analysis
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
SVF::ForkJoinAnalysis Class Reference

#include <MHP.h>

Public Types

enum  ValDomain { Empty , TDAlive , TDDead }
 semilattice Empty==>TDDead==>TDAlive More...
 
typedef SVFLoopAndDomInfo::LoopBBs LoopBBs
 
typedef TCT::InstVec InstVec
 
typedef Map< CxtStmt, ValDomainCxtStmtToAliveFlagMap
 
typedef Map< CxtStmt, NodeBSCxtStmtToTIDMap
 
typedef Set< NodePairThreadPairSet
 
typedef Map< CxtStmt, LoopBBsCxtStmtToLoopMap
 
typedef FIFOWorkList< CxtStmtCxtStmtWorkList
 

Public Member Functions

 ForkJoinAnalysis (TCT *t)
 
void collectSCEVInfo ()
 functions More...
 
void analyzeForkJoinPair ()
 
NodeBSgetDirectlyJoinedTid (const CxtStmt &cs)
 Get directly joined threadIDs based on a context-sensitive join site. More...
 
NodeBS getDirAndIndJoinedTid (const CxtStmt &cs)
 Get directly and indirectly joined threadIDs based on a context-sensitive join site. More...
 
const LoopBBsgetJoinInSymmetricLoop (const CxtStmt &cs) const
 Whether a context-sensitive join satisfies symmetric loop pattern. More...
 
bool hasJoinInSymmetricLoop (const CxtStmt &cs) const
 
bool isHBPair (NodeID tid1, NodeID tid2)
 Whether thread t1 happens-before thread t2. More...
 
bool isFullJoin (NodeID tid1, NodeID tid2)
 Whether t1 fully joins t2. More...
 
const ICFGNodegetExitInstOfParentRoutineFun (NodeID tid) const
 Get exit instruction of the start routine function of tid's parent thread. More...
 
LoopBBsgetJoinLoop (const CallICFGNode *inst)
 Get loop for join site. More...
 
bool hasJoinLoop (const CallICFGNode *inst)
 

Private Member Functions

void handleFork (const CxtStmt &cts, NodeID rootTid)
 Handle fork. More...
 
void handleJoin (const CxtStmt &cts, NodeID rootTid)
 Handle join. More...
 
void handleCall (const CxtStmt &cts, NodeID rootTid)
 Handle call. More...
 
void handleRet (const CxtStmt &cts)
 Handle return. More...
 
void handleIntra (const CxtStmt &cts)
 Handle intra. More...
 
bool isSameSCEV (const ICFGNode *forkSite, const ICFGNode *joinSite)
 Return true if the fork and join have the same SCEV. More...
 
bool sameLoopTripCount (const ICFGNode *forkSite, const ICFGNode *joinSite)
 Same loop trip count. More...
 
bool isAliasedForkJoin (const CallICFGNode *forkSite, const CallICFGNode *joinSite)
 Whether it is a matched fork join pair. More...
 
ValDomain getMarkedFlag (const CxtStmt &cs)
 Mark thread flags for cxtStmt. More...
 
void markCxtStmtFlag (const CxtStmt &tgr, ValDomain flag)
 Initialize TDAlive and TDDead flags. More...
 
void markCxtStmtFlag (const CxtStmt &tgr, const CxtStmt &src)
 Transfer function for marking context-sensitive statement. More...
 
void clearFlagMap ()
 Clear flags. More...
 
bool pushToCTSWorkList (const CxtStmt &cs)
 Worklist operations. More...
 
CxtStmt popFromCTSWorkList ()
 
void pushCxt (CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
 Push calling context. More...
 
bool matchCxt (CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
 Match context. More...
 
bool isTDFork (const ICFGNode *call)
 Whether it is a fork site. More...
 
bool isTDJoin (const ICFGNode *call)
 Whether it is a join site. More...
 
const SVFVargetForkedThread (const CallICFGNode *call)
 Get forked thread. More...
 
const SVFVargetJoinedThread (const CallICFGNode *call)
 Get joined thread. More...
 
const PTACallGraph::FunctionSetgetCallee (const ICFGNode *inst, PTACallGraph::FunctionSet &callees)
 
ThreadCallGraphgetTCG () const
 ThreadCallGraph. More...
 
void addDirectlyJoinTID (const CxtStmt &cs, NodeID tid)
 maps a context-sensitive join site to a thread id More...
 
void addToHPPair (NodeID tid1, NodeID tid2)
 
void addToHBPair (NodeID tid1, NodeID tid2)
 
void addToFullJoin (NodeID tid1, NodeID tid2)
 full join and partial join More...
 
void addToPartial (NodeID tid1, NodeID tid2)
 
void addSymmetricLoopJoin (const CxtStmt &cs, LoopBBs &lp)
 Add inloop join. More...
 

Private Attributes

TCTtct
 
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
 flags for context-sensitive statements More...
 
CxtStmtWorkList cxtStmtList
 context-sensitive statement worklist More...
 
CxtStmtToTIDMap directJoinMap
 maps a context-sensitive join site to directly joined thread ids More...
 
CxtStmtToTIDMap dirAndIndJoinMap
 maps a context-sensitive join site to directly and indirectly joined thread ids More...
 
CxtStmtToLoopMap cxtJoinInLoop
 a set of context-sensitive join inside loop More...
 
ThreadPairSet HBPair
 thread happens-before pair More...
 
ThreadPairSet HPPair
 threads happen-in-parallel More...
 
ThreadPairSet fullJoin
 t1 fully joins t2 along all program path More...
 
ThreadPairSet partialJoin
 t1 partially joins t2 along some program path(s) More...
 

Detailed Description

Definition at line 273 of file MHP.h.

Member Typedef Documentation

◆ CxtStmtToAliveFlagMap

Definition at line 287 of file MHP.h.

◆ CxtStmtToLoopMap

Definition at line 290 of file MHP.h.

◆ CxtStmtToTIDMap

Definition at line 288 of file MHP.h.

◆ CxtStmtWorkList

Definition at line 291 of file MHP.h.

◆ InstVec

Definition at line 286 of file MHP.h.

◆ LoopBBs

Definition at line 285 of file MHP.h.

◆ ThreadPairSet

Definition at line 289 of file MHP.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDDead==>TDAlive

Enumerator
Empty 
TDAlive 
TDDead 

Definition at line 278 of file MHP.h.

279  {
280  Empty, // initial(dummy) state
281  TDAlive, // thread is alive
282  TDDead, // thread is dead
283  };

Constructor & Destructor Documentation

◆ ForkJoinAnalysis()

SVF::ForkJoinAnalysis::ForkJoinAnalysis ( TCT t)
inline

Definition at line 293 of file MHP.h.

293  : tct(t)
294  {
295  collectSCEVInfo();
296  }
void collectSCEVInfo()
functions
Definition: MHP.cpp:667

Member Function Documentation

◆ addDirectlyJoinTID()

void SVF::ForkJoinAnalysis::addDirectlyJoinTID ( const CxtStmt cs,
NodeID  tid 
)
inlineprivate

maps a context-sensitive join site to a thread id

Definition at line 496 of file MHP.h.

497  {
498  directJoinMap[cs].set(tid);
499  }
CxtStmtToTIDMap directJoinMap
maps a context-sensitive join site to directly joined thread ids
Definition: MHP.h:535

◆ addSymmetricLoopJoin()

void SVF::ForkJoinAnalysis::addSymmetricLoopJoin ( const CxtStmt cs,
LoopBBs lp 
)
inlineprivate

Add inloop join.

Definition at line 528 of file MHP.h.

529  {
530  cxtJoinInLoop[cs] = lp;
531  }
CxtStmtToLoopMap cxtJoinInLoop
a set of context-sensitive join inside loop
Definition: MHP.h:537

◆ addToFullJoin()

void SVF::ForkJoinAnalysis::addToFullJoin ( NodeID  tid1,
NodeID  tid2 
)
inlineprivate

full join and partial join

Definition at line 517 of file MHP.h.

518  {
519  fullJoin.insert(std::make_pair(tid1,tid2));
520  }
ThreadPairSet fullJoin
t1 fully joins t2 along all program path
Definition: MHP.h:540

◆ addToHBPair()

void SVF::ForkJoinAnalysis::addToHBPair ( NodeID  tid1,
NodeID  tid2 
)
inlineprivate

Definition at line 509 of file MHP.h.

510  {
511  HBPair.insert(std::make_pair(tid1,tid2));
512  }
ThreadPairSet HBPair
thread happens-before pair
Definition: MHP.h:538

◆ addToHPPair()

void SVF::ForkJoinAnalysis::addToHPPair ( NodeID  tid1,
NodeID  tid2 
)
inlineprivate

happen-in-parallel pair happens-before pair

Definition at line 504 of file MHP.h.

505  {
506  HPPair.insert(std::make_pair(tid1,tid2));
507  HPPair.insert(std::make_pair(tid2,tid1));
508  }
ThreadPairSet HPPair
threads happen-in-parallel
Definition: MHP.h:539

◆ addToPartial()

void SVF::ForkJoinAnalysis::addToPartial ( NodeID  tid1,
NodeID  tid2 
)
inlineprivate

Definition at line 521 of file MHP.h.

522  {
523  partialJoin.insert(std::make_pair(tid1,tid2));
524  }
ThreadPairSet partialJoin
t1 partially joins t2 along some program path(s)
Definition: MHP.h:541

◆ analyzeForkJoinPair()

void ForkJoinAnalysis::analyzeForkJoinPair ( )

context-sensitive forward traversal from each fork site. Generate following results (1) fork join pair, maps a context-sensitive join site to its corresponding thread ids (2) never happen-in-parallel thread pairs

Context-sensitive forward traversal from each fork site

Definition at line 721 of file MHP.cpp.

722 {
723  for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
724  {
725  const CxtThread& ct = tpair.second->getCxtThread();
726  const NodeID rootTid = tpair.first;
727  clearFlagMap();
728  if (const ICFGNode* forkInst = ct.getThread())
729  {
730  CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct);
731  const ICFGNode* exitInst = getExitInstOfParentRoutineFun(rootTid);
732 
733  for(const ICFGEdge* outEdge : forkInst->getOutEdges())
734  {
735  if(outEdge->getDstNode()->getFun() == forkInst->getFun())
736  {
737  CxtStmt newCts(forkSiteCxt, outEdge->getDstNode());
738  markCxtStmtFlag(newCts, TDAlive);
739  }
740  }
741 
742  while (!cxtStmtList.empty())
743  {
744  CxtStmt cts = popFromCTSWorkList();
745  const ICFGNode* curInst = cts.getStmt();
746  DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
747  DBOUT(DMTA, cts.dump());
748  DBOUT(DMTA, outs() << "-----\n");
750  if (isTDFork(curInst))
751  {
752  handleFork(cts, rootTid);
753  }
754  else if (isTDJoin(curInst))
755  {
756  handleJoin(cts, rootTid);
757  }
758  else if (tct->isCallSite(curInst) && tct->isCandidateFun(getCallee(curInst, callees)))
759  {
760 
761  handleCall(cts, rootTid);
762  }
763  else if (isRetInstNode(curInst))
764  {
765  handleRet(cts);
766  }
767  else
768  {
769  handleIntra(cts);
770  }
771 
772  if (curInst == exitInst)
773  {
774  if (getMarkedFlag(cts) != TDAlive)
775  addToFullJoin(tct->getParentThread(rootTid), rootTid);
776  else
777  addToPartial(tct->getParentThread(rootTid), rootTid);
778  }
779  }
780  }
781  }
782 }
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DMTA
Definition: SVFType.h:505
void dump() const
Dump CxtStmt.
Definition: CxtStmt.h:110
const ICFGNode * getStmt() const
Return current statement.
Definition: CxtStmt.h:63
const ICFGNode * getThread() const
Return forksite.
Definition: CxtStmt.h:211
bool empty() const
Definition: WorkList.h:146
void addToFullJoin(NodeID tid1, NodeID tid2)
full join and partial join
Definition: MHP.h:517
ValDomain getMarkedFlag(const CxtStmt &cs)
Mark thread flags for cxtStmt.
Definition: MHP.h:389
void handleRet(const CxtStmt &cts)
Handle return.
Definition: MHP.cpp:902
CxtStmt popFromCTSWorkList()
Definition: MHP.h:445
const ICFGNode * getExitInstOfParentRoutineFun(NodeID tid) const
Get exit instruction of the start routine function of tid's parent thread.
Definition: MHP.h:341
void addToPartial(NodeID tid1, NodeID tid2)
Definition: MHP.h:521
void clearFlagMap()
Clear flags.
Definition: MHP.h:432
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition: MHP.h:464
void handleCall(const CxtStmt &cts, NodeID rootTid)
Handle call.
Definition: MHP.cpp:877
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition: MHP.h:470
void markCxtStmtFlag(const CxtStmt &tgr, ValDomain flag)
Initialize TDAlive and TDDead flags.
Definition: MHP.h:401
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
Definition: MHP.h:534
void handleIntra(const CxtStmt &cts)
Handle intra.
Definition: MHP.cpp:953
void handleFork(const CxtStmt &cts, NodeID rootTid)
Handle fork.
Definition: MHP.cpp:785
const PTACallGraph::FunctionSet & getCallee(const ICFGNode *inst, PTACallGraph::FunctionSet &callees)
Definition: MHP.h:485
void handleJoin(const CxtStmt &cts, NodeID rootTid)
Handle join.
Definition: MHP.cpp:812
Set< const SVFFunction * > FunctionSet
Definition: PTACallGraph.h:251
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition: TCT.h:271
NodeID getParentThread(NodeID tid) const
Get parent thread.
Definition: TCT.h:320
bool isCandidateFun(const PTACallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition: TCT.h:291
const CallStrCxt & getCxtOfCxtThread(const CxtThread &ct) const
get the context of a thread at its spawning site (fork site)
Definition: TCT.h:369
bool isRetInstNode(const ICFGNode *node)
Definition: SVFUtil.cpp:388
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
u32_t NodeID
Definition: GeneralType.h:55
std::vector< u32_t > CallStrCxt
Definition: GeneralType.h:122

◆ clearFlagMap()

void SVF::ForkJoinAnalysis::clearFlagMap ( )
inlineprivate

Clear flags.

Definition at line 432 of file MHP.h.

433  {
434  cxtStmtToAliveFlagMap.clear();
435  cxtStmtList.clear();
436  }
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
flags for context-sensitive statements
Definition: MHP.h:533

◆ collectSCEVInfo()

void ForkJoinAnalysis::collectSCEVInfo ( )

functions

Collect SCEV pass information for pointers at fork/join sites Because ScalarEvolution is a function pass, previous knowledge of a function may be overwritten when analyzing a new function. We use a internal wrapper class PTASCEV to record all the necessary information for determining symmetric fork/join inside loops

Definition at line 667 of file MHP.cpp.

668 {
669  // typedef Set<const ICFGNode*> CallInstSet;
670  // typedef Map<const SVFFunction*, CallInstSet> FunToFJSites;
671  // FunToFJSites funToFJSites;
672 
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  // }
680 
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  // }
688 
689  // for(FunToFJSites::const_iterator it = funToFJSites.begin(), eit = funToFJSites.end(); it!=eit; ++it)
690  // {
691  // // ScalarEvolution* SE = MTA::getSE(it->first);
692  // for(CallInstSet::const_iterator sit = it->second.begin(), esit = it->second.end(); sit!=esit; ++sit)
693  // {
694  // const SVFInstruction* callInst = *sit;
695  // if(tct->getThreadCallGraph()->isForksite(getCBN(callInst)))
696  // {
697  // // const SVFValue* forkSiteTidPtr = getForkedThread(callInst);
698  // // const SCEV *forkSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(forkSiteTidPtr));
699  // // const SCEV *baseForkTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(forkSiteTidPtr)));
700  // // forkSiteTidPtrSCEV = getSCEVMinusExpr(forkSiteTidPtrSCEV, baseForkTidPtrSCEV, SE);
701  // // PTASCEV scev(forkSiteTidPtr,nullptr,nullptr);
702  // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
703  // }
704  // else
705  // {
706  // // const SVFValue* joinSiteTidPtr = getJoinedThread(callInst);
707  // //const SCEV *joinSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(joinSiteTidPtr));
708  // //const SCEV *baseJoinTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(joinSiteTidPtr)));
709  // //joinSiteTidPtrSCEV = getSCEVMinusExpr(joinSiteTidPtrSCEV, baseJoinTidPtrSCEV, SE);
710 
711  // // PTASCEV scev(joinSiteTidPtr,nullptr,nullptr);
712  // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
713  // }
714  // }
715  // }
716 }

◆ getCallee()

const PTACallGraph::FunctionSet& SVF::ForkJoinAnalysis::getCallee ( const ICFGNode inst,
PTACallGraph::FunctionSet callees 
)
inlineprivate

Definition at line 485 of file MHP.h.

486  {
487  getTCG()->getCallees(SVFUtil::cast<CallICFGNode>(inst), callees);
488  return callees;
489  }
ThreadCallGraph * getTCG() const
ThreadCallGraph.
Definition: MHP.h:491
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Definition: PTACallGraph.h:408

◆ getDirAndIndJoinedTid()

NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid ( const CxtStmt cs)

Get directly and indirectly joined threadIDs based on a context-sensitive join site.

Return thread id(s) which are joined at this join site (1) thread t1 directly joins thread t2 (2) thread t1 indirectly joins thread t3 via directly joining t2 (t2 fully joins its child thread t3)

Definition at line 974 of file MHP.cpp.

975 {
976 
977  CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
978  if (it != dirAndIndJoinMap.end())
979  return it->second;
980 
981  const NodeBS& directJoinTids = getDirectlyJoinedTid(cs);
982  NodeBS allJoinTids = directJoinTids;
983 
984  FIFOWorkList<NodeID> worklist;
985  for (unsigned id : directJoinTids)
986  {
987  worklist.push(id);
988  }
989 
990  while (!worklist.empty())
991  {
992  NodeID tid = worklist.pop();
993  TCTNode* node = tct->getTCTNode(tid);
994  for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
995  {
996  NodeID childTid = (*it)->getDstID();
997  if (isFullJoin(tid, childTid))
998  {
999  allJoinTids.set(childTid);
1000  worklist.push(childTid);
1001  }
1002  }
1003  }
1004 
1005  dirAndIndJoinMap[cs] = allJoinTids;
1006 
1007  return allJoinTids;
1008 }
bool push(const Data &data)
Definition: WorkList.h:165
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition: MHP.h:306
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition: MHP.h:333
CxtStmtToTIDMap dirAndIndJoinMap
maps a context-sensitive join site to directly and indirectly joined thread ids
Definition: MHP.h:536
void set(unsigned Idx)
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition: TCT.h:217
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition: TCT.h:206
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition: TCT.h:221

◆ getDirectlyJoinedTid()

NodeBS& SVF::ForkJoinAnalysis::getDirectlyJoinedTid ( const CxtStmt cs)
inline

Get directly joined threadIDs based on a context-sensitive join site.

Definition at line 306 of file MHP.h.

307  {
308  return directJoinMap[cs];
309  }

◆ getExitInstOfParentRoutineFun()

const ICFGNode* SVF::ForkJoinAnalysis::getExitInstOfParentRoutineFun ( NodeID  tid) const
inline

Get exit instruction of the start routine function of tid's parent thread.

Definition at line 341 of file MHP.h.

342  {
343  NodeID parentTid = tct->getParentThread(tid);
344  const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
345  const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
346  return parentRoutine->getExitBB()->back();
347  }
const ICFGNode * back() const
Definition: SVFValue.h:600
const SVFBasicBlock * getExitBB() const
Definition: SVFValue.cpp:186
const CxtThread & getCxtThread() const
Get CxtThread.
Definition: TCT.h:101
const SVFFunction * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition: TCT.h:377

◆ getForkedThread()

const SVFVar* SVF::ForkJoinAnalysis::getForkedThread ( const CallICFGNode call)
inlineprivate

Get forked thread.

Definition at line 476 of file MHP.h.

477  {
478  return getTCG()->getThreadAPI()->getForkedThread(call);
479  }
const SVFVar * getForkedThread(const CallICFGNode *inst) const
Return arguments/attributes of pthread_create / hare_parallel_for.
Definition: ThreadAPI.cpp:164
ThreadAPI * getThreadAPI() const
Thread API.

◆ getJoinedThread()

const SVFVar* SVF::ForkJoinAnalysis::getJoinedThread ( const CallICFGNode call)
inlineprivate

Get joined thread.

Definition at line 481 of file MHP.h.

482  {
483  return getTCG()->getThreadAPI()->getJoinedThread(call);
484  }
const SVFVar * getJoinedThread(const CallICFGNode *inst) const
Return arguments/attributes of pthread_join.
Definition: ThreadAPI.cpp:207

◆ getJoinInSymmetricLoop()

const LoopBBs& SVF::ForkJoinAnalysis::getJoinInSymmetricLoop ( const CxtStmt cs) const
inline

Whether a context-sensitive join satisfies symmetric loop pattern.

Definition at line 314 of file MHP.h.

315  {
316  CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
317  assert(it!=cxtJoinInLoop.end() && "does not have the loop");
318  return it->second;
319  }

◆ getJoinLoop()

LoopBBs& SVF::ForkJoinAnalysis::getJoinLoop ( const CallICFGNode inst)
inline

Get loop for join site.

Definition at line 350 of file MHP.h.

351  {
352  return tct->getJoinLoop(inst);
353  }
LoopBBs & getJoinLoop(const CallICFGNode *join)
Get loop for join site.
Definition: TCT.h:385

◆ getMarkedFlag()

ValDomain SVF::ForkJoinAnalysis::getMarkedFlag ( const CxtStmt cs)
inlineprivate

Mark thread flags for cxtStmt.

Get the flag for a cxtStmt

Definition at line 389 of file MHP.h.

390  {
391  CxtStmtToAliveFlagMap::const_iterator it = cxtStmtToAliveFlagMap.find(cs);
392  if(it==cxtStmtToAliveFlagMap.end())
393  {
395  return Empty;
396  }
397  else
398  return it->second;
399  }

◆ getTCG()

ThreadCallGraph* SVF::ForkJoinAnalysis::getTCG ( ) const
inlineprivate

ThreadCallGraph.

Definition at line 491 of file MHP.h.

492  {
493  return tct->getThreadCallGraph();
494  }
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition: TCT.h:196

◆ handleCall()

void ForkJoinAnalysis::handleCall ( const CxtStmt cts,
NodeID  rootTid 
)
private

Handle call.

Definition at line 877 of file MHP.cpp.

878 {
879 
880  const ICFGNode* call = cts.getStmt();
881  const CallStrCxt& curCxt = cts.getContext();
882  const CallICFGNode* cbn = SVFUtil::cast<CallICFGNode>(call);
883  if (getTCG()->hasCallGraphEdge(cbn))
884  {
885  for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
886  ecgIt = getTCG()->getCallEdgeEnd(cbn);
887  cgIt != ecgIt; ++cgIt)
888  {
889  const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
890  if (isExtCall(svfcallee))
891  continue;
892  CallStrCxt newCxt = curCxt;
893  pushCxt(newCxt, cbn, svfcallee);
894  const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
895  CxtStmt newCts(newCxt, svfEntryInst);
896  markCxtStmtFlag(newCts, cts);
897  }
898  }
899 }
const CallStrCxt & getContext() const
Return current context.
Definition: CxtStmt.h:58
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition: MHP.h:453
const ICFGNode * front() const
Definition: SVFValue.h:594
const SVFBasicBlock * getEntryBlock() const
Definition: SVFValue.h:409
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278

◆ handleFork()

void ForkJoinAnalysis::handleFork ( const CxtStmt cts,
NodeID  rootTid 
)
private

Handle fork.

Definition at line 785 of file MHP.cpp.

786 {
787  const ICFGNode* call = cts.getStmt();
788  const CallStrCxt& curCxt = cts.getContext();
789 
790  assert(isTDFork(call));
791  const CallICFGNode* cbn = cast<CallICFGNode>(call);
792  if (getTCG()->hasThreadForkEdge(cbn))
793  {
794  for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
795  ecgIt = getTCG()->getForkEdgeEnd(cbn);
796  cgIt != ecgIt; ++cgIt)
797  {
798  const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction();
799  CallStrCxt newCxt = curCxt;
800  pushCxt(newCxt, cbn, callee);
801  CxtThread ct(newCxt, call);
802  if (getMarkedFlag(cts) != TDAlive)
803  addToHBPair(rootTid, tct->getTCTNode(ct)->getId());
804  else
805  addToHPPair(rootTid, tct->getTCTNode(ct)->getId());
806  }
807  }
808  handleIntra(cts);
809 }
void addToHPPair(NodeID tid1, NodeID tid2)
Definition: MHP.h:504
void addToHBPair(NodeID tid1, NodeID tid2)
Definition: MHP.h:509
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260

◆ handleIntra()

void ForkJoinAnalysis::handleIntra ( const CxtStmt cts)
private

Handle intra.

Definition at line 953 of file MHP.cpp.

954 {
955 
956  const ICFGNode* curInst = cts.getStmt();
957  const CallStrCxt& curCxt = cts.getContext();
958 
959  for(const ICFGEdge* outEdge : curInst->getOutEdges())
960  {
961  if(outEdge->getDstNode()->getFun() == curInst->getFun())
962  {
963  CxtStmt newCts(curCxt, outEdge->getDstNode());
964  markCxtStmtFlag(newCts, cts);
965  }
966  }
967 }
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition: ICFGNode.h:76

◆ handleJoin()

void ForkJoinAnalysis::handleJoin ( const CxtStmt cts,
NodeID  rootTid 
)
private

Handle join.

for the join site in a loop loop which does not join the current thread we process the loop exit

Definition at line 812 of file MHP.cpp.

813 {
814  const ICFGNode* call = cts.getStmt();
815  const CallStrCxt& curCxt = cts.getContext();
816 
817  assert(isTDJoin(call));
818  const CallICFGNode* cbn = cast<CallICFGNode>(call);
819  if (getTCG()->hasCallGraphEdge(cbn))
820  {
821  const ICFGNode* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
822  const ICFGNode* joinSite = cts.getStmt();
823 
824  if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite), SVFUtil::cast<CallICFGNode>(joinSite)))
825  {
826  if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
827  {
828  LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite));
829  std::vector<const SVFBasicBlock *> exitbbs;
830  joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
831  while (!exitbbs.empty())
832  {
833  const SVFBasicBlock* eb = exitbbs.back();
834  exitbbs.pop_back();
835  const ICFGNode* svfEntryInst = eb->front();
836  CxtStmt newCts(curCxt, svfEntryInst);
837  addDirectlyJoinTID(cts, rootTid);
838  if (isSameSCEV(forkSite, joinSite))
839  {
840  markCxtStmtFlag(newCts, TDDead);
841  addSymmetricLoopJoin(cts, joinLoop);
842  }
843  else
844  markCxtStmtFlag(cts, TDAlive);
845  }
846  }
847  else
848  {
849  markCxtStmtFlag(cts, TDDead);
850  addDirectlyJoinTID(cts, rootTid);
851  DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
852  }
853  }
856  else
857  {
858  if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
859  {
860  std::vector<const SVFBasicBlock*> exitbbs;
861  joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
862  while (!exitbbs.empty())
863  {
864  const SVFBasicBlock* eb = exitbbs.back();
865  exitbbs.pop_back();
866  const ICFGNode* svfEntryInst = eb->front();
867  CxtStmt newCts(curCxt, svfEntryInst);
868  markCxtStmtFlag(newCts, cts);
869  }
870  }
871  }
872  }
873  handleIntra(cts);
874 }
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition: MHP.h:285
bool hasJoinLoop(const CallICFGNode *inst)
Definition: MHP.h:354
void addSymmetricLoopJoin(const CxtStmt &cs, LoopBBs &lp)
Add inloop join.
Definition: MHP.h:528
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition: MHP.h:350
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition: MHP.h:496
bool isAliasedForkJoin(const CallICFGNode *forkSite, const CallICFGNode *joinSite)
Whether it is a matched fork join pair.
Definition: MHP.h:382
bool isSameSCEV(const ICFGNode *forkSite, const ICFGNode *joinSite)
Return true if the fork and join have the same SCEV.
Definition: MHP.cpp:1049
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
Definition: ICFGNode.h:82
virtual const std::string toString() const
Definition: ICFG.cpp:61
void getExitBlocksOfLoop(const SVFBasicBlock *bb, BBList &exitbbs) const
Definition: SVFValue.h:465

◆ handleRet()

void ForkJoinAnalysis::handleRet ( const CxtStmt cts)
private

Handle return.

Definition at line 902 of file MHP.cpp.

903 {
904  const ICFGNode* curInst = cts.getStmt();
905  const CallStrCxt& curCxt = cts.getContext();
906 
907  PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFun());
908  for (PTACallGraphEdge* edge : curFunNode->getInEdges())
909  {
910  if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
911  continue;
912  for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(),
913  ecit = edge->directCallsEnd();
914  cit != ecit; ++cit)
915  {
916  CallStrCxt newCxt = curCxt;
917  const ICFGNode* curNode = (*cit);
918  if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
919  {
920  for(const ICFGEdge* outEdge : curNode->getOutEdges())
921  {
922  if(outEdge->getDstNode()->getFun() == curNode->getFun())
923  {
924  CxtStmt newCts(newCxt, outEdge->getDstNode());
925  markCxtStmtFlag(newCts, cts);
926  }
927  }
928  }
929  }
930  for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
931  ecit = edge->indirectCallsEnd();
932  cit != ecit; ++cit)
933  {
934  CallStrCxt newCxt = curCxt;
935  const ICFGNode* curNode = (*cit);
936 
937  if (matchCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
938  {
939  for(const ICFGEdge* outEdge : curNode->getOutEdges())
940  {
941  if(outEdge->getDstNode()->getFun() == curNode->getFun())
942  {
943  CxtStmt newCts(newCxt, outEdge->getDstNode());
944  markCxtStmtFlag(newCts, cts);
945  }
946  }
947  }
948  }
949  }
950 }
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
Definition: MHP.h:458
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
const SVFFunction * getFunction() const
Get function of this call node.
Definition: PTACallGraph.h:198
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
Definition: PTACallGraph.h:339

◆ hasJoinInSymmetricLoop()

bool SVF::ForkJoinAnalysis::hasJoinInSymmetricLoop ( const CxtStmt cs) const
inline

Definition at line 320 of file MHP.h.

321  {
322  CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
323  return it!=cxtJoinInLoop.end();
324  }

◆ hasJoinLoop()

bool SVF::ForkJoinAnalysis::hasJoinLoop ( const CallICFGNode inst)
inline

Definition at line 354 of file MHP.h.

355  {
356  return tct->hasJoinLoop(inst);
357  }
bool hasJoinLoop(const CallICFGNode *join) const
Definition: TCT.h:393

◆ isAliasedForkJoin()

bool SVF::ForkJoinAnalysis::isAliasedForkJoin ( const CallICFGNode forkSite,
const CallICFGNode joinSite 
)
inlineprivate

Whether it is a matched fork join pair.

Definition at line 382 of file MHP.h.

383  {
384  return tct->getPTA()->alias(getForkedThread(forkSite)->getId(), getJoinedThread(joinSite)->getId()) && isSameSCEV(forkSite,joinSite);
385  }
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition: MHP.h:481
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition: MHP.h:476
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
PointerAnalysis * getPTA() const
Get PTA.
Definition: TCT.h:201

◆ isFullJoin()

bool SVF::ForkJoinAnalysis::isFullJoin ( NodeID  tid1,
NodeID  tid2 
)
inline

Whether t1 fully joins t2.

Definition at line 333 of file MHP.h.

334  {
335  bool full = fullJoin.find(std::make_pair(tid1,tid2))!=fullJoin.end();
336  bool partial = partialJoin.find(std::make_pair(tid1,tid2))!=partialJoin.end();
337  return full && !partial;
338  }

◆ isHBPair()

bool SVF::ForkJoinAnalysis::isHBPair ( NodeID  tid1,
NodeID  tid2 
)
inline

Whether thread t1 happens-before thread t2.

Definition at line 326 of file MHP.h.

327  {
328  bool nonhp = HBPair.find(std::make_pair(tid1,tid2))!=HBPair.end();
329  bool hp = HPPair.find(std::make_pair(tid1,tid2))!=HPPair.end();
330  return nonhp && !hp;
331  }

◆ isSameSCEV()

bool ForkJoinAnalysis::isSameSCEV ( const ICFGNode forkSite,
const ICFGNode joinSite 
)
private

Return true if the fork and join have the same SCEV.

We assume a pair of fork and join sites are must-alias if they have same PTASCEV (1) SCEV not inside loop (2) SCEV inside two symmetric loops, then pointers of fork thread and join thread should have same scev start and step. and should have same loop trip count

Definition at line 1049 of file MHP.cpp.

1050 {
1051 
1052  // const PTASCEV& forkse = fkjnToPTASCEVMap[forkSite];
1053  // const PTASCEV& joinse = fkjnToPTASCEVMap[joinSite];
1054 
1055  // //if(sameLoopTripCount(forkSite,joinSite) == false)
1056  // // return false;
1057 
1058  // if(forkse.inloop && joinse.inloop)
1059  // return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
1060  // else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
1061  // return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
1062  // else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
1063  // return false;
1064  // else
1065  // return true;
1066 
1067  return false;
1068 }

◆ isTDFork()

bool SVF::ForkJoinAnalysis::isTDFork ( const ICFGNode call)
inlineprivate

Whether it is a fork site.

Definition at line 464 of file MHP.h.

465  {
466  const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
467  return fork && getTCG()->getThreadAPI()->isTDFork(fork);
468  }
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
Definition: ThreadAPI.cpp:133

◆ isTDJoin()

bool SVF::ForkJoinAnalysis::isTDJoin ( const ICFGNode call)
inlineprivate

Whether it is a join site.

Definition at line 470 of file MHP.h.

471  {
472  const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
473  return join && getTCG()->getThreadAPI()->isTDJoin(join);
474  }
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.
Definition: ThreadAPI.cpp:138

◆ markCxtStmtFlag() [1/2]

void SVF::ForkJoinAnalysis::markCxtStmtFlag ( const CxtStmt tgr,
const CxtStmt src 
)
inlineprivate

Transfer function for marking context-sensitive statement.

alive is at the bottom of the semilattice, nothing needs to be done here

Definition at line 409 of file MHP.h.

410  {
411  ValDomain flag_tgr = getMarkedFlag(tgr);
412  ValDomain flag_src = getMarkedFlag(src);
413  if(flag_tgr == Empty)
414  {
415  cxtStmtToAliveFlagMap[tgr] = flag_src;
416  }
417  else if(flag_tgr == TDDead)
418  {
419  if(flag_src==TDAlive)
421  }
422  else
423  {
425  }
426  if(flag_tgr!=getMarkedFlag(tgr))
427  {
428  pushToCTSWorkList(tgr);
429  }
430  }
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
Definition: MHP.h:441
ValDomain
semilattice Empty==>TDDead==>TDAlive
Definition: MHP.h:279

◆ markCxtStmtFlag() [2/2]

void SVF::ForkJoinAnalysis::markCxtStmtFlag ( const CxtStmt tgr,
ValDomain  flag 
)
inlineprivate

Initialize TDAlive and TDDead flags.

Definition at line 401 of file MHP.h.

402  {
403  ValDomain flag_tgr = getMarkedFlag(tgr);
404  cxtStmtToAliveFlagMap[tgr] = flag;
405  if(flag_tgr!=getMarkedFlag(tgr))
406  pushToCTSWorkList(tgr);
407  }

◆ matchCxt()

bool SVF::ForkJoinAnalysis::matchCxt ( CallStrCxt cxt,
const CallICFGNode call,
const SVFFunction callee 
)
inlineprivate

Match context.

Definition at line 458 of file MHP.h.

459  {
460  return tct->matchCxt(cxt,call,callee);
461  }
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
Definition: TCT.cpp:465

◆ popFromCTSWorkList()

CxtStmt SVF::ForkJoinAnalysis::popFromCTSWorkList ( )
inlineprivate

Definition at line 445 of file MHP.h.

446  {
447  CxtStmt ctp = cxtStmtList.pop();
448  return ctp;
449  }

◆ pushCxt()

void SVF::ForkJoinAnalysis::pushCxt ( CallStrCxt cxt,
const CallICFGNode call,
const SVFFunction callee 
)
inlineprivate

Push calling context.

Definition at line 453 of file MHP.h.

454  {
455  tct->pushCxt(cxt,call,callee);
456  }
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition: TCT.cpp:444

◆ pushToCTSWorkList()

bool SVF::ForkJoinAnalysis::pushToCTSWorkList ( const CxtStmt cs)
inlineprivate

Worklist operations.

Definition at line 441 of file MHP.h.

442  {
443  return cxtStmtList.push(cs);
444  }

◆ sameLoopTripCount()

bool ForkJoinAnalysis::sameLoopTripCount ( const ICFGNode forkSite,
const ICFGNode joinSite 
)
private

Same loop trip count.

The fork and join have same loop trip count

Definition at line 1073 of file MHP.cpp.

1074 {
1075 
1076  // ScalarEvolution* forkSE = getSE(forkSite);
1077  // ScalarEvolution* joinSE = getSE(joinSite);
1078 
1079  // if(tct->hasLoop(forkSite) == false || tct->hasLoop(joinSite) == false)
1080  // return false;
1081 
1082  // // Get loops
1083  // const LoopBBs& forkSiteLoop = tct->getLoop(forkSite);
1084  // const LoopBBs& joinSiteLoop = tct->getLoop(joinSite);
1085 
1086  // const SCEV* forkLoopCountScev = forkSE->getBackedgeTakenCount(forkSiteLoop);
1087  // const SCEV* joinLoopCountScev = joinSE->getBackedgeTakenCount(joinSiteLoop);
1088 
1089  // if(forkLoopCountScev!=forkSE->getCouldNotCompute())
1090  // {
1091  // if(forkLoopCountScev==joinLoopCountScev)
1092  // {
1093  // return true;
1094  // }
1095  // }
1096  return false;
1097 }

Member Data Documentation

◆ cxtJoinInLoop

CxtStmtToLoopMap SVF::ForkJoinAnalysis::cxtJoinInLoop
private

a set of context-sensitive join inside loop

Definition at line 537 of file MHP.h.

◆ cxtStmtList

CxtStmtWorkList SVF::ForkJoinAnalysis::cxtStmtList
private

context-sensitive statement worklist

Definition at line 534 of file MHP.h.

◆ cxtStmtToAliveFlagMap

CxtStmtToAliveFlagMap SVF::ForkJoinAnalysis::cxtStmtToAliveFlagMap
private

flags for context-sensitive statements

Definition at line 533 of file MHP.h.

◆ dirAndIndJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::dirAndIndJoinMap
private

maps a context-sensitive join site to directly and indirectly joined thread ids

Definition at line 536 of file MHP.h.

◆ directJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::directJoinMap
private

maps a context-sensitive join site to directly joined thread ids

Definition at line 535 of file MHP.h.

◆ fullJoin

ThreadPairSet SVF::ForkJoinAnalysis::fullJoin
private

t1 fully joins t2 along all program path

Definition at line 540 of file MHP.h.

◆ HBPair

ThreadPairSet SVF::ForkJoinAnalysis::HBPair
private

thread happens-before pair

Definition at line 538 of file MHP.h.

◆ HPPair

ThreadPairSet SVF::ForkJoinAnalysis::HPPair
private

threads happen-in-parallel

Definition at line 539 of file MHP.h.

◆ partialJoin

ThreadPairSet SVF::ForkJoinAnalysis::partialJoin
private

t1 partially joins t2 along some program path(s)

Definition at line 541 of file MHP.h.

◆ tct

TCT* SVF::ForkJoinAnalysis::tct
private

Definition at line 532 of file MHP.h.


The documentation for this class was generated from the following files: