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 FunObjVar * > 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 FunObjVar *, const FunObjVar * > 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 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 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 CallGraph::FunctionSetgetCallee (const CallICFGNode *inst, CallGraph::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 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.
 

Private Attributes

ThreadCallGraphtcg
 TCG.
 
TCTtct
 TCT.
 
ForkJoinAnalysisfja
 ForJoin Analysis.
 
CxtThreadStmtWorkList cxtStmtList
 CxtThreadStmt worklist.
 
ThreadStmtToThreadInterleav threadStmtToThreadInterLeav
 
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:760
TCT * tct
TCT.
Definition MHP.h:265
u32_t numOfTotalQueries
Total number of queries.
Definition MHP.h:274
ThreadCallGraph * tcg
TCG.
Definition MHP.h:264
ForkJoinAnalysis * fja
ForJoin Analysis.
Definition MHP.h:266
double interleavingQueriesTime
Definition MHP.h:277
u32_t numOfMHPQueries
Number of queries are answered as may-happen-in-parallel.
Definition MHP.h:275
double interleavingTime
Definition MHP.h:276
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:190

◆ ~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:269
ThreadStmtToThreadInterleav threadStmtToThreadInterLeav
Definition MHP.h:268
bool pushToCTSWorkList(const CxtThreadStmt &cs)
WorkList helper functions.
Definition MHP.h:229
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(threadStmtToThreadInterLeav[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:497
#define TIMEINTERVAL
Definition SVFType.h:525
#define DMTA
Definition SVFType.h:518
#define DGENERAL
Definition SVFType.h:503
#define DOTIMESTAT(X)
Definition SVFType.h:499
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:101
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ 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 {
118 }
119 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
120 {
121 handleRet(cts);
122 }
123 else
124 {
126 }
127 }
128 }
129 }
130
133
136}
bool empty() const
Definition WorkList.h:146
CxtThreadStmtWorkList cxtStmtList
CxtThreadStmt worklist.
Definition MHP.h:267
void printInterleaving()
Print interleaving results.
Definition MHP.cpp:686
void updateSiblingThreads(NodeID tid)
Definition MHP.cpp:457
void handleNonCandidateFun(const CxtThreadStmt &cts)
Handle non-candidate function.
Definition MHP.cpp:179
void handleJoin(const CxtThreadStmt &cts, NodeID rootTid)
Handle join.
Definition MHP.cpp:231
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:240
void handleRet(const CxtThreadStmt &cts)
Handle return.
Definition MHP.cpp:334
void handleFork(const CxtThreadStmt &cts, NodeID rootTid)
Handle fork.
Definition MHP.cpp:201
void updateNonCandidateFunInterleaving()
Definition MHP.cpp:141
CxtThreadStmt popFromCTSWorkList()
Definition MHP.h:233
void updateAncestorThreads(NodeID tid)
Update Ancestor and sibling threads.
Definition MHP.cpp:418
void handleIntra(const CxtThreadStmt &cts)
Handle intra.
Definition MHP.cpp:403
void handleCall(const CxtThreadStmt &cts, NodeID rootTid)
Handle call.
Definition MHP.cpp:288
bool isTDJoin(const ICFGNode *call)
Whether it is a join site.
Definition MHP.h:246
static const Option< bool > PrintInterLev
Definition Options.h:156
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:265
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:285
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:258
const FunObjVar * getStartRoutineOfCxtThread(const CxtThread &ct) const
get the start routine function of a thread
Definition TCT.h:379
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:149
u32_t NodeID
Definition GeneralType.h:56

◆ executedByTheSameThread()

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

Definition at line 665 of file MHP.cpp.

666{
668 return true;
669
672 for (const CxtThreadStmt&ts1 : tsSet1)
673 {
674 for (const CxtThreadStmt& ts2 : tsSet2)
675 {
676 if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid()))
677 return false;
678 }
679 }
680 return true;
681}
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 CallGraph::FunctionSet & SVF::MHP::getCallee ( const CallICFGNode inst,
CallGraph::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.
Definition CallGraph.h:414

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

531{
532 CxtStmt cs(cxt, call);
533 return fja->getDirAndIndJoinedTid(cs);
534}
NodeBS getDirAndIndJoinedTid(const CxtStmt &cs)
Get directly and indirectly joined threadIDs based on a context-sensitive join site.
Definition MHP.cpp:1061

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

547{
548 CxtStmt cs(cxt, call);
549 return fja->getJoinInSymmetricLoop(cs);
550}
const LoopBBs & getJoinInSymmetricLoop(const CxtStmt &cs) const
Whether a context-sensitive join satisfies symmetric loop pattern.
Definition MHP.h:330

◆ 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)

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

