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

#include <VersionedFlowSensitive.h>

Inheritance diagram for SVF::VersionedFlowSensitive:
SVF::FlowSensitive SVF::WPAFSSolver< GraphType > SVF::BVDataPTAImpl SVF::WPASolver< GraphType > SVF::PointerAnalysis

Classes

class  SCC
 

Public Types

typedef Map< NodeID, VersionObjToVersionMap
 
typedef Map< VersionedVar, const DummyVersionPropSVFGNode * > VarToPropNodeMap
 
typedef std::vector< ObjToVersionMapLocVersionMap
 
typedef Map< NodeID, Map< Version, std::vector< Version > > > VersionRelianceMap
 (o -> (v -> versions with rely on o:v).
 
- Public Types inherited from SVF::FlowSensitive
typedef BVDataPTAImpl::MutDFPTDataTy MutDFPTDataTy
 
typedef BVDataPTAImpl::MutDFPTDataTy::DFPtsMap DFInOutMap
 
typedef BVDataPTAImpl::MutDFPTDataTy::PtsMap PtsMap
 
- Public Types inherited from SVF::WPASolver< GraphType >
typedef SVF::GenericGraphTraits< GraphTypeGTraits
 Define the GTraits and node iterator for printing.
 
typedef GTraits::NodeRef GNODE
 
typedef GTraits::EdgeType GEDGE
 
typedef GTraits::ChildIteratorType child_iterator
 
typedef SCCDetection< GraphTypeSCC
 
typedef FIFOWorkList< NodeIDWorkList
 
- Public Types inherited from SVF::BVDataPTAImpl
typedef PTData< NodeID, NodeSet, NodeID, PointsToPTDataTy
 
typedef DiffPTData< NodeID, NodeSet, NodeID, PointsToDiffPTDataTy
 
typedef DFPTData< NodeID, NodeSet, NodeID, PointsToDFPTDataTy
 
typedef VersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > VersionedPTDataTy
 
typedef MutablePTData< NodeID, NodeSet, NodeID, PointsToMutPTDataTy
 
typedef MutableDiffPTData< NodeID, NodeSet, NodeID, PointsToMutDiffPTDataTy
 
typedef MutableDFPTData< NodeID, NodeSet, NodeID, PointsToMutDFPTDataTy
 
typedef MutableIncDFPTData< NodeID, NodeSet, NodeID, PointsToMutIncDFPTDataTy
 
typedef MutableVersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > MutVersionedPTDataTy
 
typedef PersistentPTData< NodeID, NodeSet, NodeID, PointsToPersPTDataTy
 
typedef PersistentDiffPTData< NodeID, NodeSet, NodeID, PointsToPersDiffPTDataTy
 
typedef PersistentDFPTData< NodeID, NodeSet, NodeID, PointsToPersDFPTDataTy
 
typedef PersistentIncDFPTData< NodeID, NodeSet, NodeID, PointsToPersIncDFPTDataTy
 
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 *, FunctionSetCallEdgeMap
 
typedef SCCDetection< CallGraph * > CallGraphSCC
 
typedef Set< const GlobalObjVar * > VTableSet
 
typedef Set< const FunObjVar * > VFunSet
 

Public Member Functions

 VersionedFlowSensitive (SVFIR *_pag, PTATY type=PTATY::VFS_WPA)
 Constructor.
 
virtual void initialize () override
 Initialize analysis.
 
virtual void finalize () override
 Finalize analysis.
 
virtual const std::string PTAName () const override
 Get PTA name.
 
virtual bool isStore (const NodeID l) const
 Returns true if l is a store node.
 
virtual bool isLoad (const NodeID l) const
 Returns true if l is a load node.
 
Version getVersion (const NodeID l, const NodeID o, const LocVersionMap &lvm) const
 Shared code for getConsume and getYield. They wrap this function.
 
Version getConsume (const NodeID l, const NodeID o) const
 Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
 
Version getYield (const NodeID l, const NodeID o) const
 Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
 
std::vector< Version > & getReliantVersions (const NodeID o, const Version v)
 Returns the versions of o which rely on o:v.
 
NodeBSgetStmtReliance (const NodeID o, const Version v)
 Returns the statements which rely on o:v.
 
void dumpReliances (void) const
 Dumps versionReliance and stmtReliance.
 
void dumpLocVersionMaps (void) const
 Dumps maps consume and yield.
 
void solveAndwritePtsToFile (const std::string &filename) override
 
void writeVersionedAnalysisResultToFile (const std::string &filename)
 
void readVersionedAnalysisResultFromFile (std::ifstream &F)
 
void readPtsFromFile (const std::string &filename) override
 
- Public Member Functions inherited from SVF::FlowSensitive
 FlowSensitive (SVFIR *_pag, PTATY type=PTATY::FSSPARSE_WPA)
 Constructor.
 
 ~FlowSensitive () override=default
 Destructor.
 
virtual bool runOnModule ()
 We start from here.
 
void analyze () override
 Flow sensitive analysis.
 
virtual void solveConstraints ()
 
SVFGgetSVFG () const
 Return SVFG.
 
- Public Member Functions inherited from SVF::WPAFSSolver< GraphType >
 WPAFSSolver ()
 Constructor.
 
virtual ~WPAFSSolver ()
 Destructor.
 
virtual NodeID sccRepNode (NodeID id) const
 SCC methods.
 
- 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 PointsTogetPts (NodeID id) override
 
const NodeSetgetRevPts (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 unionPts (NodeID id, const PointsTo &target)
 
virtual bool unionPts (NodeID id, NodeID ptd)
 
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
 
- Public Member Functions inherited from SVF::PointerAnalysis
ICFGgetICFG () const
 Get ICFG.
 
u32_t getNumOfResolvedIndCallEdge () const
 Return number of resolved indirect call edges.
 
CallGraphgetCallGraph () const
 Return call graph.
 
CallGraphSCCgetCallGraphSCC () 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.
 
CallEdgeMapgetIndCallMap ()
 Get callees from an indirect callsite.
 
bool hasIndCSCallees (const CallICFGNode *cs) const
 
const FunctionSetgetIndCSCallees (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.
 
CommonCHGraphgetCHGraph () 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.
 
SVFIRgetPAG () const
 
PTAStatgetStat () const
 Get PTA stat.
 
OrderedNodeSetgetAllValidPtrs ()
 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 NodeBSgetAllFieldsObjVars (NodeID id)
 
void setObjFieldInsensitive (NodeID id)
 
bool isFieldInsensitive (NodeID id) const
 

Static Public Member Functions

static VersionedVar atKey (NodeID, Version)
 Return key into vPtD for address-taken var of a specific version.
 
static bool classof (const VersionedFlowSensitive *)
 Methods to support type inquiry through isa, cast, and dyn_cast.
 
static bool classof (const PointerAnalysis *pta)
 
static VersionedFlowSensitivecreateVFSWPA (SVFIR *_pag)
 Create single instance of versioned flow-sensitive points-to analysis.
 
static void releaseVFSWPA ()
 Release flow-sensitive pointer analysis.
 
static void dumpMeldVersion (MeldVersion &v)
 Dumps a MeldVersion to stdout.
 
- Static Public Member Functions inherited from SVF::FlowSensitive
static FlowSensitivecreateFSWPA (SVFIR *_pag)
 Create single instance of flow-sensitive pointer analysis.
 
static void releaseFSWPA ()
 Release flow-sensitive pointer analysis.
 
static bool classof (const FlowSensitive *)
 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)
 

Static Public Attributes

static const Version invalidVersion = 0
 If this version appears, there has been an error.
 
- 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_"
 

Protected Member Functions

virtual bool processLoad (const LoadSVFGNode *load) override
 
virtual bool processStore (const StoreSVFGNode *store) override
 
virtual void processNode (NodeID n) override
 Handle various constraints.
 
virtual void updateConnectedNodes (const SVFGEdgeSetTy &newEdges) override
 Update nodes connected during updating call graph.
 
virtual bool propAlongIndirectEdge (const IndirectSVFGEdge *) override
 Override to do nothing. Instead, we will use propagateVersion when necessary.
 
virtual void cluster (void) override
 Override since we want to assign different weights based on versioning.
 
- Protected Member Functions inherited from SVF::FlowSensitive
NodeStackSCCDetect () override
 SCC detection.
 
bool propFromSrcToDst (SVFGEdge *edge) override
 Propagation.
 
virtual bool propAlongDirectEdge (const DirectSVFGEdge *edge)
 Propagate points-to information along a DIRECT SVFG edge.
 
virtual bool propVarPtsFromSrcToDst (NodeID var, const SVFGNode *src, const SVFGNode *dst)
 Propagate points-to information of a certain variable from src to dst.
 
virtual bool propagateFromAPToFP (const ActualParmSVFGNode *ap, const SVFGNode *dst)
 
virtual bool propagateFromFRToAR (const FormalRetSVFGNode *fr, const SVFGNode *dst)
 
virtual bool weakUpdateOutFromIn (const SVFGNode *node)
 Handle weak updates.
 
virtual bool strongUpdateOutFromIn (const SVFGNode *node, NodeID singleton)
 Handle strong updates.
 
bool propVarPtsAfterCGUpdated (NodeID var, const SVFGNode *src, const SVFGNode *dst)
 
virtual bool propDFOutToIn (const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
 
virtual bool propDFInToIn (const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
 
bool updateOutFromIn (const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
 Update data-flow points-to data.
 
virtual bool updateInFromIn (const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
 
virtual bool updateInFromOut (const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
 
virtual bool unionPtsFromIn (const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
 
virtual bool unionPtsFromTop (const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
 
void clearAllDFOutVarFlag (const SVFGNode *stmt)
 
bool processSVFGNode (SVFGNode *node)
 
virtual bool processAddr (const AddrSVFGNode *addr)
 
virtual bool processCopy (const CopySVFGNode *copy)
 
virtual bool processPhi (const PHISVFGNode *phi)
 
virtual bool processGep (const GepSVFGNode *edge)
 
bool updateCallGraph (const CallSiteToFunPtrMap &callsites) override
 Update call graph.
 
void connectCallerAndCallee (const CallEdgeMap &newEdges, SVFGEdgeSetTy &edges)
 Connect nodes in SVFG.
 
bool isStrongUpdate (const SVFGNode *node, NodeID &singleton)
 Return TRUE if this is a strong update STORE statement.
 
virtual void countAliases (Set< std::pair< NodeID, NodeID > > cmp, unsigned *mayAliases, unsigned *noAliases)
 Fills may/noAliases for the location/pointer pairs in cmp.
 
const PointsTogetDFInPtsSet (const SVFGNode *stmt, const NodeID node)
 Get points-to set for a node from data flow IN/OUT set at a statement.
 
const PointsTogetDFOutPtsSet (const SVFGNode *stmt, const NodeID node)
 
virtual void plainMap (void) const
 Sets the global best mapping as a plain mapping, i.e. n -> n.
 
void svfgStat ()
 
const DFInOutMapgetDFInputMap () const
 
const DFInOutMapgetDFOutputMap () const
 
- Protected Member Functions inherited from SVF::WPASolver< GraphType >
 WPASolver ()
 Constructor.
 
virtual ~WPASolver ()=default
 Destructor.
 
SCCgetSCCDetector () const
 Get SCC detector.
 
const GraphType graph ()
 Get/Set graph methods.
 
void setGraph (GraphType g)
 
virtual NodeStackSCCDetect (NodeSet &candidates)
 
virtual void initWorklist ()
 
virtual void solveWorklist ()
 
virtual void collapseFields ()
 collapse positive weight cycles of a graph
 
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)
 
GNODENode (NodeID id)
 Get node on the graph.
 
NodeID Node_Index (GNODE node)
 Get node ID.
 
- Protected Member Functions inherited from SVF::BVDataPTAImpl
PTDataTygetPTDataTy () const
 Get points-to data structure.
 
DiffPTDataTygetDiffPTDataTy () const
 
DFPTDataTygetDFPTDataTy () const
 
MutDFPTDataTygetMutDFPTDataTy () const
 
VersionedPTDataTygetVersionedPTDataTy () 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.
 
virtual void normalizePointsTo ()
 
- Protected Member Functions inherited from SVF::PointerAnalysis
const CallSiteToFunPtrMapgetIndirectCallsites () 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 validateSuccessTests (std::string fun)
 
virtual void validateExpectedFailureTests (std::string fun)
 
void resetObjFieldSensitive ()
 Reset all object node as field-sensitive.
 

Private Types

typedef CoreBitVector MeldVersion
 

Private Member Functions

void prelabel (void)
 Prelabel the SVFG: set y(o) for stores and c(o) for delta nodes to a new version.
 
void meldLabel (void)
 Meld label the prelabeled SVFG.
 
void removeAllIndirectSVFGEdges (void)
 Removes all indirect edges in the SVFG.
 
void propagateVersion (NodeID o, Version v)
 
void propagateVersion (const NodeID o, const Version v, const Version vp, bool time=true)
 
virtual void buildIsStoreLoadMaps (void)
 Fills in isStoreMap and isLoadMap.
 
virtual void buildDeltaMaps (void)
 Fills in deltaMap and deltaSourceMap for the SVFG.
 
virtual bool delta (const NodeID l) const
 
virtual bool deltaSource (const NodeID l) const
 
void setVersion (const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm)
 Shared code for setConsume and setYield. They wrap this function.
 
void setConsume (const NodeID l, const NodeID o, const Version v)
 Sets the consumed version of o at l to v.
 
void setYield (const NodeID l, const NodeID o, const Version v)
 Sets the yielded version of o at l to v.
 

Static Private Member Functions

static bool meld (MeldVersion &mv1, const MeldVersion &mv2)
 Melds v2 into v1 (in place), returns whether a change occurred.
 

Private Attributes

LocVersionMap consume
 
LocVersionMap yield
 Actual yield map. Yield analogue to consume.
 
VersionRelianceMap versionReliance
 o -> (version -> versions which rely on it).
 
Map< NodeID, Map< Version, NodeBS > > stmtReliance
 o x version -> statement nodes which rely on that o/version.
 
VarToPropNodeMap versionedVarToPropNode
 
Map< NodeID, NodeIDequivalentObject
 
FIFOWorkList< NodeIDvWorklist
 
Set< NodeIDprelabeledObjects
 
BVDataPTAImpl::VersionedPTDataTyvPtD
 Points-to DS for working with versions.
 
std::vector< booldeltaMap
 
std::vector< booldeltaSourceMap
 
std::vector< boolisStoreMap
 isStoreMap[l] means SVFG node l is a store node.
 
std::vector< boolisLoadMap
 isLoadMap[l] means SVFG node l is a load node.
 
u32_t numPrelabeledNodes
 Additional statistics.
 
u32_t numPrelabelVersions
 Number of versions created during prelabeling.
 
double prelabelingTime
 Time to prelabel SVFG.
 
double meldLabelingTime
 Time to meld label SVFG.
 
double versionPropTime
 Time to propagate versions to versions which rely on them.
 

Static Private Attributes

static VersionedFlowSensitivevfspta = nullptr
 

Friends

class VersionedFlowSensitiveStat
 

Additional Inherited Members

- Public Attributes inherited from SVF::WPASolver< GraphType >
u32_t numOfIteration
 num of iterations during constraint solving
 
- Protected Types inherited from SVF::FlowSensitive
typedef SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
 
- Protected Attributes inherited from SVF::FlowSensitive
SVFGsvfg
 
SVFGBuilder memSSA
 
AndersenWaveDiffander
 
std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > candidateMappings
 Save candidate mappings for evaluation's sake.
 
u32_t numOfProcessedAddr
 Statistics.
 
u32_t numOfProcessedCopy
 Number of processed Addr node.
 
u32_t numOfProcessedGep
 Number of processed Copy node.
 
u32_t numOfProcessedPhi
 Number of processed Gep node.
 
u32_t numOfProcessedLoad
 Number of processed Phi node.
 
u32_t numOfProcessedStore
 Number of processed Load node.
 
u32_t numOfProcessedActualParam
 Number of processed Store node.
 
u32_t numOfProcessedFormalRet
 Number of processed actual param node.
 
u32_t numOfProcessedMSSANode
 Number of processed formal ret node.
 
u32_t maxSCCSize
 Number of processed mssa node.
 
u32_t numOfSCC
 
u32_t numOfNodesInSCC
 
double solveTime
 time of solve.
 
double sccTime
 time of SCC detection.
 
double processTime
 time of processNode.
 
double propagationTime
 time of points-to propagation.
 
double directPropaTime
 time of points-to propagation of address-taken objects
 
double indirectPropaTime
 time of points-to propagation of top-level pointers
 
double updateTime
 time of strong/weak updates.
 
double addrTime
 time of handling address edges
 
double copyTime
 time of handling copy edges
 
double gepTime
 time of handling gep edges
 
double loadTime
 time of load edges
 
double storeTime
 time of store edges
 
double phiTime
 time of phi nodes.
 
double updateCallGraphTime
 time of updating call graph
 
NodeBS svfgHasSU
 
- Protected Attributes inherited from SVF::WPAFSSolver< GraphType >
NodeStack nodeStack
 stack used for processing nodes.
 
- 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< SCCscc
 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.
 
PTAStatstat
 Statistics.
 
CallGraphcallgraph
 Call graph used for pointer analysis.
 
CallGraphSCCcallGraphSCC
 SCC for PTACallGraph.
 
ICFGicfg
 Interprocedural control-flow graph.
 
CommonCHGraphchgraph
 CHGraph.
 
- Static Protected Attributes inherited from SVF::FlowSensitive
static std::unique_ptr< FlowSensitivefspta
 
- Static Protected Attributes inherited from SVF::PointerAnalysis
static SVFIRpag = nullptr
 SVFIR.
 

Detailed Description

Versioned flow sensitive whole program pointer analysis

Definition at line 32 of file VersionedFlowSensitive.h.

Member Typedef Documentation

◆ LocVersionMap

Definition at line 43 of file VersionedFlowSensitive.h.

◆ MeldVersion

Definition at line 37 of file VersionedFlowSensitive.h.

◆ ObjToVersionMap

Definition at line 40 of file VersionedFlowSensitive.h.

◆ VarToPropNodeMap

Definition at line 41 of file VersionedFlowSensitive.h.

◆ VersionRelianceMap

(o -> (v -> versions with rely on o:v).

Definition at line 45 of file VersionedFlowSensitive.h.

Constructor & Destructor Documentation

◆ VersionedFlowSensitive()

VersionedFlowSensitive::VersionedFlowSensitive ( SVFIR _pag,
PTATY  type = PTATY::VFS_WPA 
)

Constructor.

Definition at line 31 of file VersionedFlowSensitive.cpp.

32 : FlowSensitive(_pag, type)
33{
36 // We'll grab vPtD in initialize.
37
38 for (SVFIR::const_iterator it = pag->begin(); it != pag->end(); ++it)
39 {
40 if (SVFUtil::isa<ObjVar>(it->second)) equivalentObject[it->first] = it->first;
41 }
42
43 assert(!Options::OPTSVFG() && "VFS: -opt-svfg not currently supported with VFS.");
44}
newitem type
Definition cJSON.cpp:2739
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
static Option< bool > OPTSVFG
Definition Options.h:146
static SVFIR * pag
SVFIR.
u32_t numPrelabelVersions
Number of versions created during prelabeling.
Map< NodeID, NodeID > equivalentObject
double meldLabelingTime
Time to meld label SVFG.
double prelabelingTime
Time to prelabel SVFG.
double versionPropTime
Time to propagate versions to versions which rely on them.
u32_t numPrelabeledNodes
Additional statistics.
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

Member Function Documentation

◆ atKey()

VersionedVar VersionedFlowSensitive::atKey ( NodeID  var,
Version  version 
)
static

Return key into vPtD for address-taken var of a specific version.

Definition at line 25 of file VersionedFlowSensitive.cpp.

26{
27 assert(version != invalidVersion && "VersionedFlowSensitive::atKey: trying to use an invalid version!");
28 return std::make_pair(var, version);
29}
static const Version invalidVersion
If this version appears, there has been an error.

◆ buildDeltaMaps()

void VersionedFlowSensitive::buildDeltaMaps ( void  )
privatevirtual

Fills in deltaMap and deltaSourceMap for the SVFG.

use pre-analysis call graph to approximate all potential callsites

Definition at line 468 of file VersionedFlowSensitive.cpp.

469{
470 deltaMap.resize(svfg->getTotalNodeNum(), false);
471
472 // Call block nodes corresponding to all delta nodes.
474
475 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
476 {
477 const NodeID l = it->first;
478 const SVFGNode *s = it->second;
479
480 // Cases:
481 // * Function entry: can get new incoming indirect edges through ind. callsites.
482 // * Callsite returns: can get new incoming indirect edges if the callsite is indirect.
483 // * Otherwise: static.
484 bool isDelta = false;
485 if (const FunObjVar *fn = svfg->isFunEntrySVFGNode(s))
486 {
490 isDelta = !callsites.empty();
491
492 if (isDelta)
493 {
494 // TODO: could we use deltaCBNs in the call above, avoiding this loop?
495 for (const CallICFGNode *cbn : callsites) deltaCBNs.insert(cbn);
496 }
497 }
498 else if (const CallICFGNode *cbn = svfg->isCallSiteRetSVFGNode(s))
499 {
500 isDelta = cbn->isIndirectCall();
501 if (isDelta) deltaCBNs.insert(cbn);
502 }
503
504 deltaMap[l] = isDelta;
505 }
506
507 deltaSourceMap.resize(svfg->getTotalNodeNum(), false);
508
509 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
510 {
511 const NodeID l = it->first;
512 const SVFGNode *s = it->second;
513
514 if (const CallICFGNode *cbn = SVFUtil::dyn_cast<CallICFGNode>(s->getICFGNode()))
515 {
516 if (deltaCBNs.find(cbn) != deltaCBNs.end()) deltaSourceMap[l] = true;
517 }
518
519 // TODO: this is an over-approximation but it sound, marking every formal out as
520 // a delta-source.
521 if (SVFUtil::isa<FormalOUTSVFGNode>(s)) deltaSourceMap[l] = true;
522 }
523}
Set< const CallICFGNode * > CallInstSet
Definition CallGraph.h:55
void getIndCallSitesInvokingCallee(const FunObjVar *callee, CallGraphEdge::CallInstSet &csSet)
AndersenWaveDiff * ander
u32_t getTotalNodeNum() const
Get total number of node/edge.
CallGraph * getCallGraph() const
Return call graph.
const CallICFGNode * isCallSiteRetSVFGNode(const SVFGNode *node) const
Whether a node is callsite return SVFGNode.
Definition SVFG.cpp:732
const FunObjVar * isFunEntrySVFGNode(const SVFGNode *node) const
Whether a node is function entry SVFGNode.
Definition SVFG.cpp:706
u32_t NodeID
Definition GeneralType.h:56

◆ buildIsStoreLoadMaps()

void VersionedFlowSensitive::buildIsStoreLoadMaps ( void  )
privatevirtual

Fills in isStoreMap and isLoadMap.

Definition at line 445 of file VersionedFlowSensitive.cpp.

446{
447 isStoreMap.resize(svfg->getTotalNodeNum(), false);
448 isLoadMap.resize(svfg->getTotalNodeNum(), false);
449 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
450 {
451 if (SVFUtil::isa<StoreSVFGNode>(it->second)) isStoreMap[it->first] = true;
452 else if (SVFUtil::isa<LoadSVFGNode>(it->second)) isLoadMap[it->first] = true;
453 }
454}
std::vector< bool > isStoreMap
isStoreMap[l] means SVFG node l is a store node.
std::vector< bool > isLoadMap
isLoadMap[l] means SVFG node l is a load node.

◆ classof() [1/2]

static bool SVF::VersionedFlowSensitive::classof ( const PointerAnalysis pta)
inlinestatic

Definition at line 74 of file VersionedFlowSensitive.h.

75 {
76 return pta->getAnalysisTy() == PTATY::VFS_WPA;
77 }
@ VFS_WPA
Versioned sparse flow-sensitive WPA.
Definition PTATY.h:21

◆ classof() [2/2]

static bool SVF::VersionedFlowSensitive::classof ( const VersionedFlowSensitive )
inlinestatic

Methods to support type inquiry through isa, cast, and dyn_cast.

Definition at line 70 of file VersionedFlowSensitive.h.

71 {
72 return true;
73 }

◆ cluster()

void VersionedFlowSensitive::cluster ( void  )
overrideprotectedvirtual

Override since we want to assign different weights based on versioning.

Reimplemented from SVF::FlowSensitive.

Definition at line 781 of file VersionedFlowSensitive.cpp.

782{
783 std::vector<std::pair<unsigned, unsigned>> keys;
784 for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit)
785 {
786 unsigned occ = 1;
787 //ABTest
788 unsigned v = pit->first;
789 if (Options::PredictPtOcc() && pag->getBaseObject(v) != nullptr) occ = stmtReliance[v].size() + 1;
790 assert(occ != 0);
791 keys.push_back(std::make_pair(v, occ));
792 }
793
794 PointsTo::MappingPtr nodeMapping =
795 std::make_shared<std::vector<NodeID>>(
797 );
798 PointsTo::MappingPtr reverseNodeMapping =
799 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
800
801 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
802}
std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > candidateMappings
Save candidate mappings for evaluation's sake.
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< bool > PredictPtOcc
Definition Options.h:63
bool print_stat
User input flags.
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:42
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:371
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:496
Map< NodeID, Map< Version, NodeBS > > stmtReliance
o x version -> statement nodes which rely on that o/version.

◆ createVFSWPA()

static VersionedFlowSensitive * SVF::VersionedFlowSensitive::createVFSWPA ( SVFIR _pag)
inlinestatic

Create single instance of versioned flow-sensitive points-to analysis.

Definition at line 81 of file VersionedFlowSensitive.h.

82 {
83 if (vfspta == nullptr)
84 {
86 vfspta->analyze();
87 }
88
89 return vfspta;
90 }
void analyze() override
Flow sensitive analysis.
static VersionedFlowSensitive * vfspta
VersionedFlowSensitive(SVFIR *_pag, PTATY type=PTATY::VFS_WPA)
Constructor.

◆ delta()

bool VersionedFlowSensitive::delta ( const NodeID  l) const
privatevirtual

Returns true if l is a delta node, i.e., may get a new incoming indirect edge due to on-the-fly callgraph construction.

Definition at line 433 of file VersionedFlowSensitive.cpp.

434{
435 assert(l < deltaMap.size() && "VFS::delta: deltaMap is missing SVFG nodes!");
436 return deltaMap[l];
437}

◆ deltaSource()

bool VersionedFlowSensitive::deltaSource ( const NodeID  l) const
privatevirtual

Returns true if l is a delta-source node, i.e., may get a new outgoing indirect edge to a delta node due to on-the-fly callgraph construction.

Definition at line 439 of file VersionedFlowSensitive.cpp.

440{
441 assert(l < deltaSourceMap.size() && "VFS::delta: deltaSourceMap is missing SVFG nodes!");
442 return deltaSourceMap[l];
443}

◆ dumpLocVersionMaps()

void VersionedFlowSensitive::dumpLocVersionMaps ( void  ) const

Dumps maps consume and yield.

Definition at line 911 of file VersionedFlowSensitive.cpp.

912{
913 SVFUtil::outs() << "# LocVersion Maps\n";
914 for (SVFG::iterator it = svfg->begin(); it != svfg->end(); ++it)
915 {
916 const NodeID loc = it->first;
917 bool locPrinted = false;
918 for (const LocVersionMap *lvm :
919 {
920 &consume, &yield
921 })
922 {
923 if (lvm->at(loc).empty()) continue;
924 if (!locPrinted)
925 {
926 SVFUtil::outs() << " " << "SVFG node " << loc << "\n";
927 locPrinted = true;
928 }
929
930 SVFUtil::outs() << " " << (lvm == &consume ? "Consume " : "Yield ") << ": ";
931
932 bool first = true;
933 for (const ObjToVersionMap::value_type &ov : lvm->at(loc))
934 {
935 const NodeID o = ov.first;
936 const Version v = ov.second;
937 SVFUtil::outs() << (first ? "" : ", ") << "<" << o << ", " << v << ">";
938 first = false;
939 }
940
941 SVFUtil::outs() << "\n";
942 }
943 }
944
945}
LocVersionMap yield
Actual yield map. Yield analogue to consume.
std::vector< ObjToVersionMap > LocVersionMap
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
unsigned Version

◆ dumpMeldVersion()

void VersionedFlowSensitive::dumpMeldVersion ( MeldVersion v)
static

Dumps a MeldVersion to stdout.

Definition at line 947 of file VersionedFlowSensitive.cpp.

948{
949 SVFUtil::outs() << "[ ";
950 bool first = true;
951 for (unsigned e : v)
952 {
953 if (!first)
954 {
955 SVFUtil::outs() << ", ";
956 }
957
958 SVFUtil::outs() << e;
959 first = false;
960 }
961
962 SVFUtil::outs() << " ]";
963}

◆ dumpReliances()

void VersionedFlowSensitive::dumpReliances ( void  ) const

Dumps versionReliance and stmtReliance.

Definition at line 854 of file VersionedFlowSensitive.cpp.

855{
856 SVFUtil::outs() << "# Version reliances\n";
857 for (const Map<NodeID, Map<Version, std::vector<Version>>>::value_type &ovrv : versionReliance)
858 {
859 NodeID o = ovrv.first;
860 SVFUtil::outs() << " Object " << o << "\n";
861 for (const Map<Version, std::vector<Version>>::value_type& vrv : ovrv.second)
862 {
863 Version v = vrv.first;
864 SVFUtil::outs() << " Version " << v << " is a reliance for: ";
865
866 bool first = true;
867 for (Version rv : vrv.second)
868 {
869 if (!first)
870 {
871 SVFUtil::outs() << ", ";
872 }
873
874 SVFUtil::outs() << rv;
875 first = false;
876 }
877
878 SVFUtil::outs() << "\n";
879 }
880 }
881
882 SVFUtil::outs() << "# Statement reliances\n";
883 for (const Map<NodeID, Map<Version, NodeBS>>::value_type &ovss : stmtReliance)
884 {
885 NodeID o = ovss.first;
886 SVFUtil::outs() << " Object " << o << "\n";
887
889 {
890 Version v = vss.first;
891 SVFUtil::outs() << " Version " << v << " is a reliance for statements: ";
892
893 const NodeBS &ss = vss.second;
894 bool first = true;
895 for (NodeID s : ss)
896 {
897 if (!first)
898 {
899 SVFUtil::outs() << ", ";
900 }
901
902 SVFUtil::outs() << s;
903 first = false;
904 }
905
906 SVFUtil::outs() << "\n";
907 }
908 }
909}
VersionRelianceMap versionReliance
o -> (version -> versions which rely on it).
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map

◆ finalize()

void VersionedFlowSensitive::finalize ( )
overridevirtual

Finalize analysis.

Reimplemented from SVF::FlowSensitive.

Definition at line 66 of file VersionedFlowSensitive.cpp.

67{
69 // vPtD->dumpPTData();
70 // dumpReliances();
71 // dumpLocVersionMaps();
72}
void finalize() override
Finalize analysis.

◆ getConsume()

Version VersionedFlowSensitive::getConsume ( const NodeID  l,
const NodeID  o 
) const

Returns the consumed version of o at l. If no such version exists, returns invalidVersion.

Definition at line 814 of file VersionedFlowSensitive.cpp.

815{
816 return getVersion(l, o, consume);
817}
Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const
Shared code for getConsume and getYield. They wrap this function.

◆ getReliantVersions()

std::vector< Version > & VersionedFlowSensitive::getReliantVersions ( const NodeID  o,
const Version  v 
)

Returns the versions of o which rely on o:v.

Definition at line 844 of file VersionedFlowSensitive.cpp.

845{
846 return versionReliance[o][v];
847}

◆ getStmtReliance()

NodeBS & VersionedFlowSensitive::getStmtReliance ( const NodeID  o,
const Version  v 
)

Returns the statements which rely on o:v.

Definition at line 849 of file VersionedFlowSensitive.cpp.

850{
851 return stmtReliance[o][v];
852}

◆ getVersion()

Version VersionedFlowSensitive::getVersion ( const NodeID  l,
const NodeID  o,
const LocVersionMap lvm 
) const

Shared code for getConsume and getYield. They wrap this function.

Definition at line 804 of file VersionedFlowSensitive.cpp.

805{
807 const NodeID op = canonObjectIt == equivalentObject.end() ? o : canonObjectIt->second;
808
809 const ObjToVersionMap &ovm = lvm[l];
810 const ObjToVersionMap::const_iterator foundVersion = ovm.find(op);
811 return foundVersion == ovm.end() ? invalidVersion : foundVersion->second;
812}
Map< NodeID, Version > ObjToVersionMap

◆ getYield()

Version VersionedFlowSensitive::getYield ( const NodeID  l,
const NodeID  o 
) const

Returns the yielded version of o at l. If no such version exists, returns invalidVersion.

Definition at line 819 of file VersionedFlowSensitive.cpp.

820{
821 // Non-store: consume == yield.
822 if (isStore(l)) return getVersion(l, o, yield);
823 else return getVersion(l, o, consume);
824}
virtual bool isStore(const NodeID l) const
Returns true if l is a store node.

◆ initialize()

void VersionedFlowSensitive::initialize ( )
overridevirtual

Initialize analysis.

Reimplemented from SVF::FlowSensitive.

Definition at line 46 of file VersionedFlowSensitive.cpp.

47{
49 // Overwrite the stat FlowSensitive::initialize gave us.
50 delete stat;
52
54
57 consume.resize(svfg->getTotalNodeNum());
58 yield.resize(svfg->getTotalNodeNum());
59
60 prelabel();
61 meldLabel();
62
64}
VersionedPTDataTy * getVersionedPTDataTy() const
void initialize() override
Initialize analysis.
PTAStat * stat
Statistics.
BVDataPTAImpl::VersionedPTDataTy * vPtD
Points-to DS for working with versions.
void removeAllIndirectSVFGEdges(void)
Removes all indirect edges in the SVFG.
virtual void buildDeltaMaps(void)
Fills in deltaMap and deltaSourceMap for the SVFG.
void prelabel(void)
Prelabel the SVFG: set y(o) for stores and c(o) for delta nodes to a new version.
virtual void buildIsStoreLoadMaps(void)
Fills in isStoreMap and isLoadMap.
void meldLabel(void)
Meld label the prelabeled SVFG.

◆ isLoad()

bool VersionedFlowSensitive::isLoad ( const NodeID  l) const
virtual

Returns true if l is a load node.

Definition at line 462 of file VersionedFlowSensitive.cpp.

463{
464 assert(l < isLoadMap.size() && "VFS::isLoad: isLoadMap is missing SVFG nodes!");
465 return isLoadMap[l];
466}

◆ isStore()

bool VersionedFlowSensitive::isStore ( const NodeID  l) const
virtual

Returns true if l is a store node.

Definition at line 456 of file VersionedFlowSensitive.cpp.

457{
458 assert(l < isStoreMap.size() && "VFS::isStore: isStoreMap is missing SVFG nodes!");
459 return isStoreMap[l];
460}

◆ meld()

bool VersionedFlowSensitive::meld ( MeldVersion mv1,
const MeldVersion mv2 
)
staticprivate

Melds v2 into v1 (in place), returns whether a change occurred.

Definition at line 427 of file VersionedFlowSensitive.cpp.

428{
429 // Meld operator is union of bit vectors.
430 return mv1 |= mv2;
431}

◆ meldLabel()

void VersionedFlowSensitive::meldLabel ( void  )
private

Meld label the prelabeled SVFG.

Definition at line 121 of file VersionedFlowSensitive.cpp.

122{
123 double start = stat->getClk(true);
124
125 assert(Options::VersioningThreads() > 0 && "VFS::meldLabel: number of versioning threads must be > 0!");
126
127 // Nodes which have at least one object on them given a prelabel + the Andersen's points-to
128 // set of interest so we don't keep calling getPts. For Store nodes, we'll fill that in, for
129 // MR nodes, we won't as its getPointsTo is cheap.
130 // TODO: preferably we cache both for ease and to avoid the dyn_cast/isa, but Andersen's points-to
131 // sets are PointsTo and MR's sets are NodeBS, which are incompatible types. Maybe when we can
132 // use std::option.
133 std::vector<std::pair<const SVFGNode *, const PointsTo *>> prelabeledNodes;
134 // Fast query for the above.
135 std::vector<bool> isPrelabeled(svfg->getTotalNodeNum(), false);
136 while (!vWorklist.empty())
137 {
138 const NodeID n = vWorklist.pop();
139 isPrelabeled[n] = true;
140
141 const SVFGNode *sn = svfg->getSVFGNode(n);
142 const PointsTo *nPts = nullptr;
143 if (const StoreSVFGNode *store = SVFUtil::dyn_cast<StoreSVFGNode>(sn))
144 {
145 const NodeID p = store->getDstNodeID();
146 nPts = &(this->ander->getPts(p));
147 }
148
149 prelabeledNodes.push_back(std::make_pair(sn, nPts));
150 }
151
152 // Delta, delta source, store, and load nodes, which require versions during
153 // solving, unlike other nodes with which we can make do with the reliance map.
154 std::vector<NodeID> nodesWhichNeedVersions;
155 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
156 {
157 const NodeID n = it->first;
158 if (delta(n) || deltaSource(n) || isStore(n) || isLoad(n)) nodesWhichNeedVersions.push_back(n);
159 }
160
161 std::mutex *versionMutexes = new std::mutex[nodesWhichNeedVersions.size()];
162
163 // Map of footprints to the canonical object "owning" the footprint.
165
166 std::queue<NodeID> objectQueue;
167 for (const NodeID o : prelabeledObjects)
168 {
169 // "Touch" maps with o so we don't need to lock on them.
172 objectQueue.push(o);
173 }
174
175 std::mutex objectQueueMutex;
176 std::mutex footprintOwnerMutex;
177
181 (const unsigned thread)
182 {
183 while (true)
184 {
185 NodeID o;
186 {
187 std::lock_guard<std::mutex> guard(objectQueueMutex);
188 // No more objects? Done.
189 if (objectQueue.empty()) return;
190 o = objectQueue.front();
191 objectQueue.pop();
192 }
193
194 // 1. Compute the SCCs for the nodes on the graph overlay of o.
195 // For starting nodes, we only need those which did prelabeling for o specifically.
196 // TODO: maybe we should move this to prelabel with a map (o -> starting nodes).
197 std::vector<const SVFGNode *> osStartingNodes;
198 for (std::pair<const SVFGNode *, const PointsTo *> snPts : prelabeledNodes)
199 {
200 const SVFGNode *sn = snPts.first;
201 const PointsTo *pts = snPts.second;
202 if (pts != nullptr)
203 {
204 if (pts->test(o)) osStartingNodes.push_back(sn);
205 }
206 else if (const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(sn))
207 {
208 if (mr->getPointsTo().test(o)) osStartingNodes.push_back(sn);
209 }
210 else
211 {
212 assert(false && "VFS::meldLabel: unexpected prelabeled node!");
213 }
214 }
215
216 std::vector<int> partOf;
217 std::vector<const IndirectSVFGEdge *> footprint;
218 unsigned numSCCs = SCC::detectSCCs(this, this->svfg, o, osStartingNodes, partOf, footprint);
219
220 // 2. Skip any further processing of a footprint we have seen before.
221 {
222 std::lock_guard<std::mutex> guard(footprintOwnerMutex);
225 if (canonOwner == footprintOwner.end())
226 {
227 this->equivalentObject[o] = o;
228 footprintOwner[footprint] = o;
229 }
230 else
231 {
232 this->equivalentObject[o] = canonOwner->second;
233 // Same version and stmt reliance as the canonical. During solving we cannot just reuse
234 // the canonical object's reliance because it may change due to on-the-fly call graph
235 // construction. Something like copy-on-write could be good... probably negligible.
236 this->versionReliance.at(o) = this->versionReliance.at(canonOwner->second);
237 this->stmtReliance.at(o) = this->stmtReliance.at(canonOwner->second);
238 continue;
239 }
240 }
241
242 // 3. a. Initialise the MeldVersion of prelabeled nodes (SCCs).
243 // b. Initialise a todo list of all the nodes we need to version,
244 // sorted according to topological order.
245 // We will use a map of sccs to meld versions for what is consumed.
246 std::vector<MeldVersion> sccToMeldVersion(numSCCs);
247 // At stores, what is consumed is different to what is yielded, so we
248 // maintain that separately.
250 // SVFG nodes of interest -- those part of an SCC from the starting nodes.
251 std::vector<NodeID> todoList;
252 unsigned bit = 0;
253 // To calculate reachable nodes, we can see what nodes n exist where
254 // partOf[n] != -1. Since the SVFG can be large this can be expensive.
255 // Instead, we can gather this from the edges in the footprint and
256 // the starting nodes (incase such nodes have no edges).
257 // TODO: should be able to do this better: too many redundant inserts.
259 for (const SVFGNode *sn : osStartingNodes) reachableNodes.insert(sn->getId());
260 for (const SVFGEdge *se : footprint)
261 {
262 reachableNodes.insert(se->getSrcNode()->getId());
263 reachableNodes.insert(se->getDstNode()->getId());
264 }
265
266 for (const NodeID n : reachableNodes)
267 {
268 if (isPrelabeled[n])
269 {
270 if (this->isStore(n)) storesYieldedMeldVersion[n].set(bit);
271 else sccToMeldVersion[partOf[n]].set(bit);
272 ++bit;
273 }
274
275 todoList.push_back(n);
276 }
277
278 // Sort topologically so each nodes is only visited once.
279 auto cmp = [&partOf](const NodeID a, const NodeID b)
280 {
281 return partOf[a] > partOf[b];
282 };
283 std::sort(todoList.begin(), todoList.end(), cmp);
284
285 // 4. a. Do meld versioning.
286 // b. Determine SCC reliances.
287 // c. Build a footprint for o (all edges which it is found on).
288 // d. Determine which SCCs belong to stores.
289
290 // sccReliance[x] = { y_1, y_2, ... } if there exists an edge from a node
291 // in SCC x to SCC y_i.
292 std::vector<Set<int>> sccReliance(numSCCs);
293 // Maps SCC to the store it corresponds to or -1 if it doesn't. TODO: unsigned vs signed -- nasty.
294 std::vector<int> storeSCC(numSCCs, -1);
295 for (size_t i = 0; i < todoList.size(); ++i)
296 {
297 const NodeID n = todoList[i];
298 const SVFGNode *sn = this->svfg->getSVFGNode(n);
299 const bool nIsStore = this->isStore(n);
300
301 int nSCC = partOf[n];
302 if (nIsStore) storeSCC[nSCC] = n;
303
304 // Given n -> m, the yielded version of n will be melded into m.
305 // For stores, that is in storesYieldedMeldVersion, otherwise, consume == yield and
306 // we can just use sccToMeldVersion.
308 for (const SVFGEdge *e : sn->getOutEdges())
309 {
310 const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
311 if (!ie) continue;
312
313 const NodeID m = ie->getDstNode()->getId();
314 // Ignoreedges which don't involve o.
315 if (!ie->getPointsTo().test(o)) continue;
316
317 int mSCC = partOf[m];
318
319 // There is an edge from the SCC n belongs to that m belongs to.
320 sccReliance[nSCC].insert(mSCC);
321
322 // Ignore edges to delta nodes (prelabeled consume).
323 // No point propagating when n's SCC == m's SCC (same meld version there)
324 // except when it is a store, because we are actually propagating n's yielded
325 // into m's consumed. Store nodes are in their own SCCs, so it is a self
326 // loop on a store node.
327 if (!this->delta(m) && (nSCC != mSCC || nIsStore))
328 {
330 }
331 }
332 }
333
334 // 5. Transform meld versions belonging to SCCs into versions.
336 std::vector<Version> sccToVersion(numSCCs, invalidVersion);
338 for (u32_t scc = 0; scc < sccToMeldVersion.size(); ++scc)
339 {
342 Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
343 sccToVersion[scc] = v;
344 }
345
346 sccToMeldVersion.clear();
347
348 // Same for storesYieldedMeldVersion.
350 for (auto const& nmv : storesYieldedMeldVersion)
351 {
352 const NodeID n = nmv.first;
353 const MeldVersion &mv = nmv.second;
354
356 Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
358 }
359
361
362 mvv.clear();
363
364 // 6. From SCC reliance, determine version reliances.
366 for (u32_t scc = 0; scc < numSCCs; ++scc)
367 {
368 if (sccReliance[scc].empty()) continue;
369
370 // Some consume relies on a yield. When it's a store, we need to pick whether to
371 // use the consume or yield unlike when it is not because they are the same.
372 const Version version
374
375 std::vector<Version> &reliantVersions = osVersionReliance[version];
376 for (const int reliantSCC : sccReliance[scc])
377 {
379 if (version != reliantVersion)
380 {
381 // sccReliance is a set, no need to worry about duplicates.
383 }
384 }
385 }
386
387 // 7. a. Save versions for nodes which need them.
388 // b. Fill in stmtReliance.
389 // TODO: maybe randomize iteration order for less contention? Needs profiling.
391 for (size_t i = 0; i < nodesWhichNeedVersions.size(); ++i)
392 {
394 std::mutex &mutex = versionMutexes[i];
395
396 const int scc = partOf[n];
397 if (scc == -1) continue;
398
399 std::lock_guard<std::mutex> guard(mutex);
400
401 const Version c = sccToVersion[scc];
402 if (c != invalidVersion)
403 {
404 this->setConsume(n, o, c);
405 if (this->isStore(n) || this->isLoad(n)) osStmtReliance[c].set(n);
406 }
407
408 if (this->isStore(n))
409 {
411 if (yIt != storesYieldedVersion.end()) this->setYield(n, o, yIt->second);
412 }
413 }
414 }
415 };
416
417 std::vector<std::thread> workers;
418 for (unsigned i = 0; i < Options::VersioningThreads(); ++i) workers.push_back(std::thread(meldVersionWorker, i));
419 for (std::thread &worker : workers) worker.join();
420
421 delete[] versionMutexes;
422
423 double end = stat->getClk(true);
425}
unsigned u32_t
Definition CommandLine.h:18
#define TIMEINTERVAL
Definition SVFType.h:621
cJSON * p
Definition cJSON.cpp:2559
cJSON * a
Definition cJSON.cpp:2560
cJSON * n
Definition cJSON.cpp:2558
const cJSON *const b
Definition cJSON.h:255
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition Andersen.h:239
const_iterator end(void) const
bool empty() const
Definition WorkList.h:161
static const Option< u32_t > VersioningThreads
Number of threads for the versioning phase.
Definition Options.h:75
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
virtual bool deltaSource(const NodeID l) const
virtual bool isLoad(const NodeID l) const
Returns true if l is a load node.
virtual bool delta(const NodeID l) const
void setConsume(const NodeID l, const NodeID o, const Version v)
Sets the consumed version of o at l to v.
void setYield(const NodeID l, const NodeID o, const Version v)
Sets the yielded version of o at l to v.
std::unique_ptr< SCC > scc
SCC.
Definition WPASolver.h:193

◆ prelabel()

void VersionedFlowSensitive::prelabel ( void  )
private

Prelabel the SVFG: set y(o) for stores and c(o) for delta nodes to a new version.

Definition at line 74 of file VersionedFlowSensitive.cpp.

75{
76 double start = stat->getClk(true);
77 for (SVFG::iterator it = svfg->begin(); it != svfg->end(); ++it)
78 {
79 NodeID l = it->first;
80 const SVFGNode *ln = it->second;
81
82 if (const StoreSVFGNode *stn = SVFUtil::dyn_cast<StoreSVFGNode>(ln))
83 {
84 // l: *p = q.
85 // If p points to o (Andersen's), l yields a new version for o.
86 NodeID p = stn->getDstNodeID();
87 for (NodeID o : ander->getPts(p))
88 {
89 prelabeledObjects.insert(o);
90 }
91
93
94 if (ander->getPts(p).count() != 0) ++numPrelabeledNodes;
95 }
96 else if (delta(l))
97 {
98 // The outgoing edges are not only what will later be propagated. SVFGOPT may
99 // move around nodes such that there can be an MRSVFGNode with no incoming or
100 // outgoing edges which will be added at runtime. In essence, we can no
101 // longer rely on the outgoing edges of a delta node when SVFGOPT is enabled.
102 const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(ln);
103 if (mr != nullptr)
104 {
105 for (const NodeID o : mr->getPointsTo())
106 {
107 prelabeledObjects.insert(o);
108 }
109
110 // Push into worklist because its consume == its yield.
112 if (mr->getPointsTo().count() != 0) ++numPrelabeledNodes;
113 }
114 }
115 }
116
117 double end = stat->getClk(true);
119}
const PointsTo & getPts(NodeID id) override
bool push(const Data &data)
Definition WorkList.h:180
const NodeBS & getPointsTo() const
Return points-to of the MR.
Definition SVFGNode.h:52
u32_t count() const
Returns number of elements.
Definition PointsTo.cpp:111
unsigned count() const

◆ processLoad()

bool VersionedFlowSensitive::processLoad ( const LoadSVFGNode load)
overrideprotectedvirtual

Process load node

Foreach node \in src pts(dst) = union pts(node)

If o is a field-insensitive object, we should also get all field nodes' points-to sets and pass them to p.

If the ptd is a field-insensitive node, we should also get all field nodes' points-to sets and pass them to pagDst.

Reimplemented from SVF::FlowSensitive.

Definition at line 648 of file VersionedFlowSensitive.cpp.

649{
650 double start = stat->getClk();
651
652 bool changed = false;
653
654 // l: p = *q
655 NodeID l = load->getId();
656 NodeID p = load->getDstNodeID();
657 NodeID q = load->getSrcNodeID();
658
659 const PointsTo& qpt = getPts(q);
660 // p = *q, the type of p must be a pointer
661 if (load->getDstNode()->isPointer())
662 {
663 for (NodeID o : qpt)
664 {
665 if (pag->isConstantObj(o)) continue;
666
667 const Version c = getConsume(l, o);
668 if (c != invalidVersion && vPtD->unionPts(p, atKey(o, c)))
669 {
670 changed = true;
671 }
672
674 {
677 const NodeBS& fields = getAllFieldsObjVars(o);
678 for (NodeID of : fields)
679 {
680 const Version c = getConsume(l, of);
681 if (c != invalidVersion && vPtD->unionPts(p, atKey(of, c)))
682 {
683 changed = true;
684 }
685 }
686 }
687 }
688 }
689 double end = stat->getClk();
690 loadTime += (end - start) / TIMEINTERVAL;
691 return changed;
692}
double loadTime
time of load edges
const ValVar * getDstNode() const
Definition VFGNode.h:217
bool isFieldInsensitive(NodeID id) const
virtual const NodeBS & getAllFieldsObjVars(NodeID id)
bool isConstantObj(NodeID id) const
Definition SVFIR.h:540
NodeID getId() const
Get ID.
Definition SVFValue.h:161
virtual bool isPointer() const
Check if this variable represents a pointer.
NodeID getSrcNodeID() const
Definition VFGNode.h:152
NodeID getDstNodeID() const
Definition VFGNode.h:157
static VersionedVar atKey(NodeID, Version)
Return key into vPtD for address-taken var of a specific version.
Version getConsume(const NodeID l, const NodeID o) const
Returns the consumed version of o at l. If no such version exists, returns invalidVersion.

◆ processNode()

void VersionedFlowSensitive::processNode ( NodeID  nodeId)
overrideprotectedvirtual

Handle various constraints.

Process each SVFG node

Reimplemented from SVF::FlowSensitive.

Definition at line 591 of file VersionedFlowSensitive.cpp.

592{
594 // Handle DummyVersPropSVFGNode here so we don't have to override the long
595 // processSVFGNode. We also don't call propagate based on its result.
596 if (const DummyVersionPropSVFGNode *dvp = SVFUtil::dyn_cast<DummyVersionPropSVFGNode>(sn))
597 {
598 propagateVersion(dvp->getObject(), dvp->getVersion());
599 }
600 else if (processSVFGNode(sn))
601 {
602 propagate(&sn);
603 }
604}
bool processSVFGNode(SVFGNode *node)
void propagateVersion(NodeID o, Version v)
virtual void propagate(GNODE *v)
Definition WPASolver.h:127

◆ processStore()

bool VersionedFlowSensitive::processStore ( const StoreSVFGNode store)
overrideprotectedvirtual

Process store node

foreach node \in dst pts(node) = union pts(src)

STORE statement can only be processed if the pointer on the LHS points to something. If we handle STORE with an empty points-to set, the OUT set will be updated from IN set. Then if LHS pointer points-to one target and it has been identified as a strong update, we can't remove those points-to information computed before this strong update from the OUT set.

check if this is a strong updates store

Reimplemented from SVF::FlowSensitive.

Definition at line 694 of file VersionedFlowSensitive.cpp.

695{
696 NodeID p = store->getDstNodeID();
697 const PointsTo &ppt = getPts(p);
698
699 if (ppt.empty()) return false;
700
701 NodeID q = store->getSrcNodeID();
702 const PointsTo &qpt = getPts(q);
703
704 NodeID l = store->getId();
705 // l: *p = q
706
707 double start = stat->getClk();
708 bool changed = false;
709 // The version for these objects would be y_l(o).
711
712 if (!qpt.empty())
713 {
714 // *p = q, the type of q must be a pointer
715 if (store->getSrcNode()->isPointer())
716 {
717 for (NodeID o : ppt)
718 {
719 if (pag->isConstantObj(o)) continue;
720
721 const Version y = getYield(l, o);
722 if (y != invalidVersion && vPtD->unionPts(atKey(o, y), q))
723 {
724 changed = true;
725 changedObjects.set(o);
726 }
727 }
728 }
729 }
730
731 double end = stat->getClk();
732 storeTime += (end - start) / TIMEINTERVAL;
733
734 double updateStart = stat->getClk();
735
736 NodeID singleton = 0;
737 bool isSU = isStrongUpdate(store, singleton);
738 if (isSU) svfgHasSU.set(l);
739 else svfgHasSU.reset(l);
740
741 // For all objects, perform pts(o:y) = pts(o:y) U pts(o:c) at loc,
742 // except when a strong update is taking place.
743 for (const ObjToVersionMap::value_type &oc : consume[l])
744 {
745 const NodeID o = oc.first;
746 const Version c = oc.second;
747
748 // Strong-updated; don't propagate.
749 if (isSU && o == singleton) continue;
750
751 const Version y = getYield(l, o);
752 if (y != invalidVersion && vPtD->unionPts(atKey(o, y), atKey(o, c)))
753 {
754 changed = true;
755 changedObjects.set(o);
756 }
757 }
758
759 double updateEnd = stat->getClk();
761
762 // Changed objects need to be propagated. Time here should be inconsequential
763 // *except* for time taken for propagateVersion, which will time itself.
764 if (!changedObjects.empty())
765 {
766 for (const NodeID o : changedObjects)
767 {
768 // Definitely has a yielded version (came from prelabelling) as these are
769 // the changed objects which must've been pointed to in Andersen's too.
770 const Version y = getYield(l, o);
772
773 // Some o/v pairs changed: statements need to know.
775 }
776 }
777
778 return changed;
779}
bool isStrongUpdate(const SVFGNode *node, NodeID &singleton)
Return TRUE if this is a strong update STORE statement.
double storeTime
time of store edges
double updateTime
time of strong/weak updates.
void set(unsigned Idx)
void reset(unsigned Idx)
const ValVar * getSrcNode() const
Definition VFGNode.h:274
Version getYield(const NodeID l, const NodeID o) const
Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
NodeBS & getStmtReliance(const NodeID o, const Version v)
Returns the statements which rely on o:v.
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:156

◆ propagateVersion() [1/2]

void VersionedFlowSensitive::propagateVersion ( const NodeID  o,
const Version  v,
const Version  vp,
bool  time = true 
)
private

Propagates version v of o to version vp of o. time indicates whether it should record time taken itself.

Definition at line 561 of file VersionedFlowSensitive.cpp.

562{
563 double start = time ? stat->getClk() : 0.0;
564
565 const VersionedVar srcVar = atKey(o, v);
566 const VersionedVar dstVar = atKey(o, vp);
567 if (vPtD->unionPts(dstVar, srcVar))
568 {
569 // o:vp has changed.
570 // Add the dummy propagation node to tell the solver to propagate it later.
571 const DummyVersionPropSVFGNode *dvp = nullptr;
572 VarToPropNodeMap::const_iterator dvpIt = versionedVarToPropNode.find(dstVar);
573 if (dvpIt == versionedVarToPropNode.end())
574 {
577 }
578 else dvp = dvpIt->second;
579
580 assert(dvp != nullptr && "VFS::propagateVersion: propagation dummy node not found?");
581 pushIntoWorklist(dvp->getId());
582
583 // Notify nodes which rely on o:vp that it changed.
585 }
586
587 double end = time ? stat->getClk() : 0.0;
588 if (time) versionPropTime += (end - start) / TIMEINTERVAL;
589}
const DummyVersionPropSVFGNode * addDummyVersionPropSVFGNode(const NodeID object, const NodeID version)
Definition SVFG.h:279
std::pair< NodeID, Version > VersionedVar

◆ propagateVersion() [2/2]

void VersionedFlowSensitive::propagateVersion ( NodeID  o,
Version  v 
)
private

Propagates version v of o to any version of o which relies on v when o/v is changed. Recursively applies to reliant versions till no new changes are made. Adds any statements which rely on any changes made to the worklist.

Definition at line 547 of file VersionedFlowSensitive.cpp.

548{
549 double start = stat->getClk();
550
551 const std::vector<Version> &reliantVersions = getReliantVersions(o, v);
553 {
554 propagateVersion(o, v, r, false);
555 }
556
557 double end = stat->getClk();
559}
std::vector< Version > & getReliantVersions(const NodeID o, const Version v)
Returns the versions of o which rely on o:v.

◆ propAlongIndirectEdge()

virtual bool SVF::VersionedFlowSensitive::propAlongIndirectEdge ( const IndirectSVFGEdge )
inlineoverrideprotectedvirtual

Override to do nothing. Instead, we will use propagateVersion when necessary.

Reimplemented from SVF::FlowSensitive.

Definition at line 106 of file VersionedFlowSensitive.h.

107 {
108 return false;
109 }

◆ PTAName()

virtual const std::string SVF::VersionedFlowSensitive::PTAName ( ) const
inlineoverridevirtual

Get PTA name.

Reimplemented from SVF::FlowSensitive.

Definition at line 63 of file VersionedFlowSensitive.h.

64 {
65 return "VersionedFlowSensitive";
66 }

◆ readPtsFromFile()

void VersionedFlowSensitive::readPtsFromFile ( const std::string &  filename)
overridevirtual

Initialization for the Solver

Load the pts from file

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 965 of file VersionedFlowSensitive.cpp.

966{
968 initialize();
970 if(!filename.empty())
971 {
972 SVFUtil::outs() << "Loading versioned pointer analysis results from '" << filename << "'...";
973
974 std::ifstream F(filename.c_str());
975 if (!F.is_open())
976 {
977 SVFUtil::outs() << " error opening file for reading!\n";
978 return ;
979 }
981
983
985
987
989
990 // Update callgraph
992
993 F.close();
994 SVFUtil::outs() << "\n";
995 }
996
998 finalize();
999}
return(char *) p.buffer
virtual void readAndSetObjFieldSensitivity(std::ifstream &f, const std::string &delimiterStr)
virtual void readPtsResultFromFile(std::ifstream &f)
virtual void readGepObjVarMapFromFile(std::ifstream &f)
bool updateCallGraph(const CallSiteToFunPtrMap &callsites) override
Update call graph.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
Definition SVFIR.h:451
void readVersionedAnalysisResultFromFile(std::ifstream &F)
virtual void initialize() override
Initialize analysis.
virtual void finalize() override
Finalize analysis.

◆ readVersionedAnalysisResultFromFile()

void VersionedFlowSensitive::readVersionedAnalysisResultFromFile ( std::ifstream &  F)

Definition at line 1069 of file VersionedFlowSensitive.cpp.

1070{
1071 std::string line;
1072 std::string delimiter1 = " -> { ";
1073 std::string delimiter2 = " }";
1074 while (F.good())
1075 {
1076 // Parse a single line in the form of "[ var version ] -> { obj1 obj2 obj3 }"
1077 getline(F, line);
1078 if (line == "---VERSIONED---") break;
1079 std::string pair = line.substr(line.find("[ ")+1, line.find(" ]"));
1080
1081 // Parse VersionKey
1082 std::istringstream ss(pair);
1083 NodeID nodeID;
1085 ss>> nodeID >> nodeVersion;
1087
1088 // Parse Point-to set
1089 size_t pos = line.find(delimiter1);
1090 if (pos == std::string::npos) break;
1091 if (line.back() != '}') break;
1092 pos = pos + delimiter1.length();
1093 size_t len = line.length() - pos - delimiter2.length();
1094 std::string objs = line.substr(pos, len);
1096 if (!objs.empty())
1097 {
1098 std::istringstream pt(objs);
1099 NodeID obj;
1100 while (pt.good())
1101 {
1102 pt >> obj;
1103 dstPts.set(obj);
1104 }
1105 }
1106
1107 // union point-to reuslt
1108 vPtD->unionPts(keyPair, dstPts);
1109 }
1110
1111}

◆ releaseVFSWPA()

static void SVF::VersionedFlowSensitive::releaseVFSWPA ( )
inlinestatic

Release flow-sensitive pointer analysis.

Definition at line 93 of file VersionedFlowSensitive.h.

94 {
95 if (vfspta) delete vfspta;
96 vfspta = nullptr;
97 }

◆ removeAllIndirectSVFGEdges()

void VersionedFlowSensitive::removeAllIndirectSVFGEdges ( void  )
private

Removes all indirect edges in the SVFG.

Definition at line 525 of file VersionedFlowSensitive.cpp.

526{
527 for (SVFG::iterator nodeIt = svfg->begin(); nodeIt != svfg->end(); ++nodeIt)
528 {
529 SVFGNode *sn = nodeIt->second;
530
532 std::vector<SVFGEdge *> toDeleteFromIn;
533 for (SVFGEdge *e : inEdges)
534 {
535 if (SVFUtil::isa<IndirectSVFGEdge>(e)) toDeleteFromIn.push_back(e);
536 }
537
538 for (SVFGEdge *e : toDeleteFromIn) svfg->removeSVFGEdge(e);
539
540 // Only need to iterate over incoming edges for each node because edges
541 // will be deleted from in/out through removeSVFGEdge.
542 }
543
544 setGraph(svfg);
545}
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
const GEdgeSetTy & getInEdges() const
void setGraph(GraphType g)
Definition WPASolver.h:78

◆ setConsume()

void VersionedFlowSensitive::setConsume ( const NodeID  l,
const NodeID  o,
const Version  v 
)
private

Sets the consumed version of o at l to v.

Definition at line 832 of file VersionedFlowSensitive.cpp.

833{
834 setVersion(l, o, v, consume);
835}
void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm)
Shared code for setConsume and setYield. They wrap this function.

◆ setVersion()

void VersionedFlowSensitive::setVersion ( const NodeID  l,
const NodeID  o,
const Version  v,
LocVersionMap lvm 
)
private

Shared code for setConsume and setYield. They wrap this function.

Definition at line 826 of file VersionedFlowSensitive.cpp.

827{
829 ovm[o] = v;
830}

◆ setYield()

void VersionedFlowSensitive::setYield ( const NodeID  l,
const NodeID  o,
const Version  v 
)
private

Sets the yielded version of o at l to v.

Definition at line 837 of file VersionedFlowSensitive.cpp.

838{
839 // Non-store: consume == yield.
840 if (isStore(l)) setVersion(l, o, v, yield);
841 else setVersion(l, o, v, consume);
842}

◆ solveAndwritePtsToFile()

void VersionedFlowSensitive::solveAndwritePtsToFile ( const std::string &  filename)
overridevirtual

Start analysis

Initialization for the Solver

finalize the analysis

Initialization for the Solver

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 1001 of file VersionedFlowSensitive.cpp.

1002{
1004 initialize();
1005 if(!filename.empty())
1008 if(!filename.empty())
1009 {
1012 }
1014 finalize();
1015}
virtual void writeToFile(const std::string &filename)
Interface for analysis result storage on filesystem.
virtual void writeObjVarToFile(const std::string &filename)
virtual void solveConstraints()
void writeVersionedAnalysisResultToFile(const std::string &filename)

◆ updateConnectedNodes()

void VersionedFlowSensitive::updateConnectedNodes ( const SVFGEdgeSetTy edges)
overrideprotectedvirtual

Update nodes connected during updating call graph.

Push nodes connected during update call graph into worklist so they will be solved during next iteration.

If this is a formal-param or actual-ret node, we need to solve this phi node in next iteration

If this is a formal-in or actual-out node, we need to propagate points-to information from its predecessor node.

If this is a field-insensitive obj, propagate all field node's pts

Reimplemented from SVF::FlowSensitive.

Definition at line 606 of file VersionedFlowSensitive.cpp.

607{
608 for (const SVFGEdge *e : newEdges)
609 {
610 SVFGNode *dstNode = e->getDstNode();
611 NodeID src = e->getSrcNode()->getId();
612 NodeID dst = dstNode->getId();
613
614 if (SVFUtil::isa<PHISVFGNode>(dstNode)
615 || SVFUtil::isa<FormalParmSVFGNode>(dstNode)
616 || SVFUtil::isa<ActualRetSVFGNode>(dstNode))
617 {
618 pushIntoWorklist(dst);
619 }
620 else
621 {
622 const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
623 assert(ie != nullptr && "VFS::updateConnectedNodes: given direct edge?");
624
625 assert(delta(dst) && "VFS::updateConnectedNodes: new edges should be to delta nodes!");
626 assert(deltaSource(src) && "VFS::updateConnectedNodes: new indirect edges should be from delta source nodes!");
627
628 const NodeBS &ept = ie->getPointsTo();
629 // For every o, such that src --o--> dst, we need to set up reliance (and propagate).
630 for (const NodeID o : ept)
631 {
632 Version srcY = getYield(src, o);
633 if (srcY == invalidVersion) continue;
634 Version dstC = getConsume(dst, o);
635 if (dstC == invalidVersion) continue;
636
637 std::vector<Version> &versionsRelyingOnSrcY = getReliantVersions(o, srcY);
638 if (std::find(versionsRelyingOnSrcY.begin(), versionsRelyingOnSrcY.end(), dstC) == versionsRelyingOnSrcY.end())
639 {
640 versionsRelyingOnSrcY.push_back(dstC);
642 }
643 }
644 }
645 }
646}

◆ writeVersionedAnalysisResultToFile()

void VersionedFlowSensitive::writeVersionedAnalysisResultToFile ( const std::string &  filename)

Definition at line 1017 of file VersionedFlowSensitive.cpp.

1018{
1019 SVFUtil::outs() << "Storing Versioned Analysis Result to '" << filename << "'...";
1020 std::error_code err;
1021 std::fstream f(filename.c_str(), std::ios_base::app);
1022 if (!f.good())
1023 {
1024 SVFUtil::outs() << " error opening file for writing!\n";
1025 return;
1026 }
1027
1029 {
1030 &this->consume, &this->yield
1031 })
1032 {
1034 {
1035 for (const VersionedFlowSensitive::ObjToVersionMap::value_type &ov : lov)
1036 {
1037 const NodeID o = ov.first;
1038 const Version v = ov.second;
1039 if (vPtD->getPts(atKey(o, v)).empty()) continue;
1040
1041 f <<"[ " <<o <<" " <<v<<" ]"<< " -> { ";
1042 const PointsTo &ovPts = vPtD->getPts(atKey(o, v));
1043 if (!ovPts.empty())
1044 {
1045 for (NodeID n: ovPts)
1046 {
1047 f << n << " ";
1048 }
1049 }
1050 else
1051 {
1052 f << " ";
1053 }
1054 f << "}\n";
1055 }
1056 }
1057 }
1058
1059 f << "---VERSIONED---\n";
1060
1061 f.close();
1062 if (f.good())
1063 {
1064 SVFUtil::outs() << "\n";
1065 return;
1066 }
1067}

Friends And Related Symbol Documentation

◆ VersionedFlowSensitiveStat

Definition at line 34 of file VersionedFlowSensitive.h.

Member Data Documentation

◆ consume

LocVersionMap SVF::VersionedFlowSensitive::consume
private

Maps locations to objects to a version. The object version is what is consumed at that location.

Definition at line 198 of file VersionedFlowSensitive.h.

◆ deltaMap

std::vector<bool> SVF::VersionedFlowSensitive::deltaMap
private

deltaMap[l] means SVFG node l is a delta node, i.e., may get new incoming edges due to OTF callgraph construction.

Definition at line 227 of file VersionedFlowSensitive.h.

◆ deltaSourceMap

std::vector<bool> SVF::VersionedFlowSensitive::deltaSourceMap
private

deltaSourceMap[l] means SVFG node l may be a source to a delta node through an dge added as a result of on-the-fly callgraph construction.

Definition at line 232 of file VersionedFlowSensitive.h.

◆ equivalentObject

Map<NodeID, NodeID> SVF::VersionedFlowSensitive::equivalentObject
private

Definition at line 214 of file VersionedFlowSensitive.h.

◆ invalidVersion

const Version VersionedFlowSensitive::invalidVersion = 0
static

If this version appears, there has been an error.

Definition at line 48 of file VersionedFlowSensitive.h.

◆ isLoadMap

std::vector<bool> SVF::VersionedFlowSensitive::isLoadMap
private

isLoadMap[l] means SVFG node l is a load node.

Definition at line 238 of file VersionedFlowSensitive.h.

◆ isStoreMap

std::vector<bool> SVF::VersionedFlowSensitive::isStoreMap
private

isStoreMap[l] means SVFG node l is a store node.

Definition at line 235 of file VersionedFlowSensitive.h.

◆ meldLabelingTime

double SVF::VersionedFlowSensitive::meldLabelingTime
private

Time to meld label SVFG.

Definition at line 246 of file VersionedFlowSensitive.h.

◆ numPrelabeledNodes

u32_t SVF::VersionedFlowSensitive::numPrelabeledNodes
private

Additional statistics.

Number of prelabeled nodes.

Definition at line 242 of file VersionedFlowSensitive.h.

◆ numPrelabelVersions

u32_t SVF::VersionedFlowSensitive::numPrelabelVersions
private

Number of versions created during prelabeling.

Definition at line 243 of file VersionedFlowSensitive.h.

◆ prelabeledObjects

Set<NodeID> SVF::VersionedFlowSensitive::prelabeledObjects
private

Definition at line 220 of file VersionedFlowSensitive.h.

◆ prelabelingTime

double SVF::VersionedFlowSensitive::prelabelingTime
private

Time to prelabel SVFG.

Definition at line 245 of file VersionedFlowSensitive.h.

◆ stmtReliance

Map<NodeID, Map<Version, NodeBS> > SVF::VersionedFlowSensitive::stmtReliance
private

o x version -> statement nodes which rely on that o/version.

Definition at line 205 of file VersionedFlowSensitive.h.

◆ versionedVarToPropNode

VarToPropNodeMap SVF::VersionedFlowSensitive::versionedVarToPropNode
private

Maps an <object, version> pair to the SVFG node indicating that pair needs to be propagated.

Definition at line 209 of file VersionedFlowSensitive.h.

◆ versionPropTime

double SVF::VersionedFlowSensitive::versionPropTime
private

Time to propagate versions to versions which rely on them.

Definition at line 247 of file VersionedFlowSensitive.h.

◆ versionReliance

VersionRelianceMap SVF::VersionedFlowSensitive::versionReliance
private

o -> (version -> versions which rely on it).

Definition at line 203 of file VersionedFlowSensitive.h.

◆ vfspta

VersionedFlowSensitive * VersionedFlowSensitive::vfspta = nullptr
staticprivate

Definition at line 250 of file VersionedFlowSensitive.h.

◆ vPtD

BVDataPTAImpl::VersionedPTDataTy* SVF::VersionedFlowSensitive::vPtD
private

Points-to DS for working with versions.

Definition at line 223 of file VersionedFlowSensitive.h.

◆ vWorklist

FIFOWorkList<NodeID> SVF::VersionedFlowSensitive::vWorklist
private

Worklist for performing meld labeling, takes SVFG node l. Nodes are added when the version they yield is changed.

Definition at line 218 of file VersionedFlowSensitive.h.

◆ yield

LocVersionMap SVF::VersionedFlowSensitive::yield
private

Actual yield map. Yield analogue to consume.

Definition at line 200 of file VersionedFlowSensitive.h.


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