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)
 
const CxtStmtToLoopMapgetSymmetricLoopJoins () const
 All SCEV-symmetric in-loop joins and their loop blocks.
 

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

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

Member Typedef Documentation

◆ CxtStmtSet

Definition at line 337 of file MHP.h.

◆ CxtStmtToAliveFlagMap

Definition at line 331 of file MHP.h.

◆ CxtStmtToLoopMap

Definition at line 334 of file MHP.h.

◆ CxtStmtToTIDMap

Definition at line 332 of file MHP.h.

◆ CxtStmtWorkList

Definition at line 335 of file MHP.h.

◆ InstToCxtStmt

Definition at line 338 of file MHP.h.

◆ InstVec

Definition at line 330 of file MHP.h.

◆ LoopBBs

Definition at line 329 of file MHP.h.

◆ ThreadPairSet

Definition at line 333 of file MHP.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDDead==>TDAlive

Enumerator
Empty 
TDAlive 
TDDead 

Definition at line 322 of file MHP.h.

323 {
324 Empty, // initial(dummy) state
325 TDAlive, // thread is alive
326 TDDead, // thread is dead
327 };

Constructor & Destructor Documentation

◆ ForkJoinAnalysis()

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

Definition at line 340 of file MHP.h.

340 : tct(t)
341 {
343 }
void collectSCEVInfo()
functions
Definition MHP.cpp:816

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

554 {
555 directJoinMap[cs].set(tid);
556 }
CxtStmtToTIDMap directJoinMap
maps a context-sensitive join site to directly joined thread ids
Definition MHP.h:604

◆ addSymmetricLoopJoin()

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

Add inloop join.

Definition at line 597 of file MHP.h.

598 {
599 cxtJoinInLoop[cs] = lp;
600 }
CxtStmtToLoopMap cxtJoinInLoop
a set of context-sensitive join inside loop
Definition MHP.h:606
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 574 of file MHP.h.

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

◆ addToHBPair()

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

Definition at line 566 of file MHP.h.

567 {
568 HBPair.insert(std::make_pair(tid1,tid2));
569 }
ThreadPairSet HBPair
thread happens-before pair
Definition MHP.h:607

◆ addToHPPair()

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

happen-in-parallel pair happens-before pair

Definition at line 561 of file MHP.h.

562 {
563 HPPair.insert(std::make_pair(tid1,tid2));
564 HPPair.insert(std::make_pair(tid2,tid1));
565 }
ThreadPairSet HPPair
threads happen-in-parallel
Definition MHP.h:608

◆ addToPartial()

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

Definition at line 578 of file MHP.h.

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

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

