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
 
typedef Set< CxtStmtCxtStmtSet
 
typedef Map< const ICFGNode *, CxtStmtSetInstToCxtStmt
 

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.
 
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 FunObjVar *callee)
 Context helper functions.
 
bool matchAndPopCxt (CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
 Match context.
 
bool isContextSuffix (const CallStrCxt &lhs, const CallStrCxt call)
 If lhs is a suffix of rhs, including equal.
 
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 CallGraph::FunctionSetgetCallee (const ICFGNode *inst, CallGraph::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)
 
const CxtStmtSetgetCxtStmtsFromInst (const ICFGNode *inst) const
 Get CxtStmtSet for an instruction.
 
bool hasCxtStmtsFromInst (const ICFGNode *inst) const
 
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)
 
InstToCxtStmt instToCxtStmt
 Map a statement to all its context-sensitive statements.
 

Detailed Description

Definition at line 286 of file MHP.h.

Member Typedef Documentation

◆ CxtStmtSet

Definition at line 306 of file MHP.h.

◆ CxtStmtToAliveFlagMap

Definition at line 300 of file MHP.h.

◆ CxtStmtToLoopMap

Definition at line 303 of file MHP.h.

◆ CxtStmtToTIDMap

Definition at line 301 of file MHP.h.

◆ CxtStmtWorkList

Definition at line 304 of file MHP.h.

◆ InstToCxtStmt

Definition at line 307 of file MHP.h.

◆ InstVec

Definition at line 299 of file MHP.h.

◆ LoopBBs

Definition at line 298 of file MHP.h.

◆ ThreadPairSet

Definition at line 302 of file MHP.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDDead==>TDAlive

Enumerator
Empty 
TDAlive 
TDDead 

Definition at line 291 of file MHP.h.

292 {
293 Empty, // initial(dummy) state
294 TDAlive, // thread is alive
295 TDDead, // thread is dead
296 };

Constructor & Destructor Documentation

◆ ForkJoinAnalysis()

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

Definition at line 310 of file MHP.h.

310 : tct(t)
311 {
313 }
void collectSCEVInfo()
functions
Definition MHP.cpp:706

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 520 of file MHP.h.

521 {
522 directJoinMap[cs].set(tid);
523 }
CxtStmtToTIDMap directJoinMap
maps a context-sensitive join site to directly joined thread ids
Definition MHP.h:571

◆ addSymmetricLoopJoin()

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

Add inloop join.

Definition at line 564 of file MHP.h.

565 {
566 cxtJoinInLoop[cs] = lp;
567 }
CxtStmtToLoopMap cxtJoinInLoop
a set of context-sensitive join inside loop
Definition MHP.h:573
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ addToFullJoin()

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

full join and partial join

Definition at line 541 of file MHP.h.

542 {
543 fullJoin.insert(std::make_pair(tid1,tid2));
544 }
ThreadPairSet fullJoin
t1 fully joins t2 along all program path
Definition MHP.h:576

◆ addToHBPair()

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

Definition at line 533 of file MHP.h.

534 {
535 HBPair.insert(std::make_pair(tid1,tid2));
536 }
ThreadPairSet HBPair
thread happens-before pair
Definition MHP.h:574

◆ addToHPPair()

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

happen-in-parallel pair happens-before pair

Definition at line 528 of file MHP.h.

529 {
530 HPPair.insert(std::make_pair(tid1,tid2));
531 HPPair.insert(std::make_pair(tid2,tid1));
532 }
ThreadPairSet HPPair
threads happen-in-parallel
Definition MHP.h:575

◆ addToPartial()

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

Definition at line 545 of file MHP.h.

546 {
547 partialJoin.insert(std::make_pair(tid1,tid2));
548 }
ThreadPairSet partialJoin
t1 partially joins t2 along some program path(s)
Definition MHP.h:577

◆ 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

Start from the instruction next to the fork site

Propagate to the return site of the call instruction, only if the callee is a non-candidate function, while for candidate function, return site should be handled after the callee is handled.

If the current instruction is an exit instruction of the start routine of a parent context thread, we need to update the join information the parent context thread.

