Static Value-Flow Analysis
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). More...
 
- 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. More...
 
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. More...
 
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. More...
 
virtual void initialize () override
 Initialize analysis. More...
 
virtual void finalize () override
 Finalize analysis. More...
 
virtual const std::string PTAName () const override
 Get PTA name. More...
 
- Public Member Functions inherited from SVF::FlowSensitive
 FlowSensitive (SVFIR *_pag, PTATY type=FSSPARSE_WPA)
 Constructor. More...
 
 ~FlowSensitive () override=default
 Destructor. More...
 
virtual bool runOnModule (SVFModule *)
 We start from here. More...
 
void analyze () override
 Flow sensitive analysis. More...
 
virtual void solveConstraints ()
 
SVFGgetSVFG () const
 Return SVFG. More...
 
- Public Member Functions inherited from SVF::WPAFSSolver< GraphType >
 WPAFSSolver ()
 Constructor. More...
 
virtual ~WPAFSSolver ()
 Destructor. More...
 
virtual NodeID sccRepNode (NodeID id) const
 SCC methods. More...
 
- Public Member Functions inherited from SVF::BVDataPTAImpl
 BVDataPTAImpl (SVFIR *pag, PointerAnalysis::PTATY type, bool alias_check=true)
 Constructor. More...
 
 ~BVDataPTAImpl () override=default
 Destructor. More...
 
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. More...
 
virtual void clearFullPts (NodeID id)
 Clear points-to set of id. More...
 
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. More...
 
virtual void expandFIObjs (const PointsTo &pts, PointsTo &expandedPts)
 Expand FI objects. More...
 
virtual void expandFIObjs (const NodeBS &pts, NodeBS &expandedPts)
 TODO: remove repetition. More...
 
void remapPointsToSets (void)
 Remap all points-to sets to use the current mapping. More...
 
virtual void writeToFile (const std::string &filename)
 Interface for analysis result storage on filesystem. More...
 
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. More...
 
AliasResult alias (NodeID node1, NodeID node2) override
 Interface expose to users of our pointer analysis, given PAGNodeID. More...
 
virtual AliasResult alias (const PointsTo &pts1, const PointsTo &pts2)
 Interface expose to users of our pointer analysis, given two pts. More...
 
void dumpCPts () override
 dump and debug, print out conditional pts More...
 
void dumpTopLevelPtsTo () override
 
void dumpAllPts () override
 
- Public Member Functions inherited from SVF::PointerAnalysis
ICFGgetICFG () const
 Get ICFG. More...
 
u32_t getNumOfResolvedIndCallEdge () const
 Return number of resolved indirect call edges. More...
 
PTACallGraphgetCallGraph () const
 Return call graph. More...
 
CallGraphSCCgetCallGraphSCC () const
 Return call graph SCC. More...
 
 PointerAnalysis (SVFIR *pag, PTATY ty=Default_PTA, bool alias_check=true)
 Constructor. More...
 
PTATY getAnalysisTy () const
 Type of pointer analysis. More...
 
PTAImplTy getImplTy () const
 Return implementation type of the pointer analysis. More...
 
bool printStat ()
 Whether print statistics. More...
 
void disablePrintStat ()
 Whether print statistics. More...
 
CallEdgeMapgetIndCallMap ()
 Get callees from an indirect callsite. More...
 
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. More...
 
void callGraphSCCDetection ()
 PTACallGraph SCC related methods. More...
 
NodeID getCallGraphSCCRepNode (NodeID id) const
 Get SCC rep node of a SVFG node. More...
 
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. More...
 
bool isInRecursion (const SVFFunction *fun) const
 
bool isLocalVarInRecursiveFun (NodeID id) const
 Whether a local variable is in function recursions. More...
 
CommonCHGraphgetCHGraph () const
 get CHGraph More...
 
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. More...
 
SVFIRgetPAG () const
 
PTAStatgetStat () const
 Get PTA stat. More...
 
SVFModulegetModule () const
 Module. More...
 
