71 dump(
"SVFG_before_opt");
120 candidates.insert(node);
124 for (SVFGNodeSet::const_iterator it = candidates.begin(), eit = candidates.end();
131 nodesToBeDeleted.insert(fp);
136 nodesToBeDeleted.insert(ar);
140 nodesToBeDeleted.insert(node);
145 nodesToBeDeleted.insert(node);
150 nodesToBeDeleted.insert(node);
154 for (SVFGNodeSet::iterator it = nodesToBeDeleted.begin(), eit = nodesToBeDeleted.end(); it != eit; ++it)
174 &&
"expecting a formal param or actual ret svfg node");
186 addCallEdge(phiId, dstId, callEdge->getCallSiteId());
188 addRetEdge(phiId, dstId, retEdge->getCallSiteId());
226 assert(node->
getInEdges().size() == 1 &&
"actual-in/formal-out can only have one incoming edge as its def size");
233 for (; it != eit; ++it)
246 for (; it != eit; ++it)
249 NodeBS intersection = inPointsTo;
252 if (intersection.
empty())
261 assert(
false &&
"expecting an inter-procedural SVFG edge");
274 for (; inIt != inEit; ++inIt)
281 for (; outIt != outEit; ++outIt)
287 if (intersection.
empty())
314 bool hasInCallRet =
false;
315 bool hasOutCallRet =
false;
319 for (; edgeIt != edgeEit; ++edgeIt)
330 for (; edgeIt != edgeEit; ++edgeIt)
334 hasOutCallRet =
true;
339 if (hasInCallRet && hasOutCallRet)
434 for (; edgeIt != edgeEit; ++edgeIt)
444 for (; edgeIt != edgeEit; ++edgeIt)
464 bool hasSelfCycle =
false;
469 for (; inEdgeIt != inEdgeEit; ++inEdgeIt)
504 for (; inEdgeIt != inEdgeEit; ++inEdgeIt)
506 const SVFGEdge* preEdge = *inEdgeIt;
513 for (; outEdgeIt != outEdgeEit; ++outEdgeIt)
515 const SVFGEdge* succEdge = *outEdgeIt;
516 const SVFGNode* dstNode = (*outEdgeIt)->getDstNode();
546 &&
"either pre or succ edge is not indirect SVFG edge");
554 if (intersection.
empty())
557 assert(
bothInterEdges(preEdge, succEdge) ==
false &&
"both edges are inter edges");
static std::string KeepNoneSelfCycle
static std::string KeepContextSelfCycle
static std::string KeepAllSelfCycle
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
const ValVar * getParam() const
Return parameter.
const CallICFGNode * getCallSite() const
Return callsite.
NodeType * getSrcNode() const
NodeType * getDstNode() const
NodeID getSrcID() const
get methods of the components
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
const NodeBS & getPointsTo() const
static const Option< bool > KeepAOFI
static const Option< std::string > SelfCycle
static const Option< bool > DumpVFG
static const Option< bool > ContextInsensitive
Set< SVFGNode * > SVFGNodeSet
bool isDefOfAInFOut(const SVFGNode *node)
SVFGEdge * addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS &cpts)
Add inter-procedural value flow edge.
void buildAndWriteSVFG(const std::string &filename)
Optimised SVFG's shouldn't be written in their optimised form; writes the full SVFG to file before op...
void replaceFParamARetWithPHI(PHISVFGNode *phi, SVFGNode *svfgNode)
Replace FormalParam/ActualRet node with PHI node.
void handleIntraValueFlow()
Remove MSSAPHI SVFG nodes.
void retargetEdgesOfAOutFIn(SVFGNode *node)
Connect actual-out/formal-in's predecessors to their successors directly.
void setFormalOUTDef(NodeID fo, NodeID def)
void setActualINDef(NodeID ai, NodeID def)
void handleInterValueFlow()
void bypassMSSAPHINode(const MSSAPHISVFGNode *node)
Remove MSSAPHI node if possible.
void removeInEdges(const SVFGNode *node)
bool addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge *preEdge, const SVFGEdge *succEdge)
Add new SVFG edge from src to dst.
bool bothInterEdges(const SVFGEdge *edge1, const SVFGEdge *edge2) const
Return TRUE if both edges are indirect call/ret edges.
bool formalInOfAddressTakenFunc(const FormalINSVFGNode *fi) const
Check if formal-in/formal-out reside in address-taken function.
bool addIntoWorklist(const SVFGNode *node)
void buildSVFG() override
Start building SVFG.
bool actualOutOfIndCS(const ActualOUTSVFGNode *ao) const
bool keepActualOutFormalIn
InterPHISVFGNode * addInterPHIForAR(const ActualRetSVFGNode *ar)
Add inter PHI SVFG node for actual return.
bool formalOutOfAddressTakenFunc(const FormalOUTSVFGNode *fo) const
WorkList worklist
storing MSSAPHI nodes which may be removed.
InterPHISVFGNode * addInterPHIForFP(const FormalParmSVFGNode *fp)
Add inter PHI SVFG node for formal parameter.
bool isConnectingTwoCallSites(const SVFGNode *node) const
Return TRUE if this node has both incoming call/ret and outgoing call/ret edges.
void readAndOptSVFG(const std::string &filename)
Optimised SVFG's aren't written in their optimised form; read full SVFG and optimise it.
bool canBeRemoved(const SVFGNode *node)
void retargetEdgesOfAInFOut(SVFGNode *node)
Retarget edges related to actual-in/-out and formal-in/-out.
void removeAllEdges(const SVFGNode *node)
Remove edges of a SVFG node.
void addInterPHIOperands(PHISVFGNode *phi, const ValVar *operand)
void parseSelfCycleHandleOption()
bool keepContextSelfCycle
void optimiseSVFG()
Separate optimisation function to avoid duplicate code.
void initialWorkList()
Initial work list with MSSAPHI nodes which may be removed.
void removeOutEdges(const SVFGNode *node)
bool actualInOfIndCS(const ActualINSVFGNode *ai) const
Check if actual-in/actual-out exist at indirect call site.
SVFGEdge * addRetIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS &cpts)
Add indirect ret edge from src to dst with one call site ID.
bool checkSelfCycleEdges(const MSSAPHISVFGNode *node)
Remove self cycle edges if needed. Return TRUE if some self cycle edges remained.
virtual void buildSVFG()
Start building SVFG.
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
void removeSVFGNode(SVFGNode *node)
Remove a SVFGNode.
virtual void writeToFile(const std::string &filename)
SVFGEdge * addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
void removeSVFGEdge(SVFGEdge *edge)
Remove a SVFG edge.
NodeID getDef(const ValVar *valVar) const
virtual void readFile(const std::string &filename)
SVFGEdge * addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Add indirect def-use edges of a memory region between two statements,.
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
NodeID getId() const
Get ID.
VFGEdgeSetTy SVFGEdgeSetTy
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
VFGEdge::VFGEdgeSetTy::iterator iterator
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *func) const
Get callsite given a callsiteID.
VFGEdge * addIntraDirectVFEdge(NodeID srcId, NodeID dstId)
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
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)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
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)
ActualParmVFGNode ActualParmSVFGNode
ActualRetVFGNode ActualRetSVFGNode
FormalParmVFGNode FormalParmSVFGNode
FormalRetVFGNode FormalRetSVFGNode