871{
872 for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
873 {
874 const CxtThread& ct = tpair.second->getCxtThread();
875 const NodeID rootTid = tpair.first;
876 clearFlagMap();
877 if (const ICFGNode* forkInst = ct.getThread())
878 {
880 for(const ICFGEdge* outEdge : forkInst->getOutEdges())
881 {
882 if(outEdge->getDstNode()->getFun() == forkInst->getFun())
883 {
884 for (const auto& forkSiteCxt : tct->getCxtOfCxtThread(ct))
885 {
886 CxtStmt newCts(forkSiteCxt.second, outEdge->getDstNode());
888 }
889 }
890 }
891
892 while (!cxtStmtList.empty())
893 {
895 const ICFGNode* curInst = cts.getStmt();
896 DBOUT(DMTA, outs() << "-----\nForkJoinAnalysis root thread: " << tpair.first << " ");
897 DBOUT(DMTA, cts.dump());
898 DBOUT(DMTA, outs() << "-----\n");
900 if (isTDFork(curInst))
901 {
903 }
904 else if (isTDJoin(curInst))
905 {
907 }
908 else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
909 {
913 const CallICFGNode *callSite = SVFUtil::cast<CallICFGNode>(curInst);
916 {
917 // Do not dive into non-candidate functions
918 CxtStmt newCts(cts.getContext(), callSite->getRetICFGNode());
920 }
921 else
922 {
924 }
925 }
926 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
927 {
928 handleRet(cts);
929 }
930 else
931 {
933 }
934
938 for (NodeID parentTid : tct->getParentThreads(rootTid))
939 {
942 if (curInst == parentRoutine->getExitBB()->back())
943 {
944 if (getMarkedFlag(cts) != TDAlive)
946 else
948 }
949 }
950 }
951 }
952 }
953}
#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:574
ValDomain getMarkedFlag(const CxtStmt &cs)
Mark thread flags for cxtStmt.
Definition MHP.h:430
const CallGraph::FunctionSet & getCallee(const ICFGNode *inst, CallGraph::FunctionSet &callees)
Definition MHP.h:542
void handleRet(const CxtStmt &cts)
Handle return.
Definition MHP.cpp:1077
CxtStmt popFromCTSWorkList()
Definition MHP.h:491
void addToPartial(NodeID tid1, NodeID tid2)
Definition MHP.h:578
void clearFlagMap()
Clear flags.
Definition MHP.h:478
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:521
void handleCall(const CxtStmt &cts, NodeID rootTid)
Handle call.
Definition MHP.cpp:1052
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:527
void markCxtStmtFlag(const CxtStmt &tgr, ValDomain flag)
Initialize TDAlive and TDDead flags.
Definition MHP.h:442
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
Definition MHP.h:603
void handleIntra(const CxtStmt &cts)
Handle intra.
Definition MHP.cpp:1150
void handleFork(const CxtStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:956
void handleJoin(const CxtStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:983
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:102
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:203
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:268
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:288
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:261
const FunObjVar * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:382
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 478 of file MHP.h.

479 {
480 cxtStmtToAliveFlagMap.clear();
482 }
CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap
flags for context-sensitive statements
Definition MHP.h:602

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

817{
818 // typedef Set<const ICFGNode*> CallInstSet;
819 // typedef Map<const FunObjVar*, CallInstSet> FunToFJSites;
820 // FunToFJSites funToFJSites;
821
822 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(),
823 // eit = tct->getThreadCallGraph()->forksitesEnd();
824 // it != eit; ++it)
825 // {
826 // const ICFGNode* fork = *it;
827 // funToFJSites[fork->getFun()].insert(fork);
828 // }
829
830 // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->joinsitesBegin(),
831 // eit = tct->getThreadCallGraph()->joinsitesEnd();
832 // it != eit; ++it)
833 // {
834 // const ICFGNode* join = *it;
835 // funToFJSites[join->getFun()].insert(join);
836 // }
837
838 // for(FunToFJSites::const_iterator it = funToFJSites.begin(), eit = funToFJSites.end(); it!=eit; ++it)
839 // {
840 // // ScalarEvolution* SE = MTA::getSE(it->first);
841 // for(CallInstSet::const_iterator sit = it->second.begin(), esit = it->second.end(); sit!=esit; ++sit)
842 // {
843 // const SVFInstruction* callInst = *sit;
844 // if(tct->getThreadCallGraph()->isForksite(getCBN(callInst)))
845 // {
846 // // const SVFValue* forkSiteTidPtr = getForkedThread(callInst);
847 // // const SCEV *forkSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(forkSiteTidPtr));
848 // // const SCEV *baseForkTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(forkSiteTidPtr)));
849 // // forkSiteTidPtrSCEV = getSCEVMinusExpr(forkSiteTidPtrSCEV, baseForkTidPtrSCEV, SE);
850 // // PTASCEV scev(forkSiteTidPtr,nullptr,nullptr);
851 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
852 // }
853 // else
854 // {
855 // // const SVFValue* joinSiteTidPtr = getJoinedThread(callInst);
856 // //const SCEV *joinSiteTidPtrSCEV = SE->getSCEV(const_cast<Value*>(joinSiteTidPtr));
857 // //const SCEV *baseJoinTidPtrSCEV = SE->getSCEV(const_cast<Value*>(getBasePtr(joinSiteTidPtr)));
858 // //joinSiteTidPtrSCEV = getSCEVMinusExpr(joinSiteTidPtrSCEV, baseJoinTidPtrSCEV, SE);
859
860 // // PTASCEV scev(joinSiteTidPtr,nullptr,nullptr);
861 // // fkjnToPTASCEVMap.insert(std::make_pair(callInst,scev));
862 // }
863 // }
864 // }
865}

◆ getCallee()

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

Definition at line 542 of file MHP.h.

543 {
544 getTCG()->getCallees(SVFUtil::cast<CallICFGNode>(inst), callees);
545 return callees;
546 }
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Definition CallGraph.h:426
ThreadCallGraph * getTCG() const
ThreadCallGraph.
Definition MHP.h:548

◆ getCxtStmtsFromInst()

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

Get CxtStmtSet for an instruction.

Definition at line 585 of file MHP.h.

586 {
587 InstToCxtStmt::const_iterator it = instToCxtStmt.find(inst);
588 assert(it!=instToCxtStmt.end() && "no CxtStmt for the instruction?");
589 return it->second;
590 }
InstToCxtStmt instToCxtStmt
Map a statement to all its context-sensitive statements.
Definition MHP.h:611

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

1172{
1173
1174 CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs);
1175 if (it != dirAndIndJoinMap.end())
1176 return it->second;
1177
1180
1181 FIFOWorkList<NodeID> worklist;
1182 for (unsigned id : directJoinTids)
1183 {
1184 worklist.push(id);
1185 }
1186
1187 while (!worklist.empty())
1188 {
1189 NodeID tid = worklist.pop();
1190 TCTNode* node = tct->getTCTNode(tid);
1191 for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it)
1192 {
1193 NodeID childTid = (*it)->getDstID();
1194 if (isFullJoin(tid, childTid))
1195 {
1196 allJoinTids.set(childTid);
1197 worklist.push(childTid);
1198 }
1199 }
1200 }
1201
1203
1204 return allJoinTids;
1205}
bool push(const Data &data)
Definition WorkList.h:180
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:380
CxtStmtToTIDMap dirAndIndJoinMap
maps a context-sensitive join site to directly and indirectly joined thread ids
Definition MHP.h:605
NodeBS & getDirectlyJoinedTid(const CxtStmt &cs)
Get directly joined threadIDs based on a context-sensitive join site.
Definition MHP.h:353
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition TCT.h:214
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition TCT.h:218

