Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
SVF::Andersen Class Reference

#include <Andersen.h>

Inheritance diagram for SVF::Andersen:
SVF::AndersenBase SVF::WPASolver< GraphType > SVF::BVDataPTAImpl SVF::PointerAnalysis SVF::AndersenSCD SVF::AndersenWaveDiff SVF::AndersenSFR

Public Types

typedef SCCDetection< ConstraintGraph * > CGSCC
 
- Public Types inherited from SVF::AndersenBase
typedef OrderedMap< const CallICFGNode *, NodeID > CallSite2DummyValPN
 
- Public Types inherited from SVF::WPASolver< GraphType >
typedef SVF::GenericGraphTraits< GraphType > GTraits
 Define the GTraits and node iterator for printing.
 
typedef GTraits::NodeRef GNODE
 
typedef GTraits::EdgeType GEDGE
 
typedef GTraits::ChildIteratorType child_iterator
 
typedef SCCDetection< GraphType > SCC
 
typedef FIFOWorkList< NodeID > WorkList
 
- Public Types inherited from SVF::BVDataPTAImpl
typedef PTData< NodeID, NodeSet, NodeID, PointsTo > PTDataTy
 
typedef DiffPTData< NodeID, NodeSet, NodeID, PointsTo > DiffPTDataTy
 
typedef DFPTData< NodeID, NodeSet, NodeID, PointsTo > DFPTDataTy
 
typedef VersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > VersionedPTDataTy
 
typedef MutablePTData< NodeID, NodeSet, NodeID, PointsTo > MutPTDataTy
 
typedef MutableDiffPTData< NodeID, NodeSet, NodeID, PointsTo > MutDiffPTDataTy
 
typedef MutableDFPTData< NodeID, NodeSet, NodeID, PointsTo > MutDFPTDataTy
 
typedef MutableIncDFPTData< NodeID, NodeSet, NodeID, PointsTo > MutIncDFPTDataTy
 
typedef MutableVersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > MutVersionedPTDataTy
 
typedef PersistentPTData< NodeID, NodeSet, NodeID, PointsTo > PersPTDataTy
 
typedef PersistentDiffPTData< NodeID, NodeSet, NodeID, PointsTo > PersDiffPTDataTy
 
typedef PersistentDFPTData< NodeID, NodeSet, NodeID, PointsTo > PersDFPTDataTy
 
typedef PersistentIncDFPTData< NodeID, NodeSet, NodeID, PointsTo > PersIncDFPTDataTy
 
typedef PersistentVersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > PersVersionedPTDataTy
 
- Public Types inherited from SVF::PointerAnalysis
typedef Set< const CallICFGNode * > CallSiteSet
 Indirect call edges type, map a callsite to a set of callees.
 
typedef SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
 
typedef Set< const FunObjVar * > FunctionSet
 
typedef OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
 
typedef SCCDetection< CallGraph * > CallGraphSCC
 
typedef Set< const GlobalObjVar * > VTableSet
 
typedef Set< const FunObjVar * > VFunSet
 

Public Member Functions

 Andersen (SVFIR *_pag, PTATY type=PTATY::Andersen_WPA, bool alias_check=true)
 Constructor.
 
virtual ~Andersen ()
 Destructor.
 
virtual void initialize ()
 Initialize analysis.
 
virtual void finalize ()
 Finalize analysis.
 
void resetData ()
 Reset data.
 
virtual const PointsTo & getPts (NodeID id)
 Operation of points-to set.
 
virtual bool unionPts (NodeID id, const PointsTo &target)
 
virtual bool unionPts (NodeID id, NodeID ptd)
 
virtual NodeBS getMayAliases (NodeID node)
 Collect exactly the SVFIR nodes q for which mayAlias(node, q) holds.
 
std::vector< NodeBS > getMayAliasesBatch (const std::vector< NodeID > &nodes)
 
void dumpTopLevelPtsTo ()
 
void setDetectPWC (bool flag)
 
- Public Member Functions inherited from SVF::AndersenBase
 AndersenBase (SVFIR *_pag, PTATY type=PTATY::Andersen_BASE, bool alias_check=true)
 Constructor.
 
 ~AndersenBase () override
 Destructor.
 
virtual void analyze () override
 Andersen analysis.
 
virtual void solveAndwritePtsToFile (const std::string &filename)
 
virtual void readPtsFromFile (const std::string &filename)
 
virtual void solveConstraints ()
 
virtual bool updateCallGraph (const CallSiteToFunPtrMap &) override
 Update call graph.
 
virtual bool updateThreadCallGraph (const CallSiteToFunPtrMap &, NodePairSet &)
 Update thread call graph.
 
virtual void connectCaller2ForkedFunParams (const CallICFGNode *cs, const FunObjVar *F, NodePairSet &cpySrcNodes)
 Connect formal and actual parameters for indirect forksites.
 
virtual void connectCaller2CalleeParams (const CallICFGNode *cs, const FunObjVar *F, NodePairSet &cpySrcNodes)
 Connect formal and actual parameters for indirect callsites.
 
ConstraintGraph * getConstraintGraph ()
 Get constraint graph.
 
NodeID sccRepNode (NodeID id) const override
 SCC methods.
 
NodeBS & sccSubNodes (NodeID repId)
 
void printStat ()
 dump statistics
 
virtual void normalizePointsTo () override
 
void cleanConsCG (NodeID id)
 remove redundant gepnodes in constraint graph
 
- Public Member Functions inherited from SVF::BVDataPTAImpl
 BVDataPTAImpl (SVFIR *pag, PTATY type, bool alias_check=true)
 Constructor.
 
 ~BVDataPTAImpl () override=default
 Destructor.
 
PersistentPointsToCache< PointsTo > & getPtCache ()
 
const PointsTo & getPts (NodeID id) override
 
const NodeSet & getRevPts (NodeID nodeId) override
 
virtual void clearPts (NodeID id, NodeID element)
 Remove element from the points-to set of id.
 
virtual void clearFullPts (NodeID id)
 Clear points-to set of id.
 
virtual bool addPts (NodeID id, NodeID ptd)
 
virtual void clearAllPts ()
 Clear all data.
 
virtual void expandFIObjs (const PointsTo &pts, PointsTo &expandedPts)
 Expand FI objects.
 
virtual void expandFIObjs (const NodeBS &pts, NodeBS &expandedPts)
 TODO: remove repetition.
 
void remapPointsToSets (void)
 Remap all points-to sets to use the current mapping.
 
virtual void writeToFile (const std::string &filename)
 Interface for analysis result storage on filesystem.
 
virtual void writeObjVarToFile (const std::string &filename)
 
virtual void writePtsResultToFile (std::fstream &f)
 
virtual void writeGepObjVarMapToFile (std::fstream &f)
 
virtual bool readFromFile (const std::string &filename)
 
virtual void readPtsResultFromFile (std::ifstream &f)
 
virtual void readGepObjVarMapFromFile (std::ifstream &f)
 
virtual void readAndSetObjFieldSensitivity (std::ifstream &f, const std::string &delimiterStr)
 
AliasResult alias (const SVFVar *V1, const SVFVar *V2) override
 Interface expose to users of our pointer analysis, given Value infos.
 
AliasResult alias (NodeID node1, NodeID node2) override
 Interface expose to users of our pointer analysis, given PAGNodeID.
 
virtual AliasResult alias (const PointsTo &pts1, const PointsTo &pts2)
 Interface expose to users of our pointer analysis, given two pts.
 
bool mayAlias (const PointsTo &pts1, const PointsTo &pts2)
 Convenience bool wrappers: return true if the two operands may/must/partial alias.
 
void dumpCPts () override
 dump and debug, print out conditional pts
 
void dumpTopLevelPtsTo () override
 
void dumpAllPts () override
 
bool mayAlias (const SVFVar *V1, const SVFVar *V2)
 
bool mayAlias (NodeID node1, NodeID node2)
 
- Public Member Functions inherited from SVF::PointerAnalysis
ICFG * getICFG () const
 Get ICFG.
 
u32_t getNumOfResolvedIndCallEdge () const
 Return number of resolved indirect call edges.
 
CallGraph * getCallGraph () const
 Return call graph.
 
CallGraphSCC * getCallGraphSCC () const
 Return call graph SCC.
 
 PointerAnalysis (SVFIR *pag, PTATY ty=PTATY::Default_PTA, bool alias_check=true)
 Constructor.
 
