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
44TCT::TCT(PointerAnalysis* p) :pta(p),TCTNodeNum(0),TCTEdgeNum(0),MaxCxtSize(0)
45{
46 tcg = SVFUtil::dyn_cast<ThreadCallGraph>(pta->getCallGraph());
47 assert(tcg != nullptr && "TCT::TCT: call graph is not a ThreadCallGraph!");
49 //tcg->updateJoinEdge(pta);
51 tcgSCC->find();
52 build();
53}
54
56{
58 {
59 delete dummyForkSite;
60 }
61}
62
69{
70 assert(inst && "null value instruction!!");
71
74 worklist.push(inst);
75
76 while(!worklist.empty())
77 {
78 const ICFGNode* inst = worklist.pop();
79 insts.insert(inst);
81 for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
82 {
83 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
84 ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
85 {
86 if(insts.insert(*cit).second)
87 worklist.push(*cit);
88 }
89 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
90 ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
91 {
92 if(insts.insert(*cit).second)
93 worklist.push(*cit);
94 }
95 }
96 }
97
98 for(const ICFGNode* i : insts)
99 {
100 if(i->getFun()->hasLoopInfo(i->getBB()))
101 return true;
102 }
103
104
105 return false;
106}
107
113bool TCT::isInRecursion(const ICFGNode* inst) const
114{
115 const FunObjVar* f = inst->getFun();
118 worklist.push(f);
119
120 while(!worklist.empty())
121 {
122 const FunObjVar* svffun = worklist.pop();
123 visits.insert(svffun);
124 if(tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId()))
125 return true;
126
128
129 for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
130 {
131 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
132 ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
133 {
134 const FunObjVar* caller = (*cit)->getFun();
135 if(visits.find(caller)==visits.end())
136 worklist.push(caller);
137 }
138 for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
139 ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
140 {
141 const FunObjVar* caller = (*cit)->getFun();
142 if(visits.find(caller)==visits.end())
143 worklist.push(caller);
144 }
145 }
146 }
147
148 return false;
149
150}
151
156{
157 for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
158 {
159 const FunObjVar* svfun = (*it)->getParent()->getParent();
161
162 for(ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), neit = tcg->getForkEdgeEnd(*it); nit!=neit; nit++)
163 {
164 const CallGraphNode* forkeeNode = (*nit)->getDstNode();
165 candidateFuncSet.insert(forkeeNode->getFunction());
166 }
167
168 }
169
170 for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; ++it)
171 {
172 const FunObjVar* svfun = (*it)->getParent()->getParent();
174 }
175
176 if(candidateFuncSet.empty())
177 writeWrnMsg("We didn't recognize any fork site, this is single thread program?");
178}
179
184{
187 PTACGNodeSet visited;
188 worklist.push(cgnode);
189 visited.insert(cgnode);
190 while(!worklist.empty())
191 {
192 const CallGraphNode* node = worklist.pop();
193 candidateFuncSet.insert(node->getFunction());
195 {
196 const CallGraphNode* srcNode = (*nit)->getSrcNode();
197 if(visited.find(srcNode)==visited.end())
198 {
199 visited.insert(srcNode);
200 worklist.push(srcNode);
201 }
202 }
203 }
204}
205
210{
212 for (const auto& item: *svfirCallGraph)
213 {
214 const FunObjVar* fun = item.second->getFunction();
215 if (SVFUtil::isExtCall(fun))
216 continue;
217 CallGraphNode* node = tcg->getCallGraphNode(fun);
218 if (!node->hasIncomingEdge())
219 {
220 entryFuncSet.insert(fun);
221 }
222 }
223 assert(!entryFuncSet.empty() && "Can't find any function in module!");
224}
225
230{
231 if (this->nodeNum == 0 )
232 return;
233
234 FIFOWorkList<TCTNode*> worklist;
235 worklist.push(getTCTNode(0));
236
237 while(!worklist.empty())
238 {
239 TCTNode* node = worklist.pop();
240 const CxtThread &ct = node->getCxtThread();
241
242 if(ct.isIncycle() || ct.isInloop())
243 {
244 node->setMultiforked(true);
245 }
246 else
247 {
248 for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getInEdges().begin(), eit = node->getInEdges().end(); it != eit;
249 ++it)
250 {
251 if ((*it)->getSrcNode()->isMultiforked())
252 node->setMultiforked(true);
253 }
254 }
255 for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getOutEdges().begin(), eit = node->getOutEdges().end(); it != eit;
256 ++it)
257 {
258 worklist.push((*it)->getDstNode());
259 }
260 }
261}
262
263
268{
269 const FunObjVar* callee = cgEdge->getDstNode()->getFunction();
270
271 CallStrCxt cxt(ctp.getContext());
272 CallStrCxt oldCxt = cxt;
273 const CallICFGNode* callNode = cs;
274
276 if(isCandidateFun(callNode->getFun()) == true)
278
279 if(cgEdge->getEdgeKind() == CallGraphEdge::CallRetEdge)
280 {
281 CxtThreadProc newctp(ctp.getTid(),cxt,callee);
283 {
284 DBOUT(DMTA,outs() << "TCT Process CallRet old ctp --"; ctp.dump());
285 DBOUT(DMTA,outs() << "TCT Process CallRet new ctp --"; newctp.dump());
286 }
287 }
288
289 else if(cgEdge->getEdgeKind() == CallGraphEdge::TDForkEdge)
290 {
294
296 {
298 if(addTCTEdge(this->getTCTNode(ctp.getTid()), spawneeNode))
299 {
300 DBOUT(DMTA,outs() << "Add TCT Edge from thread " << ctp.getTid() << " ";
301 this->getTCTNode(ctp.getTid())->getCxtThread().dump();
302 outs() << " to thread " << spawneeNode->getId() << " ";
303 spawneeNode->getCxtThread().dump();
304 outs() << "\n" );
305 }
306 DBOUT(DMTA,outs() << "TCT Process Fork old ctp --"; ctp.dump());
307 DBOUT(DMTA,outs() << "TCT Process Fork new ctp --"; newctp.dump());
308 }
309 }
310}
311
317{
318 assert(!lp.empty() && "this is not a loop, empty basic block");
319 const FunObjVar* svffun = join->getFun();
320 const SVFBasicBlock* loopheadbb = svffun->getLoopHeader(lp);
321 const SVFBasicBlock* joinbb = join->getBB();
322 assert(loopheadbb->getParent()==joinbb->getParent() && "should inside same function");
323
324 for (const SVFBasicBlock* svf_scc_bb : loopheadbb->getSuccessors())
325 {
326 if(svffun->loopContainsBB(lp,svf_scc_bb))
327 {
328 if(svffun->dominate(joinbb,svf_scc_bb)==false)
329 return false;
330 }
331 }
332
333 return true;
334}
335
341{
342 for(ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it!=eit; ++it)
343 {
344 const ICFGNode* join = *it;
345 const FunObjVar* svffun = join->getFun();
346 const SVFBasicBlock* svfbb = join->getBB();
347
348 if(svffun->hasLoopInfo(svfbb))
349 {
350 const LoopBBs& lp = svffun->getLoopInfo(svfbb);
351 if(!lp.empty() && isJoinMustExecutedInLoop(lp,join))
352 {
354 }
355 }
356
358 inRecurJoinSites.insert(join);
359 }
360}
361
366{
367 for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it)
368 {
369 if(bb->getParent()->getLoopHeader(it->second) == bb)
370 return true;
371 }
372
373 return false;
374}
375
380{
381 for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it)
382 {
383 std::vector<const SVFBasicBlock*> exitbbs;
384 it->first->getFun()->getExitBlocksOfLoop(it->first->getBB(),exitbbs);
385 while(!exitbbs.empty())
386 {
387 const SVFBasicBlock* eb = exitbbs.back();
388 exitbbs.pop_back();
389 if(eb == bb)
390 return true;
391 }
392 }
393
394 return false;
395}
396
401{
402 const FunObjVar* fun = bb->getParent();
403 return fun->getLoopInfo(bb);
404}
405
410{
411
412 markRelProcs();
413
415
416 // the fork site of main function is initialized with nullptr.
417 // the context of main is initialized with empty
418 // start routine is empty
419
421
422 for (FunSet::iterator it=entryFuncSet.begin(), eit=entryFuncSet.end(); it!=eit; ++it)
423 {
424 if (!isCandidateFun(*it))
425 continue;
426 CallStrCxt cxt;
427 CxtThreadProc dummyCtp(-1, cxt, nullptr);
430 CxtThreadProc t(mainTCTNode->getId(), cxt, *it);
432 }
433
434 while(!ctpList.empty())
435 {
437 CallGraphNode* cgNode = tcg->getCallGraphNode(ctp.getProc());
438 if(isCandidateFun(cgNode->getFunction()) == false)
439 continue;
440
441 for(CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit!=neit; nit++)
442 {
443 const CallGraphEdge* cgEdge = (*nit);
444
445 for(CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(),
446 ecit = cgEdge->directCallsEnd(); cit!=ecit; ++cit)
447 {
448 DBOUT(DMTA,outs() << "\nTCT handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
450 }
451 for(CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(),
452 eind = cgEdge->indirectCallsEnd(); ind!=eind; ++ind)
453 {
454 DBOUT(DMTA,outs() << "\nTCT handling indirect call:" << **ind << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
456 }
457 }
458 }
459
461
463 {
464 print();
465 dump("tct");
466 }
467
468}
469
473void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
474{
475 const FunObjVar* caller = call->getFun();
476 CallSiteID csId = tcg->getCallSiteID(call, callee);
477
479 {
480 cxt.push_back(csId);
481 if (cxt.size() > Options::MaxContextLen())
482 cxt.erase(cxt.begin());
483 if (cxt.size() > MaxCxtSize)
484 MaxCxtSize = cxt.size();
485 DBOUT(DMTA,dumpCxt(cxt));
486 }
487}
488
489
494{
495 const FunObjVar* caller = call->getFun();
496 CallSiteID csId = tcg->getCallSiteID(call, callee);
497
499 if(isCandidateFun(caller) == false)
500 return true;
501
503 if(cxt.empty())
504 return true;
505
507 {
508 if(cxt.back() == csId)
509 cxt.pop_back();
510 else
511 return false;
512 DBOUT(DMTA,dumpCxt(cxt));
513 }
514
515 return true;
516}
517
522{
523 if (lhs.size() > call.size())
524 return false;
525 bool isSuffix = true;
526 for (size_t i = 0; i < lhs.size(); ++i)
527 {
528 if (lhs[lhs.size() - 1 - i] != call[call.size() - 1 - i])
529 {
530 isSuffix = false;
531 break;
532 }
533 }
534 return isSuffix;
535}
536
537
542{
543 std::string str;
544 std::stringstream rawstr(str);
545 rawstr << "[:";
546 for(CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it!=eit; ++it)
547 {
548 rawstr << " ' "<< *it << " ' ";
549 rawstr << (tcg->getCallSite(*it))->valueOnlyToString();
550 rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" << tcg->getCalleeOfCallSite(*it)->getName() << ", \n";
551 }
552 rawstr << " ]";
553 outs() << "max cxt = " << cxt.size() << rawstr.str() << "\n";
554}
555
559void TCT::dump(const std::string& filename)
560{
562}
563
567void TCT::print() const
568{
569 for(TCT::const_iterator it = this->begin(), eit = this->end(); it!=eit; ++it)
570 {
571 outs() << "TID " << it->first << "\t";
572 it->second->getCxtThread().dump();
573 }
574}
575
580{
581 TCTEdge edge(src, dst, kind);
584 if (outEdge && inEdge)
585 {
586 assert(outEdge == inEdge && "edges not match");
587 return outEdge;
588 }
589 else
590 return nullptr;
591}
592
597{
598 for (TCTEdge::ThreadCreateEdgeSet::const_iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter)
599 {
600 TCTEdge* edge = (*iter);
601 if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId())
602 return edge;
603 }
604 return nullptr;
605}
606namespace SVF
607{
608
612template<>
614{
615
618 DOTGraphTraits(bool isSimple = false) :
619 DefaultDOTGraphTraits(isSimple)
620 {
621 }
622
624 static std::string getGraphName(TCT *graph)
625 {
626 return "Thread Create Tree";
627 }
629 static std::string getNodeLabel(TCTNode *node, TCT *graph)
630 {
631 return std::to_string(node->getId());
632 }
633
634 static std::string getNodeAttributes(TCTNode *node, TCT *tct)
635 {
636 std::string attr;
637 if (node->isInloop())
638 {
639 attr.append("shape=record,style=filled,fillcolor=red");
640 }
641 else if (node->isIncycle())
642 {
643 attr.append("shape=record,style=filled,fillcolor=yellow");
644 }
645 return attr;
646 }
647
648 template<class EdgeIter>
650 {
651
652 TCTEdge* edge = csThreadTree->getGraphEdge(node, *EI, TCTEdge::ThreadCreateEdge);
653 (void)edge; // Suppress warning of unused variable under release build
654 assert(edge && "No edge found!!");
656 return "color=black";
657 }
658};
659} // End namespace llvm
660
#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:56
const CxtThread & getCxtThread() const
Get thread creation context, <fork site, call string context>
Definition TCT.h:102
void setMultiforked(bool value)
Definition TCT.h:117
bool isIncycle() const
Definition TCT.h:113
bool isInloop() const
inloop, incycle attributes
Definition TCT.h:109
bool pushToCTPWorkList(const CxtThreadProc &ctp)
WorkList helper functions.
Definition TCT.h:604
bool isInRecursion(const ICFGNode *inst) const
Whether an instruction is in a recursion.
Definition TCT.cpp:113
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:203
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:521
FunSet entryFuncSet
Definition TCT.h:624
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:537
virtual void collectLoopInfoForJoin()
Handle join site in loop.
Definition TCT.cpp:340
ThreadCallGraphSCC * tcgSCC
Procedures we care about during call graph traversing when creating TCT.
Definition TCT.h:626
virtual void collectEntryFunInCallGraph()
Get entry functions that are neither called by other functions nor extern functions.
Definition TCT.cpp:209
Set< const CallGraphNode * > PTACGNodeSet
Definition TCT.h:175
ICFGNode * createDummyForkSite()
Create and get a new dummy fork site for starter routines.
Definition TCT.h:595
DummyForkSiteSet dummyForkSites
set of dummy fork sites for starter routines
Definition TCT.h:634
InstToLoopMap joinSiteToLoopMap
Map a CxtThread to its start routine function.
Definition TCT.h:632
virtual ~TCT()
Destructor.
Definition TCT.cpp:55
void dump(const std::string &filename)
Dump the graph.
Definition TCT.cpp:559
FunSet candidateFuncSet
Procedures that are neither called by other functions nor extern functions.
Definition TCT.h:625
bool inSameCallGraphSCC(const CallGraphNode *src, const CallGraphNode *dst)
Whether two functions in the same callgraph scc.
Definition TCT.h:303
TCTEdge * getGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind)
Get call graph edge via nodes.
Definition TCT.cpp:596
bool isCandidateFun(const CallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
Definition TCT.h:288
CxtThreadProcVec ctpList
Thread call graph SCC.
Definition TCT.h:627
bool matchAndPopCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Definition TCT.cpp:493
bool isInLoopInstruction(const ICFGNode *inst)
Multi-forked threads.
Definition TCT.cpp:68
bool isJoinMustExecutedInLoop(const LoopBBs &lp, const ICFGNode *join)
Return true if a join instruction must be executed inside a loop.
Definition TCT.cpp:316
virtual void markRelProcs()
Mark relevant procedures that are backward reachable from any fork/join site.
Definition TCT.cpp:155
Set< const ICFGNode * > inRecurJoinSites
Fork or Join sites in recursions.
Definition TCT.h:633
PointerAnalysis * pta
Definition TCT.h:448
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
Definition TCT.cpp:541
bool addTCTEdge(TCTNode *src, TCTNode *dst)
Add TCT edge.
Definition TCT.h:465
u32_t MaxCxtSize
Definition TCT.h:451
bool isLoopHeaderOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is a loop head of a inloop join site.
Definition TCT.cpp:365
virtual void build()
Build TCT.
Definition TCT.cpp:409
void print() const
Print TCT information.
Definition TCT.cpp:567
virtual void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
Definition TCT.cpp:267
ThreadCallGraph * tcg
Definition TCT.h:447
void collectMultiForkedThreads()
Definition TCT.cpp:229
TCT(PointerAnalysis *p)
Constructor.
Definition TCT.cpp:44
CxtThreadProc popFromCTPWorkList()
Definition TCT.h:613
TCTEdge * hasGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind) const
Whether we have already created this call graph edge.
Definition TCT.cpp:579
bool isLoopExitOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is an exit of a inloop join site.
Definition TCT.cpp:379
SVFLoopAndDomInfo::LoopBBs LoopBBs
Definition TCT.h:158
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:473
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
static std::string getEdgeAttributes(TCTNode *node, EdgeIter EI, TCT *csThreadTree)
Definition TCT.cpp:649
NodeType::iterator ChildIteratorType
Definition TCT.cpp:617
static std::string getGraphName(TCT *graph)
Return name of the graph.
Definition TCT.cpp:624
static std::string getNodeAttributes(TCTNode *node, TCT *tct)
Definition TCT.cpp:634
static std::string getNodeLabel(TCTNode *node, TCT *graph)
Return function name;.
Definition TCT.cpp:629
DOTGraphTraits(bool isSimple=false)
Definition TCT.cpp:618