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

Member Typedef Documentation

◆ CxtStmtSet

Definition at line 305 of file MHP.h.

◆ CxtStmtToAliveFlagMap

Definition at line 299 of file MHP.h.

◆ CxtStmtToLoopMap

Definition at line 302 of file MHP.h.

◆ CxtStmtToTIDMap

Definition at line 300 of file MHP.h.

◆ CxtStmtWorkList

Definition at line 303 of file MHP.h.

◆ InstToCxtStmt

Definition at line 306 of file MHP.h.

◆ InstVec

Definition at line 298 of file MHP.h.

◆ LoopBBs

Definition at line 297 of file MHP.h.

◆ ThreadPairSet

Definition at line 301 of file MHP.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDDead==>TDAlive

Enumerator
Empty 
TDAlive 
TDDead 

Definition at line 290 of file MHP.h.

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

Constructor & Destructor Documentation

◆ ForkJoinAnalysis()

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

Definition at line 309 of file MHP.h.

309 : tct(t)
310 {
312 }
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 519 of file MHP.h.

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

◆ addSymmetricLoopJoin()

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

Add inloop join.

Definition at line 563 of file MHP.h.

564 {
565 cxtJoinInLoop[cs] = lp;
566 }
CxtStmtToLoopMap cxtJoinInLoop
a set of context-sensitive join inside loop
Definition MHP.h:572
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 540 of file MHP.h.

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

◆ addToHBPair()

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

Definition at line 532 of file MHP.h.

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

◆ addToHPPair()

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

happen-in-parallel pair happens-before pair

Definition at line 527 of file MHP.h.

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

◆ addToPartial()

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

Definition at line 544 of file MHP.h.

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

◆ 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:497
#define DMTA
Definition SVFType.h:518
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:244
bool empty() const
Definition WorkList.h:146
void addToFullJoin(NodeID tid1, NodeID tid2)
full join and partial join
Definition MHP.h:540
ValDomain getMarkedFlag(const CxtStmt &cs)
Mark thread flags for cxtStmt.
Definition MHP.h:396
const CallGraph::FunctionSet & getCallee(const ICFGNode *inst, CallGraph::FunctionSet &callees)
Definition MHP.h:508
void handleRet(const CxtStmt &cts)
Handle return.
Definition MHP.cpp:967
CxtStmt popFromCTSWorkList()
Definition MHP.h:457
void addToPartial(NodeID tid1, NodeID tid2)
Definition MHP.h:544
void clearFlagMap()
Clear flags.
Definition MHP.h:444
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:487
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:493
void markCxtStmtFlag(const CxtStmt &tgr, ValDomain flag)
Initialize TDAlive and TDDead flags.
Definition MHP.h:408
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
Definition MHP.h:569
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:101
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:200
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:265
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:285
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:258
const FunObjVar * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:379
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
u32_t NodeID
Definition GeneralType.h:56

◆ clearFlagMap()

void SVF::ForkJoinAnalysis::clearFlagMap ( )
inlineprivate

Clear flags.

Definition at line 444 of file MHP.h.

445 {
446 cxtStmtToAliveFlagMap.clear();
448 }
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
flags for context-sensitive statements
Definition MHP.h:568

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

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

◆ getCxtStmtsFromInst()

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

Get CxtStmtSet for an instruction.

Definition at line 551 of file MHP.h.

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

◆ 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:165
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:349
CxtStmtToTIDMap dirAndIndJoinMap
maps a context-sensitive join site to directly and indirectly joined thread ids
Definition MHP.h:571
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition MHP.h:322
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition TCT.h:211
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition TCT.h:215

◆ getDirectlyJoinedTid()

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

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

Definition at line 322 of file MHP.h.

323 {
324 return directJoinMap[cs];
325 }

◆ getForkedThread()

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

Get forked thread.

Definition at line 499 of file MHP.h.

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

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

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

◆ getJoinLoop()

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

Get loop for join site.

Definition at line 357 of file MHP.h.

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

◆ getMarkedFlag()

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

Mark thread flags for cxtStmt.

Get the flag for a cxtStmt

Definition at line 396 of file MHP.h.

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

◆ getTCG()

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

ThreadCallGraph.

Definition at line 514 of file MHP.h.

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

◆ 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:467
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:437
std::vector< u32_t > CallStrCxt