OrderedNodeSetgetAllValidPtrs ()
 Get all Valid Pointers for resolution. More...
 
virtual ~PointerAnalysis ()
 Destructor. More...
 
virtual void computeDDAPts (NodeID)
 Compute points-to results on-demand, overridden by derived classes. More...
 
void printIndCSTargets (const CallICFGNode *cs, const FunctionSet &targets)
 Print targets of a function pointer. More...
 
virtual void dumpPts (NodeID ptr, const PointsTo &pts)
 
void printIndCSTargets ()
 
void dumpAllTypes ()
 
void dumpStat ()
 Dump the statistics. More...
 
bool containBlackHoleNode (const PointsTo &pts)
 Determine whether a points-to contains a black hole or constant node. More...
 
bool containConstantNode (const PointsTo &pts)
 
virtual bool isBlkObjOrConstantObj (NodeID ptd) const
 
bool isHeapMemObj (NodeID id) const
 Whether this object is heap or array. More...
 
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. More...
 
static bool classof (const VersionedFlowSensitive *)
 Methods to support type inquiry through isa, cast, and dyn_cast. More...
 
static bool classof (const PointerAnalysis *pta)
 
static VersionedFlowSensitivecreateVFSWPA (SVFIR *_pag)
 Create single instance of versioned flow-sensitive points-to analysis. More...
 
static void releaseVFSWPA ()
 Release flow-sensitive pointer analysis. More...
 
- Static Public Member Functions inherited from SVF::FlowSensitive
static FlowSensitivecreateFSWPA (SVFIR *_pag)
 Create single instance of flow-sensitive pointer analysis. More...
 
static void releaseFSWPA ()
 Release flow-sensitive pointer analysis. More...
 
static bool classof (const FlowSensitive *)
 Methods for support type inquiry through isa, cast, and dyn_cast. More...
 
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. More...
 
- 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. More...
 
virtual void updateConnectedNodes (const SVFGEdgeSetTy &newEdges) override
 Update nodes connected during updating call graph. More...
 
virtual bool propAlongIndirectEdge (const IndirectSVFGEdge *) override
 Override to do nothing. Instead, we will use propagateVersion when necessary. More...
 
virtual void cluster (void) override
 Override since we want to assign different weights based on versioning. More...
 
- Protected Member Functions inherited from SVF::FlowSensitive
NodeStackSCCDetect () override
 SCC detection. More...
 
bool propFromSrcToDst (SVFGEdge *edge) override
 Propagation. More...
 
virtual bool propAlongDirectEdge (const DirectSVFGEdge *edge)
 Propagate points-to information along a DIRECT SVFG edge. More...
 
virtual bool propVarPtsFromSrcToDst (NodeID var, const SVFGNode *src, const SVFGNode *dst)
 Propagate points-to information of a certain variable from src to dst. More...
 
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. More...
 
virtual bool strongUpdateOutFromIn (const SVFGNode *node, NodeID singleton)
 Handle strong updates. More...
 
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. More...
 
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. More...
 
void connectCallerAndCallee (const CallEdgeMap &newEdges, SVFGEdgeSetTy &edges)
 Connect nodes in SVFG. More...
 
bool isStrongUpdate (const SVFGNode *node, NodeID &singleton)
 Return TRUE if this is a strong update STORE statement. More...
 
virtual void countAliases (Set< std::pair< NodeID, NodeID >> cmp, unsigned *mayAliases, unsigned *noAliases)
 Fills may/noAliases for the location/pointer pairs in cmp. More...
 
const PointsTogetDFInPtsSet (const SVFGNode *stmt, const NodeID node)
 Get points-to set for a node from data flow IN/OUT set at a statement. More...
 
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. More...
 
void svfgStat ()
 
const DFInOutMapgetDFInputMap () const
 
const DFInOutMapgetDFOutputMap () const
 
- Protected Member Functions inherited from SVF::WPASolver< GraphType >
 WPASolver ()
 Constructor. More...
 
