svf-tools 1.0.1033 → 1.0.1034

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.1033",
3
+ "version": "1.0.1034",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,310 @@
1
+ //===- BasicBlockG.h -- BasicBlock node------------------------------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2025> <Yulei Sui>
6
+ //
7
+
8
+ // This program is free software: you can redistribute it and/or modify
9
+ // it under the terms of the GNU Affero General Public License as published by
10
+ // the Free Software Foundation, either version 3 of the License, or
11
+ // (at your option) any later version.
12
+
13
+ // This program is distributed in the hope that it will be useful,
14
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ // GNU Affero General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU Affero General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * ICFGNode.h
25
+ *
26
+ * Created on: 23 Jan, 2025
27
+ * Author: Jiawei, Xiao
28
+ */
29
+
30
+ #ifndef BASICBLOCKGRAPH_H_
31
+ #define BASICBLOCKGRAPH_H_
32
+ #include "GenericGraph.h"
33
+ #include <sstream>
34
+ #include <algorithm>
35
+
36
+
37
+ namespace SVF
38
+ {
39
+ class SVFBasicBlock;
40
+ class BasicBlockEdge;
41
+ class ICFGNode;
42
+ class SVFFunction;
43
+ typedef GenericEdge<SVFBasicBlock> GenericBasicBlockEdgeTy;
44
+ class BasicBlockEdge: public GenericBasicBlockEdgeTy
45
+ {
46
+ friend class SVFIRWriter;
47
+ friend class SVFIRReader;
48
+
49
+ public:
50
+ public:
51
+ /// Constructor
52
+ BasicBlockEdge(SVFBasicBlock* s, SVFBasicBlock* d) : GenericBasicBlockEdgeTy(s, d, 0)
53
+ {
54
+ }
55
+ /// Destructor
56
+ ~BasicBlockEdge() {}
57
+
58
+ /// Overloading operator << for dumping ICFG node ID
59
+ //@{
60
+ friend OutStream& operator<<(OutStream& o, const BasicBlockEdge& edge)
61
+ {
62
+ o << edge.toString();
63
+ return o;
64
+ }
65
+ //@}
66
+
67
+ virtual const std::string toString() const;
68
+ };
69
+
70
+
71
+ typedef GenericNode<SVFBasicBlock, BasicBlockEdge> GenericBasicBlockNodeTy;
72
+ class SVFBasicBlock : public GenericBasicBlockNodeTy
73
+ {
74
+ friend class LLVMModuleSet;
75
+ friend class SVFIRWriter;
76
+ friend class SVFIRReader;
77
+ friend class SVFIRBuilder;
78
+ friend class SVFFunction;
79
+ friend class ICFGBuilder;
80
+ friend class ICFG;
81
+
82
+ public:
83
+ typedef std::vector<const ICFGNode*>::const_iterator const_iterator;
84
+ std::vector<const SVFBasicBlock*> succBBs;
85
+ std::vector<const SVFBasicBlock*> predBBs;
86
+
87
+ private:
88
+ std::vector<const ICFGNode*> allICFGNodes; ///< all ICFGNodes in this BasicBlock
89
+ const SVFFunction* fun; /// Function where this BasicBlock is
90
+
91
+
92
+
93
+ protected:
94
+ ///@{ attributes to be set only through Module builders e.g., LLVMModule
95
+
96
+ inline void addICFGNode(const ICFGNode* icfgNode)
97
+ {
98
+ assert(std::find(getICFGNodeList().begin(), getICFGNodeList().end(),
99
+ icfgNode) == getICFGNodeList().end() && "duplicated icfgnode");
100
+ allICFGNodes.push_back(icfgNode);
101
+ }
102
+
103
+ /// @}
104
+
105
+ public:
106
+ /// Constructor without name
107
+ SVFBasicBlock(NodeID id, const SVFFunction* f): GenericBasicBlockNodeTy(id, BasicBlockKd), fun(f)
108
+ {
109
+
110
+ }
111
+ SVFBasicBlock() = delete;
112
+ ~SVFBasicBlock()
113
+ {
114
+
115
+ }
116
+
117
+ static inline bool classof(const SVFBaseNode* node)
118
+ {
119
+ return node->getNodeKind() == SVFBaseNode::BasicBlockKd;
120
+ }
121
+
122
+ static inline bool classof(const SVFBasicBlock* node)
123
+ {
124
+ return true;
125
+ }
126
+
127
+ //@{
128
+ friend OutStream &operator<<(OutStream &o, const SVFBasicBlock&node)
129
+ {
130
+ o << node.toString();
131
+ return o;
132
+ }
133
+ //@}
134
+
135
+
136
+ inline const std::vector<const ICFGNode*>& getICFGNodeList() const
137
+ {
138
+ return allICFGNodes;
139
+ }
140
+
141
+ inline const_iterator begin() const
142
+ {
143
+ return allICFGNodes.begin();
144
+ }
145
+
146
+ inline const_iterator end() const
147
+ {
148
+ return allICFGNodes.end();
149
+ }
150
+
151
+ inline void addSuccBasicBlock(const SVFBasicBlock* succ2)
152
+ {
153
+ // check if the edge already exists
154
+ for (auto edge: this->getOutEdges())
155
+ {
156
+ if (edge->getDstNode() == succ2)
157
+ return;
158
+ }
159
+
160
+ SVFBasicBlock* succ = const_cast<SVFBasicBlock*>(succ2);
161
+ BasicBlockEdge* edge = new BasicBlockEdge(this, succ);
162
+ this->addOutgoingEdge(edge);
163
+ succ->addIncomingEdge(edge);
164
+ this->succBBs.push_back(succ);
165
+ succ->predBBs.push_back(this);
166
+ }
167
+
168
+ inline void addPredBasicBlock(const SVFBasicBlock* pred2)
169
+ {
170
+ // check if the edge already exists
171
+ for (auto edge: this->getInEdges())
172
+ {
173
+ if (edge->getSrcNode() == pred2)
174
+ return;
175
+ }
176
+ SVFBasicBlock* pred = const_cast<SVFBasicBlock*>(pred2);
177
+ BasicBlockEdge* edge = new BasicBlockEdge(pred, this);
178
+ this->addIncomingEdge(edge);
179
+ pred->addOutgoingEdge(edge);
180
+ this->predBBs.push_back(pred);
181
+ pred->succBBs.push_back(this);
182
+ }
183
+
184
+ inline const SVFFunction* getParent() const
185
+ {
186
+ return fun;
187
+ }
188
+
189
+ inline const SVFFunction* getFunction() const
190
+ {
191
+ return fun;
192
+ }
193
+
194
+ inline const ICFGNode* front() const
195
+ {
196
+ assert(!allICFGNodes.empty() && "bb empty?");
197
+ return allICFGNodes.front();
198
+ }
199
+
200
+ inline const ICFGNode* back() const
201
+ {
202
+ assert(!allICFGNodes.empty() && "bb empty?");
203
+ return allICFGNodes.back();
204
+ }
205
+
206
+ inline std::vector<const SVFBasicBlock*> getSuccessors() const
207
+ {
208
+ std::vector<const SVFBasicBlock*> res;
209
+ for (auto edge : this->getOutEdges())
210
+ {
211
+ res.push_back(edge->getDstNode());
212
+ }
213
+ return res;
214
+ }
215
+
216
+ inline std::vector<const SVFBasicBlock*> getPredecessors() const
217
+ {
218
+ std::vector<const SVFBasicBlock*> res;
219
+ for (auto edge : this->getInEdges())
220
+ {
221
+ res.push_back(edge->getSrcNode());
222
+ }
223
+ return res;
224
+ }
225
+ u32_t getNumSuccessors() const
226
+ {
227
+ return this->getOutEdges().size();
228
+ }
229
+ u32_t getBBSuccessorPos(const SVFBasicBlock* Succ)
230
+ {
231
+ u32_t i = 0;
232
+ for (const SVFBasicBlock* SuccBB: succBBs)
233
+ {
234
+ if (SuccBB == Succ)
235
+ return i;
236
+ i++;
237
+ }
238
+ assert(false && "Didn't find successor edge?");
239
+ return 0;
240
+ }
241
+ u32_t getBBSuccessorPos(const SVFBasicBlock* Succ) const
242
+ {
243
+ u32_t i = 0;
244
+ for (const SVFBasicBlock* SuccBB: succBBs)
245
+ {
246
+ if (SuccBB == Succ)
247
+ return i;
248
+ i++;
249
+ }
250
+ assert(false && "Didn't find successor edge?");
251
+ return 0;
252
+
253
+ }
254
+ u32_t getBBPredecessorPos(const SVFBasicBlock* succbb)
255
+ {
256
+ u32_t pos = 0;
257
+ for (const SVFBasicBlock* PredBB : succbb->getPredecessors())
258
+ {
259
+ if(PredBB == this)
260
+ return pos;
261
+ ++pos;
262
+ }
263
+ assert(false && "Didn't find predecessor edge?");
264
+ return pos;
265
+ }
266
+ u32_t getBBPredecessorPos(const SVFBasicBlock* succbb) const
267
+ {
268
+ u32_t pos = 0;
269
+ for (const SVFBasicBlock* PredBB : succbb->getPredecessors())
270
+ {
271
+ if(PredBB == this)
272
+ return pos;
273
+ ++pos;
274
+ }
275
+ assert(false && "Didn't find predecessor edge?");
276
+ return pos;
277
+ }
278
+
279
+ const std::string toString() const;
280
+
281
+ };
282
+
283
+
284
+
285
+ typedef GenericGraph<SVFBasicBlock, BasicBlockEdge> GenericBasicBlockGraphTy;
286
+ class BasicBlockGraph: public GenericBasicBlockGraphTy
287
+ {
288
+ private:
289
+ NodeID id{0};
290
+ const SVFFunction* fun;
291
+ public:
292
+ /// Constructor
293
+ BasicBlockGraph(const SVFFunction* f): fun(f)
294
+ {
295
+
296
+ }
297
+
298
+ SVFBasicBlock* addBasicBlock(const std::string& bbname)
299
+ {
300
+ id++;
301
+ SVFBasicBlock* bb = new SVFBasicBlock(id, fun);
302
+ addGNode(id, bb);
303
+ bb->setName(bbname);
304
+ return bb;
305
+ }
306
+
307
+ };
308
+ }
309
+
310
+ #endif
@@ -240,6 +240,7 @@ public:
240
240
  ConstraintNodeKd, // Constraint graph node
