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< 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< NodeIDWorkList
 
- Public Types inherited from SVF::BVDataPTAImpl
enum  PTBackingType { Mutable , Persistent }
 How the PTData used is implemented. More...
 
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
enum  PTATY {
  Andersen_BASE , Andersen_WPA , AndersenSCD_WPA , AndersenSFR_WPA ,
  AndersenWaveDiff_WPA , Steensgaard_WPA , CSCallString_WPA , CSSummary_WPA ,
  FSDATAFLOW_WPA , FSSPARSE_WPA , VFS_WPA , FSCS_WPA ,
  CFLFICI_WPA , CFLFSCI_WPA , CFLFSCS_WPA , TypeCPP_WPA ,
  FieldS_DDA , FlowS_DDA , PathS_DDA , Cxt_DDA ,
  Default_PTA
}
 Pointer analysis type list. More...
 
enum  PTAImplTy { BaseImpl , BVDataImpl , CondImpl }
 Implementation type: BVDataPTAImpl or CondPTAImpl. More...
 
typedef Set< const CallICFGNode * > CallSiteSet
 Indirect call edges type, map a callsite to a set of callees.
 
typedef SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
 
typedef Set< const SVFFunction * > FunctionSet
 
typedef OrderedMap< const CallICFGNode *, FunctionSetCallEdgeMap
 
typedef SCCDetection< PTACallGraph * > CallGraphSCC
 
typedef Set< const SVFGlobalValue * > VTableSet
 
typedef Set< const SVFFunction * > VFunSet
 

Public Member Functions

 VersionedFlowSensitive (SVFIR *_pag, PTATY type=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.
 
- Public Member Functions inherited from SVF::FlowSensitive
 FlowSensitive (SVFIR *_pag, PTATY type=FSSPARSE_WPA)
 Constructor.
 
 ~FlowSensitive () override=default
 Destructor.
 
virtual bool runOnModule (SVFModule *)
 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, PointerAnalysis::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 SVFValue *V1, const SVFValue *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.
 
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.
 
PTACallGraphgetCallGraph () const
 Return call graph.
 
CallGraphSCCgetCallGraphSCC () const
 Return call graph SCC.
 
 PointerAnalysis (SVFIR *pag, PTATY ty=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 SVFFunction *fun1, const SVFFunction *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 SVFFunction *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.
 
SVFModulegetModule () const
 Module.
 
OrderedNodeSetgetAllValidPtrs ()
 Get all Valid Pointers for resolution.
 
virtual void computeDDAPts (NodeID)
 Compute points-to results on-demand, overridden by derived classes.
 
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 getBaseObjVar (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 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 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.
 
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
 
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.
 
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.
 
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
 

Static Private Member Functions

static bool meld (MeldVersion &mv1, const MeldVersion &mv2)
 Melds v2 into v1 (in place), returns whether a change occurred.
 
static void dumpMeldVersion (MeldVersion &v)
 Dumps a MeldVersion to stdout.
 

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.
 
SVFModulesvfMod
 Module.
 
PTATY ptaTy
 Pointer analysis Type.
 
PTAImplTy ptaImplTy
 PTA implementation type.
 
PTAStatstat
 Statistics.
 
PTACallGraphcallgraph
 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 = VFS_WPA 
)

Constructor.

Definition at line 30 of file VersionedFlowSensitive.cpp.

31 : FlowSensitive(_pag, type)
32{
35 // We'll grab vPtD in initialize.
36
37 for (SVFIR::const_iterator it = pag->begin(); it != pag->end(); ++it)
38 {
39 if (SVFUtil::isa<ObjVar>(it->second)) equivalentObject[it->first] = it->first;
40 }
41
42 assert(!Options::OPTSVFG() && "VFS: -opt-svfg not currently supported with VFS.");
43}
newitem type
Definition cJSON.cpp:2739
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
static Option< bool > OPTSVFG
Definition Options.h:149
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:74

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 24 of file VersionedFlowSensitive.cpp.

25{
26 assert(version != invalidVersion && "VersionedFlowSensitive::atKey: trying to use an invalid version!");
27 return std::make_pair(var, version);
28}
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 467 of file VersionedFlowSensitive.cpp.

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

◆ buildIsStoreLoadMaps()

void VersionedFlowSensitive::buildIsStoreLoadMaps ( void  )
privatevirtual

Fills in isStoreMap and isLoadMap.

Definition at line 444 of file VersionedFlowSensitive.cpp.

445{
446 isStoreMap.resize(svfg->getTotalNodeNum(), false);
447 isLoadMap.resize(svfg->getTotalNodeNum(), false);
448 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
449 {
450 if (SVFUtil::isa<StoreSVFGNode>(it->second)) isStoreMap[it->first] = true;
451 else if (SVFUtil::isa<LoadSVFGNode>(it->second)) isLoadMap[it->first] = true;
452 }
453}
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() == VFS_WPA;
77 }
@ VFS_WPA
Versioned sparse flow-sensitive WPA.

◆ 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 780 of file VersionedFlowSensitive.cpp.

781{
782 std::vector<std::pair<unsigned, unsigned>> keys;
783 for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit)
784 {
785 unsigned occ = 1;
786 unsigned v = pit->first;
787 if (Options::PredictPtOcc() && pag->getObject(v) != nullptr) occ = stmtReliance[v].size() + 1;
788 assert(occ != 0);
789 keys.push_back(std::make_pair(v, occ));
790 }
791
792 PointsTo::MappingPtr nodeMapping =
793 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::cluster(ander, keys, candidateMappings, "aux-ander"));
794 PointsTo::MappingPtr reverseNodeMapping =
795 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
796
797 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
798}
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 > 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="")
static std::vector< NodeID > getReverseNodeMapping(const std::vector< NodeID > &nodeMapping)
static const Option< bool > PredictPtOcc
Definition Options.h:66
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:42
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:371
const MemObj * getObject(NodeID id) const
Definition SVFIR.h:396
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=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 432 of file VersionedFlowSensitive.cpp.

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

