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

#include <VersionedFlowSensitive.h>

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

Classes

class  SCC
 

Public Types

typedef Map< NodeID, VersionObjToVersionMap
 
typedef Map< VersionedVar, const DummyVersionPropSVFGNode * > VarToPropNodeMap
 
typedef std::vector< ObjToVersionMapLocVersionMap
 
typedef Map< NodeID, Map< Version, std::vector< Version > > > VersionRelianceMap
 (o -> (v -> versions with rely on o:v).
 
- Public Types inherited from SVF::FlowSensitive
typedef BVDataPTAImpl::MutDFPTDataTy MutDFPTDataTy
 
typedef BVDataPTAImpl::MutDFPTDataTy::DFPtsMap DFInOutMap
 
typedef BVDataPTAImpl::MutDFPTDataTy::PtsMap PtsMap
 
- Public Types inherited from SVF::WPASolver< GraphType >
typedef SVF::GenericGraphTraits< GraphTypeGTraits
 Define the GTraits and node iterator for printing.
 
typedef GTraits::NodeRef GNODE
 
typedef GTraits::EdgeType GEDGE
 
typedef GTraits::ChildIteratorType child_iterator
 
typedef SCCDetection< GraphTypeSCC
 
typedef FIFOWorkList< NodeIDWorkList
 
- Public Types inherited from SVF::BVDataPTAImpl
typedef PTData< NodeID, NodeSet, NodeID, PointsToPTDataTy
 
typedef DiffPTData< NodeID, NodeSet, NodeID, PointsToDiffPTDataTy
 
typedef DFPTData< NodeID, NodeSet, NodeID, PointsToDFPTDataTy
 
typedef VersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > VersionedPTDataTy
 
typedef MutablePTData< NodeID, NodeSet, NodeID, PointsToMutPTDataTy
 
typedef MutableDiffPTData< NodeID, NodeSet, NodeID, PointsToMutDiffPTDataTy
 
typedef MutableDFPTData< NodeID, NodeSet, NodeID, PointsToMutDFPTDataTy
 
typedef MutableIncDFPTData< NodeID, NodeSet, NodeID, PointsToMutIncDFPTDataTy
 
typedef MutableVersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > MutVersionedPTDataTy
 
typedef PersistentPTData< NodeID, NodeSet, NodeID, PointsToPersPTDataTy
 
typedef PersistentDiffPTData< NodeID, NodeSet, NodeID, PointsToPersDiffPTDataTy
 
typedef PersistentDFPTData< NodeID, NodeSet, NodeID, PointsToPersDFPTDataTy
 
typedef PersistentIncDFPTData< NodeID, NodeSet, NodeID, PointsToPersIncDFPTDataTy
 
typedef PersistentVersionedPTData< NodeID, NodeSet, NodeID, PointsTo, VersionedVar, Set< VersionedVar > > PersVersionedPTDataTy
 
- Public Types inherited from SVF::PointerAnalysis
typedef Set< const CallICFGNode * > CallSiteSet
 Indirect call edges type, map a callsite to a set of callees.
 
typedef SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
 
typedef Set< const FunObjVar * > FunctionSet
 
typedef OrderedMap< const CallICFGNode *, FunctionSetCallEdgeMap
 
typedef SCCDetection< CallGraph * > CallGraphSCC
 
typedef Set< const GlobalObjVar * > VTableSet
 
typedef Set< const FunObjVar * > VFunSet
 

Public Member Functions

 VersionedFlowSensitive (SVFIR *_pag, PTATY type=PTATY::VFS_WPA)
 Constructor.
 
virtual void initialize () override
 Initialize analysis.
 
virtual void finalize () override
 Finalize analysis.
 
virtual const std::string PTAName () const override
 Get PTA name.
 
virtual bool isStore (const NodeID l) const
 Returns true if l is a store node.
 
virtual bool isLoad (const NodeID l) const
 Returns true if l is a load node.
 
Version getVersion (const NodeID l, const NodeID o, const LocVersionMap &lvm) const
 Shared code for getConsume and getYield. They wrap this function.
 
Version getConsume (const NodeID l, const NodeID o) const
 Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
 
Version getYield (const NodeID l, const NodeID o) const
 Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
 
std::vector< Version > & getReliantVersions (const NodeID o, const Version v)
 Returns the versions of o which rely on o:v.
 
NodeBSgetStmtReliance (const NodeID o, const Version v)
 Returns the statements which rely on o:v.
 
void dumpReliances (void) const
 Dumps versionReliance and stmtReliance.
 
void dumpLocVersionMaps (void) const
 Dumps maps consume and yield.
 
void solveAndwritePtsToFile (const std::string &filename) override
 
void writeVersionedAnalysisResultToFile (const std::string &filename)
 
void readVersionedAnalysisResultFromFile (std::ifstream &F)
 
void readPtsFromFile (const std::string &filename) override
 
- Public Member Functions inherited from SVF::FlowSensitive
 FlowSensitive (SVFIR *_pag, PTATY type=PTATY::FSSPARSE_WPA)
 Constructor.
 
 ~FlowSensitive () override=default
 Destructor.
 
virtual bool runOnModule ()
 We start from here.
 
void analyze () override
 Flow sensitive analysis.
 
virtual void solveConstraints ()
 
SVFGgetSVFG () const
 Return SVFG.
 
- Public Member Functions inherited from SVF::WPAFSSolver< GraphType >
 WPAFSSolver ()
 Constructor.
 
virtual ~WPAFSSolver ()
 Destructor.
 
virtual NodeID sccRepNode (NodeID id) const
 SCC methods.
 
- Public Member Functions inherited from SVF::BVDataPTAImpl
 BVDataPTAImpl (SVFIR *pag, PTATY type, bool alias_check=true)
 Constructor.
 
 ~BVDataPTAImpl () override=default
 Destructor.
 
PersistentPointsToCache< PointsTo > & getPtCache ()
 
const PointsTogetPts (NodeID id) override
 
const NodeSetgetRevPts (NodeID nodeId) override
 
virtual void clearPts (NodeID id, NodeID element)
 Remove element from the points-to set of id.
 
virtual void clearFullPts (NodeID id)
 Clear points-to set of id.
 
virtual bool unionPts (NodeID id, const PointsTo &target)
 
virtual bool unionPts (NodeID id, NodeID ptd)
 
virtual bool addPts (NodeID id, NodeID ptd)
 
virtual void clearAllPts ()
 Clear all data.
 
virtual void expandFIObjs (const PointsTo &pts, PointsTo &expandedPts)
 Expand FI objects.
 
virtual void expandFIObjs (const NodeBS &pts, NodeBS &expandedPts)
 TODO: remove repetition.
 
void remapPointsToSets (void)
 Remap all points-to sets to use the current mapping.
 
virtual void writeToFile (const std::string &filename)
 Interface for analysis result storage on filesystem.
 
virtual void writeObjVarToFile (const std::string &filename)
 
virtual void writePtsResultToFile (std::fstream &f)
 
virtual void writeGepObjVarMapToFile (std::fstream &f)
 
virtual bool readFromFile (const std::string &filename)
 
virtual void readPtsResultFromFile (std::ifstream &f)
 
virtual void readGepObjVarMapFromFile (std::ifstream &f)
 
virtual void readAndSetObjFieldSensitivity (std::ifstream &f, const std::string &delimiterStr)
 
AliasResult alias (const SVFVar *V1, const SVFVar *V2) override
 Interface expose to users of our pointer analysis, given Value infos.
 
AliasResult alias (NodeID node1, NodeID node2) override
 Interface expose to users of our pointer analysis, given PAGNodeID.
 
virtual AliasResult alias (const PointsTo &pts1, const PointsTo &pts2)
 Interface expose to users of our pointer analysis, given two pts.
 
bool mayAlias (const PointsTo &pts1, const PointsTo &pts2)
 Convenience bool wrappers: return true if the two operands may/must/partial alias.
 
void dumpCPts () override
 dump and debug, print out conditional pts
 
void dumpTopLevelPtsTo () override
 
void dumpAllPts () override
 
- Public Member Functions inherited from SVF::PointerAnalysis
ICFGgetICFG () const
 Get ICFG.
 
u32_t getNumOfResolvedIndCallEdge () const
 Return number of resolved indirect call edges.
 
CallGraphgetCallGraph () const
 Return call graph.
 
CallGraphSCCgetCallGraphSCC () const
 Return call graph SCC.
 
 PointerAnalysis (SVFIR *pag, PTATY ty=PTATY::Default_PTA, bool alias_check=true)
 Constructor.
 
PTATY getAnalysisTy () const
 Type of pointer analysis.
 
PTAImplTy getImplTy () const
 Return implementation type of the pointer analysis.
 
bool printStat ()
 Whether print statistics.
 
void disablePrintStat ()
 Whether print statistics.
 
CallEdgeMapgetIndCallMap ()
 Get callees from an indirect callsite.
 
bool hasIndCSCallees (const CallICFGNode *cs) const
 
const FunctionSetgetIndCSCallees (const CallICFGNode *cs) const
 
virtual void resolveIndCalls (const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
 Resolve indirect call edges.
 
void callGraphSCCDetection ()
 PTACallGraph SCC related methods.
 
NodeID getCallGraphSCCRepNode (NodeID id) const
 Get SCC rep node of a SVFG node.
 
bool inSameCallGraphSCC (const FunObjVar *fun1, const FunObjVar *fun2)
 Return TRUE if this edge is inside a PTACallGraph SCC, i.e., src node and dst node are in the same SCC on the SVFG.
 
bool isInRecursion (const FunObjVar *fun) const
 
bool isLocalVarInRecursiveFun (NodeID id) const
 Whether a local variable is in function recursions.
 
CommonCHGraphgetCHGraph () const
 get CHGraph
 
void getVFnsFromCHA (const CallICFGNode *cs, VFunSet &vfns)
 
void getVFnsFromPts (const CallICFGNode *cs, const PointsTo &target, VFunSet &vfns)
 
void connectVCallToVFns (const CallICFGNode *cs, const VFunSet &vfns, CallEdgeMap &newEdges)
 
virtual void resolveCPPIndCalls (const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
 Resolve cpp indirect call edges.
 
SVFIRgetPAG () const
 
PTAStatgetStat () const
 Get PTA stat.
 
OrderedNodeSetgetAllValidPtrs ()
 Get all Valid Pointers for resolution.
 
virtual void computeDDAPts (NodeID)
 Compute points-to results on-demand, overridden by derived classes.
 
bool mayAlias (const SVFVar *V1, const SVFVar *V2)
 Convenience bool wrappers: return true if the two operands may/must/partial alias.
 
bool mayAlias (NodeID node1, NodeID node2)
 
void printIndCSTargets (const CallICFGNode *cs, const FunctionSet &targets)
 Print targets of a function pointer.
 
virtual void dumpPts (NodeID ptr, const PointsTo &pts)
 
void printIndCSTargets ()
 
void dumpAllTypes ()
 
void dumpStat ()
 Dump the statistics.
 
bool containBlackHoleNode (const PointsTo &pts)
 Determine whether a points-to contains a black hole or constant node.
 
bool containConstantNode (const PointsTo &pts)
 
virtual bool isBlkObjOrConstantObj (NodeID ptd) const
 
bool isHeapMemObj (NodeID id) const
 Whether this object is heap or array.
 
bool isArrayMemObj (NodeID id) const
 
bool isFIObjNode (NodeID id) const
 
NodeID getBaseObjVarID (NodeID id)
 
NodeID getFIObjVar (NodeID id)
 
NodeID getGepObjVar (NodeID id, const APOffset &ap)
 
virtual const NodeBSgetAllFieldsObjVars (NodeID id)
 
void setObjFieldInsensitive (NodeID id)
 
bool isFieldInsensitive (NodeID id) const
 

Static Public Member Functions

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

Static Public Attributes

static const Version invalidVersion = 0
 If this version appears, there has been an error.
 
- Static Public Attributes inherited from SVF::PointerAnalysis
static const std::string aliasTestMayAlias = "MAYALIAS"
 
static const std::string aliasTestMayAliasMangled = "_Z8MAYALIASPvS_"
 
static const std::string aliasTestNoAlias = "NOALIAS"
 
static const std::string aliasTestNoAliasMangled = "_Z7NOALIASPvS_"
 
static const std::string aliasTestPartialAlias = "PARTIALALIAS"
 
static const std::string aliasTestPartialAliasMangled = "_Z12PARTIALALIASPvS_"
 
static const std::string aliasTestMustAlias = "MUSTALIAS"
 
static const std::string aliasTestMustAliasMangled = "_Z9MUSTALIASPvS_"
 
static const std::string aliasTestFailMayAlias = "EXPECTEDFAIL_MAYALIAS"
 
static const std::string aliasTestFailMayAliasMangled = "_Z21EXPECTEDFAIL_MAYALIASPvS_"
 
static const std::string aliasTestFailNoAlias = "EXPECTEDFAIL_NOALIAS"
 
static const std::string aliasTestFailNoAliasMangled = "_Z20EXPECTEDFAIL_NOALIASPvS_"
 

Protected Member Functions

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

Private Types

typedef CoreBitVector MeldVersion
 

Private Member Functions

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

Static Private Member Functions

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

Private Attributes

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

Static Private Attributes

static VersionedFlowSensitivevfspta = nullptr
 

Friends

class VersionedFlowSensitiveStat
 

Additional Inherited Members

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

Detailed Description

Versioned flow sensitive whole program pointer analysis

Definition at line 29 of file VersionedFlowSensitive.h.

Member Typedef Documentation

◆ LocVersionMap

Definition at line 40 of file VersionedFlowSensitive.h.

◆ MeldVersion

Definition at line 34 of file VersionedFlowSensitive.h.

◆ ObjToVersionMap

Definition at line 37 of file VersionedFlowSensitive.h.

◆ VarToPropNodeMap

Definition at line 38 of file VersionedFlowSensitive.h.

◆ VersionRelianceMap

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

Definition at line 42 of file VersionedFlowSensitive.h.

Constructor & Destructor Documentation

◆ VersionedFlowSensitive()

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

Constructor.

Definition at line 33 of file VersionedFlowSensitive.cpp.

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

Member Function Documentation

◆ atKey()

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

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

Definition at line 27 of file VersionedFlowSensitive.cpp.

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

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

◆ buildIsStoreLoadMaps()

void VersionedFlowSensitive::buildIsStoreLoadMaps ( void  )
privatevirtual

Fills in isStoreMap and isLoadMap.

Definition at line 447 of file VersionedFlowSensitive.cpp.

448{
449 isStoreMap.resize(svfg->getTotalNodeNum(), false);
450 isLoadMap.resize(svfg->getTotalNodeNum(), false);
451 for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
452 {
453 if (SVFUtil::isa<StoreSVFGNode>(it->second)) isStoreMap[it->first] = true;
454 else if (SVFUtil::isa<LoadSVFGNode>(it->second)) isLoadMap[it->first] = true;
455 }
456}
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 71 of file VersionedFlowSensitive.h.

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

◆ classof() [2/2]

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

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

Definition at line 67 of file VersionedFlowSensitive.h.

68 {
69 return true;
70 }

◆ cluster()

void VersionedFlowSensitive::cluster ( void  )
overrideprotectedvirtual

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

Reimplemented from SVF::FlowSensitive.

Definition at line 783 of file VersionedFlowSensitive.cpp.

784{
785 std::vector<std::pair<unsigned, unsigned>> keys;
786 for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit)
787 {
788 unsigned occ = 1;
789 //ABTest
790 unsigned v = pit->first;
791 if (Options::PredictPtOcc() && pag->getBaseObject(v) != nullptr) occ = stmtReliance[v].size() + 1;
792 assert(occ != 0);
793 keys.push_back(std::make_pair(v, occ));
794 }
795
796 PointsTo::MappingPtr nodeMapping =
797 std::make_shared<std::vector<NodeID>>(
799 );
800 PointsTo::MappingPtr reverseNodeMapping =
801 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
802
803 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
804}
std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > candidateMappings
Save candidate mappings for evaluation's sake.
IDToNodeMapTy::iterator iterator
Node Iterators.
static std::vector< NodeID > getReverseNodeMapping(const std::vector< NodeID > &nodeMapping)
static std::vector< NodeID > cluster(BVDataPTAImpl *pta, const std::vector< std::pair< NodeID, unsigned > > keys, std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > &candidates, std::string evalSubtitle="", bool printStat=true)
static const Option< bool > PredictPtOcc
Definition Options.h:62
bool print_stat
User input flags.
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:43
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:371
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:498
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 78 of file VersionedFlowSensitive.h.

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

◆ delta()

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

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

Definition at line 435 of file VersionedFlowSensitive.cpp.

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

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

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

◆ dumpLocVersionMaps()

void VersionedFlowSensitive::dumpLocVersionMaps ( void  ) const

Dumps maps consume and yield.

Definition at line 913 of file VersionedFlowSensitive.cpp.

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

◆ dumpMeldVersion()

void VersionedFlowSensitive::dumpMeldVersion ( MeldVersion v)
static

Dumps a MeldVersion to stdout.

Definition at line 949 of file VersionedFlowSensitive.cpp.

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

◆ dumpReliances()

void VersionedFlowSensitive::dumpReliances ( void  ) const

Dumps versionReliance and stmtReliance.

Definition at line 856 of file VersionedFlowSensitive.cpp.

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

◆ finalize()

void VersionedFlowSensitive::finalize ( )
overridevirtual

Finalize analysis.

Reimplemented from SVF::FlowSensitive.

Definition at line 68 of file VersionedFlowSensitive.cpp.

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

◆ getConsume()

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

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

Definition at line 816 of file VersionedFlowSensitive.cpp.

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

◆ getReliantVersions()

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

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

Definition at line 846 of file VersionedFlowSensitive.cpp.

847{
848 return versionReliance[o][v];
849}

◆ getStmtReliance()

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

Returns the statements which rely on o:v.

Definition at line 851 of file VersionedFlowSensitive.cpp.

852{
853 return stmtReliance[o][v];
854}

◆ getVersion()

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

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

Definition at line 806 of file VersionedFlowSensitive.cpp.

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

◆ getYield()

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

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

Definition at line 821 of file VersionedFlowSensitive.cpp.

822{
823 // Non-store: consume == yield.
824 if (isStore(l)) return getVersion(l, o, yield);
825 else return getVersion(l, o, consume);
826}
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 48 of file VersionedFlowSensitive.cpp.

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

◆ isLoad()

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

Returns true if l is a load node.

Definition at line 464 of file VersionedFlowSensitive.cpp.

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

◆ isStore()

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

Returns true if l is a store node.

Definition at line 458 of file VersionedFlowSensitive.cpp.

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

◆ meld()

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

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

Definition at line 429 of file VersionedFlowSensitive.cpp.

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

◆ meldLabel()

void VersionedFlowSensitive::meldLabel ( void  )
private

Meld label the prelabeled SVFG.

Definition at line 123 of file VersionedFlowSensitive.cpp.

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

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

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

◆ processLoad()

bool VersionedFlowSensitive::processLoad ( const LoadSVFGNode load)
overrideprotectedvirtual

Process load node

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

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

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

Reimplemented from SVF::FlowSensitive.

Definition at line 650 of file VersionedFlowSensitive.cpp.

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

◆ processNode()

void VersionedFlowSensitive::processNode ( NodeID  nodeId)
overrideprotectedvirtual

Handle various constraints.

Process each SVFG node

Reimplemented from SVF::FlowSensitive.

Definition at line 593 of file VersionedFlowSensitive.cpp.

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

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

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

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

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

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

550{
551 double start = stat->getClk();
552
553 const std::vector<Version> &reliantVersions = getReliantVersions(o, v);
555 {
556 propagateVersion(o, v, r, false);
557 }
558
559 double end = stat->getClk();
561}
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 103 of file VersionedFlowSensitive.h.

104 {
105 return false;
106 }

◆ PTAName()

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

Get PTA name.

Reimplemented from SVF::FlowSensitive.

Definition at line 60 of file VersionedFlowSensitive.h.

61 {
62 return "VersionedFlowSensitive";
63 }

◆ readPtsFromFile()

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

Initialization for the Solver

Load the pts from file

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 967 of file VersionedFlowSensitive.cpp.

968{
970 initialize();
972 if(!filename.empty())
973 {
974 SVFUtil::outs() << "Loading versioned pointer analysis results from '" << filename << "'...";
975
976 std::ifstream F(filename.c_str());
977 if (!F.is_open())
978 {
979 SVFUtil::outs() << " error opening file for reading!\n";
980 return ;
981 }
983
985
987
989
991
992 // Update callgraph
994
995 F.close();
996 SVFUtil::outs() << "\n";
997 }
998
1000 finalize();
1001}
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:453
void readVersionedAnalysisResultFromFile(std::ifstream &F)
virtual void initialize() override
Initialize analysis.
virtual void finalize() override
Finalize analysis.

◆ readVersionedAnalysisResultFromFile()

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

Definition at line 1071 of file VersionedFlowSensitive.cpp.

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

◆ releaseVFSWPA()

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

Release flow-sensitive pointer analysis.

Definition at line 90 of file VersionedFlowSensitive.h.

91 {
92 if (vfspta) delete vfspta;
93 vfspta = nullptr;
94 }

◆ removeAllIndirectSVFGEdges()

void VersionedFlowSensitive::removeAllIndirectSVFGEdges ( void  )
private

Removes all indirect edges in the SVFG.

Definition at line 527 of file VersionedFlowSensitive.cpp.

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

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

835{
836 setVersion(l, o, v, consume);
837}
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 828 of file VersionedFlowSensitive.cpp.

829{
831 ovm[o] = v;
832}

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

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

◆ solveAndwritePtsToFile()

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

Start analysis

Initialization for the Solver

finalize the analysis

Initialization for the Solver

finalize the analysis

Reimplemented from SVF::FlowSensitive.

Definition at line 1003 of file VersionedFlowSensitive.cpp.

1004{
1006 initialize();
1007 if(!filename.empty())
1010 if(!filename.empty())
1011 {
1014 }
1016 finalize();
1017}
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 608 of file VersionedFlowSensitive.cpp.

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

◆ writeVersionedAnalysisResultToFile()

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

Definition at line 1019 of file VersionedFlowSensitive.cpp.

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

Friends And Related Symbol Documentation

◆ VersionedFlowSensitiveStat

Definition at line 31 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 195 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 224 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 229 of file VersionedFlowSensitive.h.

◆ equivalentObject

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

Definition at line 211 of file VersionedFlowSensitive.h.

◆ invalidVersion

const Version VersionedFlowSensitive::invalidVersion = 0
static

If this version appears, there has been an error.

Definition at line 45 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 235 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 232 of file VersionedFlowSensitive.h.

◆ meldLabelingTime

double SVF::VersionedFlowSensitive::meldLabelingTime
private

Time to meld label SVFG.

Definition at line 243 of file VersionedFlowSensitive.h.

◆ numPrelabeledNodes

u32_t SVF::VersionedFlowSensitive::numPrelabeledNodes
private

Additional statistics.

Number of prelabeled nodes.

Definition at line 239 of file VersionedFlowSensitive.h.

◆ numPrelabelVersions

u32_t SVF::VersionedFlowSensitive::numPrelabelVersions
private

Number of versions created during prelabeling.

Definition at line 240 of file VersionedFlowSensitive.h.

◆ prelabeledObjects

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

Definition at line 217 of file VersionedFlowSensitive.h.

◆ prelabelingTime

double SVF::VersionedFlowSensitive::prelabelingTime
private

Time to prelabel SVFG.

Definition at line 242 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 202 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 206 of file VersionedFlowSensitive.h.

◆ versionPropTime

double SVF::VersionedFlowSensitive::versionPropTime
private

Time to propagate versions to versions which rely on them.

Definition at line 244 of file VersionedFlowSensitive.h.

◆ versionReliance

VersionRelianceMap SVF::VersionedFlowSensitive::versionReliance
private

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

Definition at line 200 of file VersionedFlowSensitive.h.

◆ vfspta

VersionedFlowSensitive * VersionedFlowSensitive::vfspta = nullptr
staticprivate

Definition at line 247 of file VersionedFlowSensitive.h.

◆ vPtD

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

Points-to DS for working with versions.

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

◆ yield

LocVersionMap SVF::VersionedFlowSensitive::yield
private

Actual yield map. Yield analogue to consume.

Definition at line 197 of file VersionedFlowSensitive.h.


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