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
 
template<class ICFGGraph , class CGGraph >
void analyzeForkJoinPair (ICFGGraph icfg, CGGraph cg)
 
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)
 
const CxtStmtToLoopMapgetSymmetricLoopJoins () const
 All SCEV-symmetric in-loop joins and their loop blocks.
 

Private Member Functions

template<class ICFGGraph , class CGGraph >
void handleFork (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts, NodeID rootTid)
 Handle fork.
 
template<class ICFGGraph , class CGGraph >
void handleJoin (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts, NodeID rootTid)
 Handle join.
 
template<class ICFGGraph , class CGGraph >
void handleCall (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle call.
 
template<class ICFGGraph , class CGGraph >
void handleRet (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle return.
 
template<class ICFGGraph >
void handleIntra (ICFGGraph icfg, 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.
 
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

ThreadAPI::ForkJoinAliasCache forkJoinAliasCache
 
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 344 of file MHP.h.

Member Typedef Documentation

◆ CxtStmtSet

Definition at line 364 of file MHP.h.

◆ CxtStmtToAliveFlagMap

Definition at line 358 of file MHP.h.

◆ CxtStmtToLoopMap

Definition at line 361 of file MHP.h.

◆ CxtStmtToTIDMap

Definition at line 359 of file MHP.h.

◆ CxtStmtWorkList

Definition at line 362 of file MHP.h.

◆ InstToCxtStmt

Definition at line 365 of file MHP.h.

◆ InstVec

Definition at line 357 of file MHP.h.

◆ LoopBBs

Definition at line 356 of file MHP.h.

◆ ThreadPairSet

Definition at line 360 of file MHP.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDDead==>TDAlive

Enumerator
Empty 
TDAlive 
TDDead 

Definition at line 349 of file MHP.h.

350 {
351 Empty, // initial(dummy) state
352 TDAlive, // thread is alive
353 TDDead, // thread is dead
354 };

Constructor & Destructor Documentation

◆ ForkJoinAnalysis()

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

Definition at line 367 of file MHP.h.

367 : tct(t)
368 {
370 }
void collectSCEVInfo()
functions
Definition MHP.cpp:907

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

585 {
586 directJoinMap[cs].set(tid);
587 }
CxtStmtToTIDMap directJoinMap
maps a context-sensitive join site to directly joined thread ids
Definition MHP.h:635

◆ addSymmetricLoopJoin()

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

Add inloop join.

Definition at line 628 of file MHP.h.

629 {
630 cxtJoinInLoop[cs] = lp;
631 }
CxtStmtToLoopMap cxtJoinInLoop
a set of context-sensitive join inside loop
Definition MHP.h:637
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 605 of file MHP.h.

606 {
607 fullJoin.insert(std::make_pair(tid1,tid2));
608 }
ThreadPairSet fullJoin
t1 fully joins t2 along all program path
Definition MHP.h:640

◆ addToHBPair()

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

Definition at line 597 of file MHP.h.

598 {
599 HBPair.insert(std::make_pair(tid1,tid2));
600 }
ThreadPairSet HBPair
thread happens-before pair
Definition MHP.h:638

◆ addToHPPair()

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

happen-in-parallel pair happens-before pair

Definition at line 592 of file MHP.h.

593 {
594 HPPair.insert(std::make_pair(tid1,tid2));
595 HPPair.insert(std::make_pair(tid2,tid1));
596 }
ThreadPairSet HPPair
threads happen-in-parallel
Definition MHP.h:639

◆ addToPartial()

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

Definition at line 609 of file MHP.h.

610 {
611 partialJoin.insert(std::make_pair(tid1,tid2));
612 }
ThreadPairSet partialJoin
t1 partially joins t2 along some program path(s)
Definition MHP.h:641

◆ analyzeForkJoinPair()

template<class ICFGGraph , class CGGraph >
template void ForkJoinAnalysis::analyzeForkJoinPair< const SlicedICFGView *, const SlicedThreadCallGraphView * > ( ICFGGraph  icfg,
CGGraph  cg 
)

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

963{
964 for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
965 {
966 const CxtThread& ct = tpair.second->getCxtThread();
967 const NodeID rootTid = tpair.first;
968 clearFlagMap();
969 if (const ICFGNode* forkInst = ct.getThread())
970 {
972 std::vector<const ICFGNode*> successors;
974 icfg, forkInst, successors);
975 for (const ICFGNode* successor : successors)
976 {
977 if (successor->getFun() == forkInst->getFun())
978 {
979 for (const auto& forkSiteCxt : tct->getCxtOfCxtThread(ct))
980 {
983 }
984 }
985 }
986
987 while (!cxtStmtList.empty())
988 {
990 const ICFGNode* curInst = cts.getStmt();
991 DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
992 DBOUT(DMTA, cts.dump());
993 DBOUT(DMTA, outs() << "-----\n");
994 if (isTDFork(curInst))
995 {
996 handleFork(icfg, cg, cts, rootTid);
997 }
998 else if (isTDJoin(curInst))
999 {
1000 handleJoin(icfg, cg, cts, rootTid);
1001 }
1002 else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
1003 {
1007 const CallICFGNode *callSite = SVFUtil::cast<CallICFGNode>(curInst);
1010 cg, callSite, callees);
1011 if (!tct->isCandidateFun(callees))
1012 {
1013 // Do not dive into non-candidate functions
1014 CxtStmt newCts(cts.getContext(), callSite->getRetICFGNode());
1016 }
1017 else
1018 {
1019 handleCall(icfg, cg, cts);
1020 }
1021 }
1022 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
1023 {
1024 handleRet(icfg, cg, cts);
1025 }
1026 else
1027 {
1028 handleIntra(icfg, cts);
1029 }
1030
1034 for (NodeID parentTid : tct->getParentThreads(rootTid))
1035 {
1039 icfg, parentRoutine))
1040 {
1041 if (getMarkedFlag(cts) != TDAlive)
1043 else
1045 }
1046 }
1047 }
1048 }
1049 }
1050}
#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:605
void handleIntra(ICFGGraph icfg, const CxtStmt &cts)
Handle intra.
Definition MHP.cpp:1283
ValDomain getMarkedFlag(const CxtStmt &cs)
Mark thread flags for cxtStmt.
Definition MHP.h:466
CxtStmt popFromCTSWorkList()
Definition MHP.h:527
void addToPartial(NodeID tid1, NodeID tid2)
Definition MHP.h:609
void clearFlagMap()
Clear flags.
Definition MHP.h:514
void handleRet(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle return.
Definition MHP.cpp:1199
void handleFork(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:1054
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:557
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:563
void markCxtStmtFlag(const CxtStmt &tgr, ValDomain flag)
Initialize TDAlive and TDDead flags.
Definition MHP.h:478
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
Definition MHP.h:634
void handleJoin(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:1086
void handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle call.
Definition MHP.cpp:1169
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:209
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:274
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:294
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:267
const FunObjVar * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:388
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 514 of file MHP.h.

515 {
516 cxtStmtToAliveFlagMap.clear();
518 }
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
flags for context-sensitive statements
Definition MHP.h:633

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

908{
909 // typedef Set<const ICFGNode*> CallInstSet;
910 // typedef Map<const FunObjVar*, CallInstSet> FunToFJSites;
911 // FunToFJSites funToFJSites;
912
913 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
914 // eit = tct->getThreadCallGraph()->forksitesEnd();
915 // it != eit; ++it)
916 // {
917 // const ICFGNode* fork = *it;
918 // funToFJSites[fork->getFun()].insert(fork);
919 // }
920
921 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
922 // eit = tct->getThreadCallGraph()->joinsitesEnd();
923 // it != eit; ++it)
924 // {
925 // const ICFGNode* join = *it;
926 // funToFJSites[join->getFun()].insert(join);
927 // }
928
929 // for(FunToFJSites::const_iterator it = funToFJSites.begin(), eit = funToFJSites.end(); it!=eit; ++it)
930 // {
931 // // ScalarEvolution* SE = MTA::getSE(it->first);
932 // for(CallInstSet::const_iterator sit = it->second.begin(), esit = it->second.end(); sit!=esit; ++sit)
933 // {
934 // const SVFInstruction* callInst = *sit;
935 // if(tct->getThreadCallGraph()->isForksite(getCBN(callInst)))
936 // {
937 // // const SVFValue* forkSiteTidPtr = getForkedThread(callInst);
938 // // const SCEV *forkSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(forkSiteTidPtr));
939 // // const SCEV *baseForkTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(forkSiteTidPtr)));
940 // // forkSiteTidPtrSCEV = getSCEVMinusExpr(forkSiteTidPtrSCEV, baseForkTidPtrSCEV, SE);
941 // // PTASCEV scev(forkSiteTidPtr,nullptr,nullptr);
942 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
943 // }
944 // else
945 // {
946 // // const SVFValue* joinSiteTidPtr = getJoinedThread(callInst);
947 // //const SCEV *joinSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(joinSiteTidPtr));
948 // //const SCEV *baseJoinTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(joinSiteTidPtr)));
949 // //joinSiteTidPtrSCEV = getSCEVMinusExpr(joinSiteTidPtrSCEV, baseJoinTidPtrSCEV, SE);
950
951 // // PTASCEV scev(joinSiteTidPtr,nullptr,nullptr);
952 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
953 // }
954 // }
955 // }
956}

◆ getCxtStmtsFromInst()

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

Get CxtStmtSet for an instruction.

Definition at line 616 of file MHP.h.

617 {
618 InstToCxtStmt::const_iterator it = instToCxtStmt.find(inst);
619 assert(it!=instToCxtStmt.end() && "no CxtStmt for the instruction?");
620 return it->second;
621 }
InstToCxtStmt instToCxtStmt
Map a statement to all its context-sensitive statements.
Definition MHP.h:642

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

1307{
1308
1309 CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
1310 if (it != dirAndIndJoinMap.end())
1311 return it->second;
1312
1315
1316 FIFOWorkList<NodeID> worklist;
1317 for (unsigned id : directJoinTids)
1318 {
1319 worklist.push(id);
1320 }
1321
1322 while (!worklist.empty())
1323 {
1324 NodeID tid = worklist.pop();
1325 TCTNode* node = tct->getTCTNode(tid);
1326 for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
1327 {
1328 NodeID childTid = (*it)->getDstID();
1329 if (isFullJoin(tid, childTid))
1330 {
1331 allJoinTids.set(childTid);
1332 worklist.push(childTid);
1333 }
1334 }
1335 }
1336
1338
1339 return allJoinTids;
1340}
bool push(const Data &data)
Definition WorkList.h:180
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:408
CxtStmtToTIDMap dirAndIndJoinMap
maps a context-sensitive join site to directly and indirectly joined thread ids
Definition MHP.h:636
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition MHP.h:381
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition TCT.h:220
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition TCT.h:224

◆ getDirectlyJoinedTid()

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

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

Definition at line 381 of file MHP.h.

382 {
383 return directJoinMap[cs];
384 }

◆ getForkedThread()

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

Get forked thread.

Definition at line 569 of file MHP.h.

570 {
571 return getTCG()->getThreadAPI()->getForkedThread(call);
572 }
ThreadCallGraph * getTCG() const
ThreadCallGraph.
Definition MHP.h:579
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 574 of file MHP.h.

575 {
576 return getTCG()->getThreadAPI()->getJoinedThread(call);
577 }
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 389 of file MHP.h.

390 {
391 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
392 assert(it!=cxtJoinInLoop.end() && "does not have the loop");
393 return it->second;
394 }

◆ getJoinLoop()

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

Get loop for join site.

Definition at line 416 of file MHP.h.

417 {
418 return tct->getJoinLoop(inst);
419 }
LoopBBs & getJoinLoop(const CallICFGNode *join)
Get loop for join site.
Definition TCT.h:396

◆ getMarkedFlag()

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

Mark thread flags for cxtStmt.

Get the flag for a cxtStmt

Definition at line 466 of file MHP.h.

467 {
468 CxtStmtToAliveFlagMap::const_iterator it = cxtStmtToAliveFlagMap.find(cs);
469 if(it==cxtStmtToAliveFlagMap.end())
470 {
472 return Empty;
473 }
474 else
475 return it->second;
476 }

◆ getSymmetricLoopJoins()

const CxtStmtToLoopMap & SVF::ForkJoinAnalysis::getSymmetricLoopJoins ( ) const
inline

All SCEV-symmetric in-loop joins and their loop blocks.

Definition at line 425 of file MHP.h.

426 {
427 return cxtJoinInLoop;
428 }

◆ getTCG()

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

ThreadCallGraph.

Definition at line 579 of file MHP.h.

580 {
581 return tct->getThreadCallGraph();
582 }
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:199

◆ handleCall()

template<class ICFGGraph , class CGGraph >
void ForkJoinAnalysis::handleCall ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
private

Handle call.

Definition at line 1169 of file MHP.cpp.

1171{
1172 const ICFGNode* call = cts.getStmt();
1173 const CallStrCxt& curCxt = cts.getContext();
1174 const CallICFGNode* cbn = SVFUtil::cast<CallICFGNode>(call);
1176 std::vector<const CallGraphEdge*> outEdges;
1178 for (const CallGraphEdge* edge : outEdges)
1179 {
1180 if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge ||
1182 continue;
1183 const FunObjVar* svfcallee = edge->getDstNode()->getFunction();
1184 if (isExtCall(svfcallee))
1185 continue;
1188 const ICFGNode* svfEntryInst =
1190 if (svfEntryInst == nullptr)
1191 continue;
1194 }
1195}
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition MHP.h:537
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()

template<class ICFGGraph , class CGGraph >
void ForkJoinAnalysis::handleFork ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts,
NodeID  rootTid 
)
private

Handle fork.

Definition at line 1054 of file MHP.cpp.

1056{
1057 const ICFGNode* call = cts.getStmt();
1058 const CallStrCxt& curCxt = cts.getContext();
1059
1060 assert(isTDFork(call));
1061 const CallICFGNode* cbn = cast<CallICFGNode>(call);
1063 std::vector<const CallGraphEdge*> outEdges;
1065 for (const CallGraphEdge* edge : outEdges)
1066 {
1067 if (edge->getEdgeKind() != CallGraphEdge::TDForkEdge ||
1069 continue;
1070 const FunObjVar* callee = edge->getDstNode()->getFunction();
1073 CxtThread ct(newCxt, call);
1074 if (!tct->hasTCTNode(ct))
1075 continue;
1076 if (getMarkedFlag(cts) != TDAlive)
1078 else
1080 }
1081 handleIntra(icfg, cts);
1082}
void addToHPPair(NodeID tid1, NodeID tid2)
Definition MHP.h:592
void addToHBPair(NodeID tid1, NodeID tid2)
Definition MHP.h:597
NodeID getId() const
Get ID.
Definition SVFValue.h:158
bool hasTCTNode(const CxtThread &ct) const
Find/Get TCT node.
Definition TCT.h:281

◆ handleIntra()

template<class ICFGGraph >
void ForkJoinAnalysis::handleIntra ( ICFGGraph  icfg,
const CxtStmt cts 
)
private

Handle intra.

Definition at line 1283 of file MHP.cpp.

1285{
1286 const ICFGNode* curInst = cts.getStmt();
1287 const CallStrCxt& curCxt = cts.getContext();
1288
1289 std::vector<const ICFGNode*> successors;
1291 for (const ICFGNode* successor : successors)
1292 {
1293 if (successor->getFun() == curInst->getFun())
1294 {
1297 }
1298 }
1299}

◆ handleJoin()

template<class ICFGGraph , class CGGraph >
void ForkJoinAnalysis::handleJoin ( ICFGGraph  icfg,
CGGraph  cg,
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 1086 of file MHP.cpp.

1088{
1089 const ICFGNode* call = cts.getStmt();
1090 const CallStrCxt& curCxt = cts.getContext();
1091
1092 assert(isTDJoin(call));
1093 const CallICFGNode* cbn = cast<CallICFGNode>(call);
1095 std::vector<const CallGraphEdge*> outEdges;
1097 bool hasCallGraphEdge = false;
1098 for (const CallGraphEdge* edge : outEdges)
1099 {
1101 {
1102 hasCallGraphEdge = true;
1103 break;
1104 }
1105 }
1106 if (hasCallGraphEdge)
1107 {
1109 const ICFGNode* joinSite = cts.getStmt();
1110
1111 if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite)))
1112 {
1113 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
1114 SVFUtil::cast<CallICFGNode>(joinSite)) &&
1116 )
1117 {
1118 LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite));
1119 std::vector<const SVFBasicBlock *> exitbbs;
1120 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
1121 while (!exitbbs.empty())
1122 {
1123 const SVFBasicBlock* eb = exitbbs.back();
1124 exitbbs.pop_back();
1125 const ICFGNode* svfEntryInst = eb->front();
1129 {
1132 }
1133 else
1135 }
1136 }
1139 else
1140 {
1141 std::vector<const SVFBasicBlock*> exitbbs;
1142 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
1143 while (!exitbbs.empty())
1144 {
1145 const SVFBasicBlock* eb = exitbbs.back();
1146 exitbbs.pop_back();
1147 const ICFGNode* svfEntryInst = eb->front();
1150 }
1151 }
1152 }
1153 else
1154 {
1155 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
1156 SVFUtil::cast<CallICFGNode>(joinSite)))
1157 {
1160 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
1161 }
1162 }
1163 }
1164 handleIntra(icfg, cts);
1165}
const ICFGNode * getThread() const
Return forksite.
Definition CxtStmt.h:209
bool isAliasedForkJoin(const CallICFGNode *forkSite, const CallICFGNode *joinSite)
Whether it is a matched fork join pair.
Definition MHP.cpp:1431
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition MHP.h:356
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:420
void addSymmetricLoopJoin(const CxtStmt &cs, LoopBBs &lp)
Add inloop join.
Definition MHP.h:628
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition MHP.h:584
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition MHP.h:416
bool isSameSCEV(const ICFGNode *forkSite, const ICFGNode *joinSite)
Return true if the fork and join have the same SCEV.
Definition MHP.cpp:1381
virtual const std::string toString() const
Definition ICFG.cpp:50
const ICFGNode * back() const