◆ getDirectlyJoinedTid()

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

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

Definition at line 353 of file MHP.h.

354 {
355 return directJoinMap[cs];
356 }

◆ getForkedThread()

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

Get forked thread.

Definition at line 533 of file MHP.h.

534 {
535 return getTCG()->getThreadAPI()->getForkedThread(call);
536 }
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 538 of file MHP.h.

539 {
540 return getTCG()->getThreadAPI()->getJoinedThread(call);
541 }
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 361 of file MHP.h.

362 {
363 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
364 assert(it!=cxtJoinInLoop.end() && "does not have the loop");
365 return it->second;
366 }

◆ getJoinLoop()

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

Get loop for join site.

Definition at line 388 of file MHP.h.

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

◆ getMarkedFlag()

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

Mark thread flags for cxtStmt.

Get the flag for a cxtStmt

Definition at line 430 of file MHP.h.

431 {
432 CxtStmtToAliveFlagMap::const_iterator it = cxtStmtToAliveFlagMap.find(cs);
433 if(it==cxtStmtToAliveFlagMap.end())
434 {
436 return Empty;
437 }
438 else
439 return it->second;
440 }

◆ getSymmetricLoopJoins()

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

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

Definition at line 397 of file MHP.h.

398 {
399 return cxtJoinInLoop;
400 }

◆ getTCG()

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

ThreadCallGraph.

Definition at line 548 of file MHP.h.

549 {
550 return tct->getThreadCallGraph();
551 }
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:193

◆ handleCall()

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

Handle call.

Definition at line 1052 of file MHP.cpp.

1053{
1054
1055 const ICFGNode* call = cts.getStmt();
1056 const CallStrCxt& curCxt = cts.getContext();
1057 const CallICFGNode* cbn = SVFUtil::cast<CallICFGNode>(call);
1058 if (getTCG()->hasCallGraphEdge(cbn))
1059 {
1060 for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn),
1061 ecgIt = getTCG()->getCallEdgeEnd(cbn);
1062 cgIt != ecgIt; ++cgIt)
1063 {
1064 const FunObjVar* svfcallee = (*cgIt)->getDstNode()->getFunction();
1065 if (isExtCall(svfcallee))
1066 continue;
1069 const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
1072 }
1073 }
1074}
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition MHP.h:501
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 956 of file MHP.cpp.

957{
958 const ICFGNode* call = cts.getStmt();
959 const CallStrCxt& curCxt = cts.getContext();
960
961 assert(isTDFork(call));
962 const CallICFGNode* cbn = cast<CallICFGNode>(call);
963 if (getTCG()->hasThreadForkEdge(cbn))
964 {
965 for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn),
966 ecgIt = getTCG()->getForkEdgeEnd(cbn);
967 cgIt != ecgIt; ++cgIt)
968 {
969 const FunObjVar* callee = (*cgIt)->getDstNode()->getFunction();
972 CxtThread ct(newCxt, call);
973 if (getMarkedFlag(cts) != TDAlive)
975 else
977 }
978 }
980}
void addToHPPair(NodeID tid1, NodeID tid2)
Definition MHP.h:561
void addToHBPair(NodeID tid1, NodeID tid2)
Definition MHP.h:566
NodeID getId() const
Get ID.
Definition SVFValue.h:158

