Static Value-Flow Analysis
VersionedFlowSensitive.h
Go to the documentation of this file.
1 //===- VersionedFlowSensitive.h -- Versioned flow-sensitive pointer analysis --------//
2 
3 /*
4  * VersionedFlowSensitiveAnalysis.h
5  *
6  * Created on: Jun 26, 2020
7  * Author: Mohamad Barbar
8  *
9  * The implementation is based on
10  * Mohamad Barbar, Yulei Sui and Shiping Chen. "Object Versioning for Flow-Sensitive Pointer Analysis".
11  * International Symposium on Code Generation and Optimization (CGO'21)
12  */
13 
14 #ifndef VFS_H_
15 #define VFS_H_
16 
17 #include "Graphs/SVFGOPT.h"
18 #include "MSSA/SVFGBuilder.h"
19 #include "WPA/FlowSensitive.h"
20 #include "WPA/WPAFSSolver.h"
21 #include "MemoryModel/PointsTo.h"
22 
23 namespace SVF
24 {
25 
26 class AndersenWaveDiff;
27 class SVFModule;
28 
33 {
35 
36 private:
38 
39 public:
42 
43  typedef std::vector<ObjToVersionMap> LocVersionMap;
46 
48  static const Version invalidVersion;
49 
52 
55 
57  virtual void initialize() override;
58 
60  virtual void finalize() override;
61 
63  virtual const std::string PTAName() const override
64  {
65  return "VersionedFlowSensitive";
66  }
67 
69 
70  static inline bool classof(const VersionedFlowSensitive *)
71  {
72  return true;
73  }
74  static inline bool classof(const PointerAnalysis *pta)
75  {
76  return pta->getAnalysisTy() == VFS_WPA;
77  }
79 
82  {
83  if (vfspta == nullptr)
84  {
85  vfspta = new VersionedFlowSensitive(_pag);
86  vfspta->analyze();
87  }
88 
89  return vfspta;
90  }
91 
93  static void releaseVFSWPA()
94  {
95  if (vfspta) delete vfspta;
96  vfspta = nullptr;
97  }
98 
99 protected:
100  virtual bool processLoad(const LoadSVFGNode* load) override;
101  virtual bool processStore(const StoreSVFGNode* store) override;
102  virtual void processNode(NodeID n) override;
103  virtual void updateConnectedNodes(const SVFGEdgeSetTy& newEdges) override;
104 
106  virtual bool propAlongIndirectEdge(const IndirectSVFGEdge*) override
107  {
108  return false;
109  }
110 
112  virtual void cluster(void) override;
113 
114 private:
116  void prelabel(void);
118  void meldLabel(void);
120  static bool meld(MeldVersion &mv1, const MeldVersion &mv2);
121 
123  void removeAllIndirectSVFGEdges(void);
124 
128  void propagateVersion(NodeID o, Version v);
129 
132  void propagateVersion(const NodeID o, const Version v, const Version vp, bool time=true);
133 
135  virtual void buildIsStoreLoadMaps(void);
136 
138  virtual bool isStore(const NodeID l) const;
139 
141  virtual bool isLoad(const NodeID l) const;
142 
144  virtual void buildDeltaMaps(void);
145 
148  virtual bool delta(const NodeID l) const;
149 
152  virtual bool deltaSource(const NodeID l) const;
153 
155  Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const;
156 
158  Version getConsume(const NodeID l, const NodeID o) const;
159 
161  Version getYield(const NodeID l, const NodeID o) const;
162 
164  void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm);
165 
167  void setConsume(const NodeID l, const NodeID o, const Version v);
168 
170  void setYield(const NodeID l, const NodeID o, const Version v);
171 
173  std::vector<Version> &getReliantVersions(const NodeID o, const Version v);
174 
176  NodeBS &getStmtReliance(const NodeID o, const Version v);
177 
179  void dumpReliances(void) const;
180 
182  void dumpLocVersionMaps(void) const;
183 
184  void solveAndwritePtsToFile(const std::string& filename) override;
185 
186  void writeVersionedAnalysisResultToFile(const std::string& filename);
187 
188  void readVersionedAnalysisResultFromFile(std::ifstream& F);
189 
190  void readPtsFromFile(const std::string& filename) override;
191 
193  static void dumpMeldVersion(MeldVersion &v);
194 
200 
205 
209 
210  // Maps an object o to o' if o is equivalent to o' with respect to
211  // versioning. Thus, we don't need to store the versions of o and look
212  // up those for o' instead.
214 
218 
220 
223 
226  std::vector<bool> deltaMap;
227 
231  std::vector<bool> deltaSourceMap;
232 
234  std::vector<bool> isStoreMap;
235 
237  std::vector<bool> isLoadMap;
238 
240 
243 
248 
250 
251  class SCC
252  {
253  private:
254  typedef struct NodeData
255  {
256  int index;
257  int lowlink;
258  bool onStack;
260 
261  public:
273  static unsigned detectSCCs(VersionedFlowSensitive *vfs,
274  const SVFG *svfg, const NodeID object,
275  const std::vector<const SVFGNode *> &startingNodes,
276  std::vector<int> &partOf,
277  std::vector<const IndirectSVFGEdge *> &footprint);
278 
279  private:
281  static void visit(VersionedFlowSensitive *vfs,
282  const NodeID object,
283  std::vector<int> &partOf,
284  std::vector<const IndirectSVFGEdge *> &footprint,
285  std::vector<NodeData> &nodeData,
286  std::stack<const SVFGNode *> &stack,
287  int &index,
288  int &currentSCC,
289  const SVFGNode *v);
290  };
291 };
292 
293 } // End namespace SVF
294 
295 #endif /* VFS_H_ */
#define F(f)
newitem type
Definition: cJSON.cpp:2739
cJSON * n
Definition: cJSON.cpp:2558
int index
Definition: cJSON.h:170
const char *const string
Definition: cJSON.h:172
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
Definition: FlowSensitive.h:53
void analyze() override
Flow sensitive analysis.
PTATY
Pointer analysis type list.
@ VFS_WPA
Versioned sparse flow-sensitive WPA.
PTATY getAnalysisTy() const
Type of pointer analysis.
Definition: SVFG.h:66
struct SVF::VersionedFlowSensitive::SCC::NodeData NodeData
static void visit(VersionedFlowSensitive *vfs, const NodeID object, std::vector< int > &partOf, std::vector< const IndirectSVFGEdge * > &footprint, std::vector< NodeData > &nodeData, std::stack< const SVFGNode * > &stack, int &index, int &currentSCC, const SVFGNode *v)
Called by detectSCCs then called recursively.
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)
Version getYield(const NodeID l, const NodeID o) const
Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
void dumpLocVersionMaps(void) const
Dumps maps consume and yield.
BVDataPTAImpl::VersionedPTDataTy * vPtD
Points-to DS for working with versions.
LocVersionMap yield
Actual yield map. Yield analogue to consume.
std::vector< bool > isStoreMap
isStoreMap[l] means SVFG node l is a store node.
virtual void updateConnectedNodes(const SVFGEdgeSetTy &newEdges) override
Update nodes connected during updating call graph.
virtual bool processLoad(const LoadSVFGNode *load) override
static bool meld(MeldVersion &mv1, const MeldVersion &mv2)
Melds v2 into v1 (in place), returns whether a change occurred.
VersionRelianceMap versionReliance
o -> (version -> versions which rely on it).
u32_t numPrelabelVersions
Number of versions created during prelabeling.
void removeAllIndirectSVFGEdges(void)
Removes all indirect edges in the SVFG.
Map< NodeID, NodeID > equivalentObject
void readVersionedAnalysisResultFromFile(std::ifstream &F)
virtual void buildDeltaMaps(void)
Fills in deltaMap and deltaSourceMap for the SVFG.
NodeBS & getStmtReliance(const NodeID o, const Version v)
Returns the statements which rely on o:v.
static const Version invalidVersion
If this version appears, there has been an error.
virtual bool deltaSource(const NodeID l) const
double meldLabelingTime
Time to meld label SVFG.
static VersionedFlowSensitive * vfspta
static VersionedVar atKey(NodeID, Version)
Return key into vPtD for address-taken var of a specific version.
Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const
Shared code for getConsume and getYield. They wrap this function.
std::vector< bool > isLoadMap
isLoadMap[l] means SVFG node l is a load node.
virtual const std::string PTAName() const override
Get PTA name.
static void releaseVFSWPA()
Release flow-sensitive pointer analysis.
static void dumpMeldVersion(MeldVersion &v)
Dumps a MeldVersion to stdout.
double prelabelingTime
Time to prelabel SVFG.
void propagateVersion(NodeID o, Version v)
void prelabel(void)
Prelabel the SVFG: set y(o) for stores and c(o) for delta nodes to a new version.
virtual void initialize() override
Initialize analysis.
virtual void processNode(NodeID n) override
Handle various constraints.
virtual void buildIsStoreLoadMaps(void)
Fills in isStoreMap and isLoadMap.
virtual bool isLoad(const NodeID l) const
Returns true if l is a load node.
void dumpReliances(void) const
Dumps versionReliance and stmtReliance.
Map< VersionedVar, const DummyVersionPropSVFGNode * > VarToPropNodeMap
virtual bool delta(const NodeID l) const
std::vector< ObjToVersionMap > LocVersionMap
virtual bool processStore(const StoreSVFGNode *store) override
void setConsume(const NodeID l, const NodeID o, const Version v)
Sets the consumed version of o at l to v.
virtual bool isStore(const NodeID l) const
Returns true if l is a store node.
void meldLabel(void)
Meld label the prelabeled SVFG.
void writeVersionedAnalysisResultToFile(const std::string &filename)
VersionedFlowSensitive(SVFIR *_pag, PTATY type=VFS_WPA)
Constructor.
static bool classof(const PointerAnalysis *pta)
void setYield(const NodeID l, const NodeID o, const Version v)
Sets the yielded version of o at l to v.
void solveAndwritePtsToFile(const std::string &filename) override
virtual bool propAlongIndirectEdge(const IndirectSVFGEdge *) override
Override to do nothing. Instead, we will use propagateVersion when necessary.
Map< NodeID, Map< Version, std::vector< Version > > > VersionRelianceMap
(o -> (v -> versions with rely on o:v).
virtual void finalize() override
Finalize analysis.
void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm)
Shared code for setConsume and setYield. They wrap this function.
FIFOWorkList< NodeID > vWorklist
static VersionedFlowSensitive * createVFSWPA(SVFIR *_pag)
Create single instance of versioned flow-sensitive points-to analysis.
std::vector< Version > & getReliantVersions(const NodeID o, const Version v)
Returns the versions of o which rely on o:v.
void readPtsFromFile(const std::string &filename) override
virtual void cluster(void) override
Override since we want to assign different weights based on versioning.
Map< NodeID, Map< Version, NodeBS > > stmtReliance
o x version -> statement nodes which rely on that o/version.
double versionPropTime
Time to propagate versions to versions which rely on them.
Version getConsume(const NodeID l, const NodeID o) const
Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
Map< NodeID, Version > ObjToVersionMap
static bool classof(const VersionedFlowSensitive *)
Methods to support type inquiry through isa, cast, and dyn_cast.
u32_t numPrelabeledNodes
Additional statistics.
for isBitcode
Definition: BasicTypes.h:68
std::pair< NodeID, Version > VersionedVar
Definition: GeneralType.h:125
u32_t NodeID
Definition: GeneralType.h:55
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
unsigned Version
Definition: GeneralType.h:123
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96