34 using namespace SVFUtil;
39 SVFIR::SVFIR(
bool buildFromFile) :
IRGraph(buildFromFile), svfModule(nullptr), icfg(nullptr), chgraph(nullptr)
56 addEdge(srcNode,dstNode, addrPE);
74 addEdge(srcNode,dstNode, copyPE);
86 PHINodeMap::iterator it =
phiNodeMap.find(resNode);
116 std::vector<SVFVar*> opnds = {op1Node, op2Node};
119 addEdge(op1Node, dstNode, select);
136 std::vector<SVFVar*> opnds = {op1Node, op2Node};
139 addEdge(op1Node, dstNode, cmp);
157 std::vector<SVFVar*> opnds = {op1Node, op2Node};
160 addEdge(op1Node,dstNode, binaryOP);
178 addEdge(srcNode,dstNode, unaryOP);
196 addEdge(condNode,brNode, branch);
214 addEdge(srcNode,dstNode, loadPE);
233 addEdge(srcNode,dstNode, storePE);
249 CallPE* callPE =
new CallPE(srcNode, dstNode, cs,entry);
251 addEdge(srcNode,dstNode, callPE);
267 RetPE* retPE =
new RetPE(srcNode, dstNode, cs, exit);
269 addEdge(srcNode,dstNode, retPE);
280 return pag->addAddrStmt(
pag->getBlackHoleNode(), node);
298 addEdge(srcNode,dstNode, forkPE);
316 addEdge(srcNode,dstNode, joinPE);
356 addEdge(baseNode, dstNode, gepPE);
375 addEdge(baseNode, dstNode, gepPE);
391 &&
"this node should not be created before");
403 if (
GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
404 return getGepObjVar(gepNode->getMemObj(), gepNode->getConstantFieldIdx() + apOffset);
405 else if (
FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
407 else if (
DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
411 assert(
false &&
"new gep obj node kind?");
430 APOffset newLS =
pag->getSymbolInfo()->getModulusOffset(obj, apOffset);
435 NodeOffsetMap::iterator iter =
GepObjVarMap.find(std::make_pair(base, newLS));
453 assert(0==
GepObjVarMap.count(std::make_pair(base, apOffset))
454 &&
"this node should not be created before");
489 assert(SVFUtil::isa<ObjVar>(node) &&
"need an object node");
490 const ObjVar* obj = SVFUtil::cast<ObjVar>(node);
502 assert(SVFUtil::isa<ObjVar>(node) &&
"need an object node");
503 const MemObj* mem = SVFUtil::cast<ObjVar>(node)->getMemObj();
519 GepValueVarMap::const_iterator iter =
GepValObjMap.find(curInst);
526 NodeAccessPathMap::const_iterator lit =
527 iter->second.find(std::make_pair(base, ap));
528 if (lit == iter->second.end())
557 outs() <<
"-------------------SVFIR------------------------------------\n";
559 for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
560 addrs.end(); iter != eiter; ++iter)
562 outs() << (*iter)->getSrcID() <<
" -- Addr --> " << (*iter)->getDstID()
567 for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
568 copys.end(); iter != eiter; ++iter)
570 outs() << (*iter)->getSrcID() <<
" -- Copy --> " << (*iter)->getDstID()
575 for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
576 calls.end(); iter != eiter; ++iter)
578 outs() << (*iter)->getSrcID() <<
" -- Call --> " << (*iter)->getDstID()
583 for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter =
584 rets.end(); iter != eiter; ++iter)
586 outs() << (*iter)->getSrcID() <<
" -- Ret --> " << (*iter)->getDstID()
591 for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
592 tdfks.end(); iter != eiter; ++iter)
594 outs() << (*iter)->getSrcID() <<
" -- ThreadFork --> "
595 << (*iter)->getDstID() <<
"\n";
599 for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter =
600 tdjns.end(); iter != eiter; ++iter)
602 outs() << (*iter)->getSrcID() <<
" -- ThreadJoin --> "
603 << (*iter)->getDstID() <<
"\n";
607 for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
608 ngeps.end(); iter != eiter; ++iter)
610 GepStmt* gep = SVFUtil::cast<GepStmt>(*iter);
612 outs() << (*iter)->getSrcID() <<
" -- VariantGep --> "
613 << (*iter)->getDstID() <<
"\n";
620 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
621 loads.end(); iter != eiter; ++iter)
623 outs() << (*iter)->getSrcID() <<
" -- Load --> " << (*iter)->getDstID()
628 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
629 stores.end(); iter != eiter; ++iter)
631 outs() << (*iter)->getSrcID() <<
" -- Store --> " << (*iter)->getDstID()
634 outs() <<
"----------------------------------------------------------\n";
644 NodeID nodeId = nIter->first;
663 if (!(arg->getParent()->isDeclaration()))
675 if (SVFUtil::isa<ValVar>(node))
NodeID getRHSVarID() const
NodeID getLHSVarID() const
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
IDToNodeMapTy::iterator iterator
Node Iterators.
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
APOffset getConstantStructFldIdx() const
Field index of the gep statement if it access the field of a struct.
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
NodeID getValueNode(const SVFValue *V)
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
const SVFValue * getValue() const
Get the reference value to this object.
SymID getId() const
Get the memory object id.
bool isFieldInsensitive() const
Return true if its field limit is 0.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateGepObjectId(NodeID base, u32_t offset, u32_t maxFieldLimit)
const MemObj * getMemObj() const
Return memory object.
static const Option< bool > FirstFieldEqBase
static Option< bool > HandBlackHole
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
void addOpVar(SVFVar *op, const ICFGNode *inode)
NodeID getId() const
Get ID.
NodeID addFIObjNode(const MemObj *obj)
Add a field-insensitive node, this method can only invoked by getFIGepObjNode.
GepStmt * addVariantGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Variant(Gep) edge.
NodeOffsetMap GepObjVarMap
Map a pair<base,off> to a gep obj node id.
CopyStmt * addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type)
Add Copy edge.
RetPE * addRetPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
GepStmt * addGepStmt(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
NodeID addObjNode(const SVFValue *val, NodeID i)
Add a memory obj node.
static void handleBlackHole(bool b)
SVFIR build configurations.
NodeID getFIObjVar(const MemObj *obj) const
Get a field-insensitive obj SVFIR node according to a mem obj.
void addToStmt2TypeMap(SVFStmt *edge)
Map a SVFStatement type to a set of corresponding SVF statements.
SVFStmt * addBlackHoleAddrStmt(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr)
LoadStmt * addLoadStmt(NodeID src, NodeID dst)
Add Load edge.
GepStmt * addNormalGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Offset(Gep) edge.
MemObjToFieldsMap memToFieldsMap
Map a mem object id to all its fields.
PHINodeMap phiNodeMap
A set of phi copy edges.
NodeBS getFieldsAfterCollapse(NodeID id)
NodeID addGepValNode(const SVFValue *curInst, const SVFValue *val, const AccessPath &ap, NodeID i, const SVFType *type)
Add a temp field value node, this method can only invoked by getGepValVar.
CallPE * addCallPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
bool isValidTopLevelPtr(const SVFVar *node)
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Thread join edge for parameter passing.
void destroy()
Clean up memory.
NodeID addGepObjNode(const MemObj *obj, const APOffset &apOffset, const NodeID gepId)
Add a field obj node, this method can only invoked by getGepObjVar.
NodeBS & getAllFieldsObjVars(const MemObj *obj)
Get all fields of an object.
CmpStmt * addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
AddrStmt * addAddrStmt(NodeID src, NodeID dst)
Add an edge into SVFIR.
UnaryOPStmt * addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
TDForkPE * addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
BinaryOPStmt * addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
NodeID addValNode(const SVFValue *val, NodeID i, const SVFBaseNode *gNode)
add node into SVFIR
static std::unique_ptr< SVFIR > pag
call graph
StoreStmt * addStoreStmt(NodeID src, NodeID dst, const ICFGNode *val)
Add Store edge.
PhiStmt * addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add phi node information.
OrderedNodeSet candidatePointers
SVFIR(bool buildFromFile)
Constructor.
SelectStmt * addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
PTACallGraph * callGraph
all the callsites of a program
NodeID getGepValVar(const SVFValue *curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
GepValueVarMap GepValObjMap
Map a pair<base,off> to a gep value node id.
bool isValidPointer(NodeID nodeId) const
Whether a node is a valid pointer.
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
BranchStmt * addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add BranchStmt.
void initialiseCandidatePointers()
Initialize candidate pointers.
static void releaseSVFModule()
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
virtual bool isPointer() const
Whether it is a pointer.
bool hasIncomingVariantGepEdge() const
Has incoming VariantGepEdges.
const SVFValue * getValue() const
Get/has methods of the components.
bool isArgOfUncalledFunction(const SVFValue *svfval)
Return true if this argument belongs to an uncalled function.
std::ostream & outs()
Overwrite llvm::outs()