54 return item.second->getFunction();
113 PHINodeMap::iterator it =
phiNodeMap.find(resNode);
122 it->second->addOpVar(opNode,pred);
134 addEdge(opNode, resNode, edge);
152 std::vector<ValVar*> opnds = {op1Node, op2Node};
177 std::vector<ValVar*> opnds = {op1Node, op2Node};
203 std::vector<ValVar*> opnds = {op1Node, op2Node};
319 CallPE* callPE =
new CallPE(resNode, {opNode}, {cs}, entry);
325 it->second->addOpVar(opNode, cs);
349 RetPE* retPE =
new RetPE(srcNode, dstNode, cs, exit);
367 return pag->addAddrStmt(
pag->getBlackHoleNode(), node);
385 addEdge(opNode, resNode, forkPE);
391 it->second->addOpVar(opNode, cs);
457 addEdge(baseNode, dstNode, gepPE);
475 addEdge(baseNode, dstNode, gepPE);
491 &&
"this node should not be created before");
505 return getGepObjVar(gepNode->getBaseObj(), gepNode->getConstantFieldIdx() + apOffset);
512 assert(
false &&
"new gep obj node kind?");
531 APOffset newLS =
pag->getModulusOffset(baseObj, apOffset);
536 OffsetToGepVarMap::iterator iter =
GepObjVarMap.find(std::make_pair(base, newLS));
549 assert(0==
GepObjVarMap.count(std::make_pair(base, apOffset))
550 &&
"this node should not be created before");
563 assert(0==
GepObjVarMap.count(std::make_pair(base, apOffset))
564 &&
"this node should not be created before");
616 GepValueVarMap::const_iterator iter =
GepValObjMap.find(curInst);
623 NodeAccessPathMap::const_iterator lit =
624 iter->second.find(std::make_pair(base, ap));
625 if (lit == iter->second.end())
652 outs() <<
"-------------------SVFIR------------------------------------\n";
654 for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
655 addrs.end(); iter != eiter; ++iter)
657 outs() << (*iter)->getSrcID() <<
" -- Addr --> " << (*iter)->getDstID()
662 for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
663 copys.end(); iter != eiter; ++iter)
665 outs() << (*iter)->getSrcID() <<
" -- Copy --> " << (*iter)->getDstID()
670 for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
671 calls.end(); iter != eiter; ++iter)
673 outs() << (*iter)->getSrcID() <<
" -- Call --> " << (*iter)->getDstID()
678 for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter =
679 rets.end(); iter != eiter; ++iter)
681 outs() << (*iter)->getSrcID() <<
" -- Ret --> " << (*iter)->getDstID()
686 for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
687 tdfks.end(); iter != eiter; ++iter)
689 outs() << (*iter)->getSrcID() <<
" -- ThreadFork --> "
690 << (*iter)->getDstID() <<
"\n";
694 for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter =
695 tdjns.end(); iter != eiter; ++iter)
697 outs() << (*iter)->getSrcID() <<
" -- ThreadJoin --> "
698 << (*iter)->getDstID() <<
"\n";
702 for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
703 ngeps.end(); iter != eiter; ++iter)
707 outs() << (*iter)->getSrcID() <<
" -- VariantGep --> "
708 << (*iter)->getDstID() <<
"\n";
715 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
716 loads.end(); iter != eiter; ++iter)
718 outs() << (*iter)->getSrcID() <<
" -- Load --> " << (*iter)->getDstID()
723 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
724 stores.end(); iter != eiter; ++iter)
726 outs() << (*iter)->getSrcID() <<
" -- Store --> " << (*iter)->getDstID()
729 outs() <<
"----------------------------------------------------------\n";
739 NodeID nodeId = nIter->first;
752 const SVFVar* node =
pag->getSVFVar(nodeId);
755 if (
const ValVar* pVar =
pag->getBaseValVar(nodeId))
757 if (!(arg->getParent()->isDeclaration()))
789 assert(node &&
"node cannot be nullptr.");
791 "This NodeID clashes here. Please check NodeIDAllocator. Switch "
792 "Strategy::DBUG to SEQ or DENSE");
798 assert(node &&
"node cannot be nullptr.");
800 "This NodeID clashes here. Please check NodeIDAllocator. Switch "
801 "Strategy::DBUG to SEQ or DENSE");
807 assert(obj &&
"not an object node?");
Class representing a function argument variable in the SVFIR.
NodeID getRHSVarID() const
NodeID getLHSVarID() const
bool isConstDataOrConstGlobal() const
NodeID getId() const
Get the memory object id.
bool isFieldInsensitive() const
Return true if its field limit is 0.
std::vector< std::pair< const ICFGNode *, s64_t > > SuccAndCondPairVec
bool hasGNode(NodeID id) const
IDToNodeMapTy::iterator iterator
NodeType * getGNode(NodeID id) const
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.
void setLLVMVarInstID(NodeID id)
Set the LLVM variable ID associated with this GepValVar.
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
NodeID addNode(SVFVar *node)
Add a node into the graph.
IRGraph(bool buildFromFile)
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
static bool isConstantSym(NodeID id)
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateGepObjectId(NodeID base, u32_t offset, u32_t maxFieldLimit)
static const Option< bool > FirstFieldEqBase
static Option< bool > HandBlackHole
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
GepStmt * addVariantGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Variant(Gep) edge.
CopyStmt * addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type)
Add Copy edge.
NodeID getGepValVar(NodeID curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
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.
static void handleBlackHole(bool b)
SVFIR build configurations.
FParmToCallPEMap fParmToCallPEMap
Map a formal param to its CallPE.
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.
NodeID addGepValNode(NodeID curInst, const ValVar *base, const AccessPath &ap, NodeID i, const SVFType *type, const ICFGNode *node)
Add a temp field value node, this method can only invoked by getGepValVar.
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 addObjNode(NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Add a memory obj node.
CallPE * addCallPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge (phi-like: merges actual params from all call sites into formal param).
bool isValidTopLevelPtr(const SVFVar *node)
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Thread join edge for parameter passing.
CallGraph * callGraph
all the callsites of a program
NodeSet constantObjs
Constant objects and their fields, recorded when each object node is added.
static std::string pagReadFromTxt
void destroy()
Clean up memory.
const BaseObjVar * getBaseObject(NodeID id) const
const FunObjVar * getFunObjVar(const std::string &name)
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.
NodeBS & getAllFieldsObjVars(const BaseObjVar *obj)
Get all fields of an object.
static std::unique_ptr< SVFIR > pag
Callgraph with direct calls only; no change allowed after init and use callgraph in PointerAnalysis f...
NodeID addValNode(NodeID i, const SVFType *type, const ICFGNode *icfgNode)
add node into SVFIR
StoreStmt * addStoreStmt(NodeID src, NodeID dst, const ICFGNode *val)
Add Store edge.
NodeID addGepObjNode(GepObjVar *gepObj, NodeID base, const APOffset &apOffset)
OffsetToGepVarMap GepObjVarMap
Map a pair<base,off> to a gep obj node id.
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.
GepValueVarMap GepValObjMap
Map a pair<base,off> to a gep value node id.
const GepObjVar * getGepObjVar(NodeID id) const
bool isValidPointer(NodeID nodeId) const
Whether a node is a valid pointer.
BranchStmt * addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add BranchStmt.
const ValVar * getValVar(NodeID id) const
void initialiseCandidatePointers()
Initialize candidate pointers.
NodeID getFIObjVar(const BaseObjVar *obj) const
Get a field-insensitive obj SVFIR node according to a mem obj.
NodeID addDummyObjNode(const SVFType *type)
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
NodeID getId() const
Get ID.
virtual bool isPointer() const
Check if this variable represents a pointer.
bool hasIncomingVariantGepEdge() const
Check for incoming variable field GEP edges.
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
LLVM_NODISCARD bool isa(const Y &Val)
bool isArgOfUncalledFunction(const SVFVar *svfvar)
std::ostream & outs()
Overwrite llvm::outs().
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)