Definition at line 760 of file MHP.cpp.

761{
762 for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
763 {
764 const CxtThread& ct = tpair.second->getCxtThread();
765 const NodeID rootTid = tpair.first;
766 clearFlagMap();
767 if (const ICFGNode* forkInst = ct.getThread())
768 {
770 for(const ICFGEdge* outEdge : forkInst->getOutEdges())
771 {
772 if(outEdge->getDstNode()->getFun() == forkInst->getFun())
773 {
774 for (const auto& forkSiteCxt : tct->getCxtOfCxtThread(ct))
775 {
776 CxtStmt newCts(forkSiteCxt.second, outEdge->getDstNode());
778 }
779 }
780 }
781
782 while (!cxtStmtList.empty())
783 {
785 const ICFGNode* curInst = cts.getStmt();
786 DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
787 DBOUT(DMTA, cts.dump());
788 DBOUT(DMTA, outs() << "-----\n");
790 if (isTDFork(curInst))
791 {
793 }
794 else if (isTDJoin(curInst))
795 {
797 }
798 else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
799 {
803 const CallICFGNode *callSite = SVFUtil::cast<CallICFGNode>(curInst);
806 {
807 // Do not dive into non-candidate functions
808 CxtStmt newCts(cts.getContext(), callSite->getRetICFGNode());
810 }
811 else
812 {
814 }
815 }
816 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
817 {
818 handleRet(cts);
819 }
820 else
821 {
823 }
824
828 for (NodeID parentTid : tct->getParentThreads(rootTid))
829 {
832 if (curInst == parentRoutine->getExitBB()->back())
833 {
834 if (getMarkedFlag(cts) != TDAlive)
836 else
838 }
839 }
840 }
841 }
842 }
843}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DMTA
Definition SVFType.h:597
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
bool empty() const
Definition WorkList.h:161
void addToFullJoin(NodeID tid1, NodeID tid2)
full join and partial join
Definition MHP.h:541
ValDomain getMarkedFlag(const CxtStmt &cs)
Mark thread flags for cxtStmt.
Definition MHP.h:397
const CallGraph::FunctionSet & getCallee(const ICFGNode *inst, CallGraph::FunctionSet &callees)
Definition MHP.h:509
void handleRet(const CxtStmt &cts)
Handle return.
Definition MHP.cpp:967
CxtStmt popFromCTSWorkList()
Definition MHP.h:458
void addToPartial(NodeID tid1, NodeID tid2)
Definition MHP.h:545
void clearFlagMap()
Clear flags.
Definition MHP.h:445
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:488
void handleCall(const CxtStmt &cts, NodeID rootTid)
Handle call.
Definition MHP.cpp:942
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:494
void markCxtStmtFlag(const CxtStmt &tgr, ValDomain flag)
Initialize TDAlive and TDDead flags.
Definition MHP.h:409
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
Definition MHP.h:570
void handleIntra(const CxtStmt &cts)
Handle intra.
Definition MHP.cpp:1040
void handleFork(const CxtStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:846
void handleJoin(const CxtStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:873
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:103
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:202
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:267
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:287
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:260
const FunObjVar * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:381
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
u32_t NodeID
Definition GeneralType.h:76

◆ clearFlagMap()

void SVF::ForkJoinAnalysis::clearFlagMap ( )
inlineprivate

Clear flags.

Definition at line 445 of file MHP.h.

446 {
447 cxtStmtToAliveFlagMap.clear();
449 }
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
flags for context-sensitive statements
Definition MHP.h:569

◆ 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 706 of file MHP.cpp.

707{
708 // typedef Set<const ICFGNode*> CallInstSet;
709 // typedef Map<const FunObjVar*, CallInstSet> FunToFJSites;
710 // FunToFJSites funToFJSites;
711
712 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
713 // eit = tct->getThreadCallGraph()->forksitesEnd();
714 // it != eit; ++it)
715 // {
716 // const ICFGNode* fork = *it;
717 // funToFJSites[fork->getFun()].insert(fork);
718 // }
719
720 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
721 // eit = tct->getThreadCallGraph()->joinsitesEnd();
722 // it != eit; ++it)
723 // {
724 // const ICFGNode* join = *it;
725 // funToFJSites[join->getFun()].insert(join);
726 // }
727
728 // for(FunToFJSites::const_iterator it = funToFJSites.begin(), eit = funToFJSites.end(); it!=eit; ++it)
729 // {
730 // // ScalarEvolution* SE = MTA::getSE(it->first);
731 // for(CallInstSet::const_iterator sit = it->second.begin(), esit = it->second.end(); sit!=esit; ++sit)
732 // {
733 // const SVFInstruction* callInst = *sit;
734 // if(tct->getThreadCallGraph()->isForksite(getCBN(callInst)))
735 // {
736 // // const SVFValue* forkSiteTidPtr = getForkedThread(callInst);
737 // // const SCEV *forkSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(forkSiteTidPtr));
738 // // const SCEV *baseForkTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(forkSiteTidPtr)));
739 // // forkSiteTidPtrSCEV = getSCEVMinusExpr(forkSiteTidPtrSCEV, baseForkTidPtrSCEV, SE);
740 // // PTASCEV scev(forkSiteTidPtr,nullptr,nullptr);
741 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
742 // }
743 // else
744 // {
745 // // const SVFValue* joinSiteTidPtr = getJoinedThread(callInst);
746 // //const SCEV *joinSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(joinSiteTidPtr));
747 // //const SCEV *baseJoinTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(joinSiteTidPtr)));
748 // //joinSiteTidPtrSCEV = getSCEVMinusExpr(joinSiteTidPtrSCEV, baseJoinTidPtrSCEV, SE);
749
750 // // PTASCEV scev(joinSiteTidPtr,nullptr,nullptr);
751 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
752 // }
753 // }
754 // }
755}

◆ getCallee()

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

Definition at line 509 of file MHP.h.

510 {
511 getTCG()->getCallees(SVFUtil::cast<CallICFGNode>(inst), callees);
512 return callees;
513 }
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Definition CallGraph.h:426
ThreadCallGraph * getTCG() const
ThreadCallGraph.
Definition MHP.h:515

◆ getCxtStmtsFromInst()

const CxtStmtSet & SVF::ForkJoinAnalysis::getCxtStmtsFromInst ( const ICFGNode inst) const
inlineprivate

Get CxtStmtSet for an instruction.

Definition at line 552 of file MHP.h.

553 {
554 InstToCxtStmt::const_iterator it = instToCxtStmt.find(inst);
555 assert(it!=instToCxtStmt.end() && "no CxtStmt for the instruction?");
556 return it->second;
557 }
InstToCxtStmt instToCxtStmt
Map a statement to all its context-sensitive statements.
Definition MHP.h:578

◆ 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 1061 of file MHP.cpp.

1062{
1063
1064 CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
1065 if (it != dirAndIndJoinMap.end())
1066 return it->second;
1067
1070
1071 FIFOWorkList<NodeID> worklist;
1072 for (unsigned id : directJoinTids)
1073 {
1074 worklist.push(id);
1075 }
1076
1077 while (!worklist.empty())
1078 {
1079 NodeID tid = worklist.pop();
1080 TCTNode* node = tct->getTCTNode(tid);
1081 for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
1082 {
1083 NodeID childTid = (*it)->getDstID();
1084 if (isFullJoin(tid, childTid))
1085 {
1086 allJoinTids.set(childTid);
1087 worklist.push(childTid);
1088 }
1089 }
1090 }
1091
1093
1094 return allJoinTids;
1095}
bool push(const Data &data)
Definition WorkList.h:180
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:350
CxtStmtToTIDMap dirAndIndJoinMap
maps a context-sensitive join site to directly and indirectly joined thread ids
Definition MHP.h:572
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition MHP.h:323
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition TCT.h:213
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition TCT.h:217

◆ getDirectlyJoinedTid()

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

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

Definition at line 323 of file MHP.h.

324 {
325 return directJoinMap[cs];
326 }

◆ getForkedThread()

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

Get forked thread.

Definition at line 500 of file MHP.h.

501 {
502 return getTCG()->getThreadAPI()->getForkedThread(call);
503 }
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 505 of file MHP.h.

506 {
507 return getTCG()->getThreadAPI()->getJoinedThread(call);
508 }
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 331 of file MHP.h.

332 {
333 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
334 assert(it!=cxtJoinInLoop.end() && "does not have the loop");
335 return it->second;
336 }

◆ getJoinLoop()

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

Get loop for join site.

Definition at line 358 of file MHP.h.

359 {
360 return tct->getJoinLoop(inst);
361 }
LoopBBs & getJoinLoop(const CallICFGNode *join)
Get loop for join site.
Definition TCT.h:389

◆ getMarkedFlag()

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

Mark thread flags for cxtStmt.

Get the flag for a cxtStmt

Definition at line 397 of file MHP.h.

398 {
399 CxtStmtToAliveFlagMap::const_iterator it = cxtStmtToAliveFlagMap.find(cs);
400 if(it==cxtStmtToAliveFlagMap.end())
401 {
403 return Empty;
404 }
405 else
406 return it->second;
407 }

◆ getTCG()

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

ThreadCallGraph.

Definition at line 515 of file MHP.h.

516 {
517 return tct->getThreadCallGraph();
518 }
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:192

◆ handleCall()

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

Handle call.

Definition at line 942 of file MHP.cpp.

943{
944
945 const ICFGNode* call = cts.getStmt();
946 const CallStrCxt& curCxt = cts.getContext();
947 const CallICFGNode* cbn = SVFUtil::cast<CallICFGNode>(call);
948 if (getTCG()->hasCallGraphEdge(cbn))
949 {
950 for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
951 ecgIt = getTCG()->getCallEdgeEnd(cbn);
952 cgIt != ecgIt; ++cgIt)
953 {
954 const FunObjVar* svfcallee = (*cgIt)->getDstNode()->getFunction();
955 if (isExtCall(svfcallee))
956 continue;
959 const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
962 }
963 }
964}
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition MHP.h:468
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441
std::vector< u32_t > CallStrCxt
Definition GeneralType.h:96

◆ handleFork()

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

Handle fork.

Definition at line 846 of file MHP.cpp.

847{
848 const ICFGNode* call = cts.getStmt();
849 const CallStrCxt& curCxt = cts.getContext();
850
851 assert(isTDFork(call));
852 const CallICFGNode* cbn = cast<CallICFGNode>(call);
853 if (getTCG()->hasThreadForkEdge(cbn))
854 {
855 for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
856 ecgIt = getTCG()->getForkEdgeEnd(cbn);
857 cgIt != ecgIt; ++cgIt)
858 {
859 const FunObjVar* callee = (*cgIt)->getDstNode()->getFunction();
862 CxtThread ct(newCxt, call);
863 if (getMarkedFlag(cts) != TDAlive)
865 else
867 }
868 }
870}
void addToHPPair(NodeID tid1, NodeID tid2)
Definition MHP.h:528
void addToHBPair(NodeID tid1, NodeID tid2)
Definition MHP.h:533
NodeID getId() const
Get ID.
Definition SVFValue.h:160

