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

#include <MHP.h>

Public Types

typedef Set< const SVFFunction * > FunSet
 
typedef FIFOWorkList< CxtThreadStmtCxtThreadStmtWorkList
 
typedef Set< CxtThreadStmtCxtThreadStmtSet
 
typedef Map< CxtThreadStmt, NodeBSThreadStmtToThreadInterleav
 
typedef Map< const ICFGNode *, CxtThreadStmtSetInstToThreadStmtSetMap
 
typedef SVFLoopAndDomInfo::LoopBBs LoopBBs
 
typedef Set< CxtStmtLockSpan
 
typedef std::pair< const SVFFunction *, const SVFFunction * > FuncPair
 
typedef Map< FuncPair, boolFuncPairToBool
 

Public Member Functions

 MHP (TCT *t)
 Constructor.
 
virtual ~MHP ()
 Destructor.
 
void analyze ()
 Start analysis here.
 
void analyzeInterleaving ()
 Analyze thread interleaving.
 
ThreadCallGraphgetThreadCallGraph () const
 Get ThreadCallGraph.
 
TCTgetTCT () const
 Get Thread Creation Tree.
 
bool isConnectedfromMain (const SVFFunction *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 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.
 

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
 

Private Member Functions

const PTACallGraph::FunctionSetgetCallee (const CallICFGNode *inst, PTACallGraph::FunctionSet &callees)
 
void updateNonCandidateFunInterleaving ()
 
void handleNonCandidateFun (const CxtThreadStmt &cts)
 Handle non-candidate function.
 
void handleFork (const CxtThreadStmt &cts, NodeID rootTid)
 Handle fork.
 
void handleJoin (const CxtThreadStmt &cts, NodeID rootTid)
 Handle join.
 
void handleCall (const CxtThreadStmt &cts, NodeID rootTid)
 Handle call.
 
void handleRet (const CxtThreadStmt &cts)
 Handle return.
 
void handleIntra (const CxtThreadStmt &cts)
 Handle intra.
 
void addInterleavingThread (const CxtThreadStmt &tgr, NodeID tid)
 Add/Remove interleaving thread for statement inst.
 
void addInterleavingThread (const CxtThreadStmt &tgr, const CxtThreadStmt &src)
 
void rmInterleavingThread (const CxtThreadStmt &tgr, const NodeBS &tids, const ICFGNode *joinsite)
 
void updateAncestorThreads (NodeID tid)
 Update Ancestor and sibling threads.
 
void updateSiblingThreads (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 SVFFunction *callee)
 Push calling context.
 
bool matchCxt (CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
 Match context.
 
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.
 

Private Attributes

ThreadCallGraphtcg
 TCG.
 
TCTtct
 TCT.
 
ForkJoinAnalysisfja
 ForJoin Analysis.
 
CxtThreadStmtWorkList cxtStmtList
 CxtThreadStmt worklist.
 
ThreadStmtToThreadInterleav threadStmtToTheadInterLeav
 
InstToThreadStmtSetMap instToTSMap
 Map a statement to its thread interleavings.
 
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 45 of file MHP.h.

Member Typedef Documentation

◆ CxtThreadStmtSet

Definition at line 51 of file MHP.h.

◆ CxtThreadStmtWorkList

Definition at line 50 of file MHP.h.

◆ FuncPair

Definition at line 58 of file MHP.h.

◆ FuncPairToBool

Definition at line 59 of file MHP.h.

◆ FunSet

Definition at line 49 of file MHP.h.

◆ InstToThreadStmtSetMap

Definition at line 53 of file MHP.h.

◆ LockSpan

Definition at line 56 of file MHP.h.

◆ LoopBBs

Definition at line 54 of file MHP.h.

◆ ThreadStmtToThreadInterleav

Definition at line 52 of file MHP.h.

Constructor & Destructor Documentation

◆ MHP()

MHP::MHP ( TCT t)

Constructor.

Constructor

Definition at line 44 of file MHP.cpp.

46{
49}
void analyzeForkJoinPair()
Definition MHP.cpp:721
TCT * tct
TCT.
Definition MHP.h:253
u32_t numOfTotalQueries
Total number of queries.
Definition MHP.h:262
ThreadCallGraph * tcg
TCG.
Definition MHP.h:252
ForkJoinAnalysis * fja
ForJoin Analysis.
Definition MHP.h:254
double interleavingQueriesTime
Definition MHP.h:265
u32_t numOfMHPQueries
Number of queries are answered as may-happen-in-parallel.
Definition MHP.h:263
double interleavingTime
Definition MHP.h:264
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:196

◆ ~MHP()

MHP::~MHP ( )
virtual

Destructor.

Destructor

Definition at line 54 of file MHP.cpp.

55{
56 delete fja;
57}

Member Function Documentation

◆ addInterleavingThread() [1/2]

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

Definition at line 163 of file MHP.h.

164 {
166 if(changed)
167 {
168 instToTSMap[tgr.getStmt()].insert(tgr);
170 }
171 }
InstToThreadStmtSetMap instToTSMap
Map a statement to its thread interleavings.
Definition MHP.h:257
bool pushToCTSWorkList(const CxtThreadStmt &cs)
WorkList helper functions.
Definition MHP.h:217
ThreadStmtToThreadInterleav threadStmtToTheadInterLeav
Definition MHP.h:256
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ addInterleavingThread() [2/2]

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

Add/Remove interleaving thread for statement inst.

Definition at line 155 of file MHP.h.

156 {
157 if(threadStmtToTheadInterLeav[tgr].test_and_set(tid))
158 {
159 instToTSMap[tgr.getStmt()].insert(tgr);
161 }
162 }

◆ analyze()

void MHP::analyze ( )

Start analysis here.

Start analysis here

Definition at line 62 of file MHP.cpp.

63{
64 DBOUT(DGENERAL, outs() << pasMsg("MHP interleaving analysis\n"));
65 DBOUT(DMTA, outs() << pasMsg("MHP interleaving analysis\n"));
70}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DMTA
Definition SVFType.h:505
#define DGENERAL
Definition SVFType.h:490
#define DOTIMESTAT(X)
Definition SVFType.h:486
void analyzeInterleaving()
Analyze thread interleaving.
Definition MHP.cpp:75
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50

◆ analyzeInterleaving()

void MHP::analyzeInterleaving ( )

Analyze thread interleaving.

Analyze thread interleaving

handle non-candidate function

handle candidate function

update non-candidate functions' interleaving

Definition at line 75 of file MHP.cpp.

76{
77 for (const std::pair<const NodeID, TCTNode*>& tpair : *tct)
78 {
79 const CxtThread& ct = tpair.second->getCxtThread();
80 NodeID rootTid = tpair.first;
82 const ICFGNode* svfInst = routine->getEntryBlock()->front();
83 CxtThreadStmt rootcts(rootTid, ct.getContext(), svfInst);
84
88
89 while (!cxtStmtList.empty())
90 {
92 const ICFGNode* curInst = cts.getStmt();
93 DBOUT(DMTA, outs() << "-----\nMHP analysis root thread: " << rootTid << " ");
94 DBOUT(DMTA, cts.dump());
95 DBOUT(DMTA, outs() << "current thread interleaving: < ");
97 DBOUT(DMTA, outs() << " >\n-----\n");
98
100 if (!tct->isCandidateFun(curInst->getFun()))
101 {
103 }
105 else
106 {
107 if (isTDFork(curInst))
108 {
110 }
111 else if (isTDJoin(curInst))
112 {
114 }
115 else if (tct->isCallSite(curInst) && !tct->isExtCall(curInst))
116 {
119 if (!tct->isCandidateFun(getCallee(SVFUtil::cast<CallICFGNode>(curInst), callees)))
121 }
122 else if (isRetInstNode(curInst))
123 {
124 handleRet(cts);
125 }
126 else
127 {
129 }
130 }
131 }
132 }
133
136
139}
bool empty() const
Definition WorkList.h:146
CxtThreadStmtWorkList cxtStmtList
CxtThreadStmt worklist.
Definition MHP.h:255
void printInterleaving()
Print interleaving results.
Definition MHP.cpp:647
void updateSiblingThreads(NodeID tid)
Definition MHP.cpp:418
void handleNonCandidateFun(const CxtThreadStmt &cts)
Handle non-candidate function.
Definition MHP.cpp:181
void handleJoin(const CxtThreadStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:233
void addInterleavingThread(const CxtThreadStmt &tgr, NodeID tid)
Add/Remove interleaving thread for statement inst.
Definition MHP.h:155
const NodeBS & getInterleavingThreads(const CxtThreadStmt &cts)
Get interleaving thread for statement inst.
Definition MHP.h:97
bool isTDFork(const ICFGNode *call)
Whether it is a fork site.
Definition MHP.h:228
void handleRet(const CxtThreadStmt &cts)
Handle return.
Definition MHP.cpp:319
void handleFork(const CxtThreadStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:203
void updateNonCandidateFunInterleaving()
Definition MHP.cpp:144
CxtThreadStmt popFromCTSWorkList()
Definition MHP.h:221
const PTACallGraph::FunctionSet & getCallee(const CallICFGNode *inst, PTACallGraph::FunctionSet &callees)
Definition MHP.h:126
void updateAncestorThreads(NodeID tid)
Update Ancestor and sibling threads.
Definition MHP.cpp:382
void handleIntra(const CxtThreadStmt &cts)
Handle intra.
Definition MHP.cpp:366
void handleCall(const CxtThreadStmt &cts, NodeID rootTid)
Handle call.
Definition MHP.cpp:290
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:234
static const Option< bool > PrintInterLev
Definition Options.h:159
Set< const SVFFunction * > FunctionSet
const SVFFunction * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:377
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:271
bool isCandidateFun(const PTACallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:291
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:264
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:389
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:148
u32_t NodeID
Definition GeneralType.h:55

◆ executedByTheSameThread()

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

Definition at line 626 of file MHP.cpp.

627{
629 return true;
630
633 for (const CxtThreadStmt&ts1 : tsSet1)
634 {
635 for (const CxtThreadStmt& ts2 : tsSet2)
636 {
637 if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid()))
638 return false;
639 }
640 }
641 return true;
642}
bool isMultiForkedThread(NodeID curTid)
A thread is a multiForked thread if it is in a loop or recursion.
Definition MHP.h:200
Set< CxtThreadStmt > CxtThreadStmtSet
Definition MHP.h:51
const CxtThreadStmtSet & getThreadStmtSet(const ICFGNode *inst) const
Get/has ThreadStmt.
Definition MHP.h:109
bool hasThreadStmtSet(const ICFGNode *inst) const
Definition MHP.h:115

◆ getCallee()

const PTACallGraph::FunctionSet & SVF::MHP::getCallee ( const CallICFGNode inst,
PTACallGraph::FunctionSet callees 
)
inlineprivate

Definition at line 126 of file MHP.h.

127 {
128 tcg->getCallees(inst, callees);
129 return callees;
130 }
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.

◆ getDirAndIndJoinedTid()

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

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

492{
493 CxtStmt cs(cxt, call);
494 return fja->getDirAndIndJoinedTid(cs);
495}
NodeBS getDirAndIndJoinedTid(const CxtStmt &cs)
Get directly and indirectly joined threadIDs based on a context-sensitive join site.
Definition MHP.cpp:974

◆ getInterleavingThreads()

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

Get interleaving thread for statement inst.

Definition at line 97 of file MHP.h.

98 {
100 }

◆ getJoinInSymmetricLoop()

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

Whether a context-sensitive join satisfies symmetric loop pattern.

Definition at line 507 of file MHP.cpp.

508{
509 CxtStmt cs(cxt, call);
510 return fja->getJoinInSymmetricLoop(cs);
511}
const LoopBBs & getJoinInSymmetricLoop(const CxtStmt &cs) const
Whether a context-sensitive join satisfies symmetric loop pattern.
Definition MHP.h:314

◆ getTCT()

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

Get Thread Creation Tree.

Definition at line 80 of file MHP.h.

81 {
82 return tct;
83 }

◆ getThreadCallGraph()

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

Get ThreadCallGraph.

Definition at line 74 of file MHP.h.

75 {
76 return tcg;
77 }

◆ getThreadStmtSet()

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

Get/has ThreadStmt.

Definition at line 109 of file MHP.h.

110 {
111 InstToThreadStmtSetMap::const_iterator it = instToTSMap.find(inst);
112 assert(it!=instToTSMap.end() && "no thread access the instruction?");
113 return it->second;
114 }

◆ handleCall()

void MHP::handleCall ( const CxtThreadStmt cts,
NodeID  rootTid 
)
private

Handle call.

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

Definition at line 290 of file MHP.cpp.

291{
292
293 const ICFGNode* call = cts.getStmt();
294 const CallStrCxt& curCxt = cts.getContext();
295 const CallICFGNode* cbn = cast<CallICFGNode>(call);
297 {
298 for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn),
300 cgIt != ecgIt; ++cgIt)
301 {
302
303 const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
304 if (isExtCall(svfcallee))
305 continue;
307 const CallICFGNode* callicfgnode = SVFUtil::cast<CallICFGNode>(call);
309 const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
312 }
313 }
314}
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition MHP.h:205
CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode *inst) const
CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode *inst) const
bool hasCallGraphEdge(const CallICFGNode *inst) const
Get call graph edge via call instruction.
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
std::vector< u32_t > CallStrCxt

◆ handleFork()

void MHP::handleFork ( const CxtThreadStmt cts,
NodeID  rootTid 
)
private

Handle fork.

Handle fork

Definition at line 203 of file MHP.cpp.

204{
205
206 const ICFGNode* call = cts.getStmt();
207 const CallStrCxt& curCxt = cts.getContext();
208
209 assert(isTDFork(call));
210 const CallICFGNode* cbn = cast<CallICFGNode>(call);
212 {
213
214 for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(cbn),
216 cgIt != ecgIt; ++cgIt)
217 {
218 const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction();
221 const ICFGNode* stmt = svfroutine->getEntryBlock()->front();
222 CxtThread ct(newCxt, call);
223 CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
225 }
226 }
228}
NodeID getId() const
Get ID.
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:206
ForkEdgeSet::const_iterator getForkEdgeEnd(const CallICFGNode *cs) const
ForkEdgeSet::const_iterator getForkEdgeBegin(const CallICFGNode *cs) const

◆ handleIntra()

void MHP::handleIntra ( const CxtThreadStmt cts)
private

Handle intra.

Handling intraprocedural statements (successive statements on the CFG )

Definition at line 366 of file MHP.cpp.

367{
368
369 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
370 {
371 if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
372 {
373 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), outEdge->getDstNode());
375 }
376 }
377}

◆ handleJoin()

void MHP::handleJoin ( const CxtThreadStmt cts,
NodeID  rootTid 
)
private

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

234{
235
236 const CallStrCxt& curCxt = cts.getContext();
237
238 assert(isTDJoin(cts.getStmt()));
239
240 const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(cts.getStmt());
241
243 if (!joinedTids.empty())
244 {
245 if (fja->hasJoinLoop(call))
246 {
247 std::vector<const SVFBasicBlock*> exitbbs;
248 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
249 while (!exitbbs.empty())
250 {
251 const SVFBasicBlock* eb = exitbbs.back();
252 exitbbs.pop_back();
253 const ICFGNode* svfEntryInst = eb->front();
258 }
259 }
260 else
261 {
263 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << " for thread " << rootTid << "\n");
264 }
265 }
268 else
269 {
270 if (fja->hasJoinLoop(call))
271 {
272 std::vector<const SVFBasicBlock*> exitbbs;
273 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
274 while (!exitbbs.empty())
275 {
276 const SVFBasicBlock* eb = exitbbs.back();
277 exitbbs.pop_back();
278 const ICFGNode* svfEntryInst = eb->front();
279 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), svfEntryInst);
281 }
282 }
283 }
285}
const std::string toString() const override
Definition ICFG.cpp:131
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:354
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:76
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
Definition ICFGNode.h:82
void rmInterleavingThread(const CxtThreadStmt &tgr, const NodeBS &tids, const ICFGNode *joinsite)
Definition MHP.h:172
bool hasJoinInSymmetricLoop(const CallStrCxt &cxt, const ICFGNode *call) const
Whether a context-sensitive join satisfies symmetric loop pattern.
Definition MHP.cpp:500
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:491
const ICFGNode * back() const
Definition SVFValue.h:611
void getExitBlocksOfLoop(const SVFBasicBlock *bb, BBList &exitbbs) const
Definition SVFValue.h:476

◆ handleNonCandidateFun()

void MHP::handleNonCandidateFun ( const CxtThreadStmt cts)
private

Handle non-candidate function.

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

Definition at line 181 of file MHP.cpp.

182{
183 const ICFGNode* curInst = cts.getStmt();
184 const SVFFunction* curfun = curInst->getFun();
185 assert((curInst == curfun->getEntryBlock()->front()) && "curInst is not the entry of non candidate function.");
186 const CallStrCxt& curCxt = cts.getContext();
189 {
190 const SVFFunction* callee = (*nit)->getDstNode()->getFunction();
191 if (!isExtCall(callee))
192 {
193 const ICFGNode* calleeInst = callee->getEntryBlock()->front();
196 }
197 }
198}
iterator OutEdgeEnd()
iterator OutEdgeBegin()
iterators
GEdgeSetTy::const_iterator const_iterator
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.

◆ handleRet()

void MHP::handleRet ( const CxtThreadStmt cts)
private

Handle return.

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

Definition at line 319 of file MHP.cpp.

320{
321 PTACallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun());
322 for (PTACallGraphEdge* edge : curFunNode->getInEdges())
323 {
324 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
325 continue;
326 for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
327 ecit = (edge)->directCallsEnd();
328 cit != ecit; ++cit)
329 {
330 CallStrCxt newCxt = cts.getContext();
331 if (matchCxt(newCxt, *cit, curFunNode->getFunction()))
332 {
333 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
334 {
335 if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
336 {
337 CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode());
339 }
340 }
341 }
342 }
343 for (PTACallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
344 ecit = (edge)->indirectCallsEnd();
345 cit != ecit; ++cit)
346 {
347 CallStrCxt newCxt = cts.getContext();
348 if (matchCxt(newCxt, *cit, curFunNode->getFunction()))
349 {
350 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
351 {
352 if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
353 {
354 CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode());
356 }
357 }
358 }
359 }
360 }
361}
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
Definition MHP.h:210

◆ hasInterleavingThreads()

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

Definition at line 101 of file MHP.h.

102 {
104 }

◆ hasJoinInSymmetricLoop()

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

Whether a context-sensitive join satisfies symmetric loop pattern.

Whether a context-sensitive join satisfies symmetric loop pattern

Definition at line 500 of file MHP.cpp.

501{
502 CxtStmt cs(cxt, call);
503 return fja->hasJoinInSymmetricLoop(cs);
504}
bool hasJoinInSymmetricLoop(const CxtStmt &cs) const
Definition MHP.h:320

◆ hasThreadStmtSet()

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

Definition at line 115 of file MHP.h.

116 {
117 return instToTSMap.find(inst)!=instToTSMap.end();
118 }

◆ isConnectedfromMain()

bool MHP::isConnectedfromMain ( const SVFFunction fun)

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

Definition at line 521 of file MHP.cpp.

522{
525 TCT::PTACGNodeSet visited;
526 worklist.push(cgnode);
527 visited.insert(cgnode);
528 while (!worklist.empty())
529 {
530 const PTACallGraphNode* node = worklist.pop();
531 if ("main" == node->getFunction()->getName())
532 return true;
533 for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
534 {
535 const PTACallGraphNode* srcNode = (*nit)->getSrcNode();
536 if (visited.find(srcNode) == visited.end())
537 {
538 visited.insert(srcNode);
539 worklist.push(srcNode);
540 }
541 }
542 }
543 return false;
544}
bool push(const Data &data)
Definition WorkList.h:165
iterator InEdgeBegin()
iterator InEdgeEnd()
const SVFFunction * getFunction() const
Get function of this call node.
const std::string & getName() const
Definition SVFValue.h:243
Set< const PTACallGraphNode * > PTACGNodeSet
Definition TCT.h:163

◆ isHBPair()

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

Whether thread t1 happens before t2 based on ForkJoin Analysis.

Whether two thread t1 happens-fore t2

Definition at line 516 of file MHP.cpp.

517{
518 return fja->isHBPair(tid1, tid2);
519}
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens-before thread t2.
Definition MHP.h:326

◆ isMultiForkedThread()

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

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

Definition at line 200 of file MHP.h.

201 {
203 }
bool isMultiforked() const
Definition TCT.h:120

◆ isMustJoin()

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

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

482{
483 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(joinsite);
484 assert(call && isTDJoin(call) && "not a join site!");
486}
bool isJoinSiteInRecursion(const CallICFGNode *join) const
Whether a join site is in recursion.
Definition TCT.h:428

◆ isRecurFullJoin()

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

Thread curTid can be fully joined by parentTid recursively.

Whether curTid can be fully joined by parentTid recursively

Definition at line 446 of file MHP.cpp.

447{
448 if (parentTid == curTid)
449 return true;
450
453 worklist.push(curNode);
454 while (!worklist.empty())
455 {
456 const TCTNode* node = worklist.pop();
457 for (TCTEdge* edge : node->getInEdges())
458 {
459 NodeID srcID = edge->getSrcID();
460 if (fja->isFullJoin(srcID, node->getId()))
461 {
462 if (srcID == parentTid)
463 return true;
464 else
465 worklist.push(edge->getSrcNode());
466 }
467 else
468 {
469 return false;
470 }
471 }
472 }
473 return false;
474}
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:333

◆ isTDFork()

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

Whether it is a fork site.

Definition at line 228 of file MHP.h.

229 {
230 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
231 return fork && tcg->getThreadAPI()->isTDFork(fork);
232 }
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)
inlineprivate

Whether it is a join site.

Definition at line 234 of file MHP.h.

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

◆ matchCxt()

bool SVF::MHP::matchCxt ( CallStrCxt cxt,
const CallICFGNode call,
const SVFFunction callee 
)
inlineprivate

Match context.

Definition at line 210 of file MHP.h.

211 {
212 return tct->matchCxt(cxt,call,callee);
213 }
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
Definition TCT.cpp:466

◆ mayHappenInParallel()

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

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

Definition at line 614 of file MHP.cpp.

615{
617
618 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
619 bool mhp = mayHappenInParallelCache(i1, i2);
620 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
622
623 return mhp;
624}
virtual bool mayHappenInParallelCache(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:592

◆ mayHappenInParallelCache()

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

Definition at line 592 of file MHP.cpp.

593{
594 if (!tct->isCandidateFun(i1->getFun()) && !tct->isCandidateFun(i2->getFun()))
595 {
596 FuncPair funpair = std::make_pair(i1->getFun(), i2->getFun());
597 FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
598 if (it == nonCandidateFuncMHPRelMap.end())
599 {
600 bool mhp = mayHappenInParallelInst(i1, i2);
602 return mhp;
603 }
604 else
605 {
606 if (it->second)
608 return it->second;
609 }
610 }
612}
FuncPairToBool nonCandidateFuncMHPRelMap
Definition MHP.h:258
std::pair< const SVFFunction *, const SVFFunction * > FuncPair
Definition MHP.h:58
virtual bool mayHappenInParallelInst(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:556

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

557{
558
561 return false;
562
565 for (const CxtThreadStmt& ts1 : tsSet1)
566 {
568 for (const CxtThreadStmt& ts2 : tsSet2)
569 {
571 if (ts1.getTid() != ts2.getTid())
572 {
573 if (l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
574 {
576 return true;
577 }
578 }
579 else
580 {
581 if (isMultiForkedThread(ts1.getTid()))
582 {
584 return true;
585 }
586 }
587 }
588 }
589 return false;
590}

◆ popFromCTSWorkList()

CxtThreadStmt SVF::MHP::popFromCTSWorkList ( )
inlineprivate

Definition at line 221 of file MHP.h.

222 {
223 CxtThreadStmt ctp = cxtStmtList.pop();
224 return ctp;
225 }

◆ printInterleaving()

void MHP::printInterleaving ( )

Print interleaving results.

Print interleaving results

Definition at line 647 of file MHP.cpp.

648{
649 for (const auto& pair : threadStmtToTheadInterLeav)
650 {
651 outs() << "( t" << pair.first.getTid()
652 << pair.first.getStmt()->toString() << " ) ==> [";
653 for (unsigned i : pair.second)
654 {
655 outs() << " " << i << " ";
656 }
657 outs() << "]\n";
658 }
659}

◆ pushCxt()

void SVF::MHP::pushCxt ( CallStrCxt cxt,
const CallICFGNode call,
const SVFFunction callee 
)
inlineprivate

Push calling context.

Definition at line 205 of file MHP.h.

206 {
207 tct->pushCxt(cxt,call,callee);
208 }
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
Definition TCT.cpp:445

◆ pushToCTSWorkList()

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

WorkList helper functions.

Definition at line 217 of file MHP.h.

218 {
219 return cxtStmtList.push(cs);
220 }

◆ rmInterleavingThread()

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

Definition at line 172 of file MHP.h.

173 {
175 for(NodeBS::iterator it = tids.begin(), eit = tids.end(); it!=eit; ++it)
176 {
177 if(isMustJoin(tgr.getTid(),joinsite))
178 joinedTids.set(*it);
179 }
180 if(threadStmtToTheadInterLeav[tgr].intersectWithComplement(joinedTids))
181 {
183 }
184 }
bool isMustJoin(const NodeID curTid, const ICFGNode *joinsite)
Whether a join site must join a thread t.
Definition MHP.cpp:481
SparseBitVectorIterator iterator
void set(unsigned Idx)
SparseBitVector NodeBS
Definition GeneralType.h:62

◆ updateAncestorThreads()

void MHP::updateAncestorThreads ( NodeID  curTid)
private

Update Ancestor and sibling threads.

Update interleavings of ancestor threads according to TCT

Definition at line 382 of file MHP.cpp.

383{
385 DBOUT(DMTA, outs() << "##Ancestor thread of " << curTid << " is : ");
387 DBOUT(DMTA, outs() << "\n");
388 tds.set(curTid);
389
390 for (const unsigned i : tds)
391 {
392 const CxtThread& ct = tct->getTCTNode(i)->getCxtThread();
393 if (const ICFGNode* forkInst = ct.getThread())
394 {
396 for(const ICFGEdge* outEdge : forkInst->getOutEdges())
397 {
398 if(outEdge->getDstNode()->getFun() == forkInst->getFun())
399 {
402 }
403 }
404 }
405 }
406}
const CxtThread & getCxtThread() const
Get CxtThread.
Definition TCT.h:101
NodeID getParentThread(NodeID tid) const
Get parent thread.
Definition TCT.h:320
const CallStrCxt & getCxtOfCxtThread(const CxtThread &ct) const
get the context of a thread at its spawning site (fork site)
Definition TCT.h:369
const NodeBS getAncestorThread(NodeID tid) const
Get all ancestor threads.
Definition TCT.h:329

◆ updateNonCandidateFunInterleaving()

void MHP::updateNonCandidateFunInterleaving ( )
private

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

Update non-candidate functions' interleaving

Definition at line 144 of file MHP.cpp.

145{
146 SVFModule* module = tct->getSVFModule();
147 for (const SVFFunction* fun : module->getFunctionSet())
148 {
149 if (!tct->isCandidateFun(fun) && !isExtCall(fun))
150 {
151 const ICFGNode* entryNode = fun->getEntryBlock()->front();
152
154 continue;
155
157
158 for (const CxtThreadStmt& cts : tsSet)
159 {
160 const CallStrCxt& curCxt = cts.getContext();
161
162 for (const SVFBasicBlock* svfbb : fun->getBasicBlockList())
163 {
164 for (const ICFGNode* curNode : svfbb->getICFGNodeList())
165 {
166 if (curNode == entryNode)
167 continue;
170 instToTSMap[curNode].insert(newCts);
171 }
172 }
173 }
174 }
175 }
176}

◆ updateSiblingThreads()

void MHP::updateSiblingThreads ( NodeID  curTid)
private

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

419{
421 tds.set(curTid);
422 for (const unsigned tid : tds)
423 {
425 for (const unsigned stid : siblingTds)
426 {
427 if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid))
428 continue;
429
432 const ICFGNode* stmt = routine->getEntryBlock()->front();
433 CxtThreadStmt cts(stid, ct.getContext(), stmt);
435 }
436
437 DBOUT(DMTA, outs() << "##Sibling thread of " << curTid << " is : ");
439 DBOUT(DMTA, outs() << "\n");
440 }
441}
bool isRecurFullJoin(NodeID parentTid, NodeID curTid)
Thread curTid can be fully joined by parentTid recursively.
Definition MHP.cpp:446
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens before t2 based on ForkJoin Analysis.
Definition MHP.cpp:516
const NodeBS getSiblingThread(NodeID tid) const
Get sibling threads.
Definition TCT.h:350

Member Data Documentation

◆ cxtStmtList

CxtThreadStmtWorkList SVF::MHP::cxtStmtList
private

CxtThreadStmt worklist.

Definition at line 255 of file MHP.h.

◆ fja

ForkJoinAnalysis* SVF::MHP::fja
private

ForJoin Analysis.

Definition at line 254 of file MHP.h.

◆ instToTSMap

InstToThreadStmtSetMap SVF::MHP::instToTSMap
private

Map a statement to its thread interleavings.

Map an instruction to its ThreadStmtSet

Definition at line 257 of file MHP.h.

◆ interleavingQueriesTime

double SVF::MHP::interleavingQueriesTime

Definition at line 265 of file MHP.h.

◆ interleavingTime

double SVF::MHP::interleavingTime

Definition at line 264 of file MHP.h.

◆ nonCandidateFuncMHPRelMap

FuncPairToBool SVF::MHP::nonCandidateFuncMHPRelMap
private

Definition at line 258 of file MHP.h.

◆ numOfMHPQueries

u32_t SVF::MHP::numOfMHPQueries

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

Definition at line 263 of file MHP.h.

◆ numOfTotalQueries

u32_t SVF::MHP::numOfTotalQueries

Total number of queries.

Definition at line 262 of file MHP.h.

◆ tcg

ThreadCallGraph* SVF::MHP::tcg
private

TCG.

Definition at line 252 of file MHP.h.

◆ tct

TCT* SVF::MHP::tct
private

TCT.

Definition at line 253 of file MHP.h.

◆ threadStmtToTheadInterLeav

ThreadStmtToThreadInterleav SVF::MHP::threadStmtToTheadInterLeav
private

Definition at line 256 of file MHP.h.


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