◆ handleRet()

template<class ICFGGraph , class CGGraph >
void ForkJoinAnalysis::handleRet ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
private

Handle return.

Definition at line 1199 of file MHP.cpp.

1201{
1202 const ICFGNode* curInst = cts.getStmt();
1203 const CallStrCxt& curCxt = cts.getContext();
1204
1206 std::vector<const CallGraphEdge*> inEdges;
1208 for (const CallGraphEdge* edge : inEdges)
1209 {
1210 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
1211 continue;
1212 std::vector<const CallICFGNode*> directCalls;
1214 for (const CallICFGNode* callSite : directCalls)
1215 {
1218 curFunNode->getFunction()))
1219 {
1220 std::vector<const ICFGNode*> successors;
1222 icfg, callSite, successors);
1223 for (const ICFGNode* successor : successors)
1224 {
1225 if (successor->getFun() == callSite->getFun())
1226 {
1227 // Iterate over callSite's call string context and use as the successor's context
1229 continue;
1230 for (const CxtStmt& cxtStmt:
1232 {
1233 CallStrCxt callSiteCxt = cxtStmt.getContext();
1234 // If new context is a suffix of the call site context
1236 {
1239 }
1240 }
1241 }
1242 }
1243 }
1244 }
1245 std::vector<const CallICFGNode*> indirectCalls;
1247 for (const CallICFGNode* callSite : indirectCalls)
1248 {
1251 curFunNode->getFunction()))
1252 {
1253 std::vector<const ICFGNode*> successors;
1255 icfg, callSite, successors);
1256 for (const ICFGNode* successor : successors)
1257 {
1258 if (successor->getFun() == callSite->getFun())
1259 {
1260 // Iterate over callSite's call string context and use as the successor's context
1262 continue;
1263 for (const CxtStmt& cxtStmt:
1265 {
1266 CallStrCxt callSiteCxt = cxtStmt.getContext();
1267 // If new context is a suffix of the call site context
1269 {
1272 }
1273 }
1274 }
1275 }
1276 }
1277 }
1278 }
1279}
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition MHP.h:545
bool hasCxtStmtsFromInst(const ICFGNode *inst) const
Definition MHP.h:622
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:550
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
Get CxtStmtSet for an instruction.
Definition MHP.h:616