289{
290
291 const ICFGNode* call = cts.getStmt();
292 const CallStrCxt& curCxt = cts.getContext();
293 const CallICFGNode* cbn = cast<CallICFGNode>(call);
295 {
296 for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn),
298 cgIt != ecgIt; ++cgIt)
299 {
300
301 const FunObjVar* svfcallee = (*cgIt)->getDstNode()->getFunction();
302 if (isExtCall(svfcallee))
303 continue;
305 const CallICFGNode* callicfgnode = SVFUtil::cast<CallICFGNode>(call);
307 const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front();
310 }
311 }
312
316 if (const CallICFGNode *callSite = SVFUtil::cast<CallICFGNode>(call))
317 {
320 {
321 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), callSite->getRetICFGNode());
323 }
324 }
325 else
326 {
327 assert(false && "cts.getStmt() is not a CallICFGNode!");
328 }
329}
CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode *inst) const
Definition CallGraph.h:433
bool hasCallGraphEdge(const CallICFGNode *inst) const
Get call graph edge via call instruction.
Definition CallGraph.h:429
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:244
CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode *inst) const
Definition CallGraph.h:440
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:208
const CallGraph::FunctionSet & getCallee(const CallICFGNode *inst, CallGraph::FunctionSet &callees)
Definition MHP.h:126
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:437
std::vector< u32_t > CallStrCxt

◆ handleFork()

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

Handle fork.

Handle fork

Definition at line 201 of file MHP.cpp.

202{
203
204 const ICFGNode* call = cts.getStmt();
205 const CallStrCxt& curCxt = cts.getContext();
206
207 assert(isTDFork(call));
208 const CallICFGNode* cbn = cast<CallICFGNode>(call);
210 {
211
212 for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(cbn),
214 cgIt != ecgIt; ++cgIt)
215 {
216 const FunObjVar* svfroutine = (*cgIt)->getDstNode()->getFunction();
219 const ICFGNode* stmt = svfroutine->getEntryBlock()->front();
220 CxtThread ct(newCxt, call);
221 CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt);
223 }
224 }
226}
NodeID getId() const
Get ID.
Definition SVFValue.h:160
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:200
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 403 of file MHP.cpp.

404{
405 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
406 {
407 if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun())
408 {
409 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), outEdge->getDstNode());
411 }
412 }
413}

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

232{
233
234 const CallStrCxt& curCxt = cts.getContext();
235
236 assert(isTDJoin(cts.getStmt()));
237
238 const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(cts.getStmt());
239
241 if (!joinedTids.empty())
242 {
243 if (fja->hasJoinLoop(call))
244 {
245 std::vector<const SVFBasicBlock*> exitbbs;
246 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
247 while (!exitbbs.empty())
248 {
249 const SVFBasicBlock* eb = exitbbs.back();
250 exitbbs.pop_back();
251 const ICFGNode* svfEntryInst = eb->front();
256 }
257 }
258 else
259 {
261 DBOUT(DMTA, outs() << "\n\t match join site " << call->toString() << " for thread " << rootTid << "\n");
262 }
263 }
266 else
267 {
268 if (fja->hasJoinLoop(call))
269 {
270 std::vector<const SVFBasicBlock*> exitbbs;
271 call->getFun()->getExitBlocksOfLoop(call->getBB(), exitbbs);
272 while (!exitbbs.empty())
273 {
274 const SVFBasicBlock* eb = exitbbs.back();
275 exitbbs.pop_back();
276 const ICFGNode* svfEntryInst = eb->front();
277 CxtThreadStmt newCts(cts.getTid(), cts.getContext(), svfEntryInst);
279 }
280 }
281 }
283}
const std::string toString() const override
Definition ICFG.cpp:139
bool hasJoinLoop(const CallICFGNode *inst)
Definition MHP.h:361
void getExitBlocksOfLoop(const SVFBasicBlock *bb, BBList &exitbbs) const
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:74
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
Definition ICFGNode.h:80
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:539
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:530
const ICFGNode * back() const

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

180{
181 const ICFGNode* curInst = cts.getStmt();
182 const FunObjVar* curfun = curInst->getFun();
183 assert((curInst == curfun->getEntryBlock()->front()) && "curInst is not the entry of non candidate function.");
184 const CallStrCxt& curCxt = cts.getContext();
186 for (CallGraphNode::const_iterator nit = node->OutEdgeBegin(), neit = node->OutEdgeEnd(); nit != neit; nit++)
187 {
188 const FunObjVar* callee = (*nit)->getDstNode()->getFunction();
189 if (!isExtCall(callee))
190 {
191 const ICFGNode* calleeInst = callee->getEntryBlock()->front();
194 }
195 }
196}
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
iterator OutEdgeEnd()
iterator OutEdgeBegin()
iterators
GEdgeSetTy::const_iterator const_iterator

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

335{
336 CallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun());
337 for (CallGraphEdge* edge : curFunNode->getInEdges())
338 {
339 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edge))
340 continue;
341 for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(),
342 ecit = (edge)->directCallsEnd();
343 cit != ecit; ++cit)
344 {
345 CallStrCxt newCxt = cts.getContext();
346 if (matchAndPopCxt(newCxt, *cit, curFunNode->getFunction()))
347 {
348 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
349 {
350 if(outEdge->getDstNode()->getFun() == (*cit)->getFun())
351 {
352 // Iterate over callSite's call string context and use as the successor's context
353 if (!hasThreadStmtSet(*cit))
354 continue;
356 {
357 CallStrCxt callSiteCxt = cxtThreadStmt.getContext();
358 // If new context is a suffix of the call site context
360 {
361 CxtThreadStmt newCts(cts.getTid(), callSiteCxt, outEdge->getDstNode());
363 }
364 }
365 }
366 }
367 }
368 }
369 for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(),
370 ecit = (edge)->indirectCallsEnd();
371 cit != ecit; ++cit)
372 {
373 CallStrCxt newCxt = cts.getContext();
374 if (matchAndPopCxt(newCxt, *cit, curFunNode->getFunction()))
375 {
376 for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges())
377 {
378 if(outEdge->getDstNode()->getFun() == (*cit)->getFun())
379 {
380 // Iterate over callSite's call string context and use as the successor's context
381 if (!hasThreadStmtSet(*cit))
382 continue;
384 {
385 CallStrCxt callSiteCxt = cxtThreadStmt.getContext();
386 // If new context is a suffix of the call site context
388 {
389 CxtThreadStmt newCts(cts.getTid(), callSiteCxt, outEdge->getDstNode());
391 }
392 }
393 }
394 }
395 }
396 }
397 }
398}
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition MHP.h:216
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt call)
If lhs is a suffix of rhs, including equal.
Definition MHP.h:221

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

540{
541 CxtStmt cs(cxt, call);
542 return fja->hasJoinInSymmetricLoop(cs);
543}
bool hasJoinInSymmetricLoop(const CxtStmt &cs) const
Definition MHP.h:336

◆ 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 FunObjVar fun)

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

Definition at line 560 of file MHP.cpp.

561{
564 TCT::PTACGNodeSet visited;
565 worklist.push(cgnode);
566 visited.insert(cgnode);
567 while (!worklist.empty())
568 {
569 const CallGraphNode* node = worklist.pop();
570 if ("main" == node->getFunction()->getName())
571 return true;
572 for (CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++)
573 {
574 const CallGraphNode* srcNode = (*nit)->getSrcNode();
575 if (visited.find(srcNode) == visited.end())
576 {
577 visited.insert(srcNode);
578 worklist.push(srcNode);
579 }
580 }
581 }
582 return false;
583}
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
bool push(const Data &data)
Definition WorkList.h:165
iterator InEdgeBegin()
iterator InEdgeEnd()
virtual const std::string & getName() const
Definition SVFValue.h:186
Set< const CallGraphNode * > PTACGNodeSet
Definition TCT.h:163

◆ isContextSuffix()

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

If lhs is a suffix of rhs, including equal.

Definition at line 221 of file MHP.h.

222 {
223 return tct->isContextSuffix(lhs,call);
224 }
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:497

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

556{
557 return fja->isHBPair(tid1, tid2);
558}
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens-before thread t2.
Definition MHP.h:342

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

521{
522 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(joinsite);
523 assert(call && isTDJoin(call) && "not a join site!");
525}
bool isJoinSiteInRecursion(const CallICFGNode *join) const
Whether a join site is in recursion.
Definition TCT.h:429

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

486{
487 if (parentTid == curTid)
488 return true;
489
492 worklist.push(curNode);
493 while (!worklist.empty())
494 {
495 const TCTNode* node = worklist.pop();
496 for (TCTEdge* edge : node->getInEdges())
497 {
498 NodeID srcID = edge->getSrcID();
499 if (fja->isFullJoin(srcID, node->getId()))
500 {
501 if (srcID == parentTid)
502 return true;
503 else
504 worklist.push(edge->getSrcNode());
505 }
506 else
507 {
508 return false;
509 }
510 }
511 }
512 return false;
513}
bool isFullJoin(NodeID tid1, NodeID tid2)
Whether t1 fully joins t2.
Definition MHP.h:349

◆ isTDFork()

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

Whether it is a fork site.

Definition at line 240 of file MHP.h.

241 {
242 const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
243 return fork && tcg->getThreadAPI()->isTDFork(fork);
244 }
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 246 of file MHP.h.

247 {
248 const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
249 return join && tcg->getThreadAPI()->isTDJoin(join);
250 }
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 
)
inlineprivate

Match context.

Definition at line 216 of file MHP.h.

217 {
218 return tct->matchAndPopCxt(cxt,call,callee);
219 }
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:469

◆ mayHappenInParallel()

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

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

Definition at line 653 of file MHP.cpp.

654{
656
657 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
658 bool mhp = mayHappenInParallelCache(i1, i2);
659 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
661
662 return mhp;
663}
virtual bool mayHappenInParallelCache(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:631

◆ mayHappenInParallelCache()

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

Definition at line 631 of file MHP.cpp.

632{
633 if (!tct->isCandidateFun(i1->getFun()) && !tct->isCandidateFun(i2->getFun()))
634 {
635 FuncPair funpair = std::make_pair(i1->getFun(), i2->getFun());
636 FuncPairToBool::const_iterator it = nonCandidateFuncMHPRelMap.find(funpair);
637 if (it == nonCandidateFuncMHPRelMap.end())
638 {
639 bool mhp = mayHappenInParallelInst(i1, i2);
641 return mhp;
642 }
643 else
644 {
645 if (it->second)
647 return it->second;
648 }
649 }
651}
FuncPairToBool nonCandidateFuncMHPRelMap
Definition MHP.h:270
std::pair< const FunObjVar *, const FunObjVar * > FuncPair
Definition MHP.h:58
virtual bool mayHappenInParallelInst(const ICFGNode *i1, const ICFGNode *i2)
Definition MHP.cpp:595

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

596{
597
600 return false;
601
604 for (const CxtThreadStmt& ts1 : tsSet1)
605 {
607 for (const CxtThreadStmt& ts2 : tsSet2)
608 {
610 if (ts1.getTid() != ts2.getTid())
611 {
612 if (l1.test(ts2.getTid()) && l2.test(ts1.getTid()))
613 {
615 return true;
616 }
617 }
618 else
619 {
620 if (isMultiForkedThread(ts1.getTid()))
621 {
623 return true;
624 }
625 }
626 }
627 }
628 return false;
629}

◆ popFromCTSWorkList()

CxtThreadStmt SVF::MHP::popFromCTSWorkList ( )
inlineprivate

Definition at line 233 of file MHP.h.

234 {
235 CxtThreadStmt ctp = cxtStmtList.pop();
236 return ctp;
237 }

◆ printInterleaving()

void MHP::printInterleaving ( )

Print interleaving results.

Print interleaving results

Definition at line 686 of file MHP.cpp.

687{
688 for (const auto& pair : threadStmtToThreadInterLeav)
689 {
690 outs() << "( t" << pair.first.getTid()
691 << pair.first.getStmt()->toString() << " ) ==> [";
692 for (unsigned i : pair.second)
693 {
694 outs() << " " << i << " ";
695 }
696 outs() << "]\n";
697 }
698}

◆ pushCxt()

void SVF::MHP::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 208 of file MHP.h.

209 {
211 if(tct->isCandidateFun(call->getFun()) == false)
212 return;
213 tct->pushCxt(cxt,call,callee);
214 }
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:449

◆ pushToCTSWorkList()

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

WorkList helper functions.

Definition at line 229 of file MHP.h.

230 {
231 return cxtStmtList.push(cs);
232 }

◆ 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(threadStmtToThreadInterLeav[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:520
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 418 of file MHP.cpp.

419{
421 DBOUT(DMTA, outs() << "##Ancestor thread of " << curTid << " is : ");
423 DBOUT(DMTA, outs() << "\n");
425
426 for (const unsigned tid : ancestorAndSelfTids)
427 {
428 const CxtThread& ct = tct->getTCTNode(tid)->getCxtThread();
429 if (const ICFGNode* forkInst = ct.getThread())
430 {
431 for(const ICFGEdge* outEdge : forkInst->getOutEdges())
432 {
433 // Ensure dst node is in the same function as forkInst
434 if(outEdge->getDstNode()->getFun() == forkInst->getFun())
435 {
436 for (const auto& forkSiteCxt : tct->getCxtOfCxtThread(ct))
437 {
438 CxtThreadStmt cts(forkSiteCxt.first, forkSiteCxt.second, outEdge->getDstNode());
440 }
441 }
442 }
443 }
444 }
445}
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:101
const NodeBS getAncestorThreads(NodeID tid) const
Get all ancestor threads.
Definition TCT.h:327

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

142{
143 for (const auto& item : *PAG::getPAG()->getCallGraph())
144 {
145 const FunObjVar* fun = item.second->getFunction();
146 if (!tct->isCandidateFun(fun) && !isExtCall(fun))
147 {
148 const ICFGNode* entryNode = fun->getEntryBlock()->front();
149
151 continue;
152
154
155 for (const CxtThreadStmt& cts : tsSet)
156 {
157 const CallStrCxt& curCxt = cts.getContext();
158
159 for (auto it : *fun)
160 {
161 const SVFBasicBlock* svfbb = it.second;
162 for (const ICFGNode* curNode : svfbb->getICFGNodeList())
163 {
164 if (curNode == entryNode)
165 continue;
168 instToTSMap[curNode].insert(newCts);
169 }
170 }
171 }
172 }
173 }
174}
cJSON * item
Definition cJSON.h:222
const SVFBasicBlock * getEntryBlock() const
const ICFGNode * front() const

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

458{
461 for (const unsigned tid : ancestorAndSelfTids)
462 {
464 for (const unsigned stid : siblingTds)
465 {
466 if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid))
467 continue;
468
471 const ICFGNode* stmt = routine->getEntryBlock()->front();
472 CxtThreadStmt cts(stid, ct.getContext(), stmt);
474 }
475
476 DBOUT(DMTA, outs() << "##Sibling thread of " << curTid << " is : ");
478 DBOUT(DMTA, outs() << "\n");
479 }
480}
bool isRecurFullJoin(NodeID parentTid, NodeID curTid)
Thread curTid can be fully joined by parentTid recursively.
Definition MHP.cpp:485
bool isHBPair(NodeID tid1, NodeID tid2)
Whether thread t1 happens before t2 based on ForkJoin Analysis.
Definition MHP.cpp:555
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 267 of file MHP.h.

◆ fja

ForkJoinAnalysis* SVF::MHP::fja
private

ForJoin Analysis.

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

◆ interleavingQueriesTime

double SVF::MHP::interleavingQueriesTime

Definition at line 277 of file MHP.h.

◆ interleavingTime

double SVF::MHP::interleavingTime

Definition at line 276 of file MHP.h.

◆ nonCandidateFuncMHPRelMap

FuncPairToBool SVF::MHP::nonCandidateFuncMHPRelMap
private

Definition at line 270 of file MHP.h.

◆ numOfMHPQueries

u32_t SVF::MHP::numOfMHPQueries

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

Definition at line 275 of file MHP.h.

◆ numOfTotalQueries

u32_t SVF::MHP::numOfTotalQueries

Total number of queries.

Definition at line 274 of file MHP.h.

◆ tcg

ThreadCallGraph* SVF::MHP::tcg
private

TCG.

Definition at line 264 of file MHP.h.

◆ tct

TCT* SVF::MHP::tct
private

TCT.

Definition at line 265 of file MHP.h.

◆ threadStmtToThreadInterLeav

ThreadStmtToThreadInterleav SVF::MHP::threadStmtToThreadInterLeav
private

Definition at line 268 of file MHP.h.


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