virtual ~WPASolver ()=default
 Destructor. More...
 
SCCgetSCCDetector () const
 Get SCC detector. More...
 
const GraphType graph ()
 Get/Set graph methods. More...
 
void setGraph (GraphType g)
 
virtual NodeStackSCCDetect (NodeSet &candidates)
 
virtual void initWorklist ()
 
virtual void solveWorklist ()
 
virtual void collapseFields ()
 collapse positive weight cycles of a graph More...
 
virtual void propagate (GNODE *v)
 
virtual bool propFromSrcToDst (GEDGE *)
 Propagate information from source to destination node, to be implemented in the child class. More...
 
NodeID popFromWorklist ()
 Worklist operations. More...
 
virtual void pushIntoWorklist (NodeID id)
 
bool isWorklistEmpty ()
 
bool isInWorklist (NodeID id)
 
GNODENode (NodeID id)
 Get node on the graph. More...
 
NodeID Node_Index (GNODE node)
 Get node ID. More...
 
- Protected Member Functions inherited from SVF::BVDataPTAImpl
PTDataTygetPTDataTy () const
 Get points-to data structure. More...
 
DiffPTDataTygetDiffPTDataTy () const
 
DFPTDataTygetDFPTDataTy () const
 
MutDFPTDataTygetMutDFPTDataTy () const
 
VersionedPTDataTygetVersionedPTDataTy () const
 
