74 return n.raw !=
nullptr ?
n.raw->toString() :
"";
79 std::string
str =
"shape=record";
81 if (SVFUtil::isa<FunEntryICFGNode>(node))
str +=
",color=yellow";
82 else if (SVFUtil::isa<FunExitICFGNode>(node))
str +=
",color=green";
83 else if (SVFUtil::isa<CallICFGNode>(node))
str +=
",color=red";
84 else if (SVFUtil::isa<RetICFGNode>(node))
str +=
",color=blue";
85 else if (SVFUtil::isa<GlobalICFGNode>(node))
str +=
",color=purple";
86 else str +=
",color=black";
91 template <
class EdgeIter>
95 if (e.
bridged)
return "style=dashed,color=gray";
97 return "style=solid,color=red";
99 return "style=solid,color=blue";
100 return "style=solid";
114 return "SlicedThreadCallGraph";
124 return n.raw !=
nullptr ?
n.raw->getName() :
"";
129 return "shape=record,color=black";
132 template <
class EdgeIter>
138 return "color=black";
162 return n.raw !=
nullptr ?
n.raw->toString() :
"";
167 return "shape=record,color=black";
170 template <
class EdgeIter>
173 const SVFStmt*
s =
EI.currentEdge().underlying;
174 if (SVFUtil::isa<LoadStmt>(
s))
return "color=blue";
175 if (SVFUtil::isa<StoreStmt>(
s))
return "color=red";
176 if (SVFUtil::isa<GepStmt>(
s))
return "color=purple";
177 if (SVFUtil::isa<AddrStmt>(
s))
return "color=green";
178 if (SVFUtil::isa<CallPE>(
s))
return "color=orange";
179 if (SVFUtil::isa<RetPE>(
s))
return "color=cyan";
180 return "color=black";
204 return n.raw !=
nullptr ?
n.raw->toString() :
"";
209 if (SVFUtil::isa<StoreSVFGNode>(
n.raw))
return "shape=record,color=red";
210 if (SVFUtil::isa<LoadSVFGNode>(
n.raw))
return "shape=record,color=blue";
211 return "shape=record,color=black";
214 template <
class EdgeIter>
217 const SVFGEdge* e =
EI.currentEdge().underlying;
218 if (e !=
nullptr && SVFUtil::isa<IndirectSVFGEdge>(e))
return "style=dashed";
219 return "style=solid";
232 if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(
n))
244 assert(
svfg !=
nullptr &&
"SlicedSVFGView: bind the SVFG before dumping");
276 for (
auto it = GT::child_begin(
n), e = GT::child_end(
n); it != e; ++it)
277 out.push_back((*it).raw);
289 for (
auto it = GT::child_begin(
n), e = GT::child_end(
n); it != e; ++it)
290 out.push_back((*it).raw);
343 std::vector<const ICFGNode*>
removed;
349 rid[
n] =
static_cast<int>(
removed.size());
352 const int R =
static_cast<int>(
removed.size());
360 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(it->second);
361 if (call ==
nullptr || call->
getRetICFGNode() ==
nullptr)
continue;
363 if (e && SVFUtil::isa<CallCFGEdge>(e) &&
keptNodesSet.count(e->getDstNode()) == 0)
374 for (
const ICFGEdge* e :
n->getOutEdges())
375 if (e && SVFUtil::isa<IntraCFGEdge>(e) && e->getDstNode())
376 out.push_back(e->getDstNode());
381 std::vector<std::vector<int>>
radj(
R);
382 std::vector<std::vector<const ICFGNode*>>
keptSucc(
R);
383 std::vector<const ICFGNode*>
succs;
384 for (
int i = 0;
i <
R; ++
i)
390 else radj[
i].push_back(rid[
d]);
397 std::vector<char>
onstk(
R, 0);
398 std::vector<int>
tstk;
402 if (
idx[
s0] != -1)
continue;
403 std::vector<std::pair<int, size_t>>
work;
405 while (!
work.empty())
407 int v =
work.back().first;
408 size_t&
pi =
work.back().second;
421 work.emplace_back(
w, 0);
443 int p =
work.back().first;
452 for (
int i = 0;
i <
R; ++
i)
498 <<
" bridged edges across " <<
bridgedEdges.size() <<
" source nodes\n";
506 : pag(pag), keptStmts(keptStmts)
564 const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(stmt);
575 const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(stmt);
635 for (
auto it = GT::child_edge_begin(
n), e = GT::child_edge_end(
n); it != e; ++it)
636 out.push_back((*it).underlying);
648 for (
auto it = GT::child_edge_begin(
n), e = GT::child_edge_end(
n); it != e; ++it)
649 out.push_back((*it).underlying);
677 if (!directCalls.empty())
681 else if (!indirectCalls.empty())
739 if (node !=
nullptr && node->getFun() !=
nullptr)
747 assert(tcg !=
nullptr &&
"SlicedSVFIRView expects a ThreadCallGraph");
760 pagView = std::make_unique<SlicedPAGView>(
svfIr, keptStmts);
779 SVFUtil::outs() <<
" Indirect callsites that lost all targets: "
815 std::vector<const ICFGNode*>&
out)
const
832 std::vector<const CallGraphEdge*>&
out)
const
NodeID getRHSVarID() const
NodeID getLHSVarID() const
Set< const CallICFGNode * > CallInstSet
const FunObjVar * getFunction() const
Get function of this call node.
bool hasIndCSCallees(const CallICFGNode *cs) const
const FunctionSet & getIndCSCallees(const CallICFGNode *cs) const
Set< const FunObjVar * > FunctionSet
const RetICFGNode * getRetICFGNode() const
Return callsite.
const SVFBasicBlock * getEntryBlock() const
GEdgeKind getEdgeKind() const
iterator begin()
Iterators.
IDToNodeMapTy::iterator iterator
Node Iterators.
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType >, bool simple=false)
std::list< const SVFStmt * > SVFStmtList
ICFGNodeIDToNodeMapTy::iterator iterator
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
NodeID getOpVarID(u32_t pos) const
u32_t getOpVarNum() const
const std::vector< const ICFGNode * > & getICFGNodeList() const
const ICFGNode * front() const
const CallGraph * getCallGraph()
Get CG.
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
SlicedICFGView(ICFG *icfg, CallGraph *cg, const OrderedSet< const ICFGNode * > &keepNodes, const OrderedSet< const FunObjVar * > &keptFunctions, bool buildBridged=true)
Build complete ICFG view from keepNodes and keptFunctions.
Set< const ICFGNode * > keptNodesSet
void getPredNodes(const ICFGNode *node, std::vector< const ICFGNode * > &out) const
Get predecessor nodes (including bridged edges)
Map< const ICFGNode *, OrderedSet< const ICFGNode * > > bridgedPreds
void dump(const std::string &filename) const
Dump sliced ICFG to dot file.
bool isKeptNode(const ICFGNode *node) const
Check if a node is in the sliced view.
void getSuccNodes(const ICFGNode *node, std::vector< const ICFGNode * > &out) const
Get successor nodes (including bridged edges)
Map< const ICFGNode *, OrderedSet< const ICFGNode * > > bridgedEdges
const ICFGNode * getFunEntry(const FunObjVar *fun) const
OrderedSet< const ICFGEdge * > keptEdges
void buildICFGSets(const OrderedSet< const ICFGNode * > &keepNodes, const OrderedSet< const FunObjVar * > &keptFunctions)
void getFunICFGNodes(const FunObjVar *fun, std::vector< const ICFGNode * > &out) const
Kept ICFG nodes of fun.
OrderedSet< const ICFGNode * > keptNodes
SlicedPAGView(SVFIR *pag, const OrderedSet< const SVFStmt * > &keptStmts)
Set< NodeID > keptNodeIds
void dump(const std::string &filename) const
Dump the sliced PAG to a dot file.
OrderedSet< const SVFStmt * > keptStmts
bool isKeptNode(const SVFGNode *n) const
Whether the node is retained (see the class comment for the rule).
const SlicedICFGView * icfgView
void dump(const std::string &filename) const
Dump the sliced SVFG (retained nodes/edges only) via GraphWriter.
const CallGraph * getAnalysisCallGraph() const
const Set< const FunObjVar * > & getKeptFunctions() const
Get all kept functions.
const SlicedThreadCallGraphView * getThreadCallGraph() const
Get SlicedThreadCallGraphView.
std::unique_ptr< SlicedPAGView > pagView
std::unique_ptr< SlicedThreadCallGraphView > tcgView
void dumpAll(const std::string &prefix) const
Dump all views to files.
std::unique_ptr< SlicedICFGView > icfgView
void getInEdgesOfCallGraphNode(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
void dumpStats(const std::string &prefix="") const
Output statistics.
SlicedSVFIRView(SVFIR *svfIr, CallGraph *cg, ICFG *icfg, const OrderedSet< const ICFGNode * > &keepNodes, bool buildBridged=true)
const OrderedSet< const SVFStmt * > & getKeptStatements() const
Get all kept statements.
const Set< const CallICFGNode * > & getIndirectSitesWithEmptyTargets() const
Get indirect call sites that lost all targets after filtering.
SlicedThreadCallGraphView(ThreadCallGraph *tcg, const OrderedSet< const FunObjVar * > &keptFunctions, const OrderedSet< const ICFGNode * > &extendedKeptNodes=OrderedSet< const ICFGNode * >())
void buildCallGraphSets()
bool isKeptNode(const CallGraphNode *node) const
Check if a node is in the sliced view.
void dump(const std::string &filename) const
Dump sliced ThreadCallGraph to dot file.
OrderedSet< const CallGraphNode * > keptNodes
Set< const FunObjVar * > keptFunctionsSet
CallGraph::CallGraphEdgeSet keptEdges
void getOutEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get out edges of a node (only returns kept edges and target nodes)
Set< const CallICFGNode * > indirectSitesWithEmptyTargets
void getInEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get in edges of a node (only returns kept edges and source nodes)
CallGraph * getOriginalCallGraph() const
Get original CallGraph (ThreadCallGraph inherits from CallGraph)
OrderedSet< const ICFGNode * > extendedKeptNodes
virtual const ICFGNode * getICFGNode() const
Return corresponding ICFG node.
std::ostream & outs()
Overwrite llvm::outs()
llvm::IRBuilder IRBuilder
std::string getNodeLabel(SlicedICFGNodeRef n, const SlicedICFGView *)
static std::string getNodeAttributes(SlicedICFGNodeRef n, const SlicedICFGView *)
static std::string getEdgeAttributes(SlicedICFGNodeRef, EdgeIter EI, const SlicedICFGView *)
static std::string getGraphName(const SlicedICFGView *)
static const void * getNodeIdentifier(SlicedICFGNodeRef n)
DOTGraphTraits(bool isSimple=false)
std::string getNodeLabel(SlicedPAGNodeRef n, const SlicedPAGView *)
static std::string getEdgeAttributes(SlicedPAGNodeRef, EdgeIter EI, const SlicedPAGView *)
static std::string getNodeAttributes(SlicedPAGNodeRef, const SlicedPAGView *)
DOTGraphTraits(bool isSimple=false)
static const void * getNodeIdentifier(SlicedPAGNodeRef n)
static std::string getGraphName(const SlicedPAGView *)
static const void * getNodeIdentifier(SlicedSVFGNodeRef n)
static std::string getNodeAttributes(SlicedSVFGNodeRef n, const SlicedSVFGView *)
DOTGraphTraits(bool isSimple=false)
static std::string getEdgeAttributes(SlicedSVFGNodeRef, EdgeIter EI, const SlicedSVFGView *)
std::string getNodeLabel(SlicedSVFGNodeRef n, const SlicedSVFGView *)
static std::string getGraphName(const SlicedSVFGView *)
static std::string getNodeAttributes(SlicedCallGraphNodeRef, const SlicedThreadCallGraphView *)
std::string getNodeLabel(SlicedCallGraphNodeRef n, const SlicedThreadCallGraphView *)
static const void * getNodeIdentifier(SlicedCallGraphNodeRef n)
DOTGraphTraits(bool isSimple=false)
static std::string getGraphName(const SlicedThreadCallGraphView *)
static std::string getEdgeAttributes(SlicedCallGraphNodeRef, EdgeIter EI, const SlicedThreadCallGraphView *)
const ICFGEdge * underlying