241
241
  TCTNodeKd, // Thread creation tree node
242
242
  DCHNodeKd, // DCHG node
243
+ BasicBlockKd, // Basic block node
243
244
  OtherKd // Other node kind
244
245
  };
245
246
 
@@ -33,6 +33,7 @@
33
33
  #include "SVFIR/SVFType.h"
34
34
  #include "Graphs/GraphPrinter.h"
35
35
  #include "Util/Casting.h"
36
+ #include "Graphs/BasicBlockG.h"
36
37
 
37
38
  namespace SVF
38
39
  {
@@ -299,7 +300,8 @@ class SVFFunction : public SVFValue
299
300
  friend class SVFIRBuilder;
300
301
 
301
302
  public:
302
- typedef std::vector<const SVFBasicBlock*>::const_iterator const_iterator;
303
+ typename BasicBlockGraph::IDToNodeMapTy::iterator iterator;
304
+ typedef BasicBlockGraph::IDToNodeMapTy::const_iterator const_iterator;
303
305
  typedef SVFLoopAndDomInfo::BBSet BBSet;
304
306
  typedef SVFLoopAndDomInfo::BBList BBList;
305
307
  typedef SVFLoopAndDomInfo::LoopBBs LoopBBs;
@@ -314,10 +316,10 @@ private:
314
316
  const SVFFunctionType* funcType; /// FunctionType, which is different from the type (PointerType) of this SVFFunction
315
317
  SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information
316
318
  const SVFFunction* realDefFun; /// the definition of a function across multiple modules
317
- std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function
318
319
  std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function
319
320
  SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function
320
321
  const CallGraphNode *callGraphNode; /// call graph node for this function
322
+ BasicBlockGraph* bbGraph; /// the basic block graph of this function
321
323
 
322
324
  protected:
323
325
  inline void setCallGraphNode(CallGraphNode *cgn)
@@ -325,12 +327,6 @@ protected:
325
327
  callGraphNode = cgn;
326
328
  }