◆ 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 438 of file VersionedFlowSensitive.cpp.

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

◆ dumpLocVersionMaps()

void VersionedFlowSensitive::dumpLocVersionMaps ( void  ) const
private

Dumps maps consume and yield.

Definition at line 907 of file VersionedFlowSensitive.cpp.

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

◆ dumpMeldVersion()

void VersionedFlowSensitive::dumpMeldVersion ( MeldVersion v)
staticprivate

Dumps a MeldVersion to stdout.

Definition at line 943 of file VersionedFlowSensitive.cpp.

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

◆ dumpReliances()

void VersionedFlowSensitive::dumpReliances ( void  ) const
private

Dumps versionReliance and stmtReliance.

Definition at line 850 of file VersionedFlowSensitive.cpp.

851{
852 SVFUtil::outs() << "# Version reliances\n";
853 for (const Map<NodeID, Map<Version, std::vector<Version>>>::value_type &ovrv : versionReliance)
854 {
855 NodeID o = ovrv.first;
856 SVFUtil::outs() << " Object " << o << "\n";
857 for (const Map<Version, std::vector<Version>>::value_type& vrv : ovrv.second)
858 {
859 Version v = vrv.first;
860 SVFUtil::outs() << " Version " << v << " is a reliance for: ";
861
862 bool first = true;
863 for (Version rv : vrv.second)
864 {
865 if (!first)
866 {
867 SVFUtil::outs() << ", ";
868 }
869
870 SVFUtil::outs() << rv;
871 first = false;
872 }
873
874 SVFUtil::outs() << "\n";
875 }
876 }
877
878 SVFUtil::outs() << "# Statement reliances\n";
879 for (const Map<NodeID, Map<Version, NodeBS>>::value_type &ovss : stmtReliance)
880 {
881 NodeID o = ovss.first;
882 SVFUtil::outs() << " Object " << o << "\n";
883
885 {
886 Version v = vss.first;
887 SVFUtil::outs() << " Version " << v << " is a reliance for statements: ";
888
889 const NodeBS &ss = vss.second;
890 bool first = true;
891 for (NodeID s : ss)
892 {
893 if (!first)
894 {
895 SVFUtil::outs() << ", ";
896 }
897
898 SVFUtil::outs() << s;
899 first = false;
900 }
901
902 SVFUtil::outs() << "\n";
903 }
904 }
905}
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 65 of file VersionedFlowSensitive.cpp.

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