◆ hasCxtStmtsFromInst()

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

Definition at line 622 of file MHP.h.

623 {
624 return instToCxtStmt.find(inst)!=instToCxtStmt.end();
625 }

◆ hasJoinInSymmetricLoop()

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

Definition at line 395 of file MHP.h.

396 {
397 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
398 return it!=cxtJoinInLoop.end();
399 }

◆ hasJoinLoop()

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

Definition at line 420 of file MHP.h.

421 {
422 return tct->hasJoinLoop(inst);
423 }
bool hasJoinLoop(const CallICFGNode *join) const
Definition TCT.h:404

◆ isAliasedForkJoin()

bool ForkJoinAnalysis::isAliasedForkJoin ( const CallICFGNode forkSite,
const CallICFGNode joinSite 
)
private

Whether it is a matched fork join pair.

Definition at line 1431 of file MHP.cpp.

1433{
1436}
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition MHP.h:569
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition MHP.h:574
ThreadAPI::ForkJoinAliasCache forkJoinAliasCache
Definition MHP.h:462
PointerAnalysis * getPTA() const
Get PTA.
Definition TCT.h:204
bool isAliasedForkJoin(PointerAnalysis *pta, const SVFVar *forkArg, const SVFVar *joinArg) const

◆ isContextSuffix()

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