◆ handleIntra()

void ForkJoinAnalysis::handleIntra ( const CxtStmt cts)
private

Handle intra.

Definition at line 1150 of file MHP.cpp.

1151{
1152
1153 const ICFGNode* curInst = cts.getStmt();
1154 const CallStrCxt& curCxt = cts.getContext();
1155
1156 for(const ICFGEdge* outEdge : curInst->getOutEdges())
1157 {
1158 if(outEdge->getDstNode()->getFun() == curInst->getFun())
1159 {
1160 CxtStmt newCts(curCxt, outEdge->getDstNode());
1162 }
1163 }
1164}

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

984{
985 const ICFGNode* call = cts.getStmt();
986 const CallStrCxt& curCxt = cts.getContext();
987
988 assert(isTDJoin(call));
989 const CallICFGNode* cbn = cast<CallICFGNode>(call);
990 if (getTCG()->hasCallGraphEdge(cbn))
991 {
993 const ICFGNode* joinSite = cts.getStmt();
994
995 if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite)))
996 {
997 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
998 SVFUtil::cast<CallICFGNode>(joinSite)) &&
1000 )
1001 {
1002 LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(joinSite));
1003 std::vector<const SVFBasicBlock *> exitbbs;
1004 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
1005 while (!exitbbs.empty())
1006 {
1007 const SVFBasicBlock* eb = exitbbs.back();
1008 exitbbs.pop_back();
1009 const ICFGNode* svfEntryInst = eb->front();
1013 {
1016 }
1017 else
1019 }
1020 }
1023 else
1024 {
1025 std::vector<const SVFBasicBlock*> exitbbs;
1026 joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
1027 while (!exitbbs.empty())
1028 {
1029 const SVFBasicBlock* eb = exitbbs.back();
1030 exitbbs.pop_back();
1031 const ICFGNode* svfEntryInst = eb->front();
1034 }
1035 }
1036 }
1037 else
1038 {
1039 if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite),
1040 SVFUtil::cast<CallICFGNode>(joinSite)))
1041 {
1044 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << "for thread " << rootTid << "\n");
1045 }
1046 }
1047 }
1049}
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:1296
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition MHP.h:329
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:392
void addSymmetricLoopJoin(const CxtStmt &cs, LoopBBs &lp)
Add inloop join.
Definition MHP.h:597
void addDirectlyJoinTID(const CxtStmt &cs, NodeID tid)
maps a context-sensitive join site to a thread id
Definition MHP.h:553
LoopBBs & getJoinLoop(const CallICFGNode *inst)
Get loop for join site.
Definition MHP.h:388
bool isSameSCEV(const ICFGNode *forkSite, const ICFGNode *joinSite)
Return true if the fork and join have the same SCEV.
Definition MHP.cpp:1246
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 1077 of file MHP.cpp.

1078{
1079 const ICFGNode* curInst = cts.getStmt();
1080 const CallStrCxt& curCxt = cts.getContext();
1081
1083 for (CallGraphEdge* edge : curFunNode->getInEdges())
1084 {
1085 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
1086 continue;
1087 for (CallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(),
1088 ecit = edge->directCallsEnd();
1089 cit != ecit; ++cit)
1090 {
1092 const ICFGNode* curNode = (*cit);
1093 if (matchAndPopCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
1094 {
1095 for(const ICFGEdge* outEdge : curNode->getOutEdges())
1096 {
1097 if(outEdge->getDstNode()->getFun() == curNode->getFun())
1098 {
1099 // Iterate over callSite's call string context and use as the successor's context
1100 if (!hasCxtStmtsFromInst(*cit))
1101 continue;
1102 for (const CxtStmt& cxtStmt: getCxtStmtsFromInst(*cit))
1103 {
1104 CallStrCxt callSiteCxt = cxtStmt.getContext();
1105 // If new context is a suffix of the call site context
1107 {
1108 CxtStmt newCts(callSiteCxt, outEdge->getDstNode());
1110 }
1111 }
1112 }
1113 }
1114 }
1115 }
1116 for (CallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(),
1117 ecit = edge->indirectCallsEnd();
1118 cit != ecit; ++cit)
1119 {
1121 const ICFGNode* curNode = (*cit);
1122
1123 if (matchAndPopCxt(newCxt, SVFUtil::cast<CallICFGNode>(curNode), curFunNode->getFunction()))
1124 {
1125 for(const ICFGEdge* outEdge : curNode->getOutEdges())
1126 {
1127 if(outEdge->getDstNode()->getFun() == curNode->getFun())
1128 {
1129 // Iterate over callSite's call string context and use as the successor's context
1130 if (!hasCxtStmtsFromInst(*cit))
1131 continue;
1132 for (const CxtStmt& cxtStmt: getCxtStmtsFromInst(*cit))
1133 {
1134 CallStrCxt callSiteCxt = cxtStmt.getContext();
1135 // If new context is a suffix of the call site context
1137 {
1138 CxtStmt newCts(callSiteCxt, outEdge->getDstNode());
1140 }
1141 }
1142 }
1143 }
1144 }
1145 }
1146 }
1147}
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:509
bool hasCxtStmtsFromInst(const ICFGNode *inst) const
Definition MHP.h:591
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:514
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
Get CxtStmtSet for an instruction.
Definition MHP.h:585

◆ hasCxtStmtsFromInst()

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

Definition at line 591 of file MHP.h.

592 {
593 return instToCxtStmt.find(inst)!=instToCxtStmt.end();
594 }

◆ hasJoinInSymmetricLoop()

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

Definition at line 367 of file MHP.h.

368 {
369 CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs);
370 return it!=cxtJoinInLoop.end();
371 }

◆ hasJoinLoop()

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

Definition at line 392 of file MHP.h.

393 {
394 return tct->hasJoinLoop(inst);
395 }
bool hasJoinLoop(const CallICFGNode *join) const
Definition TCT.h:398

◆ isAliasedForkJoin()

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

Whether it is a matched fork join pair.

Definition at line 1296 of file MHP.cpp.

1298{
1301}
const SVFVar * getForkedThread(const CallICFGNode *call)
Get forked thread.
Definition MHP.h:533
const SVFVar * getJoinedThread(const CallICFGNode *call)
Get joined thread.
Definition MHP.h:538
ThreadAPI::ForkJoinAliasCache forkJoinAliasCache
Definition MHP.h:426
PointerAnalysis * getPTA() const
Get PTA.
Definition TCT.h:198
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 514 of file MHP.h.

515 {
516 return tct->isContextSuffix(lhs,call);
517 }
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:521

◆ isFullJoin()

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

Whether t1 fully joins t2.

Definition at line 380 of file MHP.h.

381 {
382 bool full = fullJoin.find(std::make_pair(tid1,tid2))!=fullJoin.end();
383 bool partial = partialJoin.find(std::make_pair(tid1,tid2))!=partialJoin.end();
384 return full && !partial;
385 }

◆ isHBPair()

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

Whether thread t1 happens-before thread t2.

Definition at line 373 of file MHP.h.

374 {
375 bool nonhp = HBPair.find(std::make_pair(tid1,tid2))!=HBPair.end();
376 bool hp = HPPair.find(std::make_pair(tid1,tid2))!=HPPair.end();
377 return nonhp && !hp;
378 }

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

1247{
1248
1249 // const PTASCEV& forkse = fkjnToPTASCEVMap[forkSite];
1250 // const PTASCEV& joinse = fkjnToPTASCEVMap[joinSite];
1251
1252 // //if(sameLoopTripCount(forkSite,joinSite) == false)
1253 // // return false;
1254
1255 // if(forkse.inloop && joinse.inloop)
1256 // return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount;
1257 // else if(SVFUtil::isa<GetElementPtrInst>(forkse.ptr) && SVFUtil::isa<GetElementPtrInst>(joinse.ptr))
1258 // return accessSameArrayIndex(SVFUtil::cast<GetElementPtrInst>(forkse.ptr),SVFUtil::cast<GetElementPtrInst>(joinse.ptr));
1259 // else if(SVFUtil::isa<GetElementPtrInst, GetElementPtrInst>(joinse.ptr))
1260 // return false;
1261 // else
1262 // return true;
1263
1264 return false;
1265}

◆ isTDFork()

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

Whether it is a fork site.

Definition at line 521 of file MHP.h.

522 {
523 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
524 return fork && getTCG()->getThreadAPI()->isTDFork(fork);
525 }
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 527 of file MHP.h.

528 {
529 const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
530 return join && getTCG()->getThreadAPI()->isTDJoin(join);
531 }
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 454 of file MHP.h.