◆ getConsume()

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

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

Definition at line 810 of file VersionedFlowSensitive.cpp.

811{
812 return getVersion(l, o, consume);
813}
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 
)
private

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

Definition at line 840 of file VersionedFlowSensitive.cpp.

841{
842 return versionReliance[o][v];
843}

◆ getStmtReliance()

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

Returns the statements which rely on o:v.

Definition at line 845 of file VersionedFlowSensitive.cpp.

846{
847 return stmtReliance[o][v];
848}

◆ getVersion()

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

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

Definition at line 800 of file VersionedFlowSensitive.cpp.

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

◆ getYield()

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

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

Definition at line 815 of file VersionedFlowSensitive.cpp.

816{
817 // Non-store: consume == yield.
818 if (isStore(l)) return getVersion(l, o, yield);
819 else return getVersion(l, o, consume);
820}
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 45 of file VersionedFlowSensitive.cpp.

46{
48 // Overwrite the stat FlowSensitive::initialize gave us.
49 delete stat;
51
53
56 consume.resize(svfg->getTotalNodeNum());
57 yield.resize(svfg->getTotalNodeNum());
58
59 prelabel();
60 meldLabel();
61
63}
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
privatevirtual

Returns true if l is a load node.

Definition at line 461 of file VersionedFlowSensitive.cpp.

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

◆ isStore()

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

Returns true if l is a store node.

Definition at line 455 of file VersionedFlowSensitive.cpp.

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

◆ meld()

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

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

Definition at line 426 of file VersionedFlowSensitive.cpp.

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

◆ meldLabel()

void VersionedFlowSensitive::meldLabel ( void  )
private

Meld label the prelabeled SVFG.

Definition at line 120 of file VersionedFlowSensitive.cpp.

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

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

648{
649 double start = stat->getClk();
650
651 bool changed = false;
652
653 // l: p = *q
654 NodeID l = load->getId();
655 NodeID p = load->getPAGDstNodeID();
656 NodeID q = load->getPAGSrcNodeID();
657
658 const PointsTo& qpt = getPts(q);
659 // p = *q, the type of p must be a pointer
660 if (load->getPAGDstNode()->isPointer())
661 {
662 for (NodeID o : qpt)
663 {
664 if (pag->isConstantObj(o)) continue;
665
666 const Version c = getConsume(l, o);
667 if (c != invalidVersion && vPtD->unionPts(p, atKey(o, c)))
668 {
669 changed = true;
670 }
671
673 {
677 for (NodeID of : fields)
678 {
679 const Version c = getConsume(l, of);
680 if (c != invalidVersion && vPtD->unionPts(p, atKey(of, c)))
681 {
682 changed = true;
683 }
684 }
685 }
686 }
687 }
688 double end = stat->getClk();
689 loadTime += (end - start) / TIMEINTERVAL;
690 return changed;
691}
double loadTime
time of load edges
bool isFieldInsensitive(NodeID id) const
virtual const NodeBS & getAllFieldsObjVars(NodeID id)
NodeID getId() const
Get ID.
bool isConstantObj(NodeID id) const
Definition SVFIR.h:465
virtual bool isPointer() const
Whether it is a pointer.
NodeID getPAGDstNodeID() const
Definition VFGNode.h:157
PAGNode * getPAGDstNode() const
Definition VFGNode.h:167
NodeID getPAGSrcNodeID() const
Definition VFGNode.h:152
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 590 of file VersionedFlowSensitive.cpp.