327
329
 
328
- ///@{ attributes to be set only through Module builders e.g., LLVMModule
329
- inline void addBasicBlock(const SVFBasicBlock* bb)
330
- {
331
- allBBs.push_back(bb);
332
- }
333
-
334
330
  inline void addArgument(SVFArgument* arg)
335
331
  {
336
332
  allArgs.push_back(arg);
@@ -376,6 +372,21 @@ public:
376
372
  return isDecl;
377
373
  }
378
374
 
375
+ void setBasicBlockGraph(BasicBlockGraph* graph)
376
+ {
377
+ this->bbGraph = graph;
378
+ }
379
+
380
+ BasicBlockGraph* getBasicBlockGraph()
381
+ {
382
+ return bbGraph;
383
+ }
384
+
385
+ const BasicBlockGraph* getBasicBlockGraph() const
386
+ {
387
+ return bbGraph;
388
+ }
389
+
379
390
  inline bool isIntrinsic() const
380
391
  {
381
392
  return intrinsic;
@@ -411,13 +422,14 @@ public:
411
422
 
412
423
  inline bool hasBasicBlock() const
413
424
  {
414
- return !allBBs.empty();
425
+ return bbGraph && bbGraph->begin() != bbGraph->end();
415
426
  }
416
427
 
417
428
  inline const SVFBasicBlock* getEntryBlock() const
418
429
  {
419
430
  assert(hasBasicBlock() && "function does not have any Basicblock, external function?");
420
- return allBBs.front();
431
+ assert(bbGraph->begin()->second->getInEdges().size() == 0 && "the first basic block is not entry block");
432
+ return bbGraph->begin()->second;
421
433
  }
422
434
 
423
435
  /// Carefully! when you call getExitBB, you need ensure the function has return instruction
@@ -437,23 +449,19 @@ public:
437
449
  /// Carefully! 'back' is just the last basic block of function,
438
450
  /// but not necessarily a exit basic block
439
451
  /// more refer to: https://github.com/SVF-tools/SVF/pull/1262
440
- return allBBs.back();
452
+ return std::prev(bbGraph->end())->second;
441
453
  }