◆ handleIntra()

void ForkJoinAnalysis::handleIntra ( const CxtStmt cts)
private

Handle intra.

Definition at line 1040 of file MHP.cpp.

1041{
1042
1043 const ICFGNode* curInst = cts.getStmt();
1044 const CallStrCxt& curCxt = cts.getContext();
1045
1046 for(const ICFGEdge* outEdge : curInst->getOutEdges())
1047 {
1048 if(outEdge->getDstNode()->getFun() == curInst->getFun())
1049 {
1050 CxtStmt newCts(curCxt, outEdge->getDstNode());
1052 }
1053 }
1054}

◆ 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 873 of file MHP.cpp.

874{
875 const ICFGNode* call = cts.getStmt();
876 const CallStrCxt& curCxt = cts.getContext();
877
878 assert(isTDJoin(call));
879 const CallICFGNode* cbn = cast<CallICFGNode>(call);
880 if (getTCG()->hasCallGraphEdge(cbn))
881 {
883 const ICFGNode* joinSite = cts.getStmt();
884
885 if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite)))
886 {
887 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
888 SVFUtil::cast<CallICFGNode>(joinSite)) &&
890 )
891 {
892 LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite));
893 std::vector<const SVFBasicBlock *> exitbbs;
894 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
895 while (!exitbbs.empty())
896 {
897 const SVFBasicBlock* eb = exitbbs.back();
898 exitbbs.pop_back();
899 const ICFGNode* svfEntryInst = eb->front();
903 {
906 }
907 else
909 }
910 }
913 else
914 {
915 std::vector<const SVFBasicBlock*> exitbbs;
916 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
917 while (!exitbbs.empty())
918 {
919 const SVFBasicBlock* eb = exitbbs.back();
920 exitbbs.pop_back();
921 const ICFGNode* svfEntryInst = eb->front();
924 }
925 }
926 }
927 else
928 {
929 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
930 SVFUtil::cast<CallICFGNode>(joinSite)))
931 {
934 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
935 }
936 }
937 }
939}
const ICFGNode * getThread() const
Return forksite.
Definition CxtStmt.h:209
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition MHP.h:298
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:362
void addSymmetricLoopJoin(const CxtStmt &cs, LoopBBs &lp)
Add inloop join.
Definition MHP.h:564
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition MHP.h:520
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition MHP.h:358
bool isAliasedForkJoin(const CallICFGNode *forkSite, const CallICFGNode *joinSite)
Whether it is a matched fork join pair.
Definition MHP.h:390
bool isSameSCEV(const ICFGNode *forkSite, const ICFGNode *joinSite)
Return true if the fork and join have the same SCEV.
Definition MHP.cpp:1136
virtual const std::string toString() const
Definition ICFG.cpp:50
const ICFGNode * back() const