455 {
458 if(flag_tgr == Empty)
459 {
461 }
462 else if(flag_tgr == TDDead)
463 {
464 if(flag_src==TDAlive)
466 }
467 else
468 {
470 }
472 {
473 instToCxtStmt[tgr.getStmt()].insert(tgr);
475 }
476 }
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
Definition MHP.h:487
ValDomain
semilattice Empty==>TDDead==>TDAlive
Definition MHP.h:323

◆ markCxtStmtFlag() [2/2]

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

Initialize TDAlive and TDDead flags.

Definition at line 442 of file MHP.h.

443 {
447 {
448 instToCxtStmt[tgr.getStmt()].insert(tgr);
450 }
451
452 }

◆ matchAndPopCxt()

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

Match context.

Definition at line 509 of file MHP.h.

510 {
511 return tct->matchAndPopCxt(cxt,call,callee);
512 }
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:493

◆ popFromCTSWorkList()

CxtStmt SVF::ForkJoinAnalysis::popFromCTSWorkList ( )
inlineprivate

Definition at line 491 of file MHP.h.

492 {
493 CxtStmt ctp = cxtStmtList.pop();
494 return ctp;
495 }

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

502 {
504 if(tct->isCandidateFun(call->getFun()) == false)
505 return;
506 tct->pushCxt(cxt,call,callee);
507 }
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:473

◆ pushToCTSWorkList()

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

Worklist operations.

Definition at line 487 of file MHP.h.

488 {
489 return cxtStmtList.push(cs);
490 }

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

1271{
1272
1273 // ScalarEvolution* forkSE = getSE(forkSite);
1274 // ScalarEvolution* joinSE = getSE(joinSite);
1275
1276 // if(tct->hasLoop(forkSite) == false || tct->hasLoop(joinSite) == false)
1277 // return false;
1278
1279 // // Get loops
1280 // const LoopBBs& forkSiteLoop = tct->getLoop(forkSite);
1281 // const LoopBBs& joinSiteLoop = tct->getLoop(joinSite);
1282
1283 // const SCEV* forkLoopCountScev = forkSE->getBackedgeTakenCount(forkSiteLoop);
1284 // const SCEV* joinLoopCountScev = joinSE->getBackedgeTakenCount(joinSiteLoop);
1285
1286 // if(forkLoopCountScev!=forkSE->getCouldNotCompute())
1287 // {
1288 // if(forkLoopCountScev==joinLoopCountScev)
1289 // {
1290 // return true;
1291 // }
1292 // }
1293 return false;
1294}

Member Data Documentation

◆ cxtJoinInLoop

CxtStmtToLoopMap SVF::ForkJoinAnalysis::cxtJoinInLoop
private

a set of context-sensitive join inside loop

Definition at line 606 of file MHP.h.

◆ cxtStmtList

CxtStmtWorkList SVF::ForkJoinAnalysis::cxtStmtList
private

context-sensitive statement worklist

Definition at line 603 of file MHP.h.

◆ cxtStmtToAliveFlagMap

CxtStmtToAliveFlagMap SVF::ForkJoinAnalysis::cxtStmtToAliveFlagMap
private

flags for context-sensitive statements

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

◆ directJoinMap

CxtStmtToTIDMap SVF::ForkJoinAnalysis::directJoinMap
private

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

Definition at line 604 of file MHP.h.

◆ forkJoinAliasCache

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

Definition at line 426 of file MHP.h.

◆ fullJoin

ThreadPairSet SVF::ForkJoinAnalysis::fullJoin
private

t1 fully joins t2 along all program path

Definition at line 609 of file MHP.h.

◆ HBPair

ThreadPairSet SVF::ForkJoinAnalysis::HBPair
private

thread happens-before pair

Definition at line 607 of file MHP.h.

◆ HPPair

ThreadPairSet SVF::ForkJoinAnalysis::HPPair
private

threads happen-in-parallel

Definition at line 608 of file MHP.h.

◆ instToCxtStmt

InstToCxtStmt SVF::ForkJoinAnalysis::instToCxtStmt
private

Map a statement to all its context-sensitive statements.

Definition at line 611 of file MHP.h.

◆ partialJoin

ThreadPairSet SVF::ForkJoinAnalysis::partialJoin
private

t1 partially joins t2 along some program path(s)

Definition at line 610 of file MHP.h.

◆ tct

TCT* SVF::ForkJoinAnalysis::tct
private

Definition at line 601 of file MHP.h.


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