PTATY getAnalysisTy () const
 Type of pointer analysis.
 
PTAImplTy getImplTy () const
 Return implementation type of the pointer analysis.
 
bool printStat ()
 Whether print statistics.
 
void disablePrintStat ()
 Whether print statistics.
 
CallEdgeMap & getIndCallMap ()
 Get callees from an indirect callsite.
 
bool hasIndCSCallees (const CallICFGNode *cs) const
 
const FunctionSet & getIndCSCallees (const CallICFGNode *cs) const
 
virtual void resolveIndCalls (const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
 Resolve indirect call edges.
 
void callGraphSCCDetection ()
 PTACallGraph SCC related methods.
 
NodeID getCallGraphSCCRepNode (NodeID id) const
 Get SCC rep node of a SVFG node.
 
bool inSameCallGraphSCC (const FunObjVar *fun1, const FunObjVar *fun2)
 Return TRUE if this edge is inside a PTACallGraph SCC, i.e., src node and dst node are in the same SCC on the SVFG.
 
bool isInRecursion (const FunObjVar *fun) const
 
bool isLocalVarInRecursiveFun (NodeID id) const
 Whether a local variable is in function recursions.
 
CommonCHGraph * getCHGraph () const
 get CHGraph
 
void getVFnsFromCHA (const CallICFGNode *cs, VFunSet &vfns)
 
void getVFnsFromPts (const CallICFGNode *cs, const PointsTo &target, VFunSet &vfns)
 
void connectVCallToVFns (const CallICFGNode *cs, const VFunSet &vfns, CallEdgeMap &newEdges)
 
virtual void resolveCPPIndCalls (const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
 Resolve cpp indirect call edges.
 
SVFIR * getPAG () const
 
PTAStat * getStat () const
 Get PTA stat.
 
OrderedNodeSet & getAllValidPtrs ()
 Get all Valid Pointers for resolution.
 
virtual void computeDDAPts (NodeID)
 Compute points-to results on-demand, overridden by derived classes.
 
bool mayAlias (const SVFVar *V1, const SVFVar *V2)
 Convenience bool wrappers: return true if the two operands may/must/partial alias.
 
bool mayAlias (NodeID node1, NodeID node2)
 
void printIndCSTargets (const CallICFGNode *cs, const FunctionSet &targets)
 Print targets of a function pointer.
 
virtual void dumpPts (NodeID ptr, const PointsTo &pts)
 
void printIndCSTargets ()
 
void dumpAllTypes ()
 
void dumpStat ()
 Dump the statistics.
 
bool containBlackHoleNode (const PointsTo &pts)
 Determine whether a points-to contains a black hole or constant node.
 
bool containConstantNode (const PointsTo &pts)
 
virtual bool isBlkObjOrConstantObj (NodeID ptd) const
 
bool isHeapMemObj (NodeID id) const
 Whether this object is heap or array.
 
bool isArrayMemObj (NodeID id) const
 
bool isFIObjNode (NodeID id) const
 
NodeID getBaseObjVarID (NodeID id)
 
NodeID getFIObjVar (NodeID id)
 
NodeID getGepObjVar (NodeID id, const APOffset &ap)
 
virtual const NodeBS & getAllFieldsObjVars (NodeID id)
 
void setObjFieldInsensitive (NodeID id)
 
bool isFieldInsensitive (NodeID id) const
 

Static Public Member Functions

static bool classof (const Andersen *)
 Methods for support type inquiry through isa, cast, and dyn_cast:
 
static bool classof (const PointerAnalysis *pta)
 
- Static Public Member Functions inherited from SVF::AndersenBase
static bool classof (const AndersenBase *)
 Methods for support type inquiry through isa, cast, and dyn_cast:
 
static bool classof (const PointerAnalysis *pta)
 
- Static Public Member Functions inherited from SVF::BVDataPTAImpl
static bool classof (const PointerAnalysis *pta)
 

Protected Member Functions

virtual void computeDiffPts (NodeID id)
 Handle diff points-to set.
 
virtual const PointsTo & getDiffPts (NodeID id)
 
void updatePropaPts (NodeID dstId, NodeID srcId)
 Handle propagated points-to set.
 
void clearPropaPts (NodeID src)
 
virtual void initWorklist ()
 
virtual void processNode (NodeID nodeId)
 Override WPASolver function in order to use the default solver.
 
void processAllAddr ()
 handling various constraints
 
virtual bool processLoad (NodeID node, const ConstraintEdge *load)
 
virtual bool processStore (NodeID node, const ConstraintEdge *load)
 
virtual bool processCopy (NodeID node, const ConstraintEdge *edge)
 
virtual bool processGep (NodeID node, const GepCGEdge *edge)
 
virtual void handleCopyGep (ConstraintNode *node)
 
virtual void handleLoadStore (ConstraintNode *node)
 
virtual void processAddr (const AddrCGEdge *addr)
 
virtual bool processGepPts (const PointsTo &pts, const GepCGEdge *edge)
 
virtual bool addCopyEdge (NodeID src, NodeID dst)
 Add copy edge on constraint graph.
 
virtual void mergeNodeToRep (NodeID nodeId, NodeID newRepId)
 Merge sub node to its rep.
 
virtual bool mergeSrcToTgt (NodeID srcId, NodeID tgtId)
 
void mergeSccNodes (NodeID repNodeId, const NodeBS &subNodes)
 Merge sub node in a SCC cycle to their rep node.
 
void mergeSccCycle ()
 
virtual void collapsePWCNode (NodeID nodeId)
 Collapse a field object into its base for field insensitive analysis.
 
void collapseFields ()
 collapse positive weight cycles of a graph
 
bool collapseNodePts (NodeID nodeId)
 
bool collapseField (NodeID nodeId)
 
void updateNodeRepAndSubs (NodeID nodeId, NodeID newRepId)
 Updates subnodes of its rep, and rep node of its subs.
 
virtual NodeStack & SCCDetect ()
 SCC detection.
 
std::optional< NodeBS > collectMayAliasesFromIndex (const PointsTo &expandedPts)
 
virtual void validateSuccessTests (std::string fun)
 Also check getMayAliases on the pointers that the alias tests use.
 
void sanitizePts ()
 Sanitize pts for field insensitive objects.
 
virtual const std::string PTAName () const
 Get PTA name.
 
virtual void cluster (void) const
 
- Protected Member Functions inherited from SVF::AndersenBase
void heapAllocatorViaIndCall (const CallICFGNode *cs, NodePairSet &cpySrcNodes)
 
- Protected Member Functions inherited from SVF::WPASolver< GraphType >
 WPASolver ()
 Constructor.
 
virtual ~WPASolver ()=default
 Destructor.
 
SCC * getSCCDetector () const
 Get SCC detector.
 
const GraphType graph ()
 Get/Set graph methods.
 
void setGraph (GraphType g)
 
virtual NodeStack & SCCDetect (NodeSet &candidates)
 
virtual void solveWorklist ()
 
virtual void propagate (GNODE *v)
 
virtual bool propFromSrcToDst (GEDGE *)
 Propagate information from source to destination node, to be implemented in the child class.
 
NodeID popFromWorklist ()
 Worklist operations.
 
virtual void pushIntoWorklist (NodeID id)
 
bool isWorklistEmpty ()
 
bool isInWorklist (NodeID id)
 
GNODE * Node (NodeID id)
 Get node on the graph.
 
NodeID Node_Index (GNODE node)
 Get node ID.
 
- Protected Member Functions inherited from SVF::BVDataPTAImpl
PTDataTy * getPTDataTy () const
 Get points-to data structure.
 
void finalize () override
 Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
 
DiffPTDataTy * getDiffPTDataTy () const
 
DFPTDataTy * getDFPTDataTy () const
 
MutDFPTDataTy * getMutDFPTDataTy () const
 
VersionedPTDataTy * getVersionedPTDataTy () const
 
virtual void onTheFlyCallGraphSolve (const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
 On the fly call graph construction.
 
virtual void onTheFlyThreadCallGraphSolve (const CallSiteToFunPtrMap &callsites, CallEdgeMap &newForkEdges)
 On the fly thread call graph construction respecting forksite.
 
- Protected Member Functions inherited from SVF::PointerAnalysis
const CallSiteToFunPtrMap & getIndirectCallsites () const
 Return all indirect callsites.
 
NodeID getFunPtr (const CallICFGNode *cs) const
 Return function pointer PAGNode at a callsite cs.
 
virtual void validateTests ()
 Alias check functions to verify correctness of pointer analysis.
 
virtual void validateExpectedFailureTests (std::string fun)
 
void resetObjFieldSensitive ()
 Reset all object node as field-sensitive.
 

Protected Attributes

CallSite2DummyValPN callsite2DummyValPN
 Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator.
 
- Protected Attributes inherited from SVF::AndersenBase
ConstraintGraph * consCG
 Constraint Graph.
 
CallSite2DummyValPN callsite2DummyValPN
 
- Protected Attributes inherited from SVF::WPASolver< GraphType >
bool reanalyze
 Reanalyze if any constraint value changed.
 
u32_t iterationForPrintStat
 print out statistics for i-th iteration
 
GraphType _graph
 Graph.
 
std::unique_ptr< SCC > scc
 SCC.
 
WorkList worklist
 Worklist for resolution.
 
- Protected Attributes inherited from SVF::PointerAnalysis
bool print_stat
 User input flags.
 
bool alias_validation
 Flag for validating points-to/alias results.
 
u32_t OnTheFlyIterBudgetForStat
 Flag for iteration budget for on-the-fly statistics.
 
PTATY ptaTy
 Pointer analysis Type.
 
PTAImplTy ptaImplTy
 PTA implementation type.
 
PTAStat * stat
 Statistics.
 
CallGraph * callgraph
 Call graph used for pointer analysis.
 
CallGraphSCC * callGraphSCC
 SCC for PTACallGraph.
 
ICFG * icfg
 Interprocedural control-flow graph.
 
CommonCHGraph * chgraph
 CHGraph.
 

Additional Inherited Members

- Public Attributes inherited from SVF::AndersenBase
NodeBS redundantGepNodes
 
- Public Attributes inherited from SVF::WPASolver< GraphType >
u32_t numOfIteration
 num of iterations during constraint solving
 
- Static Public Attributes inherited from SVF::AndersenBase
static u32_t numOfProcessedAddr = 0
 Statistics.
 
static u32_t numOfProcessedCopy = 0
 Number of processed Addr edge.
 
static u32_t numOfProcessedGep = 0
 Number of processed Copy edge.
 
static u32_t numOfProcessedLoad = 0
 Number of processed Gep edge.
 
static u32_t numOfProcessedStore = 0
 Number of processed Load edge.
 
static u32_t numOfSfrs = 0
 Number of processed Store edge.
 
static u32_t numOfFieldExpand = 0
 
static u32_t numOfSCCDetection = 0
 
static double timeOfSCCDetection = 0
 
static double timeOfSCCMerges = 0
 
static double timeOfCollapse = 0
 
static u32_t AveragePointsToSetSize = 0
 
static u32_t MaxPointsToSetSize = 0
 
static double timeOfProcessCopyGep = 0
 
static double timeOfProcessLoadStore = 0
 
static double timeOfUpdateCallGraph = 0
 
- Static Public Attributes inherited from SVF::PointerAnalysis
static const std::string aliasTestMayAlias = "MAYALIAS"
 
static const std::string aliasTestMayAliasMangled = "_Z8MAYALIASPvS_"
 
static const std::string aliasTestNoAlias = "NOALIAS"
 
static const std::string aliasTestNoAliasMangled = "_Z7NOALIASPvS_"
 
static const std::string aliasTestPartialAlias = "PARTIALALIAS"
 
static const std::string aliasTestPartialAliasMangled = "_Z12PARTIALALIASPvS_"
 
static const std::string aliasTestMustAlias = "MUSTALIAS"
 
static const std::string aliasTestMustAliasMangled = "_Z9MUSTALIASPvS_"
 
static const std::string aliasTestFailMayAlias = "EXPECTEDFAIL_MAYALIAS"
 
static const std::string aliasTestFailMayAliasMangled = "_Z21EXPECTEDFAIL_MAYALIASPvS_"
 
static const std::string aliasTestFailNoAlias = "EXPECTEDFAIL_NOALIAS"
 
static const std::string aliasTestFailNoAliasMangled = "_Z20EXPECTEDFAIL_NOALIASPvS_"
 
- Static Protected Attributes inherited from SVF::PointerAnalysis
static SVFIR * pag = nullptr
 SVFIR.
 

Detailed Description

Inclusion-based Pointer Analysis

Definition at line 192 of file Andersen.h.

Member Typedef Documentation

◆ CGSCC

Definition at line 197 of file Andersen.h.

Constructor & Destructor Documentation

◆ Andersen()

SVF::Andersen::Andersen ( SVFIR *  _pag,
PTATY  type = PTATY::Andersen_WPA,
bool  alias_check = true 
)
inline

Constructor.

Definition at line 200 of file Andersen.h.

202 {
203 }
newitem type
Definition cJSON.cpp:2739
AndersenBase(SVFIR *_pag, PTATY type=PTATY::Andersen_BASE, bool alias_check=true)
Constructor.
Definition Andersen.h:68
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ ~Andersen()

virtual SVF::Andersen::~Andersen ( )
inlinevirtual

Destructor.

Definition at line 206 of file Andersen.h.

207 {
208
209 }

Member Function Documentation

◆ addCopyEdge()

virtual bool SVF::Andersen::addCopyEdge ( NodeID  src,
NodeID  dst 
)
inlineprotectedvirtual

Add copy edge on constraint graph.

Implements SVF::AndersenBase.

Reimplemented in SVF::AndersenSCD.

Definition at line 338 of file Andersen.h.

339 {
340 if (consCG->addCopyCGEdge(src, dst))
341 {
342 updatePropaPts(src, dst);
343 return true;
344 }
345 return false;
346 }
ConstraintGraph * consCG
Constraint Graph.
Definition Andersen.h:181
void updatePropaPts(NodeID dstId, NodeID srcId)
Handle propagated points-to set.
Definition Andersen.h:301
CopyCGEdge * addCopyCGEdge(NodeID src, NodeID dst)
Add Copy edge.
Definition ConsG.cpp:226

◆ classof() [1/2]

static bool SVF::Andersen::classof ( const Andersen *  )
inlinestatic

Methods for support type inquiry through isa, cast, and dyn_cast:

Definition at line 228 of file Andersen.h.

229 {
230 return true;
231 }

◆ classof() [2/2]

static bool SVF::Andersen::classof ( const PointerAnalysis *  pta)
inlinestatic

Definition at line 232 of file Andersen.h.

233 {
234 return (pta->getAnalysisTy() == PTATY::Andersen_WPA
235 || pta->getAnalysisTy() == PTATY::AndersenWaveDiff_WPA
236 || pta->getAnalysisTy() == PTATY::AndersenSCD_WPA
237 || pta->getAnalysisTy() == PTATY::AndersenSFR_WPA);
238 }
@ Andersen_WPA
Andersen PTA.
Definition PTATY.h:12
@ AndersenSFR_WPA
Stride-based field representation.
Definition PTATY.h:14
@ AndersenWaveDiff_WPA
Diff wave propagation andersen-style WPA.
Definition PTATY.h:15
@ AndersenSCD_WPA
Selective cycle detection andersen-style WPA.
Definition PTATY.h:13

◆ clearPropaPts()

void SVF::Andersen::clearPropaPts ( NodeID  src)
inlineprotected

Definition at line 309 of file Andersen.h.

310 {
311 if (Options::DiffPts())
312 {
313 NodeID rep = sccRepNode(src);
314 getDiffPTDataTy()->clearPropaPts(rep);
315 }
316 }
NodeID sccRepNode(NodeID id) const override
SCC methods.
Definition Andersen.h:132
DiffPTDataTy * getDiffPTDataTy() const
static const Option< bool > DiffPts
Definition Options.h:206
u32_t NodeID
Definition GeneralType.h:76

◆ cluster()

void Andersen::cluster ( void  ) const
protectedvirtual

Runs a Steensgaard analysis and performs clustering based on those results set the global best mapping.

Definition at line 1121 of file Andersen.cpp.

1122{
1123 assert(Options::MaxFieldLimit() == 0 && "Andersen::cluster: clustering for Andersen's is currently only supported in field-insensitive analysis");
1125 std::vector<std::pair<unsigned, unsigned>> keys;
1126 for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit)
1127 {
1128 keys.push_back(std::make_pair(pit->first, 1));
1129 }
1130
1131 std::vector<std::pair<hclust_fast_methods, std::vector<NodeID>>> candidates;
1132 PointsTo::MappingPtr nodeMapping =
1133 std::make_shared<std::vector<NodeID>>(
1134 NodeIDAllocator::Clusterer::cluster(steens, keys, candidates, "aux-steens", print_stat)
1135 );
1136 PointsTo::MappingPtr reverseNodeMapping =
1137 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
1138
1139 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
1140}
iterator begin()
Iterators.
IDToNodeMapTy::iterator iterator
Node Iterators.
static std::vector< NodeID > getReverseNodeMapping(const std::vector< NodeID > &nodeMapping)
static std::vector< NodeID > cluster(BVDataPTAImpl *pta, const std::vector< std::pair< NodeID, unsigned > > keys, std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > &candidates, std::string evalSubtitle="", bool printStat=true)
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
bool print_stat
User input flags.
static SVFIR * pag
SVFIR.
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:43
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:383
static Steensgaard * createSteensgaard(SVFIR *_pag)
Create an singleton instance.
Definition Steensgaard.h:36

◆ collapseField()

bool Andersen::collapseField ( NodeID  nodeId)
protected

Collapse field. make struct with the same base as nodeId become field-insensitive.

Black hole doesn't have structures, no collapse is needed. In later versions, instead of using base node to represent the struct, we'll create new field-insensitive node. To avoid creating a new "black hole" node, do not collapse field for black hole node.

Definition at line 791 of file Andersen.cpp.

792{
798 return false;
799
800 bool changed = false;
801
802 double start = stat->getClk();
803
804 // set base node field-insensitive.
806
807 // replace all occurrences of each field with the field-insensitive node
812 {
814 if (fieldId != baseId)
815 {
816 // use the reverse pts of this field node to find all pointers point to it
818 for (const NodeID o : revPts)
819 {
820 // change the points-to target from field to base node
822 addPts(o, baseId);
824
825 changed = true;
826 }
827 // merge field node into base node, including edges and pts.
830 if (fieldId != baseRepNodeId)
831 {
832 // gep node fieldId becomes redundant if it is merged to its base node who is set as field-insensitive
833 // two node IDs should be different otherwise this field is actually the base and should not be removed.
835 }
836 }
837 }
838
841 changed = true;
842
843 double end = stat->getClk();
844 timeOfCollapse += (end - start) / TIMEINTERVAL;
845
846 return changed;
847}
#define TIMEINTERVAL
Definition SVFType.h:604
NodeBS redundantGepNodes
Definition Andersen.h:156
static double timeOfCollapse
Definition Andersen.h:171
virtual void mergeNodeToRep(NodeID nodeId, NodeID newRepId)
Merge sub node to its rep.
Definition Andersen.cpp:907
bool collapseNodePts(NodeID nodeId)
Definition Andersen.cpp:771
const NodeSet & getRevPts(NodeID nodeId) override
virtual void clearPts(NodeID id, NodeID element)
Remove element from the points-to set of id.
virtual bool addPts(NodeID id, NodeID ptd)
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition ConsG.h:230
NodeID getFIObjVar(NodeID id)
Get a field-insensitive node of a memory object.
Definition ConsG.h:334
bool isPWCNode(NodeID nodeId)
Check/Set PWC (positive weight cycle) flag.
Definition ConsG.h:345
bool isBlkObjOrConstantObj(NodeID id)
Definition ConsG.h:307
NodeBS & getAllFieldsObjVars(NodeID id)
Definition ConsG.h:311
PTAStat * stat
Statistics.
void setObjFieldInsensitive(NodeID id)
static double getClk(bool mark=false)
Definition SVFStat.cpp:52
void set(unsigned Idx)
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:157
Set< NodeID > NodeSet
Definition GeneralType.h:87

◆ collapseFields()

void Andersen::collapseFields ( )
protectedvirtual

collapse positive weight cycles of a graph

Reimplemented from SVF::WPASolver< GraphType >.

Definition at line 717 of file Andersen.cpp.

718{
720 {
722 // collapseField() may change the points-to set of the nodes which have been processed
723 // before, in this case, we may need to re-do the analysis.
724 if (collapseField(node))
725 reanalyze = true;
726 }
727}
bool collapseField(NodeID nodeId)
Definition Andersen.cpp:791
NodeID getNextCollapseNode()
Definition ConsG.h:365
bool hasNodesToBeCollapsed() const
Add/get nodes to be collapsed.
Definition ConsG.h:357
bool reanalyze
Reanalyze if any constraint value changed.
Definition WPASolver.h:172

◆ collapseNodePts()

bool Andersen::collapseNodePts ( NodeID  nodeId)
protected

Collapse node's points-to set. Change all points-to elements into field-insensitive.

Points to set may be changed during collapse, so use a clone instead.

Definition at line 771 of file Andersen.cpp.

772{
773 bool changed = false;
774 const PointsTo& nodePts = getPts(nodeId);
777 for (PointsTo::iterator ptsIt = ptsClone.begin(), ptsEit = ptsClone.end(); ptsIt != ptsEit; ptsIt++)
778 {
780 continue;
781
782 if (collapseField(*ptsIt))
783 changed = true;
784 }
785 return changed;
786}
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition Andersen.h:242
bool isFieldInsensitive(NodeID id) const

◆ collapsePWCNode()

void Andersen::collapsePWCNode ( NodeID  nodeId)
protectedvirtual

Collapse a field object into its base for field insensitive analysis.

Detect and collapse PWC nodes produced by processing gep edges, under the constraint of field limit.

Definition at line 708 of file Andersen.cpp.

709{
710 // If a node is a PWC node, collapse all its points-to target.
711 // collapseNodePts() may change the points-to set of the nodes which have been processed
712 // before, in this case, we may need to re-do the analysis.
714 reanalyze = true;
715}

◆ collectMayAliasesFromIndex()

std::optional< NodeBS > Andersen::collectMayAliasesFromIndex ( const PointsTo &  expandedPts)
protected

Answer a may-alias query from the reverse points-to sets. Returns nullopt when those sets cannot answer it, leaving the caller to try every node.

Answer a may-alias query from the reverse points-to sets, which say which nodes may point to a given object.

Two nodes may alias exactly when their expanded points-to sets share an object. For every object in this query's expanded set, collect all raw points-to objects whose expansion can contain it: the object itself, its base, and every field of a field-insensitive base. The reverse sets of those objects therefore name the complete answer. The black-hole reverse set supplies nodes that alias everything.

Returns nullopt when reverse points-to sets are unavailable or the query itself points to the black hole, leaving the caller to try every node.

Definition at line 1023 of file Andersen.cpp.

1024{
1025 if (!getPTDataTy()->hasReversePts() || containBlackHoleNode(expandedPts))
1026 return std::nullopt;
1027
1030 for (NodeID object : expandedPts)
1031 {
1032 objects.set(object);
1033 const NodeID base = pag->getBaseObjVarID(object);
1034 objects.set(base);
1035 if (isFieldInsensitive(base))
1037 }
1039
1040 const size_t wordCount = (static_cast<size_t>(nodeBound) +
1043 for (NodeID object : objects)
1044 {
1045 for (NodeID key : getRevPts(object))
1046 {
1047 const NodeID representative = sccRepNode(key);
1048 // Reverse points-to sets can retain stale postings. Confirm the
1049 // posting with one current-set bit test before treating it as an
1050 // alias witness, unless an earlier object already confirmed it.
1051 if (!representatives.test(representative) &&
1052 getPts(representative).test(object))
1053 representatives.set(representative);
1054 }
1055 }
1056
1057 // SCC subnode sets are individually ordered, but their concatenation is
1058 // not globally ordered. Collect them densely before inserting into the
1059 // sparse result, where backward insertions would be costly.
1061 for (NodeID representative : representatives)
1062 {
1063 for (NodeID subNode : sccSubNodes(representative))
1064 answer.set(subNode);
1065 }
1066
1067 // normalizePointsTo can remove field nodes while their ids remain in
1068 // points-to sets. Do not return those stale nodes.
1070 for (NodeID id : answer)
1071 {
1072 if (pag->hasGNode(id))
1073 aliases.set(id);
1074 }
1075 return aliases;
1076}
unsigned u32_t
Definition CommandLine.h:18
NodeBS & sccSubNodes(NodeID repId)
Definition Andersen.h:136
PTDataTy * getPTDataTy() const
Get points-to data structure.
static const size_t WordSize
bool hasGNode(NodeID id) const
Has a node.
u32_t getTotalNodeNum() const
Get total number of node/edge.
NodeID getBlackHoleNode() const
Definition IRGraph.h:246
bool containBlackHoleNode(const PointsTo &pts)
Determine whether a points-to contains a black hole or constant node.
NodeID getBaseObjVarID(NodeID id) const
Base and Offset methods for Value and Object node.
Definition SVFIR.h:554
NodeBS & getAllFieldsObjVars(const BaseObjVar *obj)
Get all fields of an object.
Definition SVFIR.cpp:573

◆ computeDiffPts()

virtual void SVF::Andersen::computeDiffPts ( NodeID  id)
inlineprotectedvirtual

Handle diff points-to set.

Definition at line 283 of file Andersen.h.

284 {
285 if (Options::DiffPts())
286 {
287 NodeID rep = sccRepNode(id);
288 getDiffPTDataTy()->computeDiffPts(rep, getDiffPTDataTy()->getPts(rep));
289 }
290 }

◆ dumpTopLevelPtsTo()

void Andersen::dumpTopLevelPtsTo ( )
virtual

Print pag nodes' pts by an ascending order

Reimplemented from SVF::PointerAnalysis.

Definition at line 1145 of file Andersen.cpp.

1146{
1147 for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin();
1148 nIter != this->getAllValidPtrs().end(); ++nIter)
1149 {
1150 const SVFVar* node = getPAG()->getSVFVar(*nIter);
1151 if (getPAG()->isValidTopLevelPtr(node))
1152 {
1153 const PointsTo& pts = this->getPts(node->getId());
1154 outs() << "\nNodeID " << node->getId() << " ";
1155
1156 if (pts.empty())
1157 {
1158 outs() << "\t\tPointsTo: {empty}\n";
1159 }
1160 else
1161 {
1162 outs() << "\t\tPointsTo: { ";
1163
1165 for (PointsTo::iterator it = pts.begin(), eit = pts.end();
1166 it != eit; ++it)
1167 {
1168 line.insert(*it);
1169 }
1170 for (multiset<u32_t>::const_iterator it = line.begin(); it != line.end(); ++it)
1171 {
1173 if (auto gepNode = pag->getGepObjVar(*it))
1174 outs() << gepNode->getBaseNode() << "_" << gepNode->getConstantFieldIdx() << " ";
1175 else
1176 outs() << *it << " ";
1177 else
1178 outs() << *it << " ";
1179 }
1180 outs() << "}\n";
1181 }
1182 }
1183 }
1184
1185 outs().flush();
1186}
static const Option< bool > PrintFieldWithBasePrefix
Definition Options.h:115
SVFIR * getPAG() const
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
bool empty() const
Returns true if set is empty.
Definition PointsTo.cpp:110
const_iterator end() const
Definition PointsTo.h:133
const_iterator begin() const
Definition PointsTo.h:129
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:136
const GepObjVar * getGepObjVar(NodeID id) const
Definition SVFIR.h:170
NodeID getId() const
Get ID.
Definition SVFValue.h:158
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58

◆ finalize()

void Andersen::finalize ( )
virtual

Finalize analysis.

Finalize analysis

sanitize field insensitive obj TODO: Fields has been collapsed during Andersen::collapseField().

Reimplemented from SVF::AndersenBase.

Reimplemented in SVF::AndersenWaveDiff.

Definition at line 452 of file Andersen.cpp.

453{
454 // TODO: broken
456 {
458 const PTDataTy *ptd = getPTDataTy();
459 // TODO: should we use liveOnly?
460 // TODO: parameterise final arg.
462 if (print_stat)
463 {
465 }
466 }
467
470 // sanitizePts();
472}
virtual void finalize() override
Finalize analysis.
Definition Andersen.cpp:98
PTData< NodeID, NodeSet, NodeID, PointsTo > PTDataTy
static void printStats(std::string title, Map< std::string, std::string > &stats)
static void evaluate(const std::vector< NodeID > &nodeMap, const Map< PointsTo, unsigned > pointsToSets, Map< std::string, std::string > &stats, bool accountForOcc)
Fills in *NumWords statistics in stats..
static const Option< bool > ClusterAnder
Whether to stage Andersen's with Steensgaard and cluster based on that data.
Definition Options.h:37
static MappingPtr getCurrentBestNodeMapping()
Definition PointsTo.cpp:373

◆ getDiffPts()

virtual const PointsTo & SVF::Andersen::getDiffPts ( NodeID  id)
inlineprotectedvirtual

Definition at line 291 of file Andersen.h.

292 {
293 NodeID rep = sccRepNode(id);
294 if (Options::DiffPts())
295 return getDiffPTDataTy()->getDiffPts(rep);
296 else
297 return getPTDataTy()->getPts(rep);
298 }

◆ getMayAliases()

NodeBS Andersen::getMayAliases ( NodeID  node)
virtual

Collect exactly the SVFIR nodes q for which mayAlias(node, q) holds.

Collect every SVFIR node that may alias the given node.

Reimplemented from SVF::PointerAnalysis.

Definition at line 938 of file Andersen.cpp.

939{
940 // Reuse this expansion for the index lookup and, when necessary, every
941 // comparison in the exhaustive fallback.
945 return std::move(*aliases);
946
949 for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; ++it)
950 {
951 const NodeID candidate = it->first;
953 {
954 aliases.set(candidate);
955 continue;
956 }
957
961 expandedPts.intersects(candidatePts))
962 aliases.set(candidate);
963 }
964 return aliases;
965}
std::optional< NodeBS > collectMayAliasesFromIndex(const PointsTo &expandedPts)
virtual void expandFIObjs(const PointsTo &pts, PointsTo &expandedPts)
Expand FI objects.