◆ handleRet()

void ForkJoinAnalysis::handleRet ( const CxtStmt cts)
private

Handle return.

Definition at line 967 of file MHP.cpp.

968{
969 const ICFGNode* curInst = cts.getStmt();
970 const CallStrCxt& curCxt = cts.getContext();
971
973 for (CallGraphEdge* edge : curFunNode->getInEdges())
974 {
975 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
976 continue;
977 for (CallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(),
978 ecit = edge->directCallsEnd();
979 cit != ecit; ++cit)
980 {
982 const ICFGNode* curNode = (*cit);
983 if (matchAndPopCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
984 {
985 for(const ICFGEdge* outEdge : curNode->getOutEdges())
986 {
987 if(outEdge->getDstNode()->getFun() == curNode->getFun())
988 {
989 // Iterate over callSite's call string context and use as the successor's context
991 continue;
992 for (const CxtStmt& cxtStmt: getCxtStmtsFromInst(*cit))
993 {
994 CallStrCxt callSiteCxt = cxtStmt.getContext();
995 // If new context is a suffix of the call site context
997 {
998 CxtStmt newCts(callSiteCxt, outEdge->getDstNode());
1000 }
1001 }
1002 }
1003 }
1004 }
1005 }
1006 for (CallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
1007 ecit = edge->indirectCallsEnd();
1008 cit != ecit; ++cit)
1009 {
1011 const ICFGNode* curNode = (*cit);
1012
1013 if (matchAndPopCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
1014 {
1015 for(const ICFGEdge* outEdge : curNode->getOutEdges())
1016 {
1017 if(outEdge->getDstNode()->getFun() == curNode->getFun())
1018 {
1019 // Iterate over callSite's call string context and use as the successor's context
1020 if (!hasCxtStmtsFromInst(*cit))
1021 continue;
1022 for (const CxtStmt& cxtStmt: getCxtStmtsFromInst(*cit))
1023 {
1024 CallStrCxt callSiteCxt = cxtStmt.getContext();
1025 // If new context is a suffix of the call site context
1027 {
1028 CxtStmt newCts(callSiteCxt, outEdge->getDstNode());
1030 }
1031 }
1032 }
1033 }
1034 }
1035 }
1036 }
1037}
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition MHP.h:476
bool hasCxtStmtsFromInst(const ICFGNode *inst) const
Definition MHP.h:558
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:481
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
Get CxtStmtSet for an instruction.
Definition MHP.h:552

◆ hasCxtStmtsFromInst()

bool SVF::ForkJoinAnalysis::hasCxtStmtsFromInst ( const ICFGNode inst) const
inlineprivate

Definition at line 558 of file MHP.h.

559 {
560 return instToCxtStmt.find(inst)!=instToCxtStmt.end();
561 }

◆ hasJoinInSymmetricLoop()

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

Definition at line 337 of file MHP.h.

338 {
339 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
340 return it!=cxtJoinInLoop.end();
341 }

◆ hasJoinLoop()

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

Definition at line 362 of file MHP.h.

363 {
364 return tct->hasJoinLoop(inst);
365 }
bool hasJoinLoop(const CallICFGNode *join) const
Definition TCT.h:397

◆ isAliasedForkJoin()

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

Whether it is a matched fork join pair.

Definition at line 390 of file MHP.h.

391 {
392 return tct->getPTA()->alias(getForkedThread(forkSite)->getId(), getJoinedThread(joinSite)->getId());
393 }
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition MHP.h:500
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition MHP.h:505
virtual AliasResult alias(const SVFVar *V1, const SVFVar *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
PointerAnalysis * getPTA() const
Get PTA.
Definition TCT.h:197

◆ isContextSuffix()

bool SVF::ForkJoinAnalysis::isContextSuffix ( const CallStrCxt lhs,
const CallStrCxt  call 
)
inlineprivate

If lhs is a suffix of rhs, including equal.

Definition at line 481 of file MHP.h.

482 {
483 return tct->isContextSuffix(lhs,call);
484 }
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:497

◆ isFullJoin()

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

Whether t1 fully joins t2.

Definition at line 350 of file MHP.h.

351 {
352 bool full = fullJoin.find(std::make_pair(tid1,tid2))!=fullJoin.end();
353 bool partial = partialJoin.find(std::make_pair(tid1,tid2))!=partialJoin.end();
354 return full && !partial;
355 }

◆ isHBPair()

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

Whether thread t1 happens-before thread t2.

Definition at line 343 of file MHP.h.

344 {
345 bool nonhp = HBPair.find(std::make_pair(tid1,tid2))!=HBPair.end();
346 bool hp = HPPair.find(std::make_pair(tid1,tid2))!=HPPair.end();
347 return nonhp && !hp;
348 }

◆ 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 1136 of file MHP.cpp.

1137{
1138
1139 // const PTASCEV& forkse = fkjnToPTASCEVMap[forkSite];
1140 // const PTASCEV& joinse = fkjnToPTASCEVMap[joinSite];
1141
1142 // //if(sameLoopTripCount(forkSite,joinSite) == false)
1143 // // return false;
1144
1145 // if(forkse.inloop && joinse.inloop)
1146 // return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
1147 // else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
1148 // return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
1149 // else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
1150 // return false;
1151 // else
1152 // return true;
1153
1154 return false;
1155}

◆ isTDFork()

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

Whether it is a fork site.

Definition at line 488 of file MHP.h.

489 {
490 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
491 return fork && getTCG()->getThreadAPI()->isTDFork(fork);
492 }
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 494 of file MHP.h.

495 {
496 const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
497 return join && getTCG()->getThreadAPI()->isTDJoin(join);
498 }
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 421 of file MHP.h.

422 {
425 if(flag_tgr == Empty)
426 {
428 }
429 else if(flag_tgr == TDDead)
430 {
431 if(flag_src==TDAlive)
433 }
434 else
435 {
437 }
439 {
440 instToCxtStmt[tgr.getStmt()].insert(tgr);
442 }
443 }
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
Definition MHP.h:454
ValDomain
semilattice Empty==>TDDead==>TDAlive
Definition MHP.h:292

◆ markCxtStmtFlag() [2/2]

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

Initialize TDAlive and TDDead flags.

Definition at line 409 of file MHP.h.

410 {
414 {
415 instToCxtStmt[tgr.getStmt()].insert(tgr);
417 }
418
419 }

◆ matchAndPopCxt()

bool SVF::ForkJoinAnalysis::matchAndPopCxt ( CallStrCxt cxt,
const CallICFGNode call,
const FunObjVar callee 
)
inlineprivate

Match context.

Definition at line 476 of file MHP.h.

477 {
478 return tct->matchAndPopCxt(cxt,call,callee);
479 }
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:469

◆ popFromCTSWorkList()

CxtStmt SVF::ForkJoinAnalysis::popFromCTSWorkList ( )
inlineprivate

Definition at line 458 of file MHP.h.

459 {
460 CxtStmt ctp = cxtStmtList.pop();
461 return ctp;
462 }

◆ pushCxt()

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

Context helper functions.

Push calling context

handle calling context for candidate functions only

Definition at line 468 of file MHP.h.

469 {
471 if(tct->isCandidateFun(call->getFun()) == false)
472 return;
473 tct->pushCxt(cxt,call,callee);
474 }
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:449

◆ pushToCTSWorkList()

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

Worklist operations.

Definition at line 454 of file MHP.h.

455 {
456 return cxtStmtList.push(cs);
457 }

◆ 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 1160 of file MHP.cpp.

1161{
1162
1163 // ScalarEvolution* forkSE = getSE(forkSite);
1164 // ScalarEvolution* joinSE = getSE(joinSite);
1165
1166 // if(tct->hasLoop(forkSite) == false || tct->hasLoop(joinSite) == false)
1167 // return false;
1168
1169 // // Get loops
1170 // const LoopBBs& forkSiteLoop = tct->getLoop(forkSite);
1171 // const LoopBBs& joinSiteLoop = tct->getLoop(joinSite);
1172
1173 // const SCEV* forkLoopCountScev = forkSE->getBackedgeTakenCount(forkSiteLoop);
1174 // const SCEV* joinLoopCountScev = joinSE->getBackedgeTakenCount(joinSiteLoop);
1175
1176 // if(forkLoopCountScev!=forkSE->getCouldNotCompute())
1177 // {
1178 // if(forkLoopCountScev==joinLoopCountScev)
1179 // {
1180 // return true;
1181 // }
1182 // }
1183 return false;
1184}

Member Data Documentation

◆ cxtJoinInLoop

CxtStmtToLoopMap SVF::ForkJoinAnalysis::cxtJoinInLoop
private

a set of context-sensitive join inside loop

Definition at line 573 of file MHP.h.

◆ cxtStmtList

CxtStmtWorkList SVF::ForkJoinAnalysis::cxtStmtList
private

context-sensitive statement worklist

Definition at line 570 of file MHP.h.

◆ cxtStmtToAliveFlagMap

CxtStmtToAliveFlagMap SVF::ForkJoinAnalysis::cxtStmtToAliveFlagMap
private

flags for context-sensitive statements

Definition at line 569 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 572 of file MHP.h.

◆ directJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::directJoinMap
private

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

Definition at line 571 of file MHP.h.

◆ fullJoin

ThreadPairSet SVF::ForkJoinAnalysis::fullJoin
private

t1 fully joins t2 along all program path

Definition at line 576 of file MHP.h.

◆ HBPair

ThreadPairSet SVF::ForkJoinAnalysis::HBPair
private

thread happens-before pair

Definition at line 574 of file MHP.h.

◆ HPPair

ThreadPairSet SVF::ForkJoinAnalysis::HPPair
private

threads happen-in-parallel

Definition at line 575 of file MHP.h.

◆ instToCxtStmt

InstToCxtStmt SVF::ForkJoinAnalysis::instToCxtStmt
private

Map a statement to all its context-sensitive statements.

Definition at line 578 of file MHP.h.

◆ partialJoin

ThreadPairSet SVF::ForkJoinAnalysis::partialJoin
private

t1 partially joins t2 along some program path(s)

Definition at line 577 of file MHP.h.

◆ tct

TCT* SVF::ForkJoinAnalysis::tct
private

Definition at line 568 of file MHP.h.


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