Static Value-Flow Analysis
Loading...
Searching...
No Matches
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
 
void analyzeForkJoinPair ()
 
NodeBSgetDirectlyJoinedTid (const CxtStmt &cs)
 Get directly joined threadIDs based on a context-sensitive join site.
 
NodeBS getDirAndIndJoinedTid (const CxtStmt &cs)
 Get directly and indirectly joined threadIDs based on a context-sensitive join site.
 
const LoopBBsgetJoinInSymmetricLoop (const CxtStmt &cs) const
 Whether a context-sensitive join satisfies symmetric loop pattern.
 
bool hasJoinInSymmetricLoop (const CxtStmt &cs) const
 
bool isHBPair (NodeID tid1, NodeID tid2)
 Whether thread t1 happens-before thread t2.
 
bool isFullJoin (NodeID tid1, NodeID tid2)
 Whether t1 fully joins t2.
 
const ICFGNodegetExitInstOfParentRoutineFun (NodeID tid) const
 Get exit instruction of the start routine function of tid's parent thread.
 
LoopBBsgetJoinLoop (const CallICFGNode *inst)
 Get loop for join site.
 
bool hasJoinLoop (const CallICFGNode *inst)
 

Private Member Functions

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

Private Attributes

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

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 {
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
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ 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 {
732
733 for(const ICFGEdge* outEdge : forkInst->getOutEdges())
734 {
735 if(outEdge->getDstNode()->getFun() == forkInst->getFun())
736 {
737 CxtStmt newCts(forkSiteCxt, outEdge->getDstNode());
739 }
740 }
741
742 while (!cxtStmtList.empty())
743 {
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 {
753 }
754 else if (isTDJoin(curInst))
755 {
757 }
759 {
760
762 }
763 else if (isRetInstNode(curInst))
764 {
765 handleRet(cts);
766 }
767 else
768 {
770 }
771
772 if (curInst == exitInst)
773 {
774 if (getMarkedFlag(cts) != TDAlive)
776 else
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
bool empty() const
Definition WorkList.h:146
void addToFullJoin(NodeID tid1, NodeID tid2)
full join and partial join
Definition MHP.h:517
const PTACallGraph::FunctionSet & getCallee(const ICFGNode *inst, PTACallGraph::FunctionSet &callees)
Definition MHP.h:485
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
void addToPartial(NodeID tid1, NodeID tid2)
Definition MHP.h:521
void clearFlagMap()
Clear flags.
Definition MHP.h:432
const ICFGNode * getExitInstOfParentRoutineFun(NodeID tid) const
Get exit instruction of the start routine function of tid's parent thread.
Definition MHP.h:341
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
void handleJoin(const CxtStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:812
Set< const SVFFunction * > FunctionSet
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
const CallStrCxt & getCxtOfCxtThread(const CxtThread &ct) const
get the context of a thread at its spawning site (fork site)
Definition TCT.h:369
bool isCandidateFun(const PTACallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:291
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:389
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
u32_t NodeID
Definition GeneralType.h:55
std::vector< u32_t > CallStrCxt

◆ clearFlagMap()

void SVF::ForkJoinAnalysis::clearFlagMap ( )
inlineprivate

Clear flags.

Definition at line 432 of file MHP.h.

433 {
434 cxtStmtToAliveFlagMap.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.

◆ 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
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 {
1000 worklist.push(childTid);
1001 }
1002 }
1003 }
1004
1006
1007 return allJoinTids;
1008}
bool push(const Data &data)
Definition WorkList.h:165
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
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition MHP.h:306
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:206
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition TCT.h:217
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 {
344 const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
346 return parentRoutine->getExitBB()->back();
347 }
const ICFGNode * back() const
Definition SVFValue.h:611
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 ValVar * getForkedThread(const CallICFGNode *inst) const
Return arguments/attributes of pthread_create / hare_parallel_for.
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.

◆ 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;
894 const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
897 }
898 }
899}
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition MHP.h:453
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();
801 CxtThread ct(newCxt, call);
802 if (getMarkedFlag(cts) != TDAlive)
804 else
806 }
807 }
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.

◆ 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());
965 }
966 }
967}

◆ 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 {
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();
839 {
842 }
843 else
845 }
846 }
847 else
848 {
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();
869 }
870 }
871 }
872 }
874}
const ICFGNode * getThread() const
Return forksite.
Definition CxtStmt.h:211
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
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition MHP.h:496
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition MHP.h:350
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 std::string toString() const
Definition ICFG.cpp:61

◆ 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
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 {
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());
926 }
927 }
928 }
929 }
930 for (PTACallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
931 ecit = edge->indirectCallsEnd();
932 cit != ecit; ++cit)
933 {
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());
945 }
946 }
947 }
948 }
949 }
950}
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
Definition MHP.h:458
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.

◆ 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 {
385 }
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition MHP.h:476
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition MHP.h:481
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.

◆ 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.

◆ 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 {
413 if(flag_tgr == Empty)
414 {
416 }
417 else if(flag_tgr == TDDead)
418 {
419 if(flag_src==TDAlive)
421 }
422 else
423 {
425 }
427 {
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.

◆ 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:466

◆ 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:445

◆ 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: