Static Value-Flow Analysis
Loading...
Searching...
No Matches
TCT.cpp
Go to the documentation of this file.
1//===- TCT.cpp -- Thread creation tree-------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23
24/*
25 * TCT.cpp
26 *
27 * Created on: Jun 24, 2015
28 * Author: Yulei Sui, Peng Di
29 */
30
31#include "Util/Options.h"
32#include "MTA/TCT.h"
33#include "MTA/MTA.h"
34#include "Graphs/CallGraph.h"
35
36#include <string>
37
38using namespace SVF;
39using namespace SVFUtil;
40
41std::unique_ptr<TCT> TCT::create(PointerAnalysis* p)
42{
44}
45
46std::unique_ptr<TCT> TCT::create(PointerAnalysis* p, u32_t contextLimit)
47{
48 std::unique_ptr<TCT> tct(new TCT(p, contextLimit));
49 tct->build();
50 return tct;
51}
52
54 : tcg(nullptr), pta(p), contextLimit(contextLimit), TCTNodeNum(0),
55 TCTEdgeNum(0), MaxCxtSize(0), tcgSCC(nullptr)
56{
57 tcg = SVFUtil::dyn_cast<ThreadCallGraph>(pta->getCallGraph());
58 assert(tcg != nullptr && "TCT::TCT: call graph is not a ThreadCallGraph!");
60 //tcg->updateJoinEdge(pta);
62 tcgSCC->find();
63}
64
66{
68 {
69 delete dummyForkSite;
70 }
71}
72
79{
80 assert(inst && "null value instruction!!");
81
84 worklist.push(inst);
85
86 while(!worklist.empty())
87 {
88 const ICFGNode* inst = worklist.pop();
89 insts.insert(inst);
91 for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
92 {
93 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
94 ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
95 {
96 if(insts.insert(*cit).second)
97 worklist.push(*cit);
98 }
99 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
100 ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
101 {
102 if(insts.insert(*cit).second)
103 worklist.push(*cit);
104 }
105 }
106 }
107
108 for(const ICFGNode* i : insts)
109 {
110 if(i->getFun()->hasLoopInfo(i->getBB()))
111 return true;
112 }
113
114
115 return false;
116}
117
123bool TCT::isInRecursion(const ICFGNode* inst) const
124{
125 const FunObjVar* f = inst->getFun();
128 worklist.push(f);
129
130 while(!worklist.empty())
131 {
132 const FunObjVar* svffun = worklist.pop();
133 visits.insert(svffun);
134 if(tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId()))
135 return true;
136
138
139 for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
140 {
141 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
142 ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
143 {
144 const FunObjVar* caller = (*cit)->getFun();
145 if(visits.find(caller)==visits.end())
146 worklist.push(caller);
147 }
148 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
149 ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
150 {
151 const FunObjVar* caller = (*cit)->getFun();
152 if(visits.find(caller)==visits.end())
153 worklist.push(caller);
154 }
155 }
156 }
157
158 return false;
159
160}
161
166{
167 for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
168 {
169 const FunObjVar* svfun = (*it)->getParent()->getParent();
171
172 for(ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), neit = tcg->getForkEdgeEnd(*it); nit!=neit; nit++)
173 {
174 const CallGraphNode* forkeeNode = (*nit)->getDstNode();
175 candidateFuncSet.insert(forkeeNode->getFunction());
176 }
177
178 }
179
180 for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; ++it)
181 {
182 const FunObjVar* svfun = (*it)->getParent()->getParent();
184 }
185
186 if(candidateFuncSet.empty())
187 writeWrnMsg("We didn't recognize any fork site, this is single thread program?");
188}
189
194{
197 PTACGNodeSet visited;
198 worklist.push(cgnode);
199 visited.insert(cgnode);
200 while(!worklist.empty())
201 {
202 const CallGraphNode* node = worklist.pop();
203 candidateFuncSet.insert(node->getFunction());
205 {
206 const CallGraphNode* srcNode = (*nit)->getSrcNode();
207 if(visited.find(srcNode)==visited.end())
208 {
209 visited.insert(srcNode);
210 worklist.push(srcNode);
211 }
212 }
213 }
214}
215
220{
222 for (const auto& item: *svfirCallGraph)
223 {
224 const FunObjVar* fun = item.second->getFunction();
225 if (SVFUtil::isExtCall(fun))
226 continue;
227 CallGraphNode* node = tcg->getCallGraphNode(fun);
228 if (!node->hasIncomingEdge())
229 {
230 entryFuncSet.insert(fun);
231 }
232 }
233 assert(!entryFuncSet.empty() && "Can't find any function in module!");
234}
235
240{
241 if (this->nodeNum == 0 )
242 return;
243
244 FIFOWorkList<TCTNode*> worklist;
245 worklist.push(getTCTNode(0));
246
247 while(!worklist.empty())
248 {
249 TCTNode* node = worklist.pop();
250 const CxtThread &ct = node->getCxtThread();
251
252 if(ct.isIncycle() || ct.isInloop())
253 {
254 node->setMultiforked(true);
255 }
256 else
257 {
258 for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getInEdges().begin(), eit = node->getInEdges().end(); it != eit;
259 ++it)
260 {
261 if ((*it)->getSrcNode()->isMultiforked())
262 node->setMultiforked(true);
263 }
264 }
265 for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getOutEdges().begin(), eit = node->getOutEdges().end(); it != eit;
266 ++it)
267 {
268 worklist.push((*it)->getDstNode());
269 }
270 }
271}
272
273
278{
279 const FunObjVar* callee = cgEdge->getDstNode()->getFunction();
280
281 CallStrCxt cxt(ctp.getContext());
282 CallStrCxt oldCxt = cxt;
283 const CallICFGNode* callNode = cs;
284
286 if(isCandidateFun(callNode->getFun()) == true)
288
289 if(cgEdge->getEdgeKind() == CallGraphEdge::CallRetEdge)
290 {
291 CxtThreadProc newctp(ctp.getTid(),cxt,callee);
293 {
294 DBOUT(DMTA,outs() << "TCT Process CallRet old ctp --"; ctp.dump());
295 DBOUT(DMTA,outs() << "TCT Process CallRet new ctp --"; newctp.dump());
296 }
297 }
298
299 else if(cgEdge->getEdgeKind() == CallGraphEdge::TDForkEdge)
300 {
304
306 {
308 if(addTCTEdge(this->getTCTNode(ctp.getTid()), spawneeNode))
309 {
310 DBOUT(DMTA,outs() << "Add TCT Edge from thread " << ctp.getTid() << " ";
311 this->getTCTNode(ctp.getTid())->getCxtThread().dump();
312 outs() << " to thread " << spawneeNode->getId() << " ";
313 spawneeNode->getCxtThread().dump();
314 outs() << "\n" );
315 }
316 DBOUT(DMTA,outs() << "TCT Process Fork old ctp --"; ctp.dump());
317 DBOUT(DMTA,outs() << "TCT Process Fork new ctp --"; newctp.dump());
318 }
319 }
320}
321
327{
328 assert(!lp.empty() && "this is not a loop, empty basic block");
329 const FunObjVar* svffun = join->getFun();
330 const SVFBasicBlock* loopheadbb = svffun->getLoopHeader(lp);
331 const SVFBasicBlock* joinbb = join->getBB();
332 assert(loopheadbb->getParent()==joinbb->getParent() && "should inside same function");
333
334 for (const SVFBasicBlock* svf_scc_bb : loopheadbb->getSuccessors())
335 {
336 if(svffun->loopContainsBB(lp,svf_scc_bb))
337 {
338 if(svffun->dominate(joinbb,svf_scc_bb)==false)
339 return false;
340 }
341 }
342
343 return true;
344}
345
351{
352 for(ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it!=eit; ++it)
353 {
354 const ICFGNode* join = *it;
355 const FunObjVar* svffun = join->getFun();
356 const SVFBasicBlock* svfbb = join->getBB();
357
358 if(svffun->hasLoopInfo(svfbb))
359 {
360 const LoopBBs& lp = svffun->getLoopInfo(svfbb);
361 if(!lp.empty() && isJoinMustExecutedInLoop(lp,join))
362 {
364 }
365 }
366
368 inRecurJoinSites.insert(join);
369 }
370}
371
376{
377 for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it)
378 {
379 if(bb->getParent()->getLoopHeader(it->second) == bb)
380 return true;
381 }
382
383 return false;
384}
385
390{
391 for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it)
392 {
393 std::vector<const SVFBasicBlock*> exitbbs;
394 it->first->getFun()->getExitBlocksOfLoop(it->first->getBB(),exitbbs);
395 while(!exitbbs.empty())
396 {
397 const SVFBasicBlock* eb = exitbbs.back();
398 exitbbs.pop_back();
399 if(eb == bb)
400 return true;
401 }
402 }
403
404 return false;
405}
406
411{
412 const FunObjVar* fun = bb->getParent();
413 return fun->getLoopInfo(bb);
414}
415
420{
421
422 markRelProcs();
423
425
426 // the fork site of main function is initialized with nullptr.
427 // the context of main is initialized with empty
428 // start routine is empty
429
431
432 for (FunSet::iterator it=entryFuncSet.begin(), eit=entryFuncSet.end(); it!=eit; ++it)
433 {
434 if (!isCandidateFun(*it))
435 continue;
436 CallStrCxt cxt;
437 CxtThreadProc dummyCtp(-1, cxt, nullptr);
440 CxtThreadProc t(mainTCTNode->getId(), cxt, *it);
442 }
443
444 while(!ctpList.empty())
445 {
447 CallGraphNode* cgNode = tcg->getCallGraphNode(ctp.getProc());
448 if(isCandidateFun(cgNode->getFunction()) == false)
449 continue;
450
451 for(CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit!=neit; nit++)
452 {
453 const CallGraphEdge* cgEdge = (*nit);
454
455 for(CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(),
456 ecit = cgEdge->directCallsEnd(); cit!=ecit; ++cit)
457 {
458 DBOUT(DMTA,outs() << "\nTCT handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
460 }
461 for(CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(),
462 eind = cgEdge->indirectCallsEnd(); ind!=eind; ++ind)
463 {
464 DBOUT(DMTA,outs() << "\nTCT handling indirect call:" << **ind << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
466 }
467 }
468 }
469
471
473 {
474 print();
475 dump("tct");
476 }
477
478}
479
483void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
484{
485 const FunObjVar* caller = call->getFun();
486 CallSiteID csId = tcg->getCallSiteID(call, callee);
487
489 {
490 cxt.push_back(csId);
491 if (cxt.size() > contextLimit)
492 cxt.erase(cxt.begin());
493 if (cxt.size() > MaxCxtSize)
494 MaxCxtSize = cxt.size();
495 DBOUT(DMTA,dumpCxt(cxt));
496 }
497}
498
499
504{
505 const FunObjVar* caller = call->getFun();
506 CallSiteID csId = tcg->getCallSiteID(call, callee);
507
509 if(isCandidateFun(caller) == false)
510 return true;
511
513 if(cxt.empty())
514 return true;
515
517 {
518 if(cxt.back() == csId)
519 cxt.pop_back();
520 else
521 return false;
522 DBOUT(DMTA,dumpCxt(cxt));
523 }
524
525 return true;
526}
527
532{
533 if (lhs.size() > call.size())
534 return false;
535 bool isSuffix = true;
536 for (size_t i = 0; i < lhs.size(); ++i)
537 {
538 if (lhs[lhs.size() - 1 - i] != call[call.size() - 1 - i])
539 {
540 isSuffix = false;
541 break;
542 }
543 }
544 return isSuffix;
545}
546
547
552{
553 std::string str;
554 std::stringstream rawstr(str);
555 rawstr << "[:";
556 for(CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it!=eit; ++it)
557 {
558 rawstr << " ' "<< *it << " ' ";
559 rawstr << (tcg->getCallSite(*it))->valueOnlyToString();
560 rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" << tcg->getCalleeOfCallSite(*it)->getName() << ", \n";
561 }
562 rawstr << " ]";
563 outs() << "max cxt = " << cxt.size() << rawstr.str() << "\n";
564}
565
569void TCT::dump(const std::string& filename)
570{
572}
573
577void TCT::print() const
578{
579 for(TCT::const_iterator it = this->begin(), eit = this->end(); it!=eit; ++it)
580 {
581 outs() << "TID " << it->first << "\t";
582 it->second->getCxtThread().dump();
583 }
584}
585
590{
591 TCTEdge edge(src, dst, kind);
594 if (outEdge && inEdge)
595 {
596 assert(outEdge == inEdge && "edges not match");
597 return outEdge;
598 }
599 else
600 return nullptr;
601}
602
607{
608 for (TCTEdge::ThreadCreateEdgeSet::const_iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter)
609 {
610 TCTEdge* edge = (*iter);
611 if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId())
612 return edge;
613 }
614 return nullptr;
615}
616namespace SVF
617{
618
622template<>
624{
625
628 DOTGraphTraits(bool isSimple = false) :
629 DefaultDOTGraphTraits(isSimple)
630 {
631 }
632
634 static std::string getGraphName(TCT *graph)
635 {
636 return "Thread Create Tree";
637 }
639 static std::string getNodeLabel(TCTNode *node, TCT *graph)
640 {
641 return std::to_string(node->getId());
642 }
643
644 static std::string getNodeAttributes(TCTNode *node, TCT *tct)
645 {
646 std::string attr;
647 if (node->isInloop())
648 {
649 attr.append("shape=record,style=filled,fillcolor=red");
650 }
651 else if (node->isIncycle())
652 {
653 attr.append("shape=record,style=filled,fillcolor=yellow");
654 }
655 return attr;
656 }
657
658 template<class EdgeIter>
660 {
661
662 TCTEdge* edge = csThreadTree->getGraphEdge(node, *EI, TCTEdge::ThreadCreateEdge);
663 (void)edge; // Suppress warning of unused variable under release build
664 assert(edge && "No edge found!!");
666 return "color=black";
667 }
668};
669} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DMTA
Definition SVFType.h:597
cJSON * p
Definition cJSON.cpp:2559
cJSON * item
Definition cJSON.h:222
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
const CallICFGNode * getCallSite(CallSiteID id) const
Definition CallGraph.h:408
const FunObjVar * getCalleeOfCallSite(CallSiteID id) const
Definition CallGraph.h:413
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Get CallSiteID.
Definition CallGraph.h:389
const FunObjVar * getCaller() const
Return callsite.
Definition ICFGNode.h:453
NodeID getTid() const
Return current thread id.
Definition CxtStmt.h:410
void dump() const
Dump CxtThread.
Definition CxtStmt.h:277
bool push(const Data &data)
Definition WorkList.h:180
bool empty() const
Definition WorkList.h:161
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const SVFBasicBlock * getLoopHeader(const BBList &lp) const
const LoopBBs & getLoopInfo(const SVFBasicBlock *bb) const
iterator begin()
Iterators.
u32_t nodeNum
total num of edge
IDToNodeMapTy::const_iterator const_iterator
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeEnd()
GEdgeSetTy::iterator iterator
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
GEdgeSetTy::const_iterator const_iterator
iterator InEdgeBegin()
iterator InEdgeEnd()
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:75
static Option< u32_t > MaxContextLen
Definition Options.h:81
static const Option< bool > TCTDotGraph
Definition Options.h:159
CallGraph * getCallGraph() const
Return call graph.
CallGraphSCC * getCallGraphSCC() const
Return call graph SCC.
const FunObjVar * getParent() const
const ICFGNode * back() const
const CallGraph * getCallGraph()
Get CG.
Definition SVFIR.h:248
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const std::string & getName() const
Definition SVFValue.h:184
@ ThreadCreateEdge
Definition TCT.h:57
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:103
void setMultiforked(bool value)
Definition TCT.h:118
bool isIncycle() const
Definition TCT.h:114
bool isInloop() const
inloop, incycle attributes
Definition TCT.h:110
bool pushToCTPWorkList(const CxtThreadProc &ctp)
WorkList helper functions.
Definition TCT.h:595
bool isInRecursion(const ICFGNode *inst) const
Whether an instruction is in a recursion.
Definition TCT.cpp:123
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:209
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:531
FunSet entryFuncSet
Definition TCT.h:615
TCTNode * getOrCreateTCTNode(const CallStrCxt &cxt, const ICFGNode *fork, const CxtThreadProc &forkSiteCtp, const FunObjVar *routine)
Get or create a tct node based on CxtThread.
Definition TCT.h:528
virtual void collectLoopInfoForJoin()
Handle join site in loop.
Definition TCT.cpp:350
ThreadCallGraphSCC * tcgSCC
Procedures we care about during call graph traversing when creating TCT.
Definition TCT.h:617
virtual void collectEntryFunInCallGraph()
Get entry functions that are neither called by other functions nor extern functions.
Definition TCT.cpp:219
Set< const CallGraphNode * > PTACGNodeSet
Definition TCT.h:176
ICFGNode * createDummyForkSite()
Create and get a new dummy fork site for starter routines.
Definition TCT.h:586
static std::unique_ptr< TCT > create(PointerAnalysis *p)
Construct and build a TCT with the command-line context bound.
Definition TCT.cpp:41
DummyForkSiteSet dummyForkSites
set of dummy fork sites for starter routines
Definition TCT.h:625
InstToLoopMap joinSiteToLoopMap
Map a CxtThread to its start routine function.
Definition TCT.h:623
virtual ~TCT()
Destructor.
Definition TCT.cpp:65
void dump(const std::string &filename)
Dump the graph.
Definition TCT.cpp:569
FunSet candidateFuncSet
Procedures that are neither called by other functions nor extern functions.
Definition TCT.h:616
bool inSameCallGraphSCC(const CallGraphNode *src, const CallGraphNode *dst)
Whether two functions in the same callgraph scc.
Definition TCT.h:309
TCTEdge * getGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind)
Get call graph edge via nodes.
Definition TCT.cpp:606
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:294
CxtThreadProcVec ctpList
Thread call graph SCC.
Definition TCT.h:618
const u32_t contextLimit
Definition TCT.h:459
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:503
bool isInLoopInstruction(const ICFGNode *inst)
Multi-forked threads.
Definition TCT.cpp:78
bool isJoinMustExecutedInLoop(const LoopBBs &lp, const ICFGNode *join)
Return true if a join instruction must be executed inside a loop.
Definition TCT.cpp:326
virtual void markRelProcs()
Mark relevant procedures that are backward reachable from any fork/join site.
Definition TCT.cpp:165
Set< const ICFGNode * > inRecurJoinSites
Fork or Join sites in recursions.
Definition TCT.h:624
PointerAnalysis * pta
Definition TCT.h:458
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
Definition TCT.cpp:551
bool addTCTEdge(TCTNode *src, TCTNode *dst)
Add TCT edge.
Definition TCT.h:476
u32_t MaxCxtSize
Definition TCT.h:462
TCT(PointerAnalysis *p, u32_t contextLimit)
Definition TCT.cpp:53
bool isLoopHeaderOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is a loop head of a inloop join site.
Definition TCT.cpp:375
virtual void build()
Build TCT.
Definition TCT.cpp:419
void print() const
Print TCT information.
Definition TCT.cpp:577
virtual void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
Definition TCT.cpp:277
ThreadCallGraph * tcg
Definition TCT.h:457
void collectMultiForkedThreads()
Definition TCT.cpp:239
CxtThreadProc popFromCTPWorkList()
Definition TCT.h:604
TCTEdge * hasGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind) const
Whether we have already created this call graph edge.
Definition TCT.cpp:589
bool isLoopExitOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is an exit of a inloop join site.
Definition TCT.cpp:389
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition TCT.h:159
const LoopBBs & getLoop(const ICFGNode *inst)
Get loop for an instruction.
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:483
CallSiteSet::const_iterator forksitesEnd() const
CallSiteSet::const_iterator forksitesBegin() const
Fork sites iterators.
CallSiteSet::const_iterator joinsitesEnd() const
ForkEdgeSet::const_iterator getForkEdgeEnd(const CallICFGNode *cs) const
ForkEdgeSet::const_iterator getForkEdgeBegin(const CallICFGNode *cs) const
CallSiteSet::const_iterator joinsitesBegin() const
Join sites iterators.
void updateCallGraph(PointerAnalysis *pta)
Update call graph using pointer results.
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:72
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:78
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
std::vector< u32_t > CallStrCxt
Definition GeneralType.h:96
unsigned u32_t
Definition GeneralType.h:67
static std::string getEdgeAttributes(TCTNode *node, EdgeIter EI, TCT *csThreadTree)
Definition TCT.cpp:659
NodeType::iterator ChildIteratorType
Definition TCT.cpp:627
static std::string getGraphName(TCT *graph)
Return name of the graph.
Definition TCT.cpp:634
static std::string getNodeAttributes(TCTNode *node, TCT *tct)
Definition TCT.cpp:644
static std::string getNodeLabel(TCTNode *node, TCT *graph)
Return function name;.
Definition TCT.cpp:639
DOTGraphTraits(bool isSimple=false)
Definition TCT.cpp:628