591{
593 // Handle DummyVersPropSVFGNode here so we don't have to override the long
594 // processSVFGNode. We also don't call propagate based on its result.
595 if (const DummyVersionPropSVFGNode *dvp = SVFUtil::dyn_cast<DummyVersionPropSVFGNode>(sn))
596 {
597 propagateVersion(dvp->getObject(), dvp->getVersion());
598 }
599 else if (processSVFGNode(sn))
600 {
601 propagate(&sn);
602 }
603}
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 693 of file VersionedFlowSensitive.cpp.

694{
695 NodeID p = store->getPAGDstNodeID();
696 const PointsTo &ppt = getPts(p);
697
698 if (ppt.empty()) return false;
699
700 NodeID q = store->getPAGSrcNodeID();
701 const PointsTo &qpt = getPts(q);
702
703 NodeID l = store->getId();
704 // l: *p = q
705
706 double start = stat->getClk();
707 bool changed = false;
708 // The version for these objects would be y_l(o).
710
711 if (!qpt.empty())
712 {
713 // *p = q, the type of q must be a pointer
714 if (store->getPAGSrcNode()->isPointer())
715 {
716 for (NodeID o : ppt)
717 {
718 if (pag->isConstantObj(o)) continue;
719
720 const Version y = getYield(l, o);
721 if (y != invalidVersion && vPtD->unionPts(atKey(o, y), q))
722 {
723 changed = true;
724 changedObjects.set(o);
725 }
726 }
727 }
728 }
729
730 double end = stat->getClk();
731 storeTime += (end - start) / TIMEINTERVAL;
732
733 double updateStart = stat->getClk();
734
735 NodeID singleton = 0;
736 bool isSU = isStrongUpdate(store, singleton);
737 if (isSU) svfgHasSU.set(l);
738 else svfgHasSU.reset(l);
739
740 // For all objects, perform pts(o:y) = pts(o:y) U pts(o:c) at loc,
741 // except when a strong update is taking place.
742 for (const ObjToVersionMap::value_type &oc : consume[l])
743 {
744 const NodeID o = oc.first;
745 const Version c = oc.second;
746
747 // Strong-updated; don't propagate.
748 if (isSU && o == singleton) continue;
749
750 const Version y = getYield(l, o);
751 if (y != invalidVersion && vPtD->unionPts(atKey(o, y), atKey(o, c)))
752 {
753 changed = true;
754 changedObjects.set(o);
755 }
756 }
757
758 double updateEnd = stat->getClk();
760
761 // Changed objects need to be propagated. Time here should be inconsequential
762 // *except* for time taken for propagateVersion, which will time itself.
763 if (!changedObjects.empty())
764 {
765 for (const NodeID o : changedObjects)
766 {
767 // Definitely has a yielded version (came from prelabelling) as these are
768 // the changed objects which must've been pointed to in Andersen's too.
769 const Version y = getYield(l, o);
771
772 // Some o/v pairs changed: statements need to know.
774 }
775 }
776
777 return changed;
778}
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)
PAGNode * getPAGSrcNode() const
Definition VFGNode.h:162
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 560 of file VersionedFlowSensitive.cpp.

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

547{
548 double start = stat->getClk();
549
550 const std::vector<Version> &reliantVersions = getReliantVersions(o, v);
552 {
553 propagateVersion(o, v, r, false);
554 }
555
556 double end = stat->getClk();
558}
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)
overrideprivatevirtual

Initialization for the Solver

Load the pts from file

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 961 of file VersionedFlowSensitive.cpp.

962{
964 initialize();
966 if(!filename.empty())
967 {
968 SVFUtil::outs() << "Loading versioned pointer analysis results from '" << filename << "'...";
969
970 std::ifstream F(filename.c_str());
971 if (!F.is_open())
972 {
973 SVFUtil::outs() << " error opening file for reading!\n";
974 return ;
975 }
977
979
981
983
985
986 // Update callgraph
988
989 F.close();
990 SVFUtil::outs() << "\n";
991 }
992
994 finalize();
995}
#define F(f)
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:351
void readVersionedAnalysisResultFromFile(std::ifstream &F)
virtual void initialize() override
Initialize analysis.
virtual void finalize() override
Finalize analysis.

