30#ifndef VALUEFLOWDDA_H_
31#define VALUEFLOWDDA_H_
48template<
class CVar,
class CPtSet,
class DPIm>
106 return (pts |= targetPts);
112 return pts |= targetPts;
133 for(
typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it!=eit; ++it)
140 virtual const CPtSet&
findPT(
const DPIm& dpm)
177 const SVFGNode* node = dpm.getLoc();
196 if(load->getDstNode()->isPointer() ==
false)
201 for(
typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it)
208 if(store->getSrcNode()->isPointer() ==
false)
224 for(
typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it!=eit; ++it)
253 assert(
false &&
"unexpected kind of SVFG nodes");
261 if(
_pag->isFunPtr(dpm.getCurNodeID()))
264 for(CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
268 if(!newIndirectEdges.empty())
288 DPTItemSet dpmSet(locIt->second.begin(), locIt->second.end());
289 for(
typename DPTItemSet::const_iterator it = dpmSet.begin(),eit = dpmSet.end(); it!=eit; ++it)
291 const DPIm& dstDpm = *it;
294 if(dstDpm.getCurNodeID() == dpm.getCurNodeID())
342 DPTItemSet dpmSet(it->second.begin(), it->second.end());
343 for(
typename DPTItemSet::const_iterator dit = dpmSet.begin(),deit=dpmSet.end(); dit!=deit; ++dit)
356 const SVFGNode* node = oldDpm.getLoc();
357 NodeID obj = oldDpm.getCurNodeID();
358 if (
_pag->isConstantObj(obj))
365 const NodeBS& guard = indirEdge->getPointsTo();
369 indirEdge->getDstID() <<
" --> " << indirEdge->getSrcID() <<
"\n");
378 const SVFGNode* node = oldDpm.getLoc();
385 dirEdge->getDstID() <<
" --> " << dirEdge->getSrcID() <<
"\n");
386 const SVFGNode* srcNode = dirEdge->getSrcNode();
399 load->
getId() <<
" --> " << loadSrc->
getId() <<
"\n");
401 assert(edge &&
"Edge not found!!");
410 store->
getId() <<
" --> " << storeDst->
getId() <<
"\n");
412 assert(edge &&
"Edge not found!!");
420 store->
getId() <<
" to " << storeSrc->
getId() <<
"\n");
422 assert(edge &&
"Edge not found!!");
458 if (dstCPSet.count() == 1)
461 typename CPtSet::iterator it = dstCPSet.begin();
462 const CVar& var = *it;
477 assert(baseObj &&
"base object is null??");
480 if(
const FunObjVar* svffun =
_pag->getSVFVar(
id)->getFunction())
498 if(
_pag->isIndirectCallSites(cbn))
510 _ander->getCallGraph()->getIndCallSitesInvokingCallee(fun,csSet);
511 for(CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
649 assert(obj &&
"base object is null??");
675 assert(dpm ==
locToDpmSetMap[dpm.getLoc()].back() &&
"dpm not match with the end of vector");
692 it->second = loadDpm;
706 it->second = loadVar;
729 if(++
ddaStat->_NumOfStep > DPIm::getMaxBudget())
758 ddaStat->_NumOfStrongUpdates++;
766 if (dpmSet.erase(dpm))
768 ddaStat->_NumOfStrongUpdates--;
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
bool isFieldInsensitive() const
Return true if its field limit is 0.
Set< const CallICFGNode * > CallInstSet
void removeDpmFromLoc(const DPIm &dpm)
bool edgeInSVFGSCC(const SVFGEdge *edge)
Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the...
void backtraceAlongIndirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along indirect value flows.
OrderedSet< DPIm > DPTItemSet
virtual const CPtSet & getCachedADPointsTo(const DPIm &dpm)
bool isOutOfBudgetDpm(const DPIm &dpm) const
SVFIR::CallSiteSet CallSiteSet
SVFGBuilder svfgBuilder
SVFG Builder.
NodeID getSVFGSCCRepNode(NodeID id)
Get SCC rep node of a SVFG node.
void addLoadDpmAndCVar(const DPIm &dpm, const DPIm &loadDpm, const CVar &loadVar)
LoadDpm for must-alias analysis.
const CVar & getLoadCVar(const DPIm &dpm) const
virtual bool isLocalCVarInRecursion(const CVar &var) const
Whether a local variable is in function recursions.
virtual ~DDAVFSolver()
Destructor.
virtual void updateCachedPointsTo(const DPIm &dpm, const CPtSet &pts)
DPImToCPtSetMap dpmToADCPtSetMap
points-to caching map for address-taken vars
OrderedMap< DPIm, DPIm > DPMToDPMMap
DPImToCPtSetMap dpmToTLCPtSetMap
points-to caching map for top-level vars
virtual bool isMustAlias(const DPIm &, const DPIm &)
whether load and store are aliased
bool isFieldInsenCondMemObj(const CVar &var) const
virtual CPtSet getConservativeCPts(const DPIm &dpm)=0
Get conservative points-to results when the query is out of budget.
SCCDetection< CallGraph * > CallGraphSCC
virtual NodeID getPtrNodeID(const CVar &var) const =0
Methods to be implemented in child class.
bool testOutOfBudget(const DPIm &dpm)
void addLoadDpm(const DPIm &dpm, const DPIm &loadDpm)
Note that simply use "dpmToloadDpmMap[dpm]=loadDpm", requires DPIm have a default constructor.
AndersenWaveDiff * getAndersenAnalysis() const
Return Andersen's analysis.
CallGraphSCC * _callGraphSCC
SCC for PTACallGraph.
SCCDetection< SVFG * > SVFGSCC
const LocToDPMVecMap & getLocToDPMVecMap() const
Map a SVFGNode to its dpms for handling value-flow cycles.
SVFGSCC * _svfgSCC
SCC for SVFG.
virtual void addDDAPts(CPtSet &pts, const CVar &var)
Add pts.
virtual bool handleBKCondition(DPIm &, const SVFGEdge *)
Handle condition for context or path analysis (backward analysis).
virtual void updateCallGraphAndSVFG(const DPIm &, const CallICFGNode *, SVFGEdgeSet &)
Update call graph.
DPTItemSet backwardVisited
visited map during backward traversing
virtual bool isHeapCondMemObj(const CVar &var, const StoreSVFGNode *)
Check heap and array object.
SVFGEdge::SVFGEdgeSetTy SVFGEdgeSet
DPMToCVarMap loadToPTCVarMap
map a load dpm to its cvar pointed by its pointer operand
void markbkVisited(const DPIm &dpm)
Visited flags to avoid cycles.
void addLoadCVar(const DPIm &dpm, const CVar &loadVar)
bool isOutOfBudgetQuery() const
void backtraceAlongDirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along direct value flows.
bool isTopLevelPtrStmt(const SVFGNode *stmt)
Whether this is a top-level pointer statement.
void rmSUStat(const DPIm &dpm, const SVFGNode *node)
remove strong updates num if the dpm goes to weak updates branch
DDAVFSolver()
Constructor.
NodeBS & getCandidateQueries()
Return candidate pointers for DDA.
OrderedMap< DPIm, CPtSet > DPImToCPtSetMap
void reCompute(const DPIm &dpm)
recompute points-to for value-flow cycles and indirect calls
void handleOutOfBudgetDpm(const DPIm &dpm)
handle out-of-budget queries
virtual bool isStrongUpdate(const CPtSet &dstCPSet, const StoreSVFGNode *store)
Return TRUE if this is a strong update STORE statement.
virtual bool unionDDAPts(CPtSet &pts, const CPtSet &targetPts)
Union pts.
virtual void handleSingleStatement(const DPIm &dpm, CPtSet &pts)
Handle single statement.
bool isbkVisited(const DPIm &dpm)
bool isArrayCondMemObj(const CVar &var) const
DPMToDPMMap dpmToloadDpmMap
dpms at loads for may/must-alias analysis with stores
void setCallGraph(CallGraph *cg)
Set callgraph.
AndersenWaveDiff * _ander
Andersen's analysis.
void dumpCPtSet(const CPtSet &cpts) const
LocToDPMVecMap locToDpmSetMap
map location to its dpms
void clearbkVisited(const DPIm &dpm)
OrderedMap< NodeID, DPTItemSet > LocToDPMVecMap
DPTItemSet outOfBudgetDpms
out of budget dpm set
virtual CPtSet processGepPts(const GepSVFGNode *gep, const CPtSet &srcPts)=0
ProcessGep node to generate field object nodes of a struct.
CallGraph * _callGraph
PTACallGraph.
void OOBResetVisited()
Reset visited map if the current query is out-of-budget.
void SVFGSCCDetection()
SVFG SCC detection.
virtual const CPtSet & findPT(const DPIm &dpm)
Compute points-to.
void setCallGraphSCC(CallGraphSCC *scc)
Set callgraphSCC.
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
GetDefinition SVFG.
SVFG * getSVFG() const
Return SVFG.
const DPTItemSet & getDpmSetAtLoc(const SVFGNode *loc)
virtual DPIm getDPImWithOldCond(const DPIm &oldDpm, const CVar &var, const SVFGNode *loc)
Return dpm with old context and path conditions.
OrderedMap< const SVFGNode *, DPTItemSet > StoreToPMSetMap
void startNewPTCompFromLoadSrc(CPtSet &pts, const DPIm &oldDpm)
void reComputeForEdges(const DPIm &dpm, const SVFGEdgeSet &edgeSet, bool indirectCall=false)
Traverse along out edges to find all nodes which may be affected by locDPM.
virtual bool propagateViaObj(const CVar &storeObj, const CVar &loadObj)
If the points-to contain the object obj, we could move forward along indirect value-flow edge.
virtual void handleAddr(CPtSet &pts, const DPIm &dpm, const AddrSVFGNode *addr)=0
Handle AddrSVFGNode to add proper points-to.
virtual DPIm getDPIm(const CVar &var, const SVFGNode *loc) const
Given CVar and location (SVFGNode) return a new DPItem.
void backtraceToStoreSrc(CPtSet &pts, const DPIm &oldDpm)
bool isSVFGNodeInCycle(const SVFGNode *node)
Return whether this SVFGNode is in cycle.
SVFGSCC * getSVFGSCC() const
Return SVFGSCC.
NodeBS candidateQueries
candidate pointers;
void addOutOfBudgetDpm(const DPIm &dpm)
DDAStat * ddaStat
DDA stat.
virtual bool unionDDAPts(DPIm dpm, const CPtSet &targetPts)
Union pts.
void addSUStat(const DPIm &dpm, const SVFGNode *node)
stat strong updates num
virtual const CPtSet & getCachedPointsTo(const DPIm &dpm)
Points-to Caching for top-level pointers and address-taken objects.
OrderedSet< const SVFGEdge * > ConstSVFGEdgeSet
OrderedMap< DPIm, CVar > DPMToCVarMap
virtual void buildSVFG(SVFIR *pag)
Build SVFG.
const DPIm & getLoadDpm(const DPIm &dpm) const
virtual const CPtSet & getCachedTLPointsTo(const DPIm &dpm)
StoreToPMSetMap storeToDPMs
map store to set of DPM which have been stong updated there
virtual void backwardPropDpm(CPtSet &pts, NodeID ptr, const DPIm &oldDpm, const SVFGEdge *edge)
dpm transit during backward tracing
void addDpmToLoc(const DPIm &dpm)
DDAStat * setDDAStat(DDAStat *s)
Set DDAStat.
CallGraphEdge::CallInstSet CallInstSet
void resolveFunPtr(const DPIm &dpm)
resolve function pointer
bool outOfBudgetQuery
Whether the current query is out of step limits.
virtual void resetQuery()
Reset visited map for next points-to query.
void startNewPTCompFromStoreDst(CPtSet &pts, const DPIm &oldDpm)
NodeType * getSrcNode() const
NodeType * getDstNode() const
NodeID getSrcID() const
get methods of the components
const GEdgeSetTy & getInEdges() const
const ValVar * getSrcNode() const
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
Set< const CallICFGNode * > CallSiteSet
static double getClk(bool mark=false)
NodeID getId() const
Get ID.
bool test(unsigned Idx) const
NodeID getSrcNodeID() const
NodeID getDstNodeID() const
const ValVar * getDstNode() const
const ValVar * getSrcNode() const
VFGEdgeSetTy SVFGEdgeSetTy
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
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)
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)
std::map< Key, Value, Compare, Allocator > OrderedMap
ActualParmVFGNode ActualParmSVFGNode
std::set< Key, Compare, Allocator > OrderedSet
StoreVFGNode StoreSVFGNode
ActualRetVFGNode ActualRetSVFGNode
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)
FormalParmVFGNode FormalParmSVFGNode
FormalRetVFGNode FormalRetSVFGNode
NullPtrVFGNode NullPtrSVFGNode