virtual void onTheFlyCallGraphSolve (const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
 On the fly call graph construction. More...
 
virtual void onTheFlyThreadCallGraphSolve (const CallSiteToFunPtrMap &callsites, CallEdgeMap &newForkEdges)
 On the fly thread call graph construction respecting forksite. More...
 
virtual void normalizePointsTo ()
 
- Protected Member Functions inherited from SVF::PointerAnalysis
const CallSiteToFunPtrMapgetIndirectCallsites () const
 Return all indirect callsites. More...
 
NodeID getFunPtr (const CallICFGNode *cs) const
 Return function pointer PAGNode at a callsite cs. More...
 
virtual void validateTests ()
 Alias check functions to verify correctness of pointer analysis. More...
 
virtual void validateSuccessTests (std::string fun)
 
virtual void validateExpectedFailureTests (std::string fun)
 
void resetObjFieldSensitive ()
 Reset all object node as field-sensitive. More...
 

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. More...
 
void meldLabel (void)
 Meld label the prelabeled SVFG. More...
 
void removeAllIndirectSVFGEdges (void)
 Removes all indirect edges in the SVFG. More...
 
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. More...
 
virtual bool isStore (const NodeID l) const
 Returns true if l is a store node. More...
 
virtual bool isLoad (const NodeID l) const
 Returns true if l is a load node. More...
 
virtual void buildDeltaMaps (void)
 Fills in deltaMap and deltaSourceMap for the SVFG. More...
 
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. More...
 
Version getConsume (const NodeID l, const NodeID o) const
 Returns the consumed version of o at l. If no such version exists, returns invalidVersion. More...
 
Version getYield (const NodeID l, const NodeID o) const
 Returns the yielded version of o at l. If no such version exists, returns invalidVersion. More...
 
void setVersion (const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm)
 Shared code for setConsume and setYield. They wrap this function. More...
 
void setConsume (const NodeID l, const NodeID o, const Version v)
 Sets the consumed version of o at l to v. More...
 
void setYield (const NodeID l, const NodeID o, const Version v)
 Sets the yielded version of o at l to v. More...
 
std::vector< Version > & getReliantVersions (const NodeID o, const Version v)
 Returns the versions of o which rely on o:v. More...
 
NodeBSgetStmtReliance (const NodeID o, const Version v)
 Returns the statements which rely on o:v. More...
 
void dumpReliances (void) const
 Dumps versionReliance and stmtReliance. More...
 
void dumpLocVersionMaps (void) const
 Dumps maps consume and yield. More...
 
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. More...
 
static void dumpMeldVersion (MeldVersion &v)
 Dumps a MeldVersion to stdout. More...
 

Private Attributes

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

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 More...
 
- 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. More...
 
u32_t numOfProcessedAddr
 Statistics. More...
 
u32_t numOfProcessedCopy
 Number of processed Addr node. More...
 
u32_t numOfProcessedGep
 Number of processed Copy node. More...
 
u32_t numOfProcessedPhi
 Number of processed Gep node. More...
 
u32_t numOfProcessedLoad
 Number of processed Phi node. More...
 
u32_t numOfProcessedStore
 Number of processed Load node. More...
 
u32_t numOfProcessedActualParam
 Number of processed Store node. More...
 
u32_t numOfProcessedFormalRet
 Number of processed actual param node. More...
 
u32_t numOfProcessedMSSANode
 Number of processed formal ret node. More...
 
u32_t maxSCCSize
 Number of processed mssa node. More...
 
u32_t numOfSCC
 
u32_t numOfNodesInSCC
 
double solveTime
 time of solve. More...
 
double sccTime
 time of SCC detection. More...
 
double processTime
 time of processNode. More...
 
double propagationTime
 time of points-to propagation. More...
 
double directPropaTime
 time of points-to propagation of address-taken objects More...
 
double indirectPropaTime
 time of points-to propagation of top-level pointers More...
 
double updateTime
 time of strong/weak updates. More...
 
double addrTime
 time of handling address edges More...
 
double copyTime
 time of handling copy edges More...
 
double gepTime
 time of handling gep edges More...
 
double loadTime
 time of load edges More...
 
double storeTime
 time of store edges More...
 
double phiTime
 time of phi nodes. More...
 
double updateCallGraphTime
 time of updating call graph More...
 
NodeBS svfgHasSU
 
- Protected Attributes inherited from SVF::WPAFSSolver< GraphType >
NodeStack nodeStack
 stack used for processing nodes. More...
 
- Protected Attributes inherited from SVF::WPASolver< GraphType >
bool reanalyze
 Reanalyze if any constraint value changed. More...
 
u32_t iterationForPrintStat
 print out statistics for i-th iteration More...
 
GraphType _graph
 Graph. More...
 
std::unique_ptr< SCCscc
 SCC. More...
 
WorkList worklist
 Worklist for resolution. More...
 
- Protected Attributes inherited from SVF::PointerAnalysis
bool print_stat
 User input flags. More...
 
bool alias_validation
 Flag for validating points-to/alias results. More...
 
u32_t OnTheFlyIterBudgetForStat
 Flag for iteration budget for on-the-fly statistics. More...
 
SVFModulesvfMod
 Module. More...
 
PTATY ptaTy
 Pointer analysis Type. More...
 
PTAImplTy ptaImplTy
 PTA implementation type. More...
 
PTAStatstat
 Statistics. More...
 
PTACallGraphcallgraph
 Call graph used for pointer analysis. More...
 
CallGraphSCCcallGraphSCC
 SCC for PTACallGraph. More...
 
ICFGicfg
 Interprocedural control-flow graph. More...
 
CommonCHGraphchgraph
 CHGraph. More...
 
- Static Protected Attributes inherited from SVF::FlowSensitive
static std::unique_ptr< FlowSensitivefspta
 
- Static Protected Attributes inherited from SVF::PointerAnalysis
static SVFIRpag = nullptr
 SVFIR. More...
 

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
FlowSensitive(SVFIR *_pag, PTATY type=FSSPARSE_WPA)
Constructor.
Definition: FlowSensitive.h:61
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
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.

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.
472  Set<const CallICFGNode *> deltaCBNs;
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.
Definition: GenericGraph.h:680
Set< const CallICFGNode * > CallInstSet
Definition: PTACallGraph.h:55
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
virtual const ICFGNode * getICFGNode() const
Return corresponding ICFG node.
Definition: VFGNode.h:67
VFGNodeIDToNodeMapTy::const_iterator const_iterator
Definition: VFG.h:81
u32_t NodeID
Definition: GeneralType.h:55
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96

◆ 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.
Definition: GenericGraph.h:606
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:395
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  {
85  vfspta = new VersionedFlowSensitive(_pag);
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 }
VFGNodeIDToNodeMapTy::iterator iterator
Definition: VFG.h:80
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
Definition: GeneralType.h:123

◆ 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 
884  for (const Map<Version, NodeBS>::value_type &vss : ovss.second)
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
Definition: GeneralType.h:101

◆ 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 {
802  const Map<NodeID, NodeID>::const_iterator canonObjectIt = equivalentObject.find(o);
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;
50  stat = new VersionedFlowSensitiveStat(this);
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.
169  versionReliance[o];
170  stmtReliance[o];
171  objectQueue.push(o);
172  }
173 
174  std::mutex objectQueueMutex;
175  std::mutex footprintOwnerMutex;
176 
177  auto meldVersionWorker = [this, &footprintOwner, &objectQueue,
178  &objectQueueMutex, &footprintOwnerMutex, &versionMutexes,
179  &prelabeledNodes, &isPrelabeled, &nodesWhichNeedVersions]
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);
222  const Map<std::vector<const IndirectSVFGEdge *>, NodeID>::const_iterator canonOwner
223  = footprintOwner.find(footprint);
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.
248  Map<NodeID, MeldVersion> storesYieldedMeldVersion;
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.
257  Set<NodeID> reachableNodes;
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.
306  const MeldVersion &nMV = nIsStore ? storesYieldedMeldVersion[n] : sccToMeldVersion[nSCC];
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  {
328  sccToMeldVersion[mSCC] |= nMV;
329  }
330  }
331  }
332 
333  // 5. Transform meld versions belonging to SCCs into versions.
335  std::vector<Version> sccToVersion(numSCCs, invalidVersion);
336  Version curVersion = 0;
337  for (u32_t scc = 0; scc < sccToMeldVersion.size(); ++scc)
338  {
339  const MeldVersion &mv = sccToMeldVersion[scc];
340  Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
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.
348  Map<NodeID, Version> storesYieldedVersion;
349  for (auto const& nmv : storesYieldedMeldVersion)
350  {
351  const NodeID n = nmv.first;
352  const MeldVersion &mv = nmv.second;
353 
354  Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
355  Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
356  storesYieldedVersion[n] = v;
357  }
358 
359  storesYieldedMeldVersion.clear();
360 
361  mvv.clear();
362 
363  // 6. From SCC reliance, determine version reliances.
364  Map<Version, std::vector<Version>> &osVersionReliance = this->versionReliance.at(o);
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
372  = storeSCC[scc] != -1 ? storesYieldedVersion[storeSCC[scc]] : sccToVersion[scc];
373 
374  std::vector<Version> &reliantVersions = osVersionReliance[version];
375  for (const int reliantSCC : sccReliance[scc])
376  {
377  const Version reliantVersion = sccToVersion[reliantSCC];
378  if (version != reliantVersion)
379  {
380  // sccReliance is a set, no need to worry about duplicates.
381  reliantVersions.push_back(reliantVersion);
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.
389  Map<Version, NodeBS> &osStmtReliance = this->stmtReliance.at(o);
390  for (size_t i = 0; i < nodesWhichNeedVersions.size(); ++i)
391  {
392  const NodeID n = nodesWhichNeedVersions[i];
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  {
409  const Map<NodeID, Version>::const_iterator yIt = storesYieldedVersion.find(n);
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);
423  meldLabelingTime = (end - start) / TIMEINTERVAL;
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
NodeType * getDstNode() const
Definition: GenericGraph.h:101
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
const NodeBS & getPointsTo() const
Definition: SVFGEdge.h:60
static const Option< u32_t > VersioningThreads
Number of threads for the versioning phase.
Definition: Options.h:78
bool test(u32_t n) const
Returns true if n is in this set.
Definition: PointsTo.cpp:131
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition: SVFG.h:150
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
bool test(unsigned Idx) const
static unsigned detectSCCs(VersionedFlowSensitive *vfs, const SVFG *svfg, const NodeID object, const std::vector< const SVFGNode * > &startingNodes, std::vector< int > &partOf, std::vector< const IndirectSVFGEdge * > &footprint)
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.
FIFOWorkList< NodeID > vWorklist
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 
91  vWorklist.push(l);
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.
110  vWorklist.push(l);
111  if (mr->getPointsTo().count() != 0) ++numPrelabeledNodes;
112  }
113  }
114  }
115 
116  double end = stat->getClk(true);
117  prelabelingTime = (end - start) / TIMEINTERVAL;
118 }
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 
672  if (isFieldInsensitive(o))
673  {
676  const NodeBS& fields = getAllFieldsObjVars(o);
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 }
const PointsTo & getPts(NodeID id) override
double loadTime
time of load edges
bool isFieldInsensitive(NodeID id) const
virtual const NodeBS & getAllFieldsObjVars(NodeID id)
bool isConstantObj(NodeID id) const
Definition: SVFIR.h:443
virtual bool isPointer() const
Whether it is a pointer.
Definition: SVFVariables.h:106
NodeID getPAGDstNodeID() const
Definition: VFGNode.h:157
NodeID getPAGSrcNodeID() const
Definition: VFGNode.h:152
PAGNode * getPAGDstNode() const
Definition: VFGNode.h:167
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.
virtual bool unionPts(const VersionedKey &dstVar, const VersionedKey &srcVar)=0