◆ getMayAliasesBatch()

std::vector< NodeBS > Andersen::getMayAliasesBatch ( const std::vector< NodeID > &  nodes)

Query multiple pointers, reusing answers for equal points-to sets within this call.

Parameters
nodesInput SVFIR node IDs in query order.
Returns
One owned alias set per input: result[i] equals getMayAliases(nodes[i]). Duplicates are preserved; empty input returns an empty vector. The analysis, SVFIR, SCCs and points-to mapping must stay unchanged during the call. Equal points-to sets must imply equal answers, including in subclass overrides. Cache limits exclude the returned results; split large inputs to limit output storage.

Reuse answers only within a batch whose analysis state is unchanged. For example, queries for p and q with pts(p) = pts(q) = {o} need the same reverse-index walk. Keep the cache local so later batches and scalar queries observe current state.

Definition at line 972 of file Andersen.cpp.

973{
974 std::vector<NodeBS> results;
975 results.reserve(nodes.size());
977 size_t cachedMembers = 0;
978 // Bound the reuse cache separately from the caller-owned results.
979 constexpr size_t maxCachedSets = 256;
980 constexpr size_t maxCachedMembers = 1 << 20;
981 for (NodeID node : nodes)
982 {
983 const PointsTo& pts = getPts(node);
984 auto cached = answers.find(pts);
985 if (cached != answers.end())
986 {
987 results.push_back(cached->second);
988 continue;
989 }
990
992 const size_t members = static_cast<size_t>(pts.count()) + aliases.count();
993 if (members > maxCachedMembers)
994 {
995 results.push_back(std::move(aliases));
996 continue;
997 }
998 if (answers.size() == maxCachedSets || cachedMembers > maxCachedMembers - members)
999 {
1000 answers.clear();
1001 cachedMembers = 0;
1002 }
1003 auto inserted = answers.emplace(pts, std::move(aliases));
1004 cachedMembers += members;
1005 results.push_back(inserted.first->second);
1006 }
1007 return results;
1008}
virtual NodeBS getMayAliases(NodeID node)
Collect exactly the SVFIR nodes q for which mayAlias(node, q) holds.
Definition Andersen.cpp:938
u32_t count() const
Returns number of elements.
Definition PointsTo.cpp:123
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)