442
454
 
443
455
  inline const_iterator begin() const
444
456
  {
445
- return allBBs.begin();
457
+ return bbGraph->begin();
446
458
  }
447
459
 
448
460
  inline const_iterator end() const
449
461
  {
450
- return allBBs.end();
462
+ return bbGraph->end();
451
463
  }
452
464
 
453
- inline const std::vector<const SVFBasicBlock*>& getBasicBlockList() const
454
- {
455
- return allBBs;
456
- }
457
465
 
458
466
  inline const std::vector<const SVFBasicBlock*>& getReachableBBs() const
459
467
  {
@@ -523,113 +531,6 @@ public:
523
531
 
524
532
  class ICFGNode;
525
533
 
526
- class SVFBasicBlock : public SVFValue
527
- {
528
- friend class LLVMModuleSet;
529
- friend class SVFIRWriter;
530
- friend class SVFIRReader;
531
- friend class SVFIRBuilder;
532
- friend class SVFFunction;
533
- friend class ICFGBuilder;
534
- friend class ICFG;
535
-
536
- public:
537
- typedef std::vector<const ICFGNode*>::const_iterator const_iterator;
538
-
539
- private:
540
- std::vector<const ICFGNode*> allICFGNodes; ///< all ICFGNodes in this BasicBlock
541
- std::vector<const SVFBasicBlock*> succBBs; ///< all successor BasicBlocks of this BasicBlock
542
- std::vector<const SVFBasicBlock*> predBBs; ///< all predecessor BasicBlocks of this BasicBlock
543
- const SVFFunction* fun; /// Function where this BasicBlock is
544
-
545
- protected:
546
- ///@{ attributes to be set only through Module builders e.g., LLVMModule
547
-
548
- inline void addICFGNode(const ICFGNode* icfgNode)
549
- {
550
- assert(std::find(getICFGNodeList().begin(), getICFGNodeList().end(),
551
- icfgNode) == getICFGNodeList().end() && "duplicated icfgnode");
552
- allICFGNodes.push_back(icfgNode);
553
- }
554
-
555
- inline void addSuccBasicBlock(const SVFBasicBlock* succ)
556
- {
557
- succBBs.push_back(succ);
558
- }
559
-
560
- inline void addPredBasicBlock(const SVFBasicBlock* pred)
561
- {
562
- predBBs.push_back(pred);
563
- }
564
- /// @}
565
-
566
- public:
567
- /// Constructor without name
568
- SVFBasicBlock(const SVFType* ty, const SVFFunction* f);
569
- SVFBasicBlock() = delete;
570
- ~SVFBasicBlock() override;
571
-
572
- static inline bool classof(const SVFValue *node)
573
- {
574
- return node->getKind() == SVFBB;
575
- }
576
-
577
- inline const std::vector<const ICFGNode*>& getICFGNodeList() const
578
- {
579
- return allICFGNodes;
580
- }
581
-
582
- inline const_iterator begin() const
583
- {
584
- return allICFGNodes.begin();
585
- }
586
-
587
- inline const_iterator end() const
588
- {
589
- return allICFGNodes.end();
590
- }
591
-
592
- inline const SVFFunction* getParent() const
593
- {
594
- return fun;
595
- }
596
-
597
- inline const SVFFunction* getFunction() const
598
- {
599
- return fun;
600
- }
601
-
602
- inline const ICFGNode* front() const
603
- {
604
- assert(!allICFGNodes.empty() && "bb empty?");
605
- return allICFGNodes.front();
606
- }
607
-
608
- inline const ICFGNode* back() const
609
- {
610
- assert(!allICFGNodes.empty() && "bb empty?");
611
- return allICFGNodes.back();
612
- }
613
-
614
- inline const std::vector<const SVFBasicBlock*>& getSuccessors() const
615
- {
616
- return succBBs;
617
- }
618
-
619
- inline const std::vector<const SVFBasicBlock*>& getPredecessors() const
620
- {
621
- return predBBs;
622
- }
623
- u32_t getNumSuccessors() const
624
- {
625
- return succBBs.size();
626
- }
627
- u32_t getBBSuccessorPos(const SVFBasicBlock* succbb);
628
- u32_t getBBSuccessorPos(const SVFBasicBlock* succbb) const;
629
- u32_t getBBPredecessorPos(const SVFBasicBlock* succbb);
630
- u32_t getBBPredecessorPos(const SVFBasicBlock* succbb) const;
631
- };
632
-
633
534
  class SVFInstruction : public SVFValue
634
535
  {
635
536
  friend class SVFIRWriter;
@@ -0,0 +1,10 @@
1
+ #include "Graphs/BasicBlockG.h"
2
+
3
+ using namespace SVF;
4
+ const std::string BasicBlockEdge::toString() const
5
+ {
6
+ std::string str;
7
+ std::stringstream rawstr(str);
8
+ rawstr << "BasicBlockEdge: " << getSrcNode()->toString() << " -> " << getDstNode()->getName();
9
+ return rawstr.str();
10
+ }
@@ -186,7 +186,7 @@ void MRGenerator::collectModRefForLoadStore()
186
186
  for (SVFFunction::const_iterator iter = fun.begin(), eiter = fun.end();
187
187
  iter != eiter; ++iter)
188
188
  {
189
- const SVFBasicBlock* bb = *iter;
189
+ const SVFBasicBlock* bb = iter->second;
190
190
  for (const auto& inst: bb->getICFGNodeList())
191
191
  {
192
192
  SVFStmtList& pagEdgeList = getPAGEdgesFromInst(inst);
@@ -597,7 +597,7 @@ void MemSSA::dumpMSSA(OutStream& Out)
597
597
  for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end();
598
598
  bit != ebit; ++bit)
599
599
  {
600
- const SVFBasicBlock* bb = *bit;
600
+ const SVFBasicBlock* bb = bit->second;
601
601
  Out << bb->getName() << "\n";
602
602
  PHISet& phiSet = getPHISet(bb);
603
603
  for(PHISet::iterator pi = phiSet.begin(), epi = phiSet.end(); pi !=epi; ++pi)
@@ -72,8 +72,9 @@ void LockAnalysis::collectLockUnlocksites()
72
72
 
73
73
  for (const SVFFunction* F : tct->getSVFModule()->getFunctionSet())
74
74
  {
75
- for (const SVFBasicBlock* bb : F->getBasicBlockList())
75
+ for (auto it : *F)
76
76
  {
77
+ const SVFBasicBlock* bb = it.second;
77
78
  for (const ICFGNode* icfgNode : bb->getICFGNodeList())
78
79
  {
79
80
  if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDRelease(cast<CallICFGNode>(icfgNode)))
@@ -159,8 +159,9 @@ void MHP::updateNonCandidateFunInterleaving()
159
159
  {
160
160
  const CallStrCxt& curCxt = cts.getContext();
161
161
 
162
- for (const SVFBasicBlock* svfbb : fun->getBasicBlockList())
162
+ for (auto it : *fun)
163
163
  {
164
+ const SVFBasicBlock* svfbb = it.second;
164
165
  for (const ICFGNode* curNode : svfbb->getICFGNodeList())
165
166
  {
166
167
  if (curNode == entryNode)
@@ -139,8 +139,9 @@ void MTA::detect(SVFModule* module)
139
139
  for (const SVFFunction* F : module->getFunctionSet())
140
140
  {
141
141
  // collect and create symbols inside the function body
142
- for (const SVFBasicBlock* svfbb : F->getBasicBlockList())
142
+ for (auto it : *F)
143
143
  {
144
+ const SVFBasicBlock* svfbb = it.second;
144
145
  for (const ICFGNode* icfgNode : svfbb->getICFGNodeList())
145
146
  {
146
147
  for(const SVFStmt* stmt : pag->getSVFStmtList(icfgNode))
@@ -126,7 +126,7 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa)
126
126
  continue;
127
127
  for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit)
128
128
  {
129
- const SVFBasicBlock* bb = *bit;
129
+ const SVFBasicBlock* bb = bit->second;
130
130
  for (const auto& icfgNode : bb->getICFGNodeList())
131
131
  {
132
132
  for(const SVFStmt* stmt : pag->getSVFStmtList(icfgNode))
@@ -70,7 +70,7 @@ void SaberCondAllocator::allocate(const SVFModule *M)
70
70
  for (SVFFunction::const_iterator bit = func->begin(), ebit = func->end();
71
71
  bit != ebit; ++bit)
72
72
  {
73
- const SVFBasicBlock* bb = *bit;
73
+ const SVFBasicBlock* bb = bit->second;
74
74
  collectBBCallingProgExit(*bb);
75
75
  allocateForBB(*bb);
76
76
  }
@@ -160,11 +160,10 @@ SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft,
160
160
 
161
161
  SVFFunction::~SVFFunction()
162
162
  {
163
- for(const SVFBasicBlock* bb : allBBs)
164
- delete bb;
165
163
  for(const SVFArgument* arg : allArgs)
166
164
  delete arg;
167
165
  delete loopAndDom;
166
+ delete bbGraph;
168
167
  }
169
168
 
170
169
  u32_t SVFFunction::arg_size() const
@@ -196,72 +195,6 @@ void SVFFunction::setExitBlock(SVFBasicBlock *bb)
196
195
  exitBlock = bb;
197
196
  }
198
197
 
199
- SVFBasicBlock::SVFBasicBlock(const SVFType* ty, const SVFFunction* f)
200
- : SVFValue(ty, SVFValue::SVFBB), fun(f)
201
- {
202
- }
203
-
204
- SVFBasicBlock::~SVFBasicBlock()
205
- {
206
-
207
- }
208
-
209
- /*!
210
- * Get position of a successor basic block
211
- */
212
- u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ)
213
- {
214
- u32_t i = 0;
215
- for (const SVFBasicBlock* SuccBB: succBBs)
216
- {
217
- if (SuccBB == Succ)
218
- return i;
219
- i++;
220
- }
221
- assert(false && "Didn't find successor edge?");
222
- return 0;
223
- }
224
-
225
- u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ) const
226
- {
227
- u32_t i = 0;
228
- for (const SVFBasicBlock* SuccBB: succBBs)
229
- {
230
- if (SuccBB == Succ)
231
- return i;
232
- i++;
233
- }
234
- assert(false && "Didn't find successor edge?");
235
- return 0;
236
- }
237
-
238
- /*!
239
- * Return a position index from current bb to it successor bb
240
- */
241
- u32_t SVFBasicBlock::getBBPredecessorPos(const SVFBasicBlock* succbb)
242
- {
243
- u32_t pos = 0;
244
- for (const SVFBasicBlock* PredBB : succbb->getPredecessors())
245
- {
246
- if(PredBB == this)
247
- return pos;
248
- ++pos;
249
- }
250
- assert(false && "Didn't find predecessor edge?");
251
- return pos;
252
- }
253
- u32_t SVFBasicBlock::getBBPredecessorPos(const SVFBasicBlock* succbb) const
254
- {
255
- u32_t pos = 0;
256
- for (const SVFBasicBlock* PredBB : succbb->getPredecessors())
257
- {
258
- if(PredBB == this)
259
- return pos;
260
- ++pos;
261
- }
262
- assert(false && "Didn't find predecessor edge?");
263
- return pos;
264
- }
265
198
 
266
199
  SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b,
267
200
  bool tm, bool isRet, SVFValKind k)
@@ -171,8 +171,9 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule)
171
171
  void CDGBuilder::extractBBS(const SVF::SVFFunction *func,
172
172
  Map<const SVF::SVFBasicBlock *, std::vector<const SVFBasicBlock *>> &res)
173
173
  {
174
- for (const auto &bb: *func)
174
+ for (const auto &it: *func)
175
175
  {
176
+ const SVFBasicBlock* bb = it.second;
176
177
  for (const auto &succ: bb->getSuccessors())
177
178
  {
178
179
  if (func->postDominate(succ, bb))
@@ -48,8 +48,9 @@ CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule)
48
48
 
49
49
  for (const auto& item : *callgraph)
50
50
  {
51
- for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
51
+ for (auto it : *(item.second)->getFunction())
52
52
  {
53
+ const SVFBasicBlock* svfbb = it.second;
53
54
  for (const ICFGNode* inst : svfbb->getICFGNodeList())
54
55
  {
55
56
  if (SVFUtil::isNonInstricCallSite(inst))
@@ -80,8 +81,9 @@ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph()
80
81
  ThreadAPI* tdAPI = ThreadAPI::getThreadAPI();
81
82
  for (const auto& item: *svfirCallGraph)
82
83
  {
83
- for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
84
+ for (auto it : *(item.second)->getFunction())
84
85
  {
86
+ const SVFBasicBlock* svfbb = it.second;
85
87
  for (const ICFGNode* inst : svfbb->getICFGNodeList())
86
88
  {
87
89
  if (SVFUtil::isa<CallICFGNode>(inst) && tdAPI->isTDFork(SVFUtil::cast<CallICFGNode>(inst)))
@@ -105,8 +107,9 @@ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph()
105
107
  // record join sites
106
108
  for (const auto& item: *svfirCallGraph)
107
109
  {
108
- for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
110
+ for (auto it : *(item.second)->getFunction())
109
111
  {
112
+ const SVFBasicBlock* svfbb = it.second;
110
113
  for (const ICFGNode* node : svfbb->getICFGNodeList())
111
114
  {
112
115
  if (SVFUtil::isa<CallICFGNode>(node) && tdAPI->isTDJoin(SVFUtil::cast<CallICFGNode>(node)))
@@ -230,7 +230,7 @@ void SVFStat::branchStat()
230
230
  for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end();
231
231
  bbIt != bbEit; ++bbIt)
232
232
  {
233
- const SVFBasicBlock* bb = *bbIt;
233
+ const SVFBasicBlock* bb = bbIt->second;
234
234
  u32_t numOfSucc = bb->getNumSuccessors();
235
235
  if (numOfSucc == 2)
236
236
  numOfBB_2Succ++;
@@ -275,7 +275,7 @@ void ThreadAPI::performAPIStat(SVFModule* module)
275
275
  {
276
276
  for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit)
277
277
  {
278
- const SVFBasicBlock* bb = *bit;
278
+ const SVFBasicBlock* bb = bit->second;
279
279
  for (const auto& svfInst: bb->getICFGNodeList())
280
280
  {
281
281
  if (!SVFUtil::isCallSite(svfInst))
@@ -34,6 +34,7 @@
34
34
  #include "SVFIR/SVFValue.h"
35
35
  #include "SVFIR/SVFModule.h"
36
36
  #include "Util/Options.h"
37
+ #include "Graphs/BasicBlockG.h"
37
38
 
38
39
  namespace SVF
39
40
  {
@@ -177,11 +178,14 @@ public:
177
178
 
178
179
  void addFunctionMap(const Function* func, CallGraphNode* svfFunc);
179
180
 
180
- inline void addBasicBlockMap(const BasicBlock* bb, SVFBasicBlock* svfBB)
181
+ // create a SVFBasicBlock according to LLVM BasicBlock, then add it to SVFFunction's BasicBlockGraph
182
+ inline void addBasicBlock(SVFFunction* fun, const BasicBlock* bb)
181
183
  {
184
+ SVFBasicBlock* svfBB = fun->getBasicBlockGraph()->addBasicBlock(bb->getName().str());
182
185
  LLVMBB2SVFBB[bb] = svfBB;
183
- setValueAttr(bb,svfBB);
186
+ SVFBaseNode2LLVMValue[svfBB] = bb;
184
187
  }
188
+
185
189
  inline void addInstructionMap(const Instruction* inst, SVFInstruction* svfInst)
186
190
  {
187
191
  LLVMInst2SVFInst[inst] = svfInst;
@@ -246,7 +250,7 @@ public:
246
250
  const Value* getLLVMValue(const SVFBaseNode* value) const
247
251
  {
248
252
  SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
249
- assert(it!=SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
253
+ assert(it != SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
250
254
  return it->second;
251
255
  }
252
256
 
@@ -264,7 +268,7 @@ public:
264
268
  return it->second;
265
269
  }
266
270
 
267
- inline SVFBasicBlock* getSVFBasicBlock(const BasicBlock* bb) const
271
+ SVFBasicBlock* getSVFBasicBlock(const BasicBlock* bb)
268
272
  {
269
273
  LLVMBB2SVFBBMap::const_iterator it = LLVMBB2SVFBB.find(bb);
270
274
  assert(it!=LLVMBB2SVFBB.end() && "SVF BasicBlock not found!");
@@ -280,6 +280,8 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
280
280
  getSVFType(func->getFunctionType())),
281
281
  func->isDeclaration(), LLVMUtil::isIntrinsicFun(func),
282
282
  func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo);
283
+ BasicBlockGraph* bbGraph = new BasicBlockGraph(svfFunc);
284
+ svfFunc->setBasicBlockGraph(bbGraph);
283
285
  svfModule->addFunctionSet(svfFunc);
284
286
  addFunctionMap(func, svfFunc);
285
287
 
@@ -298,17 +300,14 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
298
300
 
299
301
  for (const BasicBlock& bb : *func)
300
302
  {
301
- SVFBasicBlock* svfBB =
302
- new SVFBasicBlock(getSVFType(bb.getType()), svfFunc);
303
- svfFunc->addBasicBlock(svfBB);
304
- addBasicBlockMap(&bb, svfBB);
303
+ addBasicBlock(svfFunc, &bb);
305
304
  for (const Instruction& inst : bb)
306
305
  {
307
306
  SVFInstruction* svfInst = nullptr;
308
307
  if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
309
308
  {
310
309
  svfInst = new SVFCallInst(
311
- getSVFType(call->getType()), svfBB,
310
+ getSVFType(call->getType()), getSVFBasicBlock(&bb),
312
311
  call->getFunctionType()->isVarArg(),
313
312
  inst.isTerminator());
314
313
  }
@@ -316,7 +315,7 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
316
315
  {
317
316
  svfInst =
318
317
  new SVFInstruction(getSVFType(inst.getType()),
319
- svfBB, inst.isTerminator(),
318
+ getSVFBasicBlock(&bb), inst.isTerminator(),
320
319
  SVFUtil::isa<ReturnInst>(inst));
321
320
  }
322
321
 
@@ -1365,8 +1364,6 @@ SVFValue* LLVMModuleSet::getSVFValue(const Value* value)
1365
1364
  {
1366
1365
  if (const Function* fun = SVFUtil::dyn_cast<Function>(value))
1367
1366
  return getSVFFunction(fun);
1368
- else if (const BasicBlock* bb = SVFUtil::dyn_cast<BasicBlock>(value))
1369
- return getSVFBasicBlock(bb);
1370
1367
  else if(const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
1371
1368
  return getSVFInstruction(inst);
1372
1369
  else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(value))
@@ -726,10 +726,6 @@ std::string SVFValue::toString() const
726
726
  {
727
727
  rawstr << "Function: " << fun->getName() << " ";
728
728
  }
729
- else if (const SVFBasicBlock* bb = SVFUtil::dyn_cast<SVFBasicBlock>(this))
730
- {
731
- rawstr << "BasicBlock: " << bb->getName() << " ";
732
- }
733
729
  else
734
730
  {
735
731
  auto llvmVal = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(this);
@@ -742,6 +738,18 @@ std::string SVFValue::toString() const
742
738
  return rawstr.str();
743
739
  }
744
740
 
741
+ const std::string SVFBasicBlock::toString() const
742
+ {
743
+ std::string str;
744
+ llvm::raw_string_ostream rawstr(str);
745
+ auto llvmVal = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(this);
746
+ if (llvmVal)
747
+ rawstr << " " << *llvmVal << " ";
748
+ else
749
+ rawstr << " No llvmVal found";
750
+ rawstr << this->getSourceLoc();
751
+ return rawstr.str();
752
+ }
745
753
 
746
754
  const std::string SVFBaseNode::valueOnlyToString() const
747
755
  {
@@ -586,8 +586,8 @@ Set<const Value *> &ObjTypeInference::bwfindAllocOfVar(const Value *var)
586
586
  if (!callee->isDeclaration())
587
587
  {
588
588
  const SVFFunction *svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee);
589
- const BasicBlock* exitBB = SVFUtil::cast<BasicBlock>(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(
590
- svfFunc->getExitBB()));
589
+ const BasicBlock* exitBB = SVFUtil::dyn_cast<BasicBlock>(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()));
590
+ assert (exitBB && "exit bb is not a basic block?");
591
591
  const Value *pValue = &exitBB->back();
592
592
  const auto *retInst = SVFUtil::dyn_cast<ReturnInst>(pValue);
593
593
  ABORT_IFNOT(retInst && retInst->getReturnValue(), "not return inst?");
@@ -894,8 +894,8 @@ Set<const Value *> &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s
894
894
  if (!callee->isDeclaration())
895
895
  {
896
896
  const SVFFunction *svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee);
897
- const BasicBlock* exitBB = SVFUtil::cast<BasicBlock>(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(
898
- svfFunc->getExitBB()));
897
+ const BasicBlock* exitBB = SVFUtil::dyn_cast<BasicBlock>(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()));
898
+ assert (exitBB && "exit bb is not a basic block?");
899
899
  const Value *pValue = &exitBB->back();
900
900
  const auto *retInst = SVFUtil::dyn_cast<ReturnInst>(pValue);
901
901
  ABORT_IFNOT(retInst && retInst->getReturnValue(), "not return inst?");