Static Value-Flow Analysis
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | List of all members
SVF::MHP Class Reference

#include <MHP.h>

Classes

struct  NodeThreadSummary
 

Public Types

enum class  StateRepresentation { MaterializedContexts , QuerySummaries }
 
typedef Set< const FunObjVar * > FunSet
 
typedef FIFOWorkList< CxtThreadStmtCxtThreadStmtWorkList
 
typedef Set< CxtThreadStmtCxtThreadStmtSet
 
typedef Map< CxtThreadStmt, NodeBSThreadStmtToThreadInterleav
 
typedef Map< const ICFGNode *, CxtThreadStmtSetInstToThreadStmtSetMap
 
typedef Map< const ICFGNode *, NodeThreadSummaryInstToThreadSummaryMap
 
typedef SVFLoopAndDomInfo::LoopBBs LoopBBs
 
typedef Set< CxtStmtLockSpan
 
typedef std::pair< const FunObjVar *, const FunObjVar * > FuncPair
 
typedef Map< FuncPair, boolFuncPairToBool
 

Public Member Functions

virtual ~MHP ()
 Destructor.
 
template<class ICFGGraph , class CGGraph >
void analyze (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph , class CGGraph >
void analyzeInterleaving (ICFGGraph icfg, CGGraph cg)
 Analyze thread interleaving.
 
ThreadCallGraphgetThreadCallGraph () const
 Get ThreadCallGraph.
 
TCTgetTCT () const
 Get Thread Creation Tree.
 
bool isConnectedfromMain (const FunObjVar *fun)
 Whether the function is connected from main function in thread call graph.
 
virtual bool mayHappenInParallel (const ICFGNode *i1, const ICFGNode *i2)
 Interface to query whether two instructions may happen-in-parallel.
 
virtual bool mayHappenInParallelCache (const ICFGNode *i1, const ICFGNode *i2)
 
virtual bool mayHappenInParallelInst (const ICFGNode *i1, const ICFGNode *i2)
 
virtual bool executedByTheSameThread (const ICFGNode *i1, const ICFGNode *i2)
 
const NodeThreadSummarygetThreadSummary (const ICFGNode *inst) const
 
const NodeBSgetInterleavingThreads (const CxtThreadStmt &cts)
 Get interleaving thread for statement inst.
 
bool hasInterleavingThreads (const CxtThreadStmt &cts) const
 
const CxtThreadStmtSetgetThreadStmtSet (const ICFGNode *inst) const
 Get/has ThreadStmt.
 
bool hasThreadStmtSet (const ICFGNode *inst) const
 
void printInterleaving ()
 Print interleaving results.
 

Static Public Member Functions

template<class ICFGGraph , class CGGraph >
static std::unique_ptr< MHPcreate (TCT *t, ICFGGraph icfg, CGGraph cg, StateRepresentation representation=StateRepresentation::MaterializedContexts)
 Construct MHP and initialize its graph-dependent ForkJoinAnalysis.
 

Public Attributes

u32_t numOfTotalQueries
 Total number of queries.
 
u32_t numOfMHPQueries
 Number of queries are answered as may-happen-in-parallel.
 
double interleavingTime
 
double interleavingQueriesTime
 

Protected Types

typedef Map< const SVFBasicBlock *, std::vector< CxtStmt > > BBToSymJoinsMap
 
typedef Map< CxtStmt, Set< const SVFBasicBlock * > > SymJoinToLoopMap
 

Protected Member Functions

 MHP (TCT *t, StateRepresentation representation=StateRepresentation::MaterializedContexts)
 
template<class ICFGGraph , class CGGraph >
void updateNonCandidateFunInterleaving (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph , class CGGraph >
void buildQuerySummaries (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph , class CGGraph >
void handleNonCandidateFun (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
 Handle non-candidate function.
 
template<class ICFGGraph , class CGGraph >
void handleFork (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
 Handle fork.
 
template<class ICFGGraph , class CGGraph >
void handleJoin (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
 Handle join.
 
template<class ICFGGraph , class CGGraph >
void handleCall (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
 Handle call.
 
template<class ICFGGraph , class CGGraph >
void handleRet (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
 Handle return.
 
template<class ICFGGraph , class CGGraph >
void handleIntra (ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
 Handle intra.
 
void buildSymJoinKillTables ()
 
NodeBS edgeFlow (const CxtThreadStmt &cts, const ICFGNode *dst)
 
void addInterleavingThread (const CxtThreadStmt &tgr, NodeID tid)
 Add/Remove interleaving thread for statement inst.
 
void addInterleavingThread (const CxtThreadStmt &tgr, const CxtThreadStmt &src)
 
void addInterleavingBits (const CxtThreadStmt &tgr, const NodeBS &bits)
 
void rmInterleavingThread (const CxtThreadStmt &tgr, const NodeBS &tids, const ICFGNode *joinsite)
 
template<class ICFGGraph , class CGGraph >
void updateAncestorThreads (ICFGGraph icfg, CGGraph cg, NodeID tid)
 Update Ancestor and sibling threads.
 
template<class ICFGGraph , class CGGraph >
void updateSiblingThreads (ICFGGraph icfg, CGGraph cg, NodeID tid)
 
bool isRecurFullJoin (NodeID parentTid, NodeID curTid)
 Thread curTid can be fully joined by parentTid recursively.
 
bool isMustJoin (const NodeID curTid, const ICFGNode *joinsite)
 Whether a join site must join a thread t.
 
bool isMultiForkedThread (NodeID curTid)
 A thread is a multiForked thread if it is in a loop or recursion.
 
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 pushToCTSWorkList (const CxtThreadStmt &cs)
 WorkList helper functions.
 
CxtThreadStmt popFromCTSWorkList ()
 
bool isTDFork (const ICFGNode *call)
 Whether it is a fork site.
 
bool isTDJoin (const ICFGNode *call)
 Whether it is a join site.
 
NodeBS getDirAndIndJoinedTid (const CallStrCxt &cxt, const ICFGNode *call)
 Return thread id(s) which are directly or indirectly joined at this join site.
 
bool hasJoinInSymmetricLoop (const CallStrCxt &cxt, const ICFGNode *call) const
 Whether a context-sensitive join satisfies symmetric loop pattern.
 
const LoopBBsgetJoinInSymmetricLoop (const CallStrCxt &cxt, const ICFGNode *call) const
 Whether a context-sensitive join satisfies symmetric loop pattern.
 
bool isHBPair (NodeID tid1, NodeID tid2)
 Whether thread t1 happens before t2 based on ForkJoin Analysis.
 

Protected Attributes

ThreadCallGraphtcg
 TCG.
 
TCTtct
 TCT.
 
ForkJoinAnalysisfja
 ForJoin Analysis.
 
CxtThreadStmtWorkList cxtStmtList
 CxtThreadStmt worklist.
 
ThreadStmtToThreadInterleav threadStmtToThreadInterLeav
 
BBToSymJoinsMap bbToSymJoins
 Map a statement to its thread interleavings.
 
SymJoinToLoopMap symJoinLoop
 symmetric in-loop join -> its loop's blocks
 
InstToThreadStmtSetMap instToTSMap
 Map an instruction to its ThreadStmtSet.
 
InstToThreadSummaryMap instToThreadSummary
 Exact per-node/per-tid query compression.
 
Map< const ICFGNode *, const ICFGNode * > querySummaryOwner
 Non-candidate node -> entry summary.
 
StateRepresentation stateRepresentation
 
FuncPairToBool nonCandidateFuncMHPRelMap
 

Detailed Description

This class serves as a base may-happen in parallel analysis for multithreaded program Given a statement under an abstract thread, it tells which abstract threads may be alive at the same time (May-happen-in-parallel).

Definition at line 51 of file MHP.h.

Member Typedef Documentation

◆ BBToSymJoinsMap

Symmetric-join loop-exit kills, applied to EDGE flows (node states stay pure unions, so paths bypassing the join keep their interleavings).

Definition at line 195 of file MHP.h.

◆ CxtThreadStmtSet

Definition at line 57 of file MHP.h.

◆ CxtThreadStmtWorkList

Definition at line 56 of file MHP.h.

◆ FuncPair

Definition at line 75 of file MHP.h.

◆ FuncPairToBool

Definition at line 76 of file MHP.h.

◆ FunSet

Definition at line 55 of file MHP.h.

◆ InstToThreadStmtSetMap

Definition at line 59 of file MHP.h.

◆ InstToThreadSummaryMap

Definition at line 70 of file MHP.h.

◆ LockSpan

Definition at line 73 of file MHP.h.

◆ LoopBBs

Definition at line 71 of file MHP.h.

◆ SymJoinToLoopMap

Definition at line 196 of file MHP.h.

◆ ThreadStmtToThreadInterleav

Definition at line 58 of file MHP.h.

Member Enumeration Documentation

◆ StateRepresentation

Enumerator
MaterializedContexts 
QuerySummaries 

Definition at line 78 of file MHP.h.

Constructor & Destructor Documentation

◆ ~MHP()

MHP::~MHP ( )
virtual

Destructor.

Destructor

Definition at line 105 of file MHP.cpp.

106{
107 delete fja;
108}
ForkJoinAnalysis * fja
ForJoin Analysis.
Definition MHP.h:323

◆ MHP()

MHP::MHP ( TCT t,
StateRepresentation  representation = StateRepresentation::MaterializedContexts 
)
explicitprotected

Construction is paired with ForkJoinAnalysis initialization by create().

Parameters
representationKeep per-context copies for clients that enumerate raw states (the pre-analysis detector and slicer). Main-phase clients issue only MHP queries and can use the exact projected query summary instead.

Constructor

Definition at line 48 of file MHP.cpp.

49 : tcg(t->getThreadCallGraph()), tct(t),
53{
55}
TCT * tct
TCT.
Definition MHP.h:322
u32_t numOfTotalQueries
Total number of queries.
Definition MHP.h:335
ThreadCallGraph * tcg
TCG.
Definition MHP.h:321
StateRepresentation stateRepresentation
Definition MHP.h:331
double interleavingQueriesTime
Definition MHP.h:338
u32_t numOfMHPQueries
Number of queries are answered as may-happen-in-parallel.
Definition MHP.h:336
double interleavingTime
Definition MHP.h:337
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:199
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

Member Function Documentation

◆ addInterleavingBits()

void SVF::MHP::addInterleavingBits ( const CxtThreadStmt tgr,
const NodeBS bits 
)
inlineprotected

Definition at line 220 of file MHP.h.

221 {
223 if(changed)
224 {
225 instToTSMap[tgr.getStmt()].insert(tgr);
227 }
228 }
InstToThreadStmtSetMap instToTSMap
Map an instruction to its ThreadStmtSet.
Definition MHP.h:328
ThreadStmtToThreadInterleav threadStmtToThreadInterLeav
Definition MHP.h:325
bool pushToCTSWorkList(const CxtThreadStmt &cs)
WorkList helper functions.
Definition MHP.h:286

◆ addInterleavingThread() [1/2]

void SVF::MHP::addInterleavingThread ( const CxtThreadStmt tgr,
const CxtThreadStmt src 
)
inlineprotected

Definition at line 211 of file MHP.h.

212 {
214 if(changed)
215 {
216 instToTSMap[tgr.getStmt()].insert(tgr);
218 }
219 }

◆ addInterleavingThread() [2/2]

void SVF::MHP::addInterleavingThread ( const CxtThreadStmt tgr,
NodeID  tid 
)
inlineprotected

Add/Remove interleaving thread for statement inst.

Definition at line 203 of file MHP.h.

204 {
205 if(threadStmtToThreadInterLeav[tgr].test_and_set(tid))
206 {
207 instToTSMap[tgr.getStmt()].insert(tgr);
209 }
210 }

◆ analyze()

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

Start analysis here. One implementation for the whole program and a slice: the compute is templated on the two graphs it traverses – the ICFG (ICFG* whole / const SlicedICFGView* sliced) and the CallGraph (CallGraph* whole / const SlicedThreadCallGraphView* sliced) – and calls their GenericGraphTraits specialisations directly (no wrapper layer).

Start analysis here

Definition at line 115 of file MHP.cpp.

116{
117 DBOUT(DGENERAL, outs() << pasMsg("MHP interleaving analysis\n"));
118 DBOUT(DMTA, outs() << pasMsg("MHP interleaving analysis\n"));
120 analyzeInterleaving(icfg, cg);
123}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DMTA
Definition SVFType.h:597
#define DGENERAL
Definition SVFType.h:582
#define DOTIMESTAT(X)
Definition SVFType.h:578
void analyzeInterleaving(ICFGGraph icfg, CGGraph cg)
Analyze thread interleaving.
Definition MHP.cpp:129
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ analyzeInterleaving()

template<class ICFGGraph , class CGGraph >
void MHP::analyzeInterleaving ( ICFGGraph  icfg,
CGGraph  cg 
)

Analyze thread interleaving.

Analyze thread interleaving

handle non-candidate function

handle candidate function

update non-candidate functions' interleaving

Definition at line 129 of file MHP.cpp.

130{
131 for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
132 {
133 const CxtThread& ct = tpair.second->getCxtThread();
134 NodeID rootTid = tpair.first;
137 CxtThreadStmt rootcts(rootTid, ct.getContext(), svfInst);
138
142
143 while (!cxtStmtList.empty())
144 {
146 const ICFGNode* curInst = cts.getStmt();
147
148 DBOUT(DMTA, outs() << "-----\nMHP analysis root thread: " << rootTid << " ");
149 DBOUT(DMTA, cts.dump());
150 DBOUT(DMTA, outs() << "current thread interleaving: < ");
152 DBOUT(DMTA, outs() << " >\n-----\n");
153
155 if (!tct->isCandidateFun(curInst->getFun()))
156 {
158 }
160 else
161 {
162 if (isTDFork(curInst))
163 {
164 handleFork(icfg, cg, cts, rootTid);
165 }
166 else if (isTDJoin(curInst))
167 {
168 handleJoin(icfg, cg, cts, rootTid);
169 }
170 else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
171 {
172 handleCall(icfg, cg, cts, rootTid);
173 }
174 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
175 {
176 handleRet(icfg, cg, cts);
177 }
178 else
179 {
180 handleIntra(icfg, cg, cts);
181 }
182 }
183 }
184 }
185
189 buildQuerySummaries(icfg, cg);
190
193}
bool empty() const
Definition WorkList.h:161
CxtThreadStmtWorkList cxtStmtList
CxtThreadStmt worklist.
Definition MHP.h:324
void handleRet(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
Handle return.
Definition MHP.cpp:507
void printInterleaving()
Print interleaving results.
Definition MHP.cpp:887
void updateSiblingThreads(ICFGGraph icfg, CGGraph cg, NodeID tid)
Definition MHP.cpp:654
void handleFork(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:341
void updateAncestorThreads(ICFGGraph icfg, CGGraph cg, NodeID tid)
Update Ancestor and sibling threads.
Definition MHP.cpp:610
void handleCall(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
Handle call.
Definition MHP.cpp:438
void addInterleavingThread(const CxtThreadStmt &tgr, NodeID tid)
Add/Remove interleaving thread for statement inst.
Definition MHP.h:203
const NodeBS & getInterleavingThreads(const CxtThreadStmt &cts)
Get interleaving thread for statement inst.
Definition MHP.h:130
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:297
void handleJoin(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:374
void buildQuerySummaries(ICFGGraph icfg, CGGraph cg)
Definition MHP.cpp:201
void updateNonCandidateFunInterleaving(ICFGGraph icfg, CGGraph cg)
Definition MHP.cpp:275
void handleIntra(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
Handle intra.
Definition MHP.cpp:585
CxtThreadStmt popFromCTSWorkList()
Definition MHP.h:290
void handleNonCandidateFun(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt &cts)
Handle non-candidate function.
Definition MHP.cpp:316
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:303
static const Option< bool > PrintInterLev
Definition Options.h:155
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
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:153
u32_t NodeID
Definition GeneralType.h:76

◆ buildQuerySummaries()

template<class ICFGGraph , class CGGraph >
void MHP::buildQuerySummaries ( ICFGGraph  icfg,
CGGraph  cg 
)
protected

Build the exact, context-compressed representation used by repeated MHP queries after the context-sensitive fixed point has converged.

Compress the converged context-sensitive states for repeated MHP queries. Contexts are retained in the propagation maps; this is a query-only index and therefore cannot change the fixed point.

Definition at line 201 of file MHP.cpp.

202{
203 instToThreadSummary.clear();
204 querySummaryOwner.clear();
205 for (const auto& instAndStates : instToTSMap)
206 {
207 NodeThreadSummary& summary = instToThreadSummary[instAndStates.first];
209 {
210 const NodeID tid = state.getTid();
211 summary.tids.set(tid);
212 ThreadStmtToThreadInterleav::const_iterator it =
215 "MHP query summary requires a converged context state");
216 summary.interleavingByTid[tid] |= it->second;
217 }
218 }
219
221 return;
222
223 // The materialized representation copies a non-candidate function entry's state
224 // unchanged to each of that function's nodes. Main-phase clients need only
225 // query answers, so project the already-compressed entry summary instead of
226 // creating one CxtThreadStmt and one NodeBS per context at every node.
228 for (auto nodeIt = CGTraits::nodes_begin(cg),
229 nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt)
230 {
231 const CallGraphNode* callGraphNode = CGTraits::getRawNode(*nodeIt);
232 const FunObjVar* fun = callGraphNode->getFunction();
233 if (tct->isCandidateFun(fun) || isExtCall(fun))
234 continue;
235
236 const ICFGNode* entryNode =
238 InstToThreadSummaryMap::const_iterator entryIt =
240 if (entryIt == instToThreadSummary.end())
241 continue;
242
243 std::vector<const ICFGNode*> funICFGNodes;
245 for (const ICFGNode* node : funICFGNodes)
246 {
247 if (node == entryNode)
248 continue;
249 const bool inserted = querySummaryOwner.emplace(node, entryNode).second;
251 "non-candidate internal node unexpectedly had a raw MHP state");
252 (void)inserted;
253 }
254 }
255}
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
InstToThreadSummaryMap instToThreadSummary
Exact per-node/per-tid query compression.
Definition MHP.h:329
Map< const ICFGNode *, const ICFGNode * > querySummaryOwner
Non-candidate node -> entry summary.
Definition MHP.h:330
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441

◆ buildSymJoinKillTables()

void MHP::buildSymJoinKillTables ( )
protected

Index the SCEV-symmetric in-loop joins by their loop blocks.

Definition at line 60 of file MHP.cpp.

61{
62 for (const auto& joinAndLoop : fja->getSymmetricLoopJoins())
63 {
65 for (const SVFBasicBlock* bb : joinAndLoop.second)
66 {
67 loopBlocks.insert(bb);
68 bbToSymJoins[bb].push_back(joinAndLoop.first);
69 }
70 }
71}
BBToSymJoinsMap bbToSymJoins
Map a statement to its thread interleavings.
Definition MHP.h:326
SymJoinToLoopMap symJoinLoop
symmetric in-loop join -> its loop's blocks
Definition MHP.h:327

◆ create()

template<class ICFGGraph , class CGGraph >
std::unique_ptr< MHP > SVF::MHP::create ( TCT t,
ICFGGraph  icfg,
CGGraph  cg,
StateRepresentation  representation = StateRepresentation::MaterializedContexts 
)
static

Construct MHP and initialize its graph-dependent ForkJoinAnalysis.

Definition at line 646 of file MHP.h.

648{
649 std::unique_ptr<MHP> mhp(new MHP(t, representation));
650 mhp->fja->analyzeForkJoinPair(icfg, cg);
651 mhp->buildSymJoinKillTables();
652 return mhp;
653}
MHP(TCT *t, StateRepresentation representation=StateRepresentation::MaterializedContexts)
Definition MHP.cpp:48

◆ edgeFlow()

NodeBS MHP::edgeFlow ( const CxtThreadStmt cts,
const ICFGNode dst 
)
protected

Flow along edge cts.stmt -> dst: an edge leaving a symmetric join loop drops the joined tids (edge kill; the destination's state is never subtracted from).

Definition at line 77 of file MHP.cpp.

78{
80 const SVFBasicBlock* srcBB = cts.getStmt()->getBB();
81 const SVFBasicBlock* dstBB = dst->getBB();
82 if (srcBB == nullptr || dstBB == nullptr || srcBB == dstBB)
83 return flow;
84 BBToSymJoinsMap::const_iterator it = bbToSymJoins.find(srcBB);
85 if (it == bbToSymJoins.end())
86 return flow;
87 for (const CxtStmt& join : it->second)
88 {
89 if (join.getContext() != cts.getContext())
90 continue;
92 if (loopBlocks.find(dstBB) != loopBlocks.end())
93 continue; // edge stays inside the loop
94 if (!isMustJoin(cts.getTid(), join.getStmt()))
95 continue;
96 flow.intersectWithComplement(
97 getDirAndIndJoinedTid(join.getContext(), join.getStmt()));
98 }
99 return flow;
100}
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
Definition ICFGNode.h:81
bool isMustJoin(const NodeID curTid, const ICFGNode *joinsite)
Whether a join site must join a thread t.
Definition MHP.cpp:719
NodeBS getDirAndIndJoinedTid(const CallStrCxt &cxt, const ICFGNode *call)
Return thread id(s) which are directly or indirectly joined at this join site.
Definition MHP.cpp:729

◆ executedByTheSameThread()

bool MHP::executedByTheSameThread ( const ICFGNode i1,
const ICFGNode i2 
)
virtual

Definition at line 866 of file MHP.cpp.

867{
868 const NodeThreadSummary* summary1 = getThreadSummary(i1);
869 const NodeThreadSummary* summary2 = getThreadSummary(i2);
870 if (summary1 == nullptr || summary2 == nullptr)
871 return true;
872
873 for (NodeID tid1 : summary1->tids)
874 {
875 for (NodeID tid2 : summary2->tids)
876 {
878 return false;
879 }
880 }
881 return true;
882}
bool isMultiForkedThread(NodeID curTid)
A thread is a multiForked thread if it is in a loop or recursion.
Definition MHP.h:257
const NodeThreadSummary * getThreadSummary(const ICFGNode *inst) const
Definition MHP.cpp:257

◆ getDirAndIndJoinedTid()

NodeBS MHP::getDirAndIndJoinedTid ( const CallStrCxt cxt,
const ICFGNode call 
)
protected

Return thread id(s) which are directly or indirectly joined at this join site.

Return thread id(s) which are directly or indirectly joined at this join site

Definition at line 729 of file MHP.cpp.

730{
731 CxtStmt cs(cxt, call);
732 return fja->getDirAndIndJoinedTid(cs);
733}
NodeBS getDirAndIndJoinedTid(const CxtStmt &cs)
Get directly and indirectly joined threadIDs based on a context-sensitive join site.
Definition MHP.cpp:1306

◆ getInterleavingThreads()

const NodeBS & SVF::MHP::getInterleavingThreads ( const CxtThreadStmt cts)
inline

Get interleaving thread for statement inst.

Definition at line 130 of file MHP.h.

131 {
133 }

◆ getJoinInSymmetricLoop()

const MHP::LoopBBs & MHP::getJoinInSymmetricLoop ( const CallStrCxt cxt,
const ICFGNode call 
) const
protected

Whether a context-sensitive join satisfies symmetric loop pattern.

Definition at line 745 of file MHP.cpp.

746{
747 CxtStmt cs(cxt, call);
748 return fja->getJoinInSymmetricLoop(cs);
749}
const LoopBBs & getJoinInSymmetricLoop(const CxtStmt &cs) const
Whether a context-sensitive join satisfies symmetric loop pattern.
Definition MHP.h:389

◆ getTCT()

TCT * SVF::MHP::getTCT ( ) const
inline

Get Thread Creation Tree.

Definition at line 110 of file MHP.h.

111 {
112 return tct;
113 }

◆ getThreadCallGraph()

ThreadCallGraph * SVF::MHP::getThreadCallGraph ( ) const
inline

Get ThreadCallGraph.

Definition at line 104 of file MHP.h.

105 {
106 return tcg;
107 }

◆ getThreadStmtSet()

const CxtThreadStmtSet & SVF::MHP::getThreadStmtSet ( const ICFGNode inst) const
inline

Get/has ThreadStmt.

Definition at line 142 of file MHP.h.

143 {
144 InstToThreadStmtSetMap::const_iterator it = instToTSMap.find(inst);
145 assert(it!=instToTSMap.end() && "no thread access the instruction?");
146 return it->second;
147 }

◆ getThreadSummary()

const MHP::NodeThreadSummary * MHP::getThreadSummary ( const ICFGNode inst) const

Representation-independent per-thread summary used by MHP clients. Available after analyze() in both materialized and summary-only modes.

Definition at line 257 of file MHP.cpp.

258{
259 InstToThreadSummaryMap::const_iterator it = instToThreadSummary.find(inst);
260 if (it != instToThreadSummary.end())
261 return &it->second;
262 const auto ownerIt = querySummaryOwner.find(inst);
263 if (ownerIt == querySummaryOwner.end())
264 return nullptr;
265 it = instToThreadSummary.find(ownerIt->second);
266 assert(it != instToThreadSummary.end() &&
267 "non-candidate query-summary owner has no entry summary");
268 return &it->second;
269}

◆ handleCall()

template<class ICFGGraph , class CGGraph >
void MHP::handleCall ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts,
NodeID  rootTid 
)
protected

Handle call.

Handle call instruction in the current thread scope (excluding any 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.

Definition at line 438 of file MHP.cpp.

439{
440
441 const ICFGNode* call = cts.getStmt();
442 const CallStrCxt& curCxt = cts.getContext();
443 const CallICFGNode* cbn = cast<CallICFGNode>(call);
445 std::vector<const CallGraphEdge*> outEdges;
447 for (const CallGraphEdge* edge : outEdges)
448 {
449 if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge ||
451 continue;
452 const FunObjVar* svfcallee = edge->getDstNode()->getFunction();
453 if (isExtCall(svfcallee))
454 continue;
455
458 const ICFGNode* svfEntryInst =
460 if (svfEntryInst == nullptr)
461 continue;
464
465 // Return-flow rendezvous: if the callee's exit already has state
466 // under newCxt, forward it now (handleRet cannot see late callsites).
467 if (tct->isCandidateFun(svfcallee) && svfcallee->hasBasicBlock())
468 {
469 const ICFGNode* exitInst =
471 if (exitInst == nullptr)
472 continue;
476 {
477 CxtThreadStmt retCts(cts.getTid(), curCxt,
478 cbn->getRetICFGNode());
480 }
481 }
482 }
483
487 if (const CallICFGNode *callSite = SVFUtil::cast<CallICFGNode>(call))
488 {
492 {
493 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), callSite->getRetICFGNode());
495 }
496 }
497 else
498 {
499 assert(false && "cts.getStmt() is not a CallICFGNode!");
500 }
501}
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition MHP.h:265
std::vector< u32_t > CallStrCxt
Definition GeneralType.h:96

◆ handleFork()

template<class ICFGGraph , class CGGraph >
void MHP::handleFork ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts,
NodeID  rootTid 
)
protected

Handle fork.

Handle fork

Definition at line 341 of file MHP.cpp.

342{
343
344 const ICFGNode* call = cts.getStmt();
345 const CallStrCxt& curCxt = cts.getContext();
346
347 assert(isTDFork(call));
348 const CallICFGNode* cbn = cast<CallICFGNode>(call);
350 std::vector<const CallGraphEdge*> outEdges;
352 for (const CallGraphEdge* edge : outEdges)
353 {
354 if (edge->getEdgeKind() != CallGraphEdge::TDForkEdge ||
356 continue;
357 const FunObjVar* svfroutine = edge->getDstNode()->getFunction();
361 CxtThread ct(newCxt, call);
362 if (!tct->hasTCTNode(ct))
363 continue;
364 CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
366 }
367 handleIntra(icfg, cg, cts);
368}
NodeID getId() const
Get ID.
Definition SVFValue.h:158
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:209
bool hasTCTNode(const CxtThread &ct) const
Find/Get TCT node.
Definition TCT.h:281

◆ handleIntra()

template<class ICFGGraph , class CGGraph >
void MHP::handleIntra ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts 
)
protected

Handle intra.

Handling intraprocedural statements (successive statements on the CFG )

Definition at line 585 of file MHP.cpp.

586{
587 const SVFBasicBlock* srcBB = cts.getStmt()->getBB();
588 const bool mayExitSymJoinLoop =
589 srcBB != nullptr && bbToSymJoins.find(srcBB) != bbToSymJoins.end();
590
591 std::vector<const ICFGNode*> succ;
593 for (const ICFGNode* dst : succ)
594 {
595 if(dst->getFun() == cts.getStmt()->getFun())
596 {
597 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), dst);
600 else
602 }
603 }
604}
NodeBS edgeFlow(const CxtThreadStmt &cts, const ICFGNode *dst)
Definition MHP.cpp:77
void addInterleavingBits(const CxtThreadStmt &tgr, const NodeBS &bits)
Definition MHP.h:220
const_iterator end() const

◆ handleJoin()

template<class ICFGGraph , class CGGraph >
void MHP::handleJoin ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts,
NodeID  rootTid 
)
protected

Handle join.

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

375{
376
377 const CallStrCxt& curCxt = cts.getContext();
378
379 assert(isTDJoin(cts.getStmt()));
380
381 const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(cts.getStmt());
382
384 if (!joinedTids.empty())
385 {
386 if (fja->hasJoinLoop(call))
387 {
388 // Seed the loop exits with the flow along the exiting edge (see
389 // edgeFlow): the kill applies to the flow, not the exit's state.
391 if (hasJoinInSymmetricLoop(curCxt, call) && isMustJoin(cts.getTid(), call))
392 flow.intersectWithComplement(joinedTids);
393
394 std::vector<const SVFBasicBlock*> exitbbs;
395 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
396 while (!exitbbs.empty())
397 {
398 const SVFBasicBlock* eb = exitbbs.back();
399 exitbbs.pop_back();
400 // Seed the post-join interleaving at the loop-exit entry. The slicer
401 // retains these entries as anchors, so the seed always lands on a kept
402 // node (no runtime projection needed).
403 CxtThreadStmt newCts(cts.getTid(), curCxt, eb->front());
405 }
406 }
407 else
408 {
410 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << " for thread " << rootTid << "\n");
411 }
412 }
415 else
416 {
417 if (fja->hasJoinLoop(call))
418 {
419 std::vector<const SVFBasicBlock*> exitbbs;
420 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
421 while (!exitbbs.empty())
422 {
423 const SVFBasicBlock* eb = exitbbs.back();
424 exitbbs.pop_back();
425 // Seed at the loop-exit entry (a retained anchor; see above).
426 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), eb->front());
428 }
429 }
430 }
431 handleIntra(icfg, cg, cts);
432}
const std::string toString() const override
Definition ICFG.cpp:129
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:420
void getExitBlocksOfLoop(const SVFBasicBlock *bb, BBList &exitbbs) const
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:75
void rmInterleavingThread(const CxtThreadStmt &tgr, const NodeBS &tids, const ICFGNode *joinsite)
Definition MHP.h:229
bool hasJoinInSymmetricLoop(const CallStrCxt &cxt, const ICFGNode *call) const
Whether a context-sensitive join satisfies symmetric loop pattern.
Definition MHP.cpp:738
const ICFGNode * back() const

◆ handleNonCandidateFun()

template<class ICFGGraph , class CGGraph >
void MHP::handleNonCandidateFun ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts 
)
protected

Handle non-candidate function.

Handle call instruction in the current thread scope (excluding any fork site)

Definition at line 316 of file MHP.cpp.

317{
318 const ICFGNode* curInst = cts.getStmt();
319 const FunObjVar* curfun = curInst->getFun();
320 assert((curInst == GenericGraphTraits<ICFGGraph>::getFunEntry(icfg, curfun)) && "curInst is not the entry of non candidate function.");
321 const CallStrCxt& curCxt = cts.getContext();
323 std::vector<const CallGraphEdge*> outEdges;
325 for (const CallGraphEdge* edge : outEdges)
326 {
327 const FunObjVar* callee = edge->getDstNode()->getFunction();
328 if (!isExtCall(callee))
329 {
333 }
334 }
335}

◆ handleRet()

template<class ICFGGraph , class CGGraph >
void MHP::handleRet ( ICFGGraph  icfg,
CGGraph  cg,
const CxtThreadStmt cts 
)
protected

Handle return.

Handle return instruction in the current thread scope (excluding any join site)

Definition at line 507 of file MHP.cpp.

508{
509 CallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun());
510 std::vector<const CallGraphEdge*> inEdges;
512 for (const CallGraphEdge* edgeConst : inEdges)
513 {
514 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edgeConst))
515 continue;
516 std::vector<const CallICFGNode*> directCalls;
518 for (const CallICFGNode* callSite : directCalls)
519 {
520 CallStrCxt newCxt = cts.getContext();
521 if (matchAndPopCxt(newCxt, callSite, curFunNode->getFunction()))
522 {
523 std::vector<const ICFGNode*> succ;
525 for (const ICFGNode* dst : succ)
526 {
527 if(dst->getFun() == callSite->getFun())
528 {
529 // Iterate over callSite's call string context and use as the successor's context
531 continue;
532 for (const CxtThreadStmt& cxtThreadStmt:
534 {
535 CallStrCxt callSiteCxt = cxtThreadStmt.getContext();
536 // If new context is a suffix of the call site context
538 {
539 CxtThreadStmt newCts(cts.getTid(), callSiteCxt, dst);
541 }
542 }
543 }
544 }
545 }
546 }
547 std::vector<const CallICFGNode*> indirectCalls;
549 for (const CallICFGNode* callSite : indirectCalls)
550 {
551 CallStrCxt newCxt = cts.getContext();
552 if (matchAndPopCxt(newCxt, callSite, curFunNode->getFunction()))
553 {
554 std::vector<const ICFGNode*> succ;
556 for (const ICFGNode* dst : succ)
557 {
558 if(dst->getFun() == callSite->getFun())
559 {
560 // Iterate over callSite's call string context and use as the successor's context
562 continue;
563 for (const CxtThreadStmt& cxtThreadStmt:
565 {
566 CallStrCxt callSiteCxt = cxtThreadStmt.getContext();
567 // If new context is a suffix of the call site context
569 {
570 CxtThreadStmt newCts(cts.getTid(), callSiteCxt, dst);
572 }
573 }
574 }
575 }
576 }
577 }
578 }
579}
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition MHP.h:273
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:278
const CxtThreadStmtSet & getThreadStmtSet(const ICFGNode *inst) const
Get/has ThreadStmt.
Definition MHP.h:142
bool hasThreadStmtSet(const ICFGNode *inst) const
Definition MHP.h:148

◆ hasInterleavingThreads()

bool SVF::MHP::hasInterleavingThreads ( const CxtThreadStmt cts) const
inline

Definition at line 134 of file MHP.h.

135 {
137 }

◆ hasJoinInSymmetricLoop()

bool MHP::hasJoinInSymmetricLoop ( const CallStrCxt cxt,
const ICFGNode call 
) const
protected

Whether a context-sensitive join satisfies symmetric loop pattern.

Whether a context-sensitive join satisfies symmetric loop pattern

Definition at line 738 of file MHP.cpp.

739{
740 CxtStmt cs(cxt, call);
741 return fja->hasJoinInSymmetricLoop(cs);
742}
bool hasJoinInSymmetricLoop(const CxtStmt &cs) const
Definition MHP.h:395

◆ hasThreadStmtSet()

bool SVF::MHP::hasThreadStmtSet ( const ICFGNode inst) const
inline

Definition at line 148 of file MHP.h.

149 {
150 return instToTSMap.find(inst)!=instToTSMap.end();
151 }

◆ isConnectedfromMain()

bool MHP::isConnectedfromMain ( const FunObjVar fun)

Whether the function is connected from main function in thread call graph.

Definition at line 759 of file MHP.cpp.

760{
763 TCT::PTACGNodeSet visited;
764 worklist.push(cgnode);
765 visited.insert(cgnode);
766 while (!worklist.empty())
767 {
768 const CallGraphNode* node = worklist.pop();
770 return true;
771 for (CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
772 {
773 const CallGraphNode* srcNode = (*nit)->getSrcNode();
774 if (visited.find(srcNode) == visited.end())
775 {
776 visited.insert(srcNode);
777 worklist.push(srcNode);
778 }
779 }
780 }
781 return false;
782}
bool push(const Data &data)
Definition WorkList.h:180
GEdgeSetTy::const_iterator const_iterator
iterator InEdgeBegin()
iterator InEdgeEnd()
Set< const CallGraphNode * > PTACGNodeSet
Definition TCT.h:176
bool isProgEntryFunction(const FunObjVar *)
Program entry function e.g. main.
Definition SVFUtil.cpp:446

◆ isContextSuffix()

bool SVF::MHP::isContextSuffix ( const CallStrCxt lhs,
const CallStrCxt  call 
)
inlineprotected

If lhs is a suffix of rhs, including equal.

Definition at line 278 of file MHP.h.

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

◆ isHBPair()

bool MHP::isHBPair ( NodeID  tid1,
NodeID  tid2 
)
protected

Whether thread t1 happens before t2 based on ForkJoin Analysis.

Whether two thread t1 happens-fore t2

Definition at line 754 of file MHP.cpp.

755{
756 return fja->isHBPair(tid1, tid2);
757}
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens-before thread t2.
Definition MHP.h:401

◆ isMultiForkedThread()

bool SVF::MHP::isMultiForkedThread ( NodeID  curTid)
inlineprotected

A thread is a multiForked thread if it is in a loop or recursion.

Definition at line 257 of file MHP.h.

258 {
260 }
bool isMultiforked() const
Definition TCT.h:122

◆ isMustJoin()

bool MHP::isMustJoin ( const NodeID  curTid,
const ICFGNode joinsite 
)
protected

Whether a join site must join a thread t.

A join site must join t if (1) t is not a multiforked thread (2) the join site of t is not in recursion

Definition at line 719 of file MHP.cpp.

720{
721 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(joinsite);
722 assert(call && isTDJoin(call) && "not a join site!");
724}
bool isJoinSiteInRecursion(const CallICFGNode *join) const
Whether a join site is in recursion.
Definition TCT.h:438

◆ isRecurFullJoin()

bool MHP::isRecurFullJoin ( NodeID  parentTid,
NodeID  curTid 
)
protected

Thread curTid can be fully joined by parentTid recursively.

Whether curTid can be fully joined by parentTid recursively

Definition at line 684 of file MHP.cpp.

685{
686 if (parentTid == curTid)
687 return true;
688
691 worklist.push(curNode);
692 while (!worklist.empty())
693 {
694 const TCTNode* node = worklist.pop();
695 for (TCTEdge* edge : node->getInEdges())
696 {
697 NodeID srcID = edge->getSrcID();
698 if (fja->isFullJoin(srcID, node->getId()))
699 {
700 if (srcID == parentTid)
701 return true;
702 else
703 worklist.push(edge->getSrcNode());
704 }
705 else
706 {
707 return false;
708 }
709 }
710 }
711 return false;
712}
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:408

◆ isTDFork()

bool SVF::MHP::isTDFork ( const ICFGNode call)
inlineprotected

Whether it is a fork site.

Definition at line 297 of file MHP.h.

298 {
299 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
300 return fork && tcg->getThreadAPI()->isTDFork(fork);
301 }
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
ThreadAPI * getThreadAPI() const
Thread API.

◆ isTDJoin()

bool SVF::MHP::isTDJoin ( const ICFGNode call)
inlineprotected

Whether it is a join site.

Definition at line 303 of file MHP.h.

304 {
305 const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
306 return join && tcg->getThreadAPI()->isTDJoin(join);
307 }
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.

◆ matchAndPopCxt()

bool SVF::MHP::matchAndPopCxt ( CallStrCxt cxt,
const CallICFGNode call,
const FunObjVar callee 
)
inlineprotected

Match context.

Definition at line 273 of file MHP.h.

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

◆ mayHappenInParallel()

bool MHP::mayHappenInParallel ( const ICFGNode i1,
const ICFGNode i2 
)
virtual

Interface to query whether two instructions may happen-in-parallel.

Definition at line 854 of file MHP.cpp.

855{
857
858 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
859 bool mhp = mayHappenInParallelCache(i1, i2);
860 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
862
863 return mhp;
864}
virtual bool mayHappenInParallelCache(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:832

◆ mayHappenInParallelCache()

bool MHP::mayHappenInParallelCache ( const ICFGNode i1,
const ICFGNode i2 
)
virtual

Definition at line 832 of file MHP.cpp.

833{
834 if (!tct->isCandidateFun(i1->getFun()) && !tct->isCandidateFun(i2->getFun()))
835 {
836 FuncPair funpair = std::make_pair(i1->getFun(), i2->getFun());
837 FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
838 if (it == nonCandidateFuncMHPRelMap.end())
839 {
840 bool mhp = mayHappenInParallelInst(i1, i2);
842 return mhp;
843 }
844 else
845 {
846 if (it->second)
848 return it->second;
849 }
850 }
852}
FuncPairToBool nonCandidateFuncMHPRelMap
Definition MHP.h:332
std::pair< const FunObjVar *, const FunObjVar * > FuncPair
Definition MHP.h:75
virtual bool mayHappenInParallelInst(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:794

◆ mayHappenInParallelInst()

bool MHP::mayHappenInParallelInst ( const ICFGNode i1,
const ICFGNode i2 
)
virtual

Answer MHP queries For a pair of ThreadStmts (t1,s1) = <l1> (t2,s2) = <l2> They may happen in parallel if (1) t1 == t2 and t1 inloop/incycle (2) t1!=t2 and t1 \in l2 and t2 \in l1

TODO: Any instruction in dead function is assumed no MHP with others.

Definition at line 794 of file MHP.cpp.

795{
797 const NodeThreadSummary* summary1 = getThreadSummary(i1);
798 const NodeThreadSummary* summary2 = getThreadSummary(i2);
799 if (summary1 == nullptr || summary2 == nullptr)
800 return false;
801
802 // Original rule for distinct tids:
803 // exists c1,c2. L(i1,tid1,c1)[tid2] && L(i2,tid2,c2)[tid1].
804 // The two context choices are independent, so this is exactly equivalent
805 // to testing the two per-tid context unions. No context correlation is lost.
806 for (NodeID tid1 : summary1->tids)
807 {
808 if (summary2->tids.test(tid1) && isMultiForkedThread(tid1))
809 {
811 return true;
812 }
813
814 const auto firstFlowIt = summary1->interleavingByTid.find(tid1);
815 assert(firstFlowIt != summary1->interleavingByTid.end());
817 {
818 if (tid1 == tid2 || !summary2->tids.test(tid2))
819 continue;
820 const auto secondFlowIt = summary2->interleavingByTid.find(tid2);
821 assert(secondFlowIt != summary2->interleavingByTid.end());
822 if (secondFlowIt->second.test(tid1))
823 {
825 return true;
826 }
827 }
828 }
829 return false;
830}

◆ popFromCTSWorkList()

CxtThreadStmt SVF::MHP::popFromCTSWorkList ( )
inlineprotected

Definition at line 290 of file MHP.h.

291 {
292 CxtThreadStmt ctp = cxtStmtList.pop();
293 return ctp;
294 }

◆ printInterleaving()

void MHP::printInterleaving ( )

Print interleaving results.

Print interleaving results

Definition at line 887 of file MHP.cpp.

888{
889 for (const auto& pair : threadStmtToThreadInterLeav)
890 {
891 outs() << "( t" << pair.first.getTid()
892 << pair.first.getStmt()->toString() << " ) ==> [";
893 for (unsigned i : pair.second)
894 {
895 outs() << " " << i << " ";
896 }
897 outs() << "]\n";
898 }
899}

◆ pushCxt()

void SVF::MHP::pushCxt ( CallStrCxt cxt,
const CallICFGNode call,
const FunObjVar callee 
)
inlineprotected

Context helper functions.

Push calling context

handle calling context for candidate functions only

Definition at line 265 of file MHP.h.

266 {
268 if(tct->isCandidateFun(call->getFun()) == false)
269 return;
270 tct->pushCxt(cxt,call,callee);
271 }
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:483

◆ pushToCTSWorkList()

bool SVF::MHP::pushToCTSWorkList ( const CxtThreadStmt cs)
inlineprotected

WorkList helper functions.

Definition at line 286 of file MHP.h.

287 {
288 return cxtStmtList.push(cs);
289 }

◆ rmInterleavingThread()

void SVF::MHP::rmInterleavingThread ( const CxtThreadStmt tgr,
const NodeBS tids,
const ICFGNode joinsite 
)
inlineprotected

Definition at line 229 of file MHP.h.

230 {
232 for(NodeBS::iterator it = tids.begin(), eit = tids.end(); it!=eit; ++it)
233 {
234 if(isMustJoin(tgr.getTid(),joinsite))
235 joinedTids.set(*it);
236 }
237 if(threadStmtToThreadInterLeav[tgr].intersectWithComplement(joinedTids))
238 {
240 }
241 }
SparseBitVectorIterator iterator
void set(unsigned Idx)
SparseBitVector NodeBS
Definition GeneralType.h:82

◆ updateAncestorThreads()

template<class ICFGGraph , class CGGraph >
void MHP::updateAncestorThreads ( ICFGGraph  icfg,
CGGraph  cg,
NodeID  curTid 
)
protected

Update Ancestor and sibling threads.

Update interleavings of ancestor threads according to TCT

Definition at line 610 of file MHP.cpp.

611{
613 DBOUT(DMTA, outs() << "##Ancestor thread of " << curTid << " is : ");
615 DBOUT(DMTA, outs() << "\n");
617
618 for (const unsigned tid : ancestorAndSelfTids)
619 {
620 const CxtThread& ct = tct->getTCTNode(tid)->getCxtThread();
621 if (const ICFGNode* forkInst = ct.getThread())
622 {
623 // Mark the fork site's successors under the graph, so a sliced run
624 // marks kept successors (a marker on a removed node would strand).
625 std::vector<const ICFGNode*> succ;
627 for(const ICFGNode* dst : succ)
628 {
629 // Ensure dst node is in the same function as forkInst
630 if(dst->getFun() == forkInst->getFun())
631 {
632 for (const auto& forkSiteCxt : tct->getCxtOfCxtThread(ct))
633 {
634 CxtThreadStmt cts(forkSiteCxt.first, forkSiteCxt.second, dst);
636 }
637 }
638 }
639 }
640 }
641}
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:103
const NodeBS getAncestorThreads(NodeID tid) const
Get all ancestor threads.
Definition TCT.h:336

◆ updateNonCandidateFunInterleaving()

template<class ICFGGraph , class CGGraph >
void MHP::updateNonCandidateFunInterleaving ( ICFGGraph  icfg,
CGGraph  cg 
)
protected

Update non-candidate functions' interleaving. Copy interleaving threads of the entry inst to other insts.

Update non-candidate functions' interleaving

Definition at line 275 of file MHP.cpp.

276{
277 // Copy each non-candidate function entry's interleaving to the function's
278 // other nodes under the graph. Runs after the worklist has drained, so
279 // addInterleavingThread's push is inert.
281 for (auto nodeIt = CGTraits::nodes_begin(cg),
282 nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt)
283 {
284 const CallGraphNode* callGraphNode = CGTraits::getRawNode(*nodeIt);
285 const FunObjVar* fun = callGraphNode->getFunction();
286 if (tct->isCandidateFun(fun) || isExtCall(fun))
287 continue;
288
291 continue;
292
294
295 std::vector<const ICFGNode*> funICFGNodes;
297
298 for (const CxtThreadStmt& cts : tsSet)
299 {
300 const CallStrCxt& curCxt = cts.getContext();
301 for (const ICFGNode* curNode : funICFGNodes)
302 {
303 if (curNode == entryNode)
304 continue;
307 }
308 }
309 }
310}
Set< CxtThreadStmt > CxtThreadStmtSet
Definition MHP.h:57

◆ updateSiblingThreads()

template<class ICFGGraph , class CGGraph >
void MHP::updateSiblingThreads ( ICFGGraph  icfg,
CGGraph  cg,
NodeID  curTid 
)
protected

Update interleavings of sibling threads according to TCT

Exclude sibling thread that never happen in parallel based on ForkJoinAnalysis

The interleaving of a thread t is not unnecessary to be updated if (1) t HB Sibling and t fully joins curTid recursively or (2) Sibling HB t

Definition at line 654 of file MHP.cpp.

655{
658 for (const unsigned tid : ancestorAndSelfTids)
659 {
661 for (const unsigned stid : siblingTds)
662 {
663 if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid))
664 continue;
665
668 // The entry node under the graph: the same node the sibling thread's
669 // own propagation starts from (see analyzeInterleaving's root cts).
671 CxtThreadStmt cts(stid, ct.getContext(), stmt);
673 }
674
675 DBOUT(DMTA, outs() << "##Sibling thread of " << curTid << " is : ");
677 DBOUT(DMTA, outs() << "\n");
678 }
679}
bool isRecurFullJoin(NodeID parentTid, NodeID curTid)
Thread curTid can be fully joined by parentTid recursively.
Definition MHP.cpp:684
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens before t2 based on ForkJoin Analysis.
Definition MHP.cpp:754
const NodeBS getSiblingThread(NodeID tid) const
Get sibling threads.
Definition TCT.h:359

Member Data Documentation

◆ bbToSymJoins

BBToSymJoinsMap SVF::MHP::bbToSymJoins
protected

Map a statement to its thread interleavings.

loop block -> symmetric in-loop joins of that loop

Definition at line 326 of file MHP.h.

◆ cxtStmtList

CxtThreadStmtWorkList SVF::MHP::cxtStmtList
protected

CxtThreadStmt worklist.

Definition at line 324 of file MHP.h.

◆ fja

ForkJoinAnalysis* SVF::MHP::fja
protected

ForJoin Analysis.

Definition at line 323 of file MHP.h.

◆ instToThreadSummary

InstToThreadSummaryMap SVF::MHP::instToThreadSummary
protected

Exact per-node/per-tid query compression.

Definition at line 329 of file MHP.h.

◆ instToTSMap

InstToThreadStmtSetMap SVF::MHP::instToTSMap
protected

Map an instruction to its ThreadStmtSet.

Definition at line 328 of file MHP.h.

◆ interleavingQueriesTime

double SVF::MHP::interleavingQueriesTime

Definition at line 338 of file MHP.h.

◆ interleavingTime

double SVF::MHP::interleavingTime

Definition at line 337 of file MHP.h.

◆ nonCandidateFuncMHPRelMap

FuncPairToBool SVF::MHP::nonCandidateFuncMHPRelMap
protected

Definition at line 332 of file MHP.h.

◆ numOfMHPQueries

u32_t SVF::MHP::numOfMHPQueries

Number of queries are answered as may-happen-in-parallel.

Definition at line 336 of file MHP.h.

◆ numOfTotalQueries

u32_t SVF::MHP::numOfTotalQueries

Total number of queries.

Definition at line 335 of file MHP.h.

◆ querySummaryOwner

Map<const ICFGNode*, const ICFGNode*> SVF::MHP::querySummaryOwner
protected

Non-candidate node -> entry summary.

Definition at line 330 of file MHP.h.

◆ stateRepresentation

StateRepresentation SVF::MHP::stateRepresentation
protected

Definition at line 331 of file MHP.h.

◆ symJoinLoop

SymJoinToLoopMap SVF::MHP::symJoinLoop
protected

symmetric in-loop join -> its loop's blocks

Definition at line 327 of file MHP.h.

◆ tcg

ThreadCallGraph* SVF::MHP::tcg
protected

TCG.

Definition at line 321 of file MHP.h.

◆ tct

TCT* SVF::MHP::tct
protected

TCT.

Definition at line 322 of file MHP.h.

◆ threadStmtToThreadInterLeav

ThreadStmtToThreadInterleav SVF::MHP::threadStmtToThreadInterLeav
protected

Definition at line 325 of file MHP.h.


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