If lhs is a suffix of rhs, including equal.

Definition at line 550 of file MHP.h.

551 {
552 return tct->isContextSuffix(lhs,call);
553 }
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:531

◆ isFullJoin()

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

Whether t1 fully joins t2.

Definition at line 408 of file MHP.h.

409 {
410 bool full = fullJoin.find(std::make_pair(tid1,tid2))!=fullJoin.end();
411 bool partial = partialJoin.find(std::make_pair(tid1,tid2))!=partialJoin.end();
412 return full && !partial;
413 }

◆ isHBPair()

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

Whether thread t1 happens-before thread t2.

Definition at line 401 of file MHP.h.

402 {
403 bool nonhp = HBPair.find(std::make_pair(tid1,tid2))!=HBPair.end();
404 bool hp = HPPair.find(std::make_pair(tid1,tid2))!=HPPair.end();
405 return nonhp && !hp;
406 }

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

1382{
1383
1384 // const PTASCEV& forkse = fkjnToPTASCEVMap[forkSite];
1385 // const PTASCEV& joinse = fkjnToPTASCEVMap[joinSite];
1386
1387 // //if(sameLoopTripCount(forkSite,joinSite) == false)
1388 // // return false;
1389
1390 // if(forkse.inloop && joinse.inloop)
1391 // return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
1392 // else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
1393 // return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
1394 // else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
1395 // return false;
1396 // else
1397 // return true;
1398
1399 return false;
1400}