◆ 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 {
592  SVFGNode* sn = svfg->getSVFGNode(n);
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).
709  NodeBS changedObjects;
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();
759  updateTime += (updateEnd - updateStart) / TIMEINTERVAL;
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);
770  propagateVersion(o, y);
771 
772  // Some o/v pairs changed: statements need to know.
773  for (NodeID s : getStmtReliance(o, y)) pushIntoWorklist(s);
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.
bool empty() const
Returns true if set is empty.
Definition: PointsTo.cpp:98
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  {
574  dvp = svfg->addDummyVersionPropSVFGNode(o, vp);
575  versionedVarToPropNode[dstVar] = dvp;
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.
583  for (NodeID s : getStmtReliance(o, vp)) pushIntoWorklist(s);
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
Definition: GeneralType.h:125

◆ 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);
551  for (Version r : reliantVersions)
552  {
553  propagateVersion(o, v, r, false);
554  }
555 
556  double end = stat->getClk();
557  versionPropTime += (end - start) / TIMEINTERVAL;
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:350
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;
1080  Version nodeVersion;
1081  ss>> nodeID >> nodeVersion;
1082  VersionedVar keyPair = atKey(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);
1091  PointsTo dstPts;
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 }
const char *const string
Definition: cJSON.h:172
void set(u32_t n)
Inserts n in the set.
Definition: PointsTo.cpp:157

◆ 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 
530  const SVFGEdgeSetTy &inEdges = sn->getInEdges();
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
Definition: FlowSensitive.h:53
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
void removeSVFGEdge(SVFGEdge *edge)
Remove a SVFG edge.
Definition: SVFG.h:238
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 {
824  ObjToVersionMap &ovm = lvm[l];
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())
1002  writeObjVarToFile(filename);
1003  solveConstraints();
1004  if(!filename.empty())
1005  {
1007  writeToFile(filename);
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);
640  propagateVersion(o, srcY, 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 
1024  for (const VersionedFlowSensitive::LocVersionMap *lvm :
1025  {
1026  &this->consume, &this->yield
1027  })
1028  {
1029  for (const VersionedFlowSensitive::ObjToVersionMap &lov : *lvm)
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 }
virtual const DataSet & getPts(const VersionedKey &vk)=0

Friends And Related Function Documentation

◆ VersionedFlowSensitiveStat

friend class VersionedFlowSensitiveStat
friend

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: