svf-lib 1.0.708 → 1.0.709

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
@@ -200,6 +200,14 @@ private:
200
200
  std::vector<Word> words;
201
201
  };
202
202
 
203
+ template <>
204
+ struct Hash<CoreBitVector>
205
+ {
206
+ size_t operator()(const CoreBitVector &cbv) const {
207
+ return cbv.hash();
208
+ }
209
+ };
210
+
203
211
  };
204
212
 
205
213
  #endif // COREBITVECTOR_H_
@@ -73,6 +73,9 @@ public:
73
73
  /// Time limit for the Andersen's analyses.
74
74
  static const llvm::cl::opt<unsigned> AnderTimeLimit;
75
75
 
76
+ /// Number of threads for the versioning phase.
77
+ static const llvm::cl::opt<unsigned> VersioningThreads;
78
+
76
79
  // ContextDDA.cpp
77
80
  static const llvm::cl::opt<unsigned long long> CxtBudget;
78
81
 
@@ -82,7 +82,6 @@ typedef u32_t EdgeID;
82
82
  typedef unsigned SymID;
83
83
  typedef unsigned CallSiteID;
84
84
  typedef unsigned ThreadID;
85
- typedef unsigned Version;
86
85
 
87
86
  typedef llvm::SparseBitVector<> NodeBS;
88
87
  typedef llvm::SparseBitVector<> SparseBitVector;
@@ -111,7 +110,6 @@ template <typename T, unsigned N>
111
110
  using SmallVector = llvm::SmallVector<T, N>;
112
111
 
113
112
  typedef std::pair<NodeID, NodeID> NodePair;
114
- typedef std::pair<NodeID, Version> VersionedVar;
115
113
  typedef OrderedSet<NodeID> OrderedNodeSet;
116
114
  typedef Set<NodeID> NodeSet;
117
115
  typedef Set<NodePair> NodePairSet;
@@ -127,6 +125,11 @@ typedef NodeSet EdgeSet;
127
125
  typedef SmallVector16 CallStrCxt;
128
126
  typedef llvm::StringMap<u32_t> StringMap;
129
127
 
128
+ typedef unsigned Version;
129
+ typedef Set<Version> VersionSet;
130
+ typedef std::pair<NodeID, Version> VersionedVar;
131
+ typedef Set<VersionedVar> VersionedVarSet;
132
+
130
133
  // TODO: be explicit that this is a pair of 32-bit unsigneds?
131
134
  template <> struct Hash<NodePair>
132
135
  {
@@ -298,4 +301,21 @@ struct std::hash<llvm::SparseBitVector<N>>
298
301
  }
299
302
  };
300
303
 
304
+ template <typename T>
305
+ struct std::hash<std::vector<T>>
306
+ {
307
+ size_t operator()(const std::vector<T> &v) const {
308
+ // TODO: repetition with CBV.
309
+ size_t h = v.size();
310
+
311
+ SVF::Hash<T> hf;
312
+ for (const T &t : v)
313
+ {
314
+ h ^= hf(t) + 0x9e3779b9 + (h << 6) + (h >> 2);
315
+ }
316
+
317
+ return h;
318
+ }
319
+ };
320
+
301
321
  #endif /* INCLUDE_UTIL_SVFBASICTYPES_H_ */
@@ -30,30 +30,16 @@ class VersionedFlowSensitive : public FlowSensitive
30
30
  friend class VersionedFlowSensitiveStat;
31
31
 
32
32
  private:
33
- typedef llvm::SparseBitVector<> MeldVersion;
33
+ typedef CoreBitVector MeldVersion;
34
34
 
35
35
  public:
36
36
  typedef Map<NodeID, Version> ObjToVersionMap;
37
- typedef Map<NodeID, MeldVersion> ObjToMeldVersionMap;
38
37
  typedef Map<VersionedVar, const DummyVersionPropSVFGNode *> VarToPropNodeMap;
39
38
 
40
- typedef Map<NodeID, ObjToVersionMap> LocVersionMap;
41
- /// Maps locations to all versions it sees (through objects).
42
- typedef Map<NodeID, ObjToMeldVersionMap> LocMeldVersionMap;
39
+ typedef std::vector<ObjToVersionMap> LocVersionMap;
43
40
  /// (o -> (v -> versions with rely on o:v).
44
41
  typedef Map<NodeID, Map<Version, std::vector<Version>>> VersionRelianceMap;
45
42
 
46
- /// For caching the first step in LocVersionMaps.
47
- typedef struct VersionCache
48
- {
49
- /// SVFG node ID.
50
- NodeID l;
51
- /// Nested map, i.e. consume[l] or yield[l].
52
- ObjToVersionMap *ovm;
53
- /// Whether l and ovm can be accessed.
54
- bool valid;
55
- } VersionCache;
56
-
57
43
  /// If this version appears, there has been an error.
58
44
  static const Version invalidVersion;
59
45
 
@@ -126,16 +112,8 @@ private:
126
112
  /// Melds v2 into v1 (in place), returns whether a change occurred.
127
113
  static bool meld(MeldVersion &mv1, const MeldVersion &mv2);
128
114
 
129
- /// Moves meldConsume/Yield to consume/yield.
130
- void mapMeldVersions();
131
-
132
- /// Returns a new MeldVersion for o during the prelabeling phase.
133
- MeldVersion newMeldVersion(NodeID o);
134
-
135
- /// Determine which versions rely on which versions (e.g. c_l'(o) relies on y_l(o)
136
- /// given l-o->l' and y_l(o) = a, c_l'(o) = b), and which statements rely on which
137
- /// versions (e.g. node l relies on c_l(o)).
138
- void determineReliance(void);
115
+ /// Removes all indirect edges in the SVFG.
116
+ void removeAllIndirectSVFGEdges(void);
139
117
 
140
118
  /// Propagates version v of o to any version of o which relies on v when o/v is changed.
141
119
  /// Recursively applies to reliant versions till no new changes are made.
@@ -146,22 +124,37 @@ private:
146
124
  /// taken itself.
147
125
  void propagateVersion(const NodeID o, const Version v, const Version vp, bool time=true);
148
126
 
149
- /// Returns true if l is a delta node, i.e., may have new incoming edges due to
150
- /// on-the-fly call graph resolution. approxCallGraph is the over-approximate
151
- /// call graph built by the pre-analysis.
152
- virtual bool delta(NodeID l) const;
127
+ /// Fills in isStoreMap and isLoadMap.
128
+ virtual void buildIsStoreLoadMaps(void);
129
+
130
+ /// Returns true if l is a store node.
131
+ virtual bool isStore(const NodeID l) const;
132
+
133
+ /// Returns true if l is a load node.
134
+ virtual bool isLoad(const NodeID l) const;
135
+
136
+ /// Fills in deltaMap and deltaSourceMap for the SVFG.
137
+ virtual void buildDeltaMaps(void);
138
+
139
+ /// Returns true if l is a delta node, i.e., may get a new incoming indirect
140
+ /// edge due to on-the-fly callgraph construction.
141
+ virtual bool delta(const NodeID l) const;
142
+
143
+ /// Returns true if l is a delta-source node, i.e., may get a new outgoing indirect
144
+ /// edge to a delta node due to on-the-fly callgraph construction.
145
+ virtual bool deltaSource(const NodeID l) const;
153
146
 
154
147
  /// Shared code for getConsume and getYield. They wrap this function.
155
- Version getVersion(const NodeID l, const NodeID o, VersionCache &cache, LocVersionMap &lvm);
148
+ Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const;
156
149
 
157
150
  /// Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
158
- Version getConsume(const NodeID l, const NodeID o);
151
+ Version getConsume(const NodeID l, const NodeID o) const;
159
152
 
160
153
  /// Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
161
- Version getYield(const NodeID l, const NodeID o);
154
+ Version getYield(const NodeID l, const NodeID o) const;
162
155
 
163
156
  /// Shared code for setConsume and setYield. They wrap this function.
164
- void setVersion(const NodeID l, const NodeID o, const Version v, VersionCache &cache, LocVersionMap &lvm);
157
+ void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm);
165
158
 
166
159
  /// Sets the consumed version of o at l to v.
167
160
  void setConsume(const NodeID l, const NodeID o, const Version v);
@@ -169,11 +162,11 @@ private:
169
162
  /// Sets the yielded version of o at l to v.
170
163
  void setYield(const NodeID l, const NodeID o, const Version v);
171
164
 
172
- /// Invalidates yieldCache.
173
- void invalidateYieldCache(void);
165
+ /// Returns the versions of o which rely on o:v.
166
+ std::vector<Version> &getReliantVersions(const NodeID o, const Version v);
174
167
 
175
- /// Invalidates consumeCache.
176
- void invalidateConsumeCache(void);
168
+ /// Returns the statements which rely on o:v.
169
+ NodeBS &getStmtReliance(const NodeID o, const Version v);
177
170
 
178
171
  /// Dumps versionReliance and stmtReliance.
179
172
  void dumpReliances(void) const;
@@ -184,35 +177,12 @@ private:
184
177
  /// Dumps a MeldVersion to stdout.
185
178
  static void dumpMeldVersion(MeldVersion &v);
186
179
 
187
- /// SVFG node (label) x object -> version to consume.
188
- /// Used during meld labeling. We use MeldVersions and Versions for performance.
189
- /// MeldVersions are currently SparseBitVectors which are necessary for the meld operator,
190
- /// but when meld labeling is complete, we don't want to carry around SBVs and use them; integers
191
- /// are better.
192
- LocMeldVersionMap meldConsume;
193
- /// SVFG node (label) x object -> version to yield.
194
- /// Used during meld labeling.
195
- /// For non-stores, yield == consume, so meldYield only has entries for stores.
196
- LocMeldVersionMap meldYield;
197
- /// Object -> MeldVersion counter. Used in the prelabeling phase to generate a
198
- /// new MeldVersion.
199
- Map<NodeID, unsigned> meldVersions;
200
-
201
- /// Like meldConsume but with Versions, not MeldVersions.
202
- /// Created after meld labeling from meldConsume and used during the analysis.
203
- /// When modifying consume itself (not a value) outside of setConsume, invalidateConsumeCache
204
- /// should be called. E.g. if a call like consume[l] is an insertion.
180
+ /// Maps locations to objects to a version. The object version is what is
181
+ /// consumed at that location.
205
182
  LocVersionMap consume;
206
183
  /// Actual yield map. Yield analogue to consume.
207
- /// When modifying yield itself (not a value) outside of setYield, invalidateYieldCache
208
- /// should be called.
209
184
  LocVersionMap yield;
210
185
 
211
- /// Cache for the nested map in consume.
212
- VersionCache consumeCache;
213
- /// Cache for the nested map in yield.
214
- VersionCache yieldCache;
215
-
216
186
  /// o -> (version -> versions which rely on it).
217
187
  VersionRelianceMap versionReliance;
218
188
  /// o x version -> statement nodes which rely on that o/version.
@@ -222,26 +192,87 @@ private:
222
192
  /// needs to be propagated.
223
193
  VarToPropNodeMap versionedVarToPropNode;
224
194
 
195
+ // Maps an object o to o' if o is equivalent to o' with respect to
196
+ // versioning. Thus, we don't need to store the versions of o and look
197
+ // up those for o' instead.
198
+ Map<NodeID, NodeID> equivalentObject;
199
+
225
200
  /// Worklist for performing meld labeling, takes SVFG node l.
226
201
  /// Nodes are added when the version they yield is changed.
227
202
  FIFOWorkList<NodeID> vWorklist;
228
203
 
204
+ Set<NodeID> prelabeledObjects;
205
+
229
206
  /// Points-to DS for working with versions.
230
207
  BVDataPTAImpl::VersionedPTDataTy *vPtD;
231
208
 
209
+ /// deltaMap[l] means SVFG node l is a delta node, i.e., may get new
210
+ /// incoming edges due to OTF callgraph construction.
211
+ std::vector<bool> deltaMap;
212
+
213
+ /// deltaSourceMap[l] means SVFG node l *may* be a source to a delta node
214
+ /// through an dge added as a result of on-the-fly callgraph
215
+ /// construction.
216
+ std::vector<bool> deltaSourceMap;
217
+
218
+ /// isStoreMap[l] means SVFG node l is a store node.
219
+ std::vector<bool> isStoreMap;
220
+
221
+ /// isLoadMap[l] means SVFG node l is a load node.
222
+ std::vector<bool> isLoadMap;
223
+
232
224
  /// Additional statistics.
233
225
  //@{
234
226
  Size_t numPrelabeledNodes; ///< Number of prelabeled nodes.
235
227
  Size_t numPrelabelVersions; ///< Number of versions created during prelabeling.
236
228
 
237
- double relianceTime; ///< Time to determine version and statement reliance.
238
229
  double prelabelingTime; ///< Time to prelabel SVFG.
239
230
  double meldLabelingTime; ///< Time to meld label SVFG.
240
- double meldMappingTime; ///< Time to map MeldVersions to Versions.
241
231
  double versionPropTime; ///< Time to propagate versions to versions which rely on them.
242
232
  //@}
243
233
 
244
234
  static VersionedFlowSensitive *vfspta;
235
+
236
+ class SCC
237
+ {
238
+ private:
239
+ typedef struct NodeData
240
+ {
241
+ int index;
242
+ int lowlink;
243
+ bool onStack;
244
+ } NodeData;
245
+
246
+ public:
247
+ /// Determines the strongly connected components of svfg following only
248
+ /// edges labelled with object. partOf[n] = scc means nodes n is part of
249
+ /// SCC scc. startingNodes contains the nodes to begin the search from.
250
+ /// After completion, footprint will contain all edges which object
251
+ /// appears on (as reached through the algorithm described above) sorted.
252
+ ///
253
+ /// This is not a general SCC detection but specifically for versioning,
254
+ /// so edges to delta nodes are skipped as they are prelabelled. Edges
255
+ /// to stores are also skipped to as they yield a new version (they
256
+ /// cannot be part of an SCC containing more than themselves).
257
+ /// Skipped edges still form part of the footprint.
258
+ static unsigned detectSCCs(VersionedFlowSensitive *vfs,
259
+ const SVFG *svfg, const NodeID object,
260
+ const std::vector<const SVFGNode *> &startingNodes,
261
+ std::vector<int> &partOf,
262
+ std::vector<const IndirectSVFGEdge *> &footprint);
263
+
264
+ private:
265
+ /// Called by detectSCCs then called recursively.
266
+ static void visit(VersionedFlowSensitive *vfs,
267
+ const NodeID object,
268
+ std::vector<int> &partOf,
269
+ std::vector<const IndirectSVFGEdge *> &footprint,
270
+ std::vector<NodeData> &nodeData,
271
+ std::stack<const SVFGNode *> &stack,
272
+ int &index,
273
+ int &currentSCC,
274
+ const SVFGNode *v);
275
+ };
245
276
  };
246
277
 
247
278
  } // End namespace SVF
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-lib",
3
- "version": "1.0.708",
3
+ "version": "1.0.709",
4
4
  "description": "SVF's npm support",
5
5
  "main": "index.js",
6
6
  "scripts": {