◆ getPts()

virtual const PointsTo & SVF::Andersen::getPts ( NodeID  id)
inlinevirtual

Operation of points-to set.

Implements SVF::PointerAnalysis.

Definition at line 242 of file Andersen.h.

243 {
244 return getPTDataTy()->getPts(sccRepNode(id));
245 }

◆ handleCopyGep()

void Andersen::handleCopyGep ( ConstraintNode *  node)
protectedvirtual

Process copy and gep edges

Reimplemented in SVF::AndersenSCD.

Definition at line 498 of file Andersen.cpp.

499{
500 NodeID nodeId = node->getId();
502
503 if (!getDiffPts(nodeId).empty())
504 {
505 for (ConstraintEdge* edge : node->getCopyOutEdges())
507 for (ConstraintEdge* edge : node->getGepOutEdges())
508 {
509 if (GepCGEdge* gepEdge = SVFUtil::dyn_cast<GepCGEdge>(edge))
511 }
512 }
513}
virtual void computeDiffPts(NodeID id)
Handle diff points-to set.
Definition Andersen.h:283
virtual const PointsTo & getDiffPts(NodeID id)
Definition Andersen.h:291
virtual bool processGep(NodeID node, const GepCGEdge *edge)
Definition Andersen.cpp:635
virtual bool processCopy(NodeID node, const ConstraintEdge *edge)
Definition Andersen.cpp:615