◆ isTDFork()

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

Whether it is a fork site.

Definition at line 557 of file MHP.h.

558 {
559 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
560 return fork && getTCG()->getThreadAPI()->isTDFork(fork);
561 }
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 563 of file MHP.h.

564 {
565 const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
566 return join && getTCG()->getThreadAPI()->isTDJoin(join);
567 }
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 490 of file MHP.h.

491 {
494 if(flag_tgr == Empty)
495 {
497 }
498 else if(flag_tgr == TDDead)
499 {
500 if(flag_src==TDAlive)
502 }
503 else
504 {
506 }
508 {
509 instToCxtStmt[tgr.getStmt()].insert(tgr);
511 }
512 }
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
Definition MHP.h:523
ValDomain
semilattice Empty==>TDDead==>TDAlive
Definition MHP.h:350

◆ markCxtStmtFlag() [2/2]

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

Initialize TDAlive and TDDead flags.

Definition at line 478 of file MHP.h.

479 {
483 {
484 instToCxtStmt[tgr.getStmt()].insert(tgr);
486 }
487
488 }

◆ matchAndPopCxt()

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

Match context.

Definition at line 545 of file MHP.h.

546 {
547 return tct->matchAndPopCxt(cxt,call,callee);
548 }
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:503

◆ popFromCTSWorkList()

CxtStmt SVF::ForkJoinAnalysis::popFromCTSWorkList ( )
inlineprivate

Definition at line 527 of file MHP.h.

528 {
529 CxtStmt ctp = cxtStmtList.pop();
530 return ctp;
531 }

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

538 {
540 if(tct->isCandidateFun(call->getFun()) == false)
541 return;
542 tct->pushCxt(cxt,call,callee);
543 }
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:483

◆ pushToCTSWorkList()

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

Worklist operations.

Definition at line 523 of file MHP.h.

524 {
525 return cxtStmtList.push(cs);
526 }

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

1406{
1407
1408 // ScalarEvolution* forkSE = getSE(forkSite);
1409 // ScalarEvolution* joinSE = getSE(joinSite);
1410
1411 // if(tct->hasLoop(forkSite) == false || tct->hasLoop(joinSite) == false)
1412 // return false;
1413
1414 // // Get loops
1415 // const LoopBBs& forkSiteLoop = tct->getLoop(forkSite);
1416 // const LoopBBs& joinSiteLoop = tct->getLoop(joinSite);
1417
1418 // const SCEV* forkLoopCountScev = forkSE->getBackedgeTakenCount(forkSiteLoop);
1419 // const SCEV* joinLoopCountScev = joinSE->getBackedgeTakenCount(joinSiteLoop);
1420
1421 // if(forkLoopCountScev!=forkSE->getCouldNotCompute())
1422 // {
1423 // if(forkLoopCountScev==joinLoopCountScev)
1424 // {
1425 // return true;
1426 // }
1427 // }
1428 return false;
1429}

Member Data Documentation

◆ cxtJoinInLoop

CxtStmtToLoopMap SVF::ForkJoinAnalysis::cxtJoinInLoop
private

a set of context-sensitive join inside loop

Definition at line 637 of file MHP.h.

◆ cxtStmtList

CxtStmtWorkList SVF::ForkJoinAnalysis::cxtStmtList
private

context-sensitive statement worklist

Definition at line 634 of file MHP.h.

◆ cxtStmtToAliveFlagMap

CxtStmtToAliveFlagMap SVF::ForkJoinAnalysis::cxtStmtToAliveFlagMap
private

flags for context-sensitive statements

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

◆ directJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::directJoinMap
private

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

Definition at line 635 of file MHP.h.

◆ forkJoinAliasCache

ThreadAPI::ForkJoinAliasCache SVF::ForkJoinAnalysis::forkJoinAliasCache
private

Definition at line 462 of file MHP.h.

◆ fullJoin

ThreadPairSet SVF::ForkJoinAnalysis::fullJoin
private

t1 fully joins t2 along all program path

Definition at line 640 of file MHP.h.

◆ HBPair

ThreadPairSet SVF::ForkJoinAnalysis::HBPair
private

thread happens-before pair

Definition at line 638 of file MHP.h.

◆ HPPair

ThreadPairSet SVF::ForkJoinAnalysis::HPPair
private

threads happen-in-parallel

Definition at line 639 of file MHP.h.

◆ instToCxtStmt

InstToCxtStmt SVF::ForkJoinAnalysis::instToCxtStmt
private

Map a statement to all its context-sensitive statements.

Definition at line 642 of file MHP.h.

◆ partialJoin

ThreadPairSet SVF::ForkJoinAnalysis::partialJoin
private

t1 partially joins t2 along some program path(s)

Definition at line 641 of file MHP.h.

◆ tct

TCT* SVF::ForkJoinAnalysis::tct
private

Definition at line 632 of file MHP.h.


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