◆ 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:527
void addToHBPair(NodeID tid1, NodeID tid2)
Definition MHP.h:532
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:211
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition MHP.h:297
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:361
void addSymmetricLoopJoin(const CxtStmt &cs, LoopBBs &lp)
Add inloop join.
Definition MHP.h:563
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition MHP.h:519
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition MHP.h:357
bool isAliasedForkJoin(const CallICFGNode *forkSite, const CallICFGNode *joinSite)
Whether it is a matched fork join pair.
Definition MHP.h:389
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:60
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:475
bool hasCxtStmtsFromInst(const ICFGNode *inst) const
Definition MHP.h:557
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:480
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
Get CxtStmtSet for an instruction.
Definition MHP.h:551

◆ hasCxtStmtsFromInst()

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

Definition at line 557 of file MHP.h.

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

◆ hasJoinInSymmetricLoop()

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

Definition at line 336 of file MHP.h.

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

◆ hasJoinLoop()

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

Definition at line 361 of file MHP.h.

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

◆ isAliasedForkJoin()

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

Whether it is a matched fork join pair.

Definition at line 389 of file MHP.h.

390 {
391 return tct->getPTA()->alias(getForkedThread(forkSite)->getId(), getJoinedThread(joinSite)->getId());
392 }
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition MHP.h:499
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition MHP.h:504
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:195

◆ isContextSuffix()

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

If lhs is a suffix of rhs, including equal.

Definition at line 480 of file MHP.h.

481 {
482 return tct->isContextSuffix(lhs,call);
483 }
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 349 of file MHP.h.

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

◆ isHBPair()

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

Whether thread t1 happens-before thread t2.

Definition at line 342 of file MHP.h.

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

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

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

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

421 {
424 if(flag_tgr == Empty)
425 {
427 }
428 else if(flag_tgr == TDDead)
429 {
430 if(flag_src==TDAlive)
432 }
433 else
434 {
436 }
438 {
439 instToCxtStmt[tgr.getStmt()].insert(tgr);
441 }
442 }
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
Definition MHP.h:453
ValDomain
semilattice Empty==>TDDead==>TDAlive
Definition MHP.h:291

◆ markCxtStmtFlag() [2/2]

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

Initialize TDAlive and TDDead flags.

Definition at line 408 of file MHP.h.

409 {
413 {
414 instToCxtStmt[tgr.getStmt()].insert(tgr);
416 }
417
418 }

◆ matchAndPopCxt()

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

Match context.

Definition at line 475 of file MHP.h.

476 {
477 return tct->matchAndPopCxt(cxt,call,callee);
478 }
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 457 of file MHP.h.

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

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

468 {
470 if(tct->isCandidateFun(call->getFun()) == false)
471 return;
472 tct->pushCxt(cxt,call,callee);
473 }
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 453 of file MHP.h.

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

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

◆ cxtStmtList

CxtStmtWorkList SVF::ForkJoinAnalysis::cxtStmtList
private

context-sensitive statement worklist

Definition at line 569 of file MHP.h.

◆ cxtStmtToAliveFlagMap

CxtStmtToAliveFlagMap SVF::ForkJoinAnalysis::cxtStmtToAliveFlagMap
private

flags for context-sensitive statements

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

◆ directJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::directJoinMap
private

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

Definition at line 570 of file MHP.h.

◆ fullJoin

ThreadPairSet SVF::ForkJoinAnalysis::fullJoin
private

t1 fully joins t2 along all program path

Definition at line 575 of file MHP.h.

◆ HBPair

ThreadPairSet SVF::ForkJoinAnalysis::HBPair
private

thread happens-before pair

Definition at line 573 of file MHP.h.

◆ HPPair

ThreadPairSet SVF::ForkJoinAnalysis::HPPair
private

threads happen-in-parallel

Definition at line 574 of file MHP.h.

◆ instToCxtStmt

InstToCxtStmt SVF::ForkJoinAnalysis::instToCxtStmt
private

Map a statement to all its context-sensitive statements.

Definition at line 577 of file MHP.h.

◆ partialJoin

ThreadPairSet SVF::ForkJoinAnalysis::partialJoin
private

t1 partially joins t2 along some program path(s)

Definition at line 576 of file MHP.h.

◆ tct

TCT* SVF::ForkJoinAnalysis::tct
private

Definition at line 567 of file MHP.h.


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