◆ readVersionedAnalysisResultFromFile()

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

Definition at line 1065 of file VersionedFlowSensitive.cpp.

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

◆ 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 524 of file VersionedFlowSensitive.cpp.

525{
526 for (SVFG::iterator nodeIt = svfg->begin(); nodeIt != svfg->end(); ++nodeIt)
527 {
528 SVFGNode *sn = nodeIt->second;
529
531 std::vector<SVFGEdge *> toDeleteFromIn;
532 for (SVFGEdge *e : inEdges)
533 {
534 if (SVFUtil::isa<IndirectSVFGEdge>(e)) toDeleteFromIn.push_back(e);
535 }
536
537 for (SVFGEdge *e : toDeleteFromIn) svfg->removeSVFGEdge(e);
538
539 // Only need to iterate over incoming edges for each node because edges
540 // will be deleted from in/out through removeSVFGEdge.
541 }
542
543 setGraph(svfg);
544}
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 828 of file VersionedFlowSensitive.cpp.

829{
830 setVersion(l, o, v, consume);
831}
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 822 of file VersionedFlowSensitive.cpp.

823{
825 ovm[o] = v;
826}

◆ 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 833 of file VersionedFlowSensitive.cpp.

834{
835 // Non-store: consume == yield.
836 if (isStore(l)) setVersion(l, o, v, yield);
837 else setVersion(l, o, v, consume);
838}

◆ solveAndwritePtsToFile()

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

Start analysis

Initialization for the Solver

finalize the analysis

Initialization for the Solver

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 997 of file VersionedFlowSensitive.cpp.

998{
1000 initialize();
1001 if(!filename.empty())
1004 if(!filename.empty())
1005 {
1008 }
1010 finalize();
1011}
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 605 of file VersionedFlowSensitive.cpp.

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

◆ writeVersionedAnalysisResultToFile()

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

Definition at line 1013 of file VersionedFlowSensitive.cpp.

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

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 197 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 226 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 231 of file VersionedFlowSensitive.h.

◆ equivalentObject

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

Definition at line 213 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 237 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 234 of file VersionedFlowSensitive.h.

◆ meldLabelingTime

double SVF::VersionedFlowSensitive::meldLabelingTime
private

Time to meld label SVFG.

Definition at line 245 of file VersionedFlowSensitive.h.

◆ numPrelabeledNodes

u32_t SVF::VersionedFlowSensitive::numPrelabeledNodes
private

Additional statistics.

Number of prelabeled nodes.

Definition at line 241 of file VersionedFlowSensitive.h.

◆ numPrelabelVersions

u32_t SVF::VersionedFlowSensitive::numPrelabelVersions
private

Number of versions created during prelabeling.

Definition at line 242 of file VersionedFlowSensitive.h.

◆ prelabeledObjects

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

Definition at line 219 of file VersionedFlowSensitive.h.

◆ prelabelingTime

double SVF::VersionedFlowSensitive::prelabelingTime
private

Time to prelabel SVFG.

Definition at line 244 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 204 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 208 of file VersionedFlowSensitive.h.

◆ versionPropTime

double SVF::VersionedFlowSensitive::versionPropTime
private

Time to propagate versions to versions which rely on them.

Definition at line 246 of file VersionedFlowSensitive.h.

◆ versionReliance

VersionRelianceMap SVF::VersionedFlowSensitive::versionReliance
private

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

Definition at line 202 of file VersionedFlowSensitive.h.

◆ vfspta

VersionedFlowSensitive * VersionedFlowSensitive::vfspta = nullptr
staticprivate

Definition at line 249 of file VersionedFlowSensitive.h.

◆ vPtD

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

Points-to DS for working with versions.

Definition at line 222 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 217 of file VersionedFlowSensitive.h.

◆ yield

LocVersionMap SVF::VersionedFlowSensitive::yield
private

Actual yield map. Yield analogue to consume.

Definition at line 199 of file VersionedFlowSensitive.h.


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