◆ handleLoadStore()

void Andersen::handleLoadStore ( ConstraintNode *  node)
protectedvirtual

Process load and store edges

Reimplemented in SVF::AndersenSCD.

Definition at line 518 of file Andersen.cpp.

519{
520 NodeID nodeId = node->getId();
521 for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter =
522 getPts(nodeId).end(); piter != epiter; ++piter)
523 {
524 NodeID ptd = *piter;
525 // handle load
527 eit = node->outgoingLoadsEnd(); it != eit; ++it)
528 {
529 if (processLoad(ptd, *it))
531 }
532
533 // handle store
535 eit = node->incomingStoresEnd(); it != eit; ++it)
536 {
537 if (processStore(ptd, *it))
538 pushIntoWorklist((*it)->getSrcID());
539 }
540 }
541}
virtual bool processLoad(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:575
virtual bool processStore(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:595
const_iterator outgoingLoadsEnd() const
Definition ConsGNode.h:194
const_iterator incomingStoresBegin() const
Definition ConsGNode.h:215
const_iterator incomingStoresEnd() const
Definition ConsGNode.h:219
ConstraintEdge::ConstraintEdgeSetTy::const_iterator const_iterator
Definition ConsGNode.h:45
const_iterator outgoingLoadsBegin() const
Definition ConsGNode.h:190

◆ initialize()

void Andersen::initialize ( )
virtual

Initialize analysis.

 Connect formal and actual parameters for indirect callsites
&zwj;/

void AndersenBase::connectCaller2CalleeParams(const CallICFGNode* cs, const FunObjVar* F, NodePairSet &cpySrcNodes) { assert(F);

DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs->valueOnlyToString() << " to callee " << *F << "\n");

const CallICFGNode* callBlockNode = cs; const RetICFGNode* retBlockNode = cs->getRetICFGNode();

if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode)) { heapAllocatorViaIndCall(cs,cpySrcNodes); }

if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode)) { const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode); const PAGNode* fun_return = pag->getFunRet(F); if (cs_return->isPointer() && fun_return->isPointer()) { NodeID dstrec = sccRepNode(cs_return->getId()); NodeID srcret = sccRepNode(fun_return->getId()); if(addCopyEdge(srcret, dstrec)) { cpySrcNodes.insert(std::make_pair(srcret,dstrec)); } } else { DBOUT(DAndersen, outs() << "not a pointer ignored\n"); } }

if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F)) {

connect actual and formal param const SVFIR::ValVarList& csArgList = pag->getCallSiteArgsList(callBlockNode); const SVFIR::ValVarList& funArgList = pag->getFunArgsList(F); Go through the fixed parameters. DBOUT(DPAGBuild, outs() << " args:"); SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); SVFIR::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt) { Some programs (e.g. Linux kernel) leave unneeded parameters empty. if (csArgIt == csArgEit) { DBOUT(DAndersen, outs() << " !! not enough args\n"); break; } const PAGNode *cs_arg = *csArgIt ; const PAGNode *fun_arg = *funArgIt;

if (cs_arg->isPointer() && fun_arg->isPointer()) { DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n"); NodeID srcAA = sccRepNode(cs_arg->getId()); NodeID dstFA = sccRepNode(fun_arg->getId()); if(addCopyEdge(srcAA, dstFA)) { cpySrcNodes.insert(std::make_pair(srcAA,dstFA)); } } }

Any remaining actual args must be varargs. if (F->isVarArg()) { NodeID vaF = sccRepNode(pag->getVarargNode(F)); DBOUT(DPAGBuild, outs() << "\n varargs:"); for (; csArgIt != csArgEit; ++csArgIt) { const PAGNode *cs_arg = *csArgIt; if (cs_arg->isPointer()) { NodeID vnAA = sccRepNode(cs_arg->getId()); if (addCopyEdge(vnAA,vaF)) { cpySrcNodes.insert(std::make_pair(vnAA,vaF)); } } } } if(csArgIt != csArgEit) { writeWrnMsg("too many args to non-vararg func."); writeWrnMsg("(" + cs->getSourceLoc() + ")"); } } }

void AndersenBase::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes) { assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?"); const RetICFGNode* retBlockNode = cs->getRetICFGNode(); const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode); NodeID srcret; CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs); if(it != callsite2DummyValPN.end()) { srcret = sccRepNode(it->second); } else { NodeID valNode = pag->addDummyValNode(); NodeID objNode = pag->addDummyObjNode(cs->getType()); addPts(valNode,objNode); callsite2DummyValPN.insert(std::make_pair(cs,valNode)); consCG->addConstraintNode(new ConstraintNode(valNode),valNode); consCG->addConstraintNode(new ConstraintNode(objNode),objNode); srcret = valNode; }

NodeID dstrec = sccRepNode(cs_return->getId()); if(addCopyEdge(srcret, dstrec)) cpySrcNodes.insert(std::make_pair(srcret,dstrec)); }

void AndersenBase::normalizePointsTo() { SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap(); SVFIR::OffsetToGepVarMap &GepObjVarMap = pag->getGepObjNodeMap();

clear GepObjVarMap/memToFieldsMap/nodeToSubsMap/nodeToRepMap for redundant gepnodes and remove those nodes from pag for (NodeID n: redundantGepNodes) { NodeID base = pag->getBaseObjVarID(n); const GepObjVar* gepNode = pag->getGepObjVar(n); assert(gepNode && "Not a gep node in redundantGepNodes set"); const APOffset apOffset = gepNode->getConstantFieldIdx(); GepObjVarMap.erase(std::make_pair(base, apOffset)); memToFieldsMap[base].reset(n); cleanConsCG(n);

pag->removeGNode(const_cast<GepObjVar*>(gepNode)); } }

/*! Initialize analysis

Initialize worklist

Reimplemented from SVF::AndersenBase.

Reimplemented in SVF::AndersenWaveDiff, and SVF::AndersenSFR.

Definition at line 438 of file Andersen.cpp.

439{
440 resetData();
442
444
447}
virtual void initialize() override
Initialize analysis.
Definition Andersen.cpp:82
void resetData()
Reset data.
Definition Andersen.h:218
void processAllAddr()
handling various constraints
Definition Andersen.cpp:546
virtual void cluster(void) const

◆ initWorklist()

virtual void SVF::Andersen::initWorklist ( )
inlineprotectedvirtual

Reimplemented from SVF::WPASolver< GraphType >.

Definition at line 318 of file Andersen.h.

318{}

◆ mergeNodeToRep()

void Andersen::mergeNodeToRep ( NodeID  nodeId,
NodeID  newRepId 
)
protectedvirtual

Merge sub node to its rep.

Definition at line 907 of file Andersen.cpp.

908{
909
912}
virtual bool mergeSrcToTgt(NodeID srcId, NodeID tgtId)
Definition Andersen.cpp:876
void setPWCNode(NodeID nodeId)
Definition ConsG.h:349

◆ mergeSccCycle()

void Andersen::mergeSccCycle ( )
protected

Definition at line 732 of file Andersen.cpp.

733{
734 NodeStack topoOrder = getSCCDetector()->topoNodeStack();
735
736 while (!topoOrder.empty())
737 {
738 NodeID repNodeId = topoOrder.top();
739 topoOrder.pop();
740 const NodeBS& subNodes = getSCCDetector()->subNodes(repNodeId);
741 // merge sub nodes to rep node
742 mergeSccNodes(repNodeId, subNodes);
743 if (subNodes.count() > 1)
744 {
746 reanalyze = true;
747 }
748 }
749}
void mergeSccNodes(NodeID repNodeId, const NodeBS &subNodes)
Merge sub node in a SCC cycle to their rep node.
Definition Andersen.cpp:756
unsigned count() const
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:68
std::stack< NodeID > NodeStack
Definition GeneralType.h:92

◆ mergeSccNodes()

void Andersen::mergeSccNodes ( NodeID  repNodeId,
const NodeBS &  subNodes 
)
protected

Merge sub node in a SCC cycle to their rep node.

Union points-to of subscc nodes into its rep nodes Move incoming/outgoing direct edges of sub node to rep node

Definition at line 756 of file Andersen.cpp.

757{
758 for (NodeBS::iterator nodeIt = subNodes.begin(); nodeIt != subNodes.end(); nodeIt++)
759 {
761 if (subNodeId != repNodeId)
762 {
764 }
765 }
766}
iterator begin() const

◆ mergeSrcToTgt()

bool Andersen::mergeSrcToTgt ( NodeID  nodeId,
NodeID  newRepId 
)
protectedvirtual

merge nodeId to newRepId. Return true if the newRepId is a PWC node

union pts of node to rep

move the edges from node to rep, and remove the node

  1. if find gep edges inside SCC cycle, the rep node will become a PWC node and its pts should be collapsed later.
  2. if the node to be merged is already a PWC node, the rep node will also become a PWC node as it will have a self-cycle gep edge.

set rep and sub relations

Reimplemented in SVF::AndersenSFR.

Definition at line 876 of file Andersen.cpp.

877{
878
879 if(nodeId==newRepId)
880 return false;
881
885
889
894 if(node->isPWCNode())
895 pwc = true;
896
899
901
902 return pwc;
903}
virtual bool unionPts(NodeID id, const PointsTo &target)
Definition Andersen.h:246
void updateNodeRepAndSubs(NodeID nodeId, NodeID newRepId)
Updates subnodes of its rep, and rep node of its subs.
Definition Andersen.cpp:917
void removeConstraintNode(ConstraintNode *node)
Definition ConsG.h:118
ConstraintNode * getConstraintNode(NodeID id) const
Get/add/remove constraint node.
Definition ConsG.h:104
bool moveEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition ConsG.h:281
bool isPWCNode() const
Whether a node involves in PWC, if so, all its points-to elements should become field-insensitive.
Definition ConsGNode.h:81

◆ processAddr()

void Andersen::processAddr ( const AddrCGEdge *  addr)
protectedvirtual

Process address edges

Reimplemented in SVF::AndersenSCD.

Definition at line 560 of file Andersen.cpp.

561{
563
564 NodeID dst = addr->getDstID();
565 NodeID src = addr->getSrcID();
566 if(addPts(dst,src))
567 pushIntoWorklist(dst);
568}
static u32_t numOfProcessedAddr
Statistics.
Definition Andersen.h:160

◆ processAllAddr()

void Andersen::processAllAddr ( )
protected

handling various constraints

Process address edges

Definition at line 546 of file Andersen.cpp.

547{
549 {
550 ConstraintNode * cgNode = nodeIt->second;
552 it != eit; ++it)
553 processAddr(SVFUtil::cast<AddrCGEdge>(*it));
554 }
555}
virtual void processAddr(const AddrCGEdge *addr)
Definition Andersen.cpp:560
const_iterator incomingAddrsBegin() const
Definition ConsGNode.h:181
const_iterator incomingAddrsEnd() const
Definition ConsGNode.h:185

◆ processCopy()

bool Andersen::processCopy ( NodeID  node,
const ConstraintEdge *  edge 
)
protectedvirtual

Process copy edges src –copy--> dst, union pts(dst) with pts(src)

Definition at line 615 of file Andersen.cpp.

616{
618
619 assert((SVFUtil::isa<CopyCGEdge>(edge)) && "not copy/call/ret ??");
620 NodeID dst = edge->getDstID();
621 const PointsTo& srcPts = getDiffPts(node);
622
623 bool changed = unionPts(dst, srcPts);
624 if (changed)
625 pushIntoWorklist(dst);
626 return changed;
627}
static u32_t numOfProcessedCopy
Number of processed Addr edge.
Definition Andersen.h:161

◆ processGep()

bool Andersen::processGep ( NodeID  node,
const GepCGEdge *  edge 
)
protectedvirtual

Process gep edges src –gep--> dst, for each srcPtdNode \in pts(src) ==> add fieldSrcPtdNode into tmpDstPts union pts(dst) with tmpDstPts

Definition at line 635 of file Andersen.cpp.

636{
637 const PointsTo& srcPts = getDiffPts(edge->getSrcID());
638 return processGepPts(srcPts, edge);
639}
virtual bool processGepPts(const PointsTo &pts, const GepCGEdge *edge)
Definition Andersen.cpp:644

◆ processGepPts()

bool Andersen::processGepPts ( const PointsTo &  pts,
const GepCGEdge *  edge 
)
protectedvirtual

Compute points-to for gep edges

Reimplemented in SVF::AndersenSFR.

Definition at line 644 of file Andersen.cpp.

645{
647
649 if (SVFUtil::isa<VariantGepCGEdge>(edge))
650 {
651 // If a pointer is connected by a variant gep edge,
652 // then set this memory object to be field insensitive,
653 // unless the object is a black hole/constant.
654 for (NodeID o : pts)
655 {
657 {
658 tmpDstPts.set(o);
659 continue;
660 }
661
662 if (!isFieldInsensitive(o))
663 {
666 }
667
668 // Add the field-insensitive node into pts.
670 tmpDstPts.set(baseId);
671 }
672 }
673 else if (const NormalGepCGEdge* normalGepEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
674 {
675 // TODO: after the node is set to field insensitive, handling invariant
676 // gep edge may lose precision because offsets here are ignored, and the
677 // base object is always returned.
678 for (NodeID o : pts)
679 {
681 {
682 tmpDstPts.set(o);
683 continue;
684 }
685
686 NodeID fieldSrcPtdNode = consCG->getGepObjVar(o, normalGepEdge->getAccessPath().getConstantStructFldIdx());
688 }
689 }
690 else
691 {
692 assert(false && "Andersen::processGepPts: New type GEP edge type?");
693 }
694
695 NodeID dstId = edge->getDstID();
697 {
699 return true;
700 }
701
702 return false;
703}
static u32_t numOfProcessedGep
Number of processed Copy edge.
Definition Andersen.h:162
void addNodeToBeCollapsed(NodeID id)
Definition ConsG.h:361
NodeID getBaseObjVarID(NodeID id)
Definition ConsG.h:315
NodeID getGepObjVar(NodeID id, const APOffset &apOffset)
Get a field of a memory object.
Definition ConsG.h:325
void set(u32_t n)
Inserts n in the set.
Definition PointsTo.cpp:169

◆ processLoad()

bool Andersen::processLoad ( NodeID  node,
const ConstraintEdge *  load 
)
protectedvirtual

Process load edges src –load--> dst, node \in pts(src) ==> node–copy-->dst

TODO: New copy edges are also added for black hole obj node to make gcc in spec 2000 pass the flow-sensitive analysis. Try to handle black hole obj in an appropriate way.

Definition at line 575 of file Andersen.cpp.

576{
580// if (pag->isBlkObjOrConstantObj(node))
581 if (pag->isConstantObj(node) || pag->getSVFVar(load->getDstID())->isPointer() == false)
582 return false;
583
585
586 NodeID dst = load->getDstID();
587 return addCopyEdge(node, dst);
588}
static u32_t numOfProcessedLoad
Number of processed Gep edge.
Definition Andersen.h:163
virtual bool addCopyEdge(NodeID src, NodeID dst)
Add copy edge on constraint graph.
Definition Andersen.h:338
NodeID getDstID() const
bool isConstantObj(NodeID id) const
Definition SVFIR.h:545
virtual bool isPointer() const
Check if this variable represents a pointer.

◆ processNode()

void Andersen::processNode ( NodeID  nodeId)
protectedvirtual

Override WPASolver function in order to use the default solver.

Start constraint solving

Reimplemented from SVF::WPASolver< GraphType >.

Reimplemented in SVF::AndersenWaveDiff.

Definition at line 477 of file Andersen.cpp.

478{
479 // sub nodes do not need to be processed
480 if (sccRepNode(nodeId) != nodeId)
481 return;
482
484 double insertStart = stat->getClk();
485 handleLoadStore(node);
486 double insertEnd = stat->getClk();
488
489 double propStart = stat->getClk();
490 handleCopyGep(node);
491 double propEnd = stat->getClk();
493}
static double timeOfProcessLoadStore
Definition Andersen.h:175
static double timeOfProcessCopyGep
Definition Andersen.h:174
virtual void handleLoadStore(ConstraintNode *node)
Definition Andersen.cpp:518
virtual void handleCopyGep(ConstraintNode *node)
Definition Andersen.cpp:498

◆ processStore()

bool Andersen::processStore ( NodeID  node,
const ConstraintEdge *  store 
)
protectedvirtual

Process store edges src –store--> dst, node \in pts(dst) ==> src–copy-->node

TODO: New copy edges are also added for black hole obj node to make gcc in spec 2000 pass the flow-sensitive analysis. Try to handle black hole obj in an appropriate way

Definition at line 595 of file Andersen.cpp.

596{
600// if (pag->isBlkObjOrConstantObj(node))
601 if (pag->isConstantObj(node) || pag->getSVFVar(store->getSrcID())->isPointer() == false)
602 return false;
603
605
606 NodeID src = store->getSrcID();
607 return addCopyEdge(src, node);
608}
static u32_t numOfProcessedStore
Number of processed Load edge.
Definition Andersen.h:164
NodeID getSrcID() const
get methods of the components

◆ PTAName()

virtual const std::string SVF::Andersen::PTAName ( ) const
inlineprotectedvirtual

Get PTA name.

Reimplemented from SVF::PointerAnalysis.

Definition at line 404 of file Andersen.h.

405 {
406 return "AndersenWPA";
407 }

◆ resetData()

void SVF::Andersen::resetData ( )
inline

Reset data.

Definition at line 218 of file Andersen.h.

219 {
224 }
static u32_t MaxPointsToSetSize
Definition Andersen.h:173
static u32_t AveragePointsToSetSize
Definition Andersen.h:172

◆ sanitizePts()

void SVF::Andersen::sanitizePts ( )
inlineprotected

Sanitize pts for field insensitive objects.

Definition at line 382 of file Andersen.h.

383 {
384 for(ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it!=eit; ++it)
385 {
386 const PointsTo& pts = getPts(it->first);
388
389 for (NodeID o : pts)
390 {
393 }
394
395 for (NodeID o : fldInsenObjs)
396 {
398 for (NodeID f : allFields) addPts(it->first, f);
399 }
400 }
401 }
SparseBitVector NodeBS
Definition GeneralType.h:82

◆ SCCDetect()

NodeStack & Andersen::SCCDetect ( )
protectedvirtual

SCC detection.

SCC detection on constraint graph

Reimplemented from SVF::WPASolver< GraphType >.

Reimplemented in SVF::AndersenSCD.

Definition at line 852 of file Andersen.cpp.

853{
855
856 double sccStart = stat->getClk();
858 double sccEnd = stat->getClk();
859
861
862 double mergeStart = stat->getClk();
863
865
866 double mergeEnd = stat->getClk();
867
869
870 return getSCCDetector()->topoNodeStack();
871}
static double timeOfSCCMerges
Definition Andersen.h:170
static u32_t numOfSCCDetection
Definition Andersen.h:168
static double timeOfSCCDetection
Definition Andersen.h:169
void mergeSccCycle()
Definition Andersen.cpp:732
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPASolver.h:87

◆ setDetectPWC()

void SVF::Andersen::setDetectPWC ( bool  flag)
inline

Definition at line 273 of file Andersen.h.

274 {
276 }
void setValue(T v)
static Option< bool > DetectPWC
Definition Options.h:207

◆ unionPts() [1/2]

virtual bool SVF::Andersen::unionPts ( NodeID  id,
const PointsTo &  target 
)
inlinevirtual

Union/add points-to. Add the reverse points-to for node collapse purpose To be noted that adding reverse pts might incur 10% total overhead during solving

Reimplemented from SVF::BVDataPTAImpl.

Definition at line 246 of file Andersen.h.

247 {
248 id = sccRepNode(id);
249 return getPTDataTy()->unionPts(id, target);
250 }

◆ unionPts() [2/2]

virtual bool SVF::Andersen::unionPts ( NodeID  id,
NodeID  ptd 
)
inlinevirtual

Reimplemented from SVF::BVDataPTAImpl.

Definition at line 251 of file Andersen.h.

252 {
253 id = sccRepNode(id);
254 ptd = sccRepNode(ptd);
255 return getPTDataTy()->unionPts(id,ptd);
256 }

◆ updateNodeRepAndSubs()

void Andersen::updateNodeRepAndSubs ( NodeID  nodeId,
NodeID  newRepId 
)
protected

Updates subnodes of its rep, and rep node of its subs.

update nodeToRepMap, for each subs of current node updates its rep to newRepId

Definition at line 917 of file Andersen.cpp.

918{
923 // update nodeToSubsMap, union its subs with its rep Subs
925 for(NodeBS::iterator sit = nodeSubs.begin(), esit = nodeSubs.end(); sit!=esit; ++sit)
926 {
927 NodeID subId = *sit;
929 }
930 repSubs |= nodeSubs;
933}
void setSubs(NodeID node, NodeBS &subs)
Definition ConsG.h:247
void resetSubs(NodeID node)
Definition ConsG.h:251
NodeBS & sccSubNodes(NodeID id)
Definition ConsG.h:238
void setRep(NodeID node, NodeID rep)
Definition ConsG.h:243

◆ updatePropaPts()

void SVF::Andersen::updatePropaPts ( NodeID  dstId,
NodeID  srcId 
)
inlineprotected

Handle propagated points-to set.

Definition at line 301 of file Andersen.h.

302 {
303 if (!Options::DiffPts())
304 return;
307 getDiffPTDataTy()->updatePropaPtsMap(srcRep, dstRep);
308 }

◆ validateSuccessTests()

void Andersen::validateSuccessTests ( std::string  fun)
protectedvirtual

Also check getMayAliases on the pointers that the alias tests use.

Run the alias tests, then check getMayAliases on every pointer they use: it must return exactly the nodes that mayAlias reports

Reimplemented from SVF::PointerAnalysis.

Definition at line 1082 of file Andersen.cpp.

1083{
1085
1086 PointerAnalysis* pta = this;
1087 const FunObjVar* checkFun = pag->getFunObjVar(fun);
1088 if (!checkFun)
1089 return;
1090 for (const CallICFGNode* callNode : pag->getCallSiteSet())
1091 {
1092 if (callNode->getCalledFunction() != checkFun)
1093 continue;
1094 std::vector<NodeID> queries;
1095 for (u32_t i = 0; i < callNode->arg_size(); ++i)
1096 queries.push_back(callNode->getArgument(i)->getId());
1097 const std::vector<NodeBS> aliases = getMayAliasesBatch(queries);
1098 assert(aliases.size() == queries.size() && "getMayAliasesBatch result count mismatch!");
1099 for (size_t i = 0; i < queries.size(); ++i)
1100 {
1101 const NodeID ptr = queries[i];
1103 for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; ++it)
1104 {
1105 if (mayAlias(ptr, it->first))
1106 expected.set(it->first);
1107 }
1108 if (aliases[i] == expected && pta->getMayAliases(ptr) == expected)
1109 outs() << sucMsg("\t SUCCESS :") << "getMayAliases check <id:" << ptr << "> at ("
1110 << callNode->getSourceLoc() << ")\n";
1111 else
1112 {
1113 SVFUtil::errs() << errMsg("\t FAILURE :") << "getMayAliases check <id:" << ptr
1114 << "> at (" << callNode->getSourceLoc() << ")\n";
1115 assert(false && "getMayAliases disagrees with mayAlias!");
1116 }
1117 }
1118 }
1119}
std::vector< NodeBS > getMayAliasesBatch(const std::vector< NodeID > &nodes)
Definition Andersen.cpp:972
bool mayAlias(const PointsTo &pts1, const PointsTo &pts2)
Convenience bool wrappers: return true if the two operands may/must/partial alias.
virtual NodeBS getMayAliases(NodeID node)
virtual void validateSuccessTests(std::string fun)
const FunObjVar * getFunObjVar(const std::string &name)
Definition SVFIR.cpp:48
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:75
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:98
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:64

Member Data Documentation

◆ callsite2DummyValPN

CallSite2DummyValPN SVF::Andersen::callsite2DummyValPN
protected

Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator.

Definition at line 280 of file Andersen.h.


The documentation for this class was generated from the following files: