39using namespace SVFUtil;
48 assert(inst &&
"null value instruction!!");
54 while(!worklist.
empty())
61 for(PTACallGraphEdge::CallInstSet::const_iterator
cit = (*nit)->directCallsBegin(),
64 if(
insts.insert(*cit).second)
67 for(PTACallGraphEdge::CallInstSet::const_iterator
cit = (*nit)->indirectCallsBegin(),
70 if(
insts.insert(*cit).second)
78 if(
i->getFun()->hasLoopInfo(
i->getBB()))
98 while(!worklist.
empty())
109 for(PTACallGraphEdge::CallInstSet::const_iterator
cit = (*nit)->directCallsBegin(),
116 for(PTACallGraphEdge::CallInstSet::const_iterator
cit = (*nit)->indirectCallsBegin(),
155 writeWrnMsg(
"We didn't recognize any fork site, this is single thread program?");
168 while(!worklist.
empty())
175 if(visited.find(
srcNode)==visited.end())
215 while(!worklist.
empty())
220 if(
ct.isIncycle() ||
ct.isInloop())
229 if ((*it)->getSrcNode()->isMultiforked())
236 worklist.
push((*it)->getDstNode());
293 assert(!
lp.empty() &&
"this is not a loop, empty basic block");
358 std::vector<const SVFBasicBlock*>
exitbbs;
359 it->first->getFun()->getExitBlocksOfLoop(
it->first->getBB(),
exitbbs);
417 for(PTACallGraphEdge::CallInstSet::const_iterator
cit =
cgEdge->directCallsBegin(),
420 DBOUT(
DMTA,
outs() <<
"\nTCT handling direct call:" << **
cit <<
"\t" <<
cgEdge->getSrcNode()->getFunction()->getName() <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName() <<
"\n");
423 for(PTACallGraphEdge::CallInstSet::const_iterator
ind =
cgEdge->indirectCallsBegin(),
426 DBOUT(
DMTA,
outs() <<
"\nTCT handling indirect call:" << **
ind <<
"\t" <<
cgEdge->getSrcNode()->getFunction()->getName() <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName() <<
"\n");
482 if(cxt.back() == csId)
501 for(CallStrCxt::const_iterator
it = cxt.begin(),
eit = cxt.end();
it!=
eit; ++
it)
508 outs() <<
"max cxt = " << cxt.size() <<
rawstr.str() <<
"\n";
527 outs() <<
"TID " <<
it->first <<
"\t";
528 it->second->getCxtThread().dump();
557 if (
edge->getEdgeKind() == kind &&
edge->getDstID() == dst->
getId())
582 return "Thread Create Tree";
587 return std::to_string(node->
getId());
595 attr.append(
" style=filled fillcolor=red");
599 attr.append(
" style=filled fillcolor=yellow");
604 template<
class EdgeIter>
612 return "color=black";
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
const SVFFunction * getCaller() const
Return callsite.
NodeID getTid() const
Return current thread id.
bool push(const Data &data)
iterator begin()
Iterators.
u32_t nodeNum
total num of edge
IDToNodeMapTy::const_iterator const_iterator
NodeType * getGNode(NodeID id) const
Get a node.
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
GEdgeSetTy::iterator iterator
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
GEdgeSetTy::const_iterator const_iterator
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType >, bool simple=false)
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
static const Option< bool > TCTDotGraph
const SVFFunction * getFunction() const
Get function of this call node.
const CallICFGNode * getCallSite(CallSiteID id) const
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *callee) const
Get CallSiteID.
const SVFFunction * getCalleeOfCallSite(CallSiteID id) const
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
NodeID getId() const
Get ID.
const SVFFunction * getParent() const
const ICFGNode * back() const
const LoopBBs & getLoopInfo(const SVFBasicBlock *bb) const
const SVFBasicBlock * getLoopHeader(const BBList &lp) const
CallGraph * getCallGraph()
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
const std::string & getName() const
const CxtThread & getCxtThread() const
Get CxtThread.
void setMultiforked(bool value)
bool isInloop() const
inloop, incycle attributes
bool pushToCTPWorkList(const CxtThreadProc &ctp)
WorkList helper functions.
bool isInRecursion(const ICFGNode *inst) const
Whether an instruction is in a recursion.
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
void collectLoopInfoForJoin()
Handle join site in loop.
ThreadCallGraphSCC * tcgSCC
Procedures we care about during call graph traversing when creating TCT.
void collectEntryFunInCallGraph()
Get entry functions that are neither called by other functions nor extern functions.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Push calling context.
InstToLoopMap joinSiteToLoopMap
Map a CxtThread to its start routine function.
void dump(const std::string &filename)
Dump the graph.
FunSet candidateFuncSet
Procedures that are neither called by other functions nor extern functions.
TCTEdge * getGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind)
Get call graph edge via nodes.
CxtThreadProcVec ctpList
Thread call graph SCC.
bool isInLoopInstruction(const ICFGNode *inst)
Multi-forked threads.
bool isJoinMustExecutedInLoop(const LoopBBs &lp, const ICFGNode *join)
Return true if a join instruction must be executed inside a loop.
void markRelProcs()
Mark relevant procedures that are backward reachable from any fork/join site.
Set< const ICFGNode * > inRecurJoinSites
Fork or Join sites in recursions.
void handleCallRelation(CxtThreadProc &ctp, const PTACallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
bool inSameCallGraphSCC(const PTACallGraphNode *src, const PTACallGraphNode *dst)
Whether two functions in the same callgraph scc.
TCTNode * getOrCreateTCTNode(const CallStrCxt &cxt, const ICFGNode *fork, const CallStrCxt &oldCxt, const SVFFunction *routine)
Get or create a tct node based on CxtThread.
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const SVFFunction *callee)
Match context.
bool isCandidateFun(const PTACallGraph::FunctionSet &callees) const
Whether it is a candidate function for indirect call.
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
bool addTCTEdge(TCTNode *src, TCTNode *dst)
Add TCT edge.
bool isLoopHeaderOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is a loop head of a inloop join site.
void print() const
Print TCT information.
void collectMultiForkedThreads()
CxtThreadProc popFromCTPWorkList()
TCTEdge * hasGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind) const
Whether we have already created this call graph edge.
bool isLoopExitOfJoinLoop(const SVFBasicBlock *bb)
Whether a given bb is an exit of a inloop join site.
SVFLoopAndDomInfo::LoopBBs LoopBBs
const LoopBBs & getLoop(const ICFGNode *inst)
Get loop for an instruction.
Set< const PTACallGraphNode * > PTACGNodeSet
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.
bool isExtCall(const SVFFunction *fun)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
std::ostream & outs()
Overwrite llvm::outs()
llvm::IRBuilder IRBuilder
std::vector< u32_t > CallStrCxt
static std::string getEdgeAttributes(TCTNode *node, EdgeIter EI, TCT *csThreadTree)
NodeType::iterator ChildIteratorType
static std::string getGraphName(TCT *graph)
Return name of the graph.
static std::string getNodeAttributes(TCTNode *node, TCT *tct)
static std::string getNodeLabel(TCTNode *node, TCT *graph)
Return function name;.
DOTGraphTraits(bool isSimple=false)