svf-lib 1.0.2680 → 1.0.2682

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.
Files changed (26) hide show
  1. package/SVF-linux-aarch64/bin/mta +0 -0
  2. package/SVF-linux-aarch64/include/AE/Core/NumericValue.h +1 -1
  3. package/SVF-linux-aarch64/include/Graphs/CDG.h +1 -1
  4. package/SVF-linux-aarch64/include/Graphs/CallGraph.h +34 -3
  5. package/SVF-linux-aarch64/include/Graphs/ICFG.h +6 -0
  6. package/SVF-linux-aarch64/include/Graphs/SVFG.h +6 -0
  7. package/SVF-linux-aarch64/include/Graphs/SlicedGraphs.h +119 -84
  8. package/SVF-linux-aarch64/include/Graphs/ThreadCallGraph.h +37 -0
  9. package/SVF-linux-aarch64/include/Graphs/VFG.h +1 -1
  10. package/SVF-linux-aarch64/include/MTA/FSMPTA.h +50 -34
  11. package/SVF-linux-aarch64/include/MTA/LockAnalysis.h +95 -55
  12. package/SVF-linux-aarch64/include/MTA/MHP.h +65 -24
  13. package/SVF-linux-aarch64/include/MTA/MTA.h +99 -51
  14. package/SVF-linux-aarch64/include/MTA/MTASVFGBuilder.h +115 -50
  15. package/SVF-linux-aarch64/include/MTA/MTASlicer.h +73 -79
  16. package/SVF-linux-aarch64/include/MTA/MTAStat.h +54 -6
  17. package/SVF-linux-aarch64/include/MTA/TCT.h +13 -22
  18. package/SVF-linux-aarch64/include/SVF-LLVM/GEPTypeBridgeIterator.h +2 -2
  19. package/SVF-linux-aarch64/include/SVF-LLVM/ObjTypeInference.h +1 -1
  20. package/SVF-linux-aarch64/include/Util/Options.h +2 -4
  21. package/SVF-linux-aarch64/include/Util/SparseBitVector.h +2 -2
  22. package/SVF-linux-aarch64/lib/libSvfCore.so.3.4 +0 -0
  23. package/SVF-linux-aarch64/lib/libSvfLLVM.so.3.4 +0 -0
  24. package/SVF-linux-x86_64/include/SVF-LLVM/GEPTypeBridgeIterator.h +7 -3
  25. package/SVF-linux-x86_64/lib/libSvfLLVM.so.3.4 +0 -0
  26. package/package.json +1 -1
@@ -29,10 +29,6 @@
29
29
  * The base data race detector is based on
30
30
  * Yulei Sui, Peng Di, and Jingling Xue. "Sparse Flow-Sensitive Pointer Analysis for Multithreaded Programs".
31
31
  * 2016 International Symposium on Code Generation and Optimization (CGO'16)
32
- *
33
- * This file also declares SlicedMTA, the multi-stage on-demand program slicing
34
- * pipeline (MSli) introduced in "Multi-Stage On-Demand Program Slicing for
35
- * Modular Analysis of Multi-Threaded Programs" (ISSTA 2026).
36
32
  */
37
33
 
38
34
  #ifndef MTA_H_
@@ -41,7 +37,6 @@
41
37
  #include <set>
42
38
  #include <string>
43
39
  #include <vector>
44
- #include <functional>
45
40
  #include <memory>
46
41
  #include <utility>
47
42
  #include "SVFIR/SVFIR.h"
@@ -51,6 +46,7 @@
51
46
  #include "MemoryModel/PointsTo.h"
52
47
  #include "MTA/MHP.h"
53
48
  #include "MTA/LockAnalysis.h"
49
+ #include "MTA/MTASVFGBuilder.h"
54
50
  #include "WPA/Andersen.h"
55
51
  #include "Graphs/CallGraph.h"
56
52
 
@@ -70,7 +66,6 @@ class SVFStmt;
70
66
  class SVFIR;
71
67
  class ICFGNode;
72
68
  // Forward declarations for the SlicedMTA slicing pipeline (see SlicedMTA impl).
73
- class MTASVFGBuilder;
74
69
  class SVFG;
75
70
  class FlowSensitive;
76
71
  class SlicedSVFGView;
@@ -102,9 +97,6 @@ public:
102
97
  /// Run the shared detector and print a race report
103
98
  virtual void reportRaces();
104
99
 
105
- // Not implemented for now
106
- // void dump(Module &module, MHP *mhp, LockAnalysis *lsa);
107
-
108
100
  MHP* getMHP()
109
101
  {
110
102
  return mhp;
@@ -120,22 +112,33 @@ public:
120
112
  {
121
113
  const SVFStmt* stmt1;
122
114
  const SVFStmt* stmt2;
123
- RacePair(const SVFStmt* s1, const SVFStmt* s2) : stmt1(s1), stmt2(s2) {}
115
+ RacePair(const SVFStmt* s1, const SVFStmt* s2)
116
+ : stmt1(statementLess(s2, s1) ? s2 : s1),
117
+ stmt2(statementLess(s2, s1) ? s1 : s2)
118
+ {
119
+ }
120
+
121
+ static bool statementLess(const SVFStmt* lhs, const SVFStmt* rhs)
122
+ {
123
+ return lhs->getEdgeID() < rhs->getEdgeID();
124
+ }
125
+
124
126
  bool operator<(const RacePair& other) const
125
127
  {
126
- if (stmt1 != other.stmt1) return stmt1 < other.stmt1;
127
- return stmt2 < other.stmt2;
128
+ if (stmt1->getEdgeID() != other.stmt1->getEdgeID())
129
+ return stmt1->getEdgeID() < other.stmt1->getEdgeID();
130
+ return stmt2->getEdgeID() < other.stmt2->getEdgeID();
128
131
  }
129
132
  };
130
133
 
131
134
  /// Shared equivalence-class race detector (used by both MTA::reportRaces and
132
135
  /// the SlicedMTA pipeline). Returns the racy statements and fills outRacePairs.
133
136
  static std::set<const SVFStmt*> detectRace(
134
- SVFIR* svfIr, AndersenBase* pta, MHP* mhp, LockAnalysis* lockAnalysis,
137
+ SVFIR* svfir, AndersenBase* pta, MHP* mhp, LockAnalysis* lockAnalysis,
135
138
  CallGraph* callGraph, std::set<RacePair>& outRacePairs);
136
139
 
137
140
  /// Escape/points-to helpers for the shared detector.
138
- static PointsTo getGlobalObjectVariables(SVFIR* svfIr);
141
+ static PointsTo getGlobalObjectVariables(SVFIR* svfir);
139
142
  static PointsTo getPointsToClosure(AndersenBase* pta, const PointsTo& pts);
140
143
 
141
144
  /// Whether the program has any thread (fork-target) function reachable via a
@@ -150,12 +153,47 @@ private:
150
153
  const ICFGNode* node;
151
154
  bool isStore;
152
155
  NodeID tid;
153
- NodeBS interleav;
156
+ const NodeBS* interleaving;
157
+ bool locked;
158
+ };
159
+
160
+ struct RaceClass
161
+ {
162
+ bool isStore;
163
+ bool locked;
164
+ size_t representative;
165
+ std::vector<size_t> members;
166
+ };
167
+
168
+ struct RaceClassKey
169
+ {
170
+ NodeID tid;
171
+ bool isStore;
172
+ const NodeBS* interleaving;
154
173
  bool locked;
174
+ NodeID lockNodeId;
175
+
176
+ bool operator<(const RaceClassKey& other) const;
155
177
  };
156
178
 
179
+ using ObjectToRaceOccurrences = Map<NodeID, std::vector<size_t>>;
180
+
157
181
  /// Helpers for the equivalence-class race detector.
158
182
  //@{
183
+ static void collectRaceOccurrences(
184
+ SVFIR* svfir, AndersenBase* pta, MHP* mhp,
185
+ LockAnalysis* lockAnalysis, CallGraph* callGraph,
186
+ const PointsTo& escapedObjects,
187
+ std::vector<RaceOccurrence>& occurrences,
188
+ ObjectToRaceOccurrences& objectToOccurrences);
189
+ static std::vector<RaceClass> buildRaceClasses(
190
+ const std::vector<RaceOccurrence>& occurrences,
191
+ const std::vector<size_t>& occurrenceIndices);
192
+ static void emitRacePairs(
193
+ MHP* mhp, LockAnalysis* lockAnalysis,
194
+ const std::vector<RaceOccurrence>& occurrences,
195
+ const std::vector<RaceClass>& classes,
196
+ std::set<RacePair>& outRacePairs);
159
197
  static bool occurrencesRace(MHP* mhp, const RaceOccurrence& first, const RaceOccurrence& second);
160
198
  static void commitRacePair(std::set<RacePair>& out,
161
199
  const RaceOccurrence& first, const RaceOccurrence& second);
@@ -178,21 +216,16 @@ private:
178
216
  * 4. PTA slicing + main flow-sensitive FSAM (FSMPTA) on the slice
179
217
  * 5. final race detection on the sliced graph using FSAM points-to
180
218
  *
181
- * It operates entirely on the SVFIR (LLVM-free). The single LLVM-dependent step --
182
- * materialising resolved indirect calls into the PAG -- is injected by the caller
183
- * as a callback (see runOnModule).
219
+ * It operates entirely on the SVFIR (LLVM-free). The LLVM-aware caller runs the
220
+ * Andersen pre-analysis and materialises its resolved indirect calls into the
221
+ * PAG before invoking runOnModule.
184
222
  *
185
- * Behaviour is controlled by Options (MTFlowSensitive, EnableSlicing,
186
- * SlicingSingle, SlicedDumpDot).
223
+ * Behaviour is controlled by Options (MTFlowSensitive, MTAEnableSlicing,
224
+ * MTASingleStageSlicing, DumpMTAGraphs).
187
225
  */
188
226
  class SlicedMTA
189
227
  {
190
228
  public:
191
- /// The one LLVM-dependent step of the pipeline: resolve the indirect-call
192
- /// edges discovered by Andersen into PAG copy/call edges. The caller (the
193
- /// LLVM-aware tool) supplies it via SVFIRBuilder::updateCallGraph.
194
- using ResolveIndirectCalls = std::function<void(CallGraph*)>;
195
-
196
229
  /// The shared race detector lives in MTA; reuse its race-pair type.
197
230
  using RacePair = MTA::RacePair;
198
231
 
@@ -204,20 +237,37 @@ public:
204
237
  SlicedMTA(const SlicedMTA&) = delete;
205
238
  SlicedMTA& operator=(const SlicedMTA&) = delete;
206
239
 
207
- /// Run the slicing pipeline on a pre-built SVFIR.
208
- void runOnModule(SVFIR* pag, const ResolveIndirectCalls& resolveIndirectCalls);
240
+ /// Run the slicing pipeline with its prepared Andersen pre-analysis.
241
+ bool runOnModule(SVFIR* pag, AndersenWaveDiff& preAnalysis);
209
242
 
210
243
  private:
211
244
  // --- pipeline stages ---
212
- bool runPreAnalysis(const ResolveIndirectCalls& resolveIndirectCalls);
245
+ bool runPreAnalysis();
213
246
  bool runMTASlicingAndAnalysis();
214
247
  bool runPTASlicingAndAnalysis();
215
248
  bool runFinalRaceDetection();
216
- void buildVFGPre();
249
+ void buildPreAnalysisSVFG();
250
+
251
+ /// Pipeline utilities shared by the sliced and whole-program paths.
252
+ //@{
253
+ static void reportOriginalStatistics(SVFIR* svfir);
254
+ static std::set<const ICFGNode*> collectICFGNodes(
255
+ SVFG* svfg, const NodeBS& svfgNodeIds);
256
+ static void reportPTASliceStatistics(
257
+ const std::set<const ICFGNode*>& icfgNodes);
258
+ struct RaceDigests
259
+ {
260
+ u64_t alarm;
261
+ u64_t pair;
262
+ };
263
+ static std::string raceStatementKey(const SVFStmt* statement);
264
+ static void updateDigest(u64_t& digest, const std::string& value);
265
+ static RaceDigests computeRaceDigests(const std::set<RacePair>& pairs);
266
+ //@}
217
267
 
218
268
  /// No-slice A/B baseline: run the FSAM detection on the whole program (no
219
269
  /// slicing), so its time and race set can be compared against the sliced run.
220
- void runWholeProgramDetection();
270
+ bool runWholeProgramDetection();
221
271
 
222
272
  /// Main pointer-analysis instance feeding final race detection (the
223
273
  /// flow-sensitive FSAM, a BVDataPTAImpl queried polymorphically).
@@ -227,47 +277,45 @@ private:
227
277
  std::set<const SVFStmt*> getVulnerableStmts() const;
228
278
 
229
279
  // --- race detection ---
230
- /// Re-check the candidate race pairs on the sliced graph using FSAM points-to.
280
+ /// Refine the pre-analysis candidate pairs with main-phase ILA and FSAM.
231
281
  std::set<RacePair> detectRacePairsOnSlicedGraph(
232
- BVDataPTAImpl* slicedPTA, MHP* slicedMHP, LockAnalysis* slicedLockAnalysis);
233
-
234
- // Lock analysis over the WHOLE ICFG (real control flow, no bridging) for the
235
- // final detection's lock signature. The sliced lock analysis walks bridged
236
- // edges, which fabricate lock-carrying paths the whole program lacks (a
237
- // query-preservation break); lock-span is control-flow-sensitive, so it must
238
- // see real edges. Built lazily, cheap (no FSAM/MHP) next to the slicing win.
239
- LockAnalysis* buildFullLockAnalysis();
282
+ const std::set<RacePair>& preAnalysisRacePairs,
283
+ BVDataPTAImpl* slicedPTA, MHP* slicedMHP,
284
+ LockAnalysis* slicedLockAnalysis);
240
285
 
241
286
  // --- pipeline state (owned unless noted) ---
242
- SVFIR* svfIr = nullptr;
287
+ SVFIR* svfir = nullptr;
243
288
  // Main-phase context depth, set by runOnModule; the pre-analysis uses it
244
289
  // to reconcile context-truncation-merged thread instances.
245
- u32_t mainCxtDepth = 2;
290
+ u32_t mainContextDepth;
246
291
  std::unique_ptr<TCT> tct;
247
292
  std::unique_ptr<MHP> mhp;
248
293
  std::unique_ptr<LockAnalysis> lockAnalysis;
249
294
  // Inclusion-based Andersen's pre-analysis (a shared singleton, not owned
250
- // here -- released once in the destructor). Feeds the TCT / MHP / lock /
295
+ // here; the tool releases it after this object is destroyed). Feeds TCT/MHP/lock/
251
296
  // race pre-analysis, the thread-aware VFG_pre, and the main FSMPTA.
252
- AndersenWaveDiff* preAnder = nullptr;
253
- std::unique_ptr<MTASVFGBuilder> vfgPreBuilder; // owns vfgPre
254
- SVFG* vfgPre = nullptr;
297
+ AndersenWaveDiff* preAndersen = nullptr;
298
+ ThreadCallGraph* threadCallGraph = nullptr;
299
+ std::unique_ptr<MTASVFGBuilder> preSVFGBuilder; // owns preSVFG
300
+ SVFG* preSVFG = nullptr;
255
301
  std::unique_ptr<MultiStageSlicer> multiStageSlicer;
302
+ NodeBS preCandidateSolveNodeIds;
256
303
  std::unique_ptr<SingleSlicer> singleSlicer;
304
+ /// VFG'_pre endpoint-filtered, context-insensitive pre-MHP candidates.
305
+ /// This is only a conservative worklist for rebuilding Main-TVF; the main
306
+ /// phase independently re-decides every edge with main MHP and lock facts.
307
+ MTASVFGBuilder::ThreadVFCandidateList selectedThreadVFCandidates;
257
308
  // -mta-slicing-single: the one unified slice, computed in MTA slicing and reused
258
309
  // (not recomputed) for PTA slicing so both stages share V_Single.
259
310
  std::set<const ICFGNode*> singleSlicedNodes;
311
+ NodeBS singleSlicedSVFGNodeIds;
260
312
  std::unique_ptr<SlicedSVFIRView> mtaSlicedView;
261
313
  std::unique_ptr<SlicedSVFIRView> ptaSlicedView;
262
314
  std::unique_ptr<SlicedSVFGView> slicedSVFGView;
263
- std::unique_ptr<FlowSensitive> mtaFSMPTA;
315
+ std::unique_ptr<FlowSensitive> mainFSMPTA;
264
316
  std::unique_ptr<SlicedTCT> slicedTCT;
265
- std::unique_ptr<MHP> slicedMhp;
317
+ std::unique_ptr<MHP> slicedMHP;
266
318
  std::unique_ptr<LockAnalysis> slicedLockAnalysis;
267
- // Whole-ICFG lock analysis for the final detection (see buildFullLockAnalysis).
268
- std::unique_ptr<SlicedSVFIRView> fullLockView;
269
- std::unique_ptr<SlicedTCT> fullLockTCT;
270
- std::unique_ptr<LockAnalysis> fullLockAnalysis;
271
319
  bool hasThreadFunctions = false;
272
320
  std::set<RacePair> racePairs;
273
321
  };
@@ -24,15 +24,6 @@
24
24
  * MTASVFGBuilder.h
25
25
  *
26
26
  * Author: Jiawei Yang
27
- *
28
- * Builds a *thread-aware* Sparse Value-Flow Graph (SVFG) for the FSAM
29
- * flow-sensitive multithreaded pointer analysis (Sui, Di, Xue, CGO'16).
30
- *
31
- * On top of the stock thread-oblivious SVFG, it adds inter-thread (interference)
32
- * indirect value-flow edges between store/load and store/store statements that
33
- * (1) may-happen-in-parallel (MHP), and
34
- * (2) may-alias on the address-taken object, and
35
- * (3) are not excluded by a common lock (non-interference lock-pair pruning).
36
27
  */
37
28
 
38
29
  #ifndef INCLUDE_MTA_MTASVFGBUILDER_H_
@@ -44,14 +35,13 @@
44
35
  #include "MTA/MHP.h"
45
36
  #include "MTA/LockAnalysis.h"
46
37
  #include "MemoryModel/PointsTo.h"
47
- #include <map>
48
- #include <set>
49
38
  #include <utility>
39
+ #include <vector>
50
40
 
51
41
  namespace SVF
52
42
  {
53
43
 
54
- class SlicedICFGView;
44
+ class SlicedSVFGView;
55
45
 
56
46
  class MTASVFGBuilder : public SVFGBuilder
57
47
  {
@@ -59,25 +49,21 @@ public:
59
49
  typedef Set<const StmtSVFGNode*> SVFGNodeSet;
60
50
  typedef NodeBS SVFGNodeIDSet;
61
51
 
62
- /// Constructor: driven by the interleaving (MHP) and lock analyses.
63
- MTASVFGBuilder(MHP* m, LockAnalysis* la) : SVFGBuilder(), mhp(m), lockana(la) {}
64
- ~MTASVFGBuilder() override = default;
52
+ enum class InterferenceEdgeMode
53
+ {
54
+ Analysis, ///< Build labelled edges for FSMPTA.
55
+ SlicingOnly ///< Build unlabelled connectivity for VFG_pre slicing.
56
+ };
65
57
 
66
- /// Number of thread-aware (interference) SVFG edges added.
67
- static u32_t numOfNewSVFGEdges;
68
-
69
- /// Configure the builder for the main (post-slicing) FSAM solve rather than
70
- /// the pre-analysis VFG_pre:
71
- /// - slice != null restricts the interference-edge construction to kept
72
- /// store/load nodes (a sliced-out endpoint's edge is inert in the gated
73
- /// solve, so it need not be built);
74
- /// - the [THREAD-VF] query map is skipped, as only VFG_pre slicing reads it.
75
- /// The pre-analysis build leaves this unset (whole program, query map built).
76
- void configureForMainSolve(const SlicedICFGView* slice)
58
+ /// Constructor: driven by the interleaving (MHP) and lock analyses.
59
+ MTASVFGBuilder(MHP* mhp, LockAnalysis* lockAnalysis,
60
+ InterferenceEdgeMode edgeMode = InterferenceEdgeMode::Analysis)
61
+ : SVFGBuilder(),
62
+ labelInterferenceEdges(edgeMode == InterferenceEdgeMode::Analysis),
63
+ mhp(mhp), lockAnalysis(lockAnalysis)
77
64
  {
78
- icfgSlice = slice;
79
- recordThreadVF = false;
80
65
  }
66
+ ~MTASVFGBuilder() override = default;
81
67
 
82
68
  /// A candidate thread-aware value-flow edge s --o--> s' (src store, dst
83
69
  /// load/store), keyed by its endpoint SVFG nodes.
@@ -98,11 +84,81 @@ public:
98
84
  ///
99
85
  /// The value stores only the additional lock-span witnesses; the endpoint
100
86
  /// ICFG nodes are implicit in the key and consumers must add them back.
101
- const std::map<ThreadVFEdge, std::set<const ICFGNode*>>& getThreadVFQueryMap() const
87
+ using ThreadVFQueryMap = Map<ThreadVFEdge, Set<const ICFGNode*>>;
88
+ const ThreadVFQueryMap& getThreadVFQueryMap() const
102
89
  {
103
90
  return threadVFQueryMap;
104
91
  }
105
92
 
93
+ struct ThreadVFCandidate
94
+ {
95
+ ThreadVFCandidate(NodeID sourceNodeId, NodeID destinationNodeId)
96
+ : sourceNodeId(sourceNodeId), destinationNodeId(destinationNodeId)
97
+ {
98
+ }
99
+
100
+ bool operator<(const ThreadVFCandidate& other) const
101
+ {
102
+ return sourceNodeId < other.sourceNodeId ||
103
+ (sourceNodeId == other.sourceNodeId &&
104
+ destinationNodeId < other.destinationNodeId);
105
+ }
106
+
107
+ bool operator==(const ThreadVFCandidate& other) const
108
+ {
109
+ return sourceNodeId == other.sourceNodeId &&
110
+ destinationNodeId == other.destinationNodeId;
111
+ }
112
+
113
+ NodeID sourceNodeId;
114
+ NodeID destinationNodeId;
115
+ };
116
+ using ThreadVFCandidateList = std::vector<ThreadVFCandidate>;
117
+
118
+ class ThreadVFBuildConfig
119
+ {
120
+ public:
121
+ static ThreadVFBuildConfig mainPhase(
122
+ const SlicedSVFGView& scope,
123
+ const ThreadVFCandidateList* candidates = nullptr)
124
+ {
125
+ return ThreadVFBuildConfig(&scope, candidates);
126
+ }
127
+
128
+ static ThreadVFBuildConfig wholeProgram()
129
+ {
130
+ return ThreadVFBuildConfig(nullptr, nullptr);
131
+ }
132
+
133
+ private:
134
+ friend class MTASVFGBuilder;
135
+ ThreadVFBuildConfig(const SlicedSVFGView* scope,
136
+ const ThreadVFCandidateList* candidates)
137
+ : scope(scope), candidates(candidates)
138
+ {
139
+ }
140
+
141
+ const SlicedSVFGView* scope = nullptr; ///< null means the whole base SVFG
142
+ /// Optional conservative candidate universe selected from VFG_pre.
143
+ /// Main MHP/lock facts still decide every emitted edge; this only avoids
144
+ /// re-querying alias pairs that context-insensitive pre MHP rejected or
145
+ /// whose endpoints do not survive VFG'_pre.
146
+ const ThreadVFCandidateList* candidates = nullptr;
147
+ };
148
+
149
+ /// Replace only the ILA-dependent thread-aware overlay. The underlying
150
+ /// MemorySSA, stock SVFG, and fork/join value flow remain unchanged.
151
+ void replaceThreadAwareOverlay(MHP* mhp, LockAnalysis* lockAnalysis,
152
+ const ThreadVFBuildConfig& config);
153
+
154
+ /// Remove all currently attached thread-aware interference edges.
155
+ void clearThreadAwareOverlay();
156
+
157
+ size_t getThreadAwareEdgeCount() const
158
+ {
159
+ return threadAwareEdges.size();
160
+ }
161
+
106
162
  protected:
107
163
  /// Rewrite the SVFG build hook: build the stock SVFG, then add MHP edges.
108
164
  void buildSVFG() override;
@@ -112,13 +168,16 @@ protected:
112
168
  std::unique_ptr<MRGenerator> createMRGenerator(BVDataPTAImpl* pta, bool ptrOnlyMSSA) override;
113
169
 
114
170
  private:
115
- /// Main-solve configuration (see configureForMainSolve); defaults suit VFG_pre.
116
- const SlicedICFGView* icfgSlice = nullptr; ///< null = whole program
117
- bool recordThreadVF = true; ///< false = skip [THREAD-VF] recording
171
+ /// Active overlay configuration; defaults suit VFG_pre.
172
+ const SlicedSVFGView* overlayScope = nullptr; ///< null = whole base SVFG
173
+ const ThreadVFCandidateList* overlayCandidates = nullptr;
174
+ bool recordThreadVFQueries = true; ///< false = skip [THREAD-VF] recording
175
+ bool labelInterferenceEdges = true; ///< false = VFG_pre (sliced-only): omit edge points-to labels
118
176
 
119
177
  /// Collect the store/load SVFG nodes to pair for interference edges (all of
120
178
  /// them, or -- when a slice is set -- only the kept ones).
121
179
  void collectLoadStoreSVFGNodes();
180
+ bool isInOverlayScope(const SVFGNode* node) const;
122
181
 
123
182
  /// FSAM join-related thread-oblivious value flow (the "return" half of
124
183
  /// treating a join as a call without a forward): connect each start
@@ -131,44 +190,50 @@ private:
131
190
  /// join, mirroring SVFG::addInterIndirectVFRetEdge using the public SVFG API
132
191
  /// (points-to intersection + dedup via hasInterVFGEdge + addSVFGEdge).
133
192
  void addJoinRetEdge(const FormalOUTSVFGNode* formalOut,
134
- const ActualOUTSVFGNode* actualOut, CallSiteID csId);
193
+ const ActualOUTSVFGNode* actualOut,
194
+ CallSiteID callSiteId);
135
195
 
136
196
  /// Connect inter-thread (interference) value-flow edges for MHP pairs.
137
197
  void connectMHPEdges(PointerAnalysis* pta);
138
198
 
139
- void handleStoreLoad(const StmtSVFGNode* n1, const StmtSVFGNode* n2, PointerAnalysis* pta);
140
- void handleStoreStore(const StmtSVFGNode* n1, const StmtSVFGNode* n2, PointerAnalysis* pta);
199
+ void handleStoreLoad(const StmtSVFGNode* store,
200
+ const StmtSVFGNode* load, PointerAnalysis* pta);
201
+ void handleStoreStore(const StmtSVFGNode* firstStore,
202
+ const StmtSVFGNode* secondStore,
203
+ PointerAnalysis* pta);
141
204
 
142
205
  /// Record the [THREAD-VF] slicing sources for one candidate pair s --o--> s'
143
- /// (s = src store, sp = dst load/store). Adds the endpoints, and — when the
206
+ /// (source = store, destination = load/store). Adds the endpoints, and — when the
144
207
  /// pair is protected by a common lock — the in-span successor/predecessor
145
208
  /// witnesses needed to re-decide the non-interference (tail/head) test.
146
- void recordThreadVFSource(const StmtSVFGNode* s, const StmtSVFGNode* sp, bool commonLock);
209
+ void recordThreadVFSource(const StmtSVFGNode* source,
210
+ const StmtSVFGNode* destination,
211
+ bool commonLock);
147
212
 
148
213
  /// Add a thread-MHP indirect value-flow edge srcId -> dstId carrying pts.
149
214
  SVFGEdge* addTDEdge(NodeID srcId, NodeID dstId, const PointsTo& pts);
150
215
 
151
216
  /// Lock-span head/tail tests (non-interference lock-pair pruning).
152
217
  //@{
153
- SVFGNodeIDSet getPrevNodes(const StmtSVFGNode* n);
154
- SVFGNodeIDSet getSuccNodes(const StmtSVFGNode* n);
155
- bool isHeadOfSpan(const StmtSVFGNode* n);
156
- bool isTailOfSpan(const StmtSVFGNode* n);
218
+ SVFGNodeIDSet getPredecessorNodes(const StmtSVFGNode* node);
219
+ SVFGNodeIDSet getSuccessorNodes(const StmtSVFGNode* node);
220
+ bool isHeadOfSpan(const StmtSVFGNode* node);
221
+ bool isTailOfSpan(const StmtSVFGNode* node);
157
222
  //@}
158
223
 
159
- SVFGNodeSet stnodeSet; ///< all store SVFG nodes
160
- SVFGNodeSet ldnodeSet; ///< all load SVFG nodes
224
+ SVFGNodeSet storeNodes;
225
+ SVFGNodeSet loadNodes;
161
226
 
162
227
  /// [THREAD-VF] per-edge query map (see getThreadVFQueryMap).
163
- std::map<ThreadVFEdge, std::set<const ICFGNode*>> threadVFQueryMap;
164
-
228
+ ThreadVFQueryMap threadVFQueryMap;
165
229
  MHP* mhp;
166
- LockAnalysis* lockana;
230
+ LockAnalysis* lockAnalysis;
167
231
 
168
- Map<const StmtSVFGNode*, SVFGNodeIDSet> prevset;
169
- Map<const StmtSVFGNode*, SVFGNodeIDSet> succset;
170
- Map<const StmtSVFGNode*, bool> headmap;
171
- Map<const StmtSVFGNode*, bool> tailmap;
232
+ Map<const StmtSVFGNode*, SVFGNodeIDSet> predecessorCache;
233
+ Map<const StmtSVFGNode*, SVFGNodeIDSet> successorCache;
234
+ Map<const StmtSVFGNode*, bool> spanHeadCache;
235
+ Map<const StmtSVFGNode*, bool> spanTailCache;
236
+ SVFGEdgeSet threadAwareEdges;
172
237
  };
173
238
 
174
239
  } // End namespace SVF