svf-tools 1.0.648 → 1.0.650
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/LICENSE.TXT
CHANGED
|
@@ -32,10 +32,13 @@ licenses, and/or restrictions:
|
|
|
32
32
|
|
|
33
33
|
Program Directory/File
|
|
34
34
|
------- --------------
|
|
35
|
-
fastcluster/hclust-cpp include/FastCluster/
|
|
36
|
-
lib/FastCluster/
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
fastcluster/hclust-cpp svf/include/FastCluster/
|
|
36
|
+
svf/lib/FastCluster/
|
|
37
|
+
(License under the folder)
|
|
38
|
+
LLVM's SparseBitVector svf/include/Util/SparseBitVector.h
|
|
39
|
+
(Apache License v2.0)
|
|
40
|
+
cJSON svf/include/Util/cJSON.h
|
|
41
|
+
(MIT License)
|
|
39
42
|
|
|
40
43
|
|
|
41
44
|
==============================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.650",
|
|
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": {
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
5
|
-
// Copyright (C) <2013
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
// This program is free software: you can redistribute it and/or modify
|
|
9
|
-
// it under the terms of the GNU
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
10
|
// the Free Software Foundation, either version 3 of the License, or
|
|
11
11
|
// (at your option) any later version.
|
|
12
12
|
|
|
13
13
|
// This program is distributed in the hope that it will be useful,
|
|
14
14
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
15
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
-
// GNU
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
17
|
|
|
18
|
-
// You should have received a copy of the GNU
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
19
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
//
|
|
21
21
|
//===----------------------------------------------------------------------===//
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
/*
|
|
24
24
|
* WTO.h
|
|
25
25
|
*
|
|
26
|
+
* The implementation is based on F. Bourdoncle's paper:
|
|
27
|
+
* "Efficient chaotic iteration strategies with widenings", Formal
|
|
28
|
+
* Methods in Programming and Their Applications, 1993, pages 128-141.
|
|
29
|
+
*
|
|
26
30
|
* Created on: Jul 3, 2022
|
|
27
31
|
* Author: Xiao Cheng, Jiawei Wang
|
|
28
32
|
*
|
|
@@ -31,143 +35,121 @@
|
|
|
31
35
|
#ifndef WTO_H_
|
|
32
36
|
#define WTO_H_
|
|
33
37
|
|
|
34
|
-
#include <memory>
|
|
35
|
-
#include <sstream>
|
|
36
|
-
#include <unordered_map>
|
|
37
|
-
#include <utility>
|
|
38
|
-
#include <vector>
|
|
39
|
-
|
|
40
38
|
#include "SVFIR/SVFType.h"
|
|
41
39
|
#include "SVFIR/SVFValue.h"
|
|
40
|
+
#include "Graphs/CFBasicBlockG.h"
|
|
42
41
|
|
|
43
42
|
|
|
44
43
|
namespace SVF
|
|
45
44
|
{
|
|
46
45
|
|
|
47
|
-
class
|
|
48
|
-
|
|
49
|
-
class WtoVertex;
|
|
50
|
-
|
|
51
|
-
class WtoCycle;
|
|
52
|
-
|
|
53
|
-
/// \brief Weak topological order visitor
|
|
54
|
-
class WtoComponentVisitor
|
|
55
|
-
{
|
|
56
|
-
public:
|
|
57
|
-
typedef WtoVertex WtoVertexT;
|
|
58
|
-
typedef WtoCycle WtoCycleT;
|
|
59
|
-
|
|
60
|
-
public:
|
|
61
|
-
/// \brief Default constructor
|
|
62
|
-
WtoComponentVisitor() = default;
|
|
63
|
-
|
|
64
|
-
/// \brief Copy constructor
|
|
65
|
-
WtoComponentVisitor(const WtoComponentVisitor &) noexcept = default;
|
|
66
|
-
|
|
67
|
-
/// \brief Move constructor
|
|
68
|
-
WtoComponentVisitor(WtoComponentVisitor &&) noexcept = default;
|
|
69
|
-
|
|
70
|
-
/// \brief Copy assignment operator
|
|
71
|
-
WtoComponentVisitor &operator=(const WtoComponentVisitor &) noexcept = default;
|
|
72
|
-
|
|
73
|
-
/// \brief Move assignment operator
|
|
74
|
-
WtoComponentVisitor &operator=(WtoComponentVisitor &&) noexcept = default;
|
|
75
|
-
|
|
76
|
-
/// \brief Visit the given vertex
|
|
77
|
-
virtual void visit(const WtoVertexT &) = 0;
|
|
78
|
-
|
|
79
|
-
/// \brief Visit the given cycle
|
|
80
|
-
virtual void visit(const WtoCycleT &) = 0;
|
|
81
|
-
|
|
82
|
-
/// \brief Destructor
|
|
83
|
-
virtual ~WtoComponentVisitor() = default;
|
|
84
|
-
|
|
85
|
-
}; // end class WtoComponentVisitor
|
|
46
|
+
class CFBasicBlockGWTO;
|
|
86
47
|
|
|
48
|
+
class CFBasicBlockGWTONode;
|
|
87
49
|
|
|
50
|
+
class CFBasicBlockGWTOCycle;
|
|
88
51
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
52
|
+
/*!
|
|
53
|
+
* Cycle depth of a WTO Component
|
|
54
|
+
*
|
|
55
|
+
* The cycle depth is represented as **a list of cycle's heads**,
|
|
56
|
+
* **from the outermost to the innermost**.
|
|
57
|
+
*
|
|
58
|
+
* e.g., consider the following nested cycle:
|
|
59
|
+
*
|
|
60
|
+
* -->1 --> 2 --> 3 --> 4
|
|
61
|
+
* \ /
|
|
62
|
+
* <-- 6 <-- 5 <--
|
|
63
|
+
* \ /
|
|
64
|
+
* >7>
|
|
65
|
+
*
|
|
66
|
+
* where C1: (1 2 3 4 5 6 7) is the outer cycle, where 1 is the head,
|
|
67
|
+
* and C2: (5 6 7) is the inner cycle, where 5 is the head.
|
|
68
|
+
*
|
|
69
|
+
* The cycle depth is as following:
|
|
70
|
+
* ---------------------------------
|
|
71
|
+
* | Node NO. | Cycle Depth |
|
|
72
|
+
* --------------------------------
|
|
73
|
+
* | 1 (head of C1) | [ ] |
|
|
74
|
+
* --------------------------------
|
|
75
|
+
* | 2, 3, 4 | [1] |
|
|
76
|
+
* --------------------------------
|
|
77
|
+
* | 5 (head of C2) | [1] |
|
|
78
|
+
* --------------------------------
|
|
79
|
+
* | 6, 7 | [1, 5] |
|
|
80
|
+
* --------------------------------
|
|
81
|
+
*/
|
|
82
|
+
template <typename NodeRef>
|
|
83
|
+
class WTOCycleDepth
|
|
96
84
|
{
|
|
97
85
|
public:
|
|
98
|
-
|
|
99
|
-
typedef std::vector<const SVFBasicBlock*> NodeRefList;
|
|
100
|
-
|
|
101
|
-
public:
|
|
86
|
+
typedef std::vector<NodeRef> NodeRefList;
|
|
102
87
|
typedef typename NodeRefList::const_iterator Iterator;
|
|
103
88
|
|
|
104
89
|
private:
|
|
105
|
-
NodeRefList
|
|
90
|
+
NodeRefList _heads;
|
|
106
91
|
|
|
107
92
|
public:
|
|
108
|
-
///
|
|
109
|
-
|
|
93
|
+
/// Default Constructor
|
|
94
|
+
WTOCycleDepth() = default;
|
|
110
95
|
|
|
111
|
-
///
|
|
112
|
-
|
|
96
|
+
/// Default Copy Constructor
|
|
97
|
+
WTOCycleDepth(const WTOCycleDepth &) = default;
|
|
113
98
|
|
|
114
|
-
///
|
|
115
|
-
|
|
99
|
+
/// Default Move Constructor
|
|
100
|
+
WTOCycleDepth(WTOCycleDepth &&) = default;
|
|
116
101
|
|
|
117
|
-
///
|
|
118
|
-
|
|
102
|
+
/// Default Copy Operator=
|
|
103
|
+
WTOCycleDepth &operator=(const WTOCycleDepth &) = default;
|
|
119
104
|
|
|
120
|
-
///
|
|
121
|
-
|
|
105
|
+
/// Default Move Operator=
|
|
106
|
+
WTOCycleDepth &operator=(WTOCycleDepth &&) = default;
|
|
122
107
|
|
|
123
|
-
///
|
|
124
|
-
~
|
|
108
|
+
/// Default Destructor
|
|
109
|
+
~WTOCycleDepth() = default;
|
|
125
110
|
|
|
126
|
-
///
|
|
127
|
-
void
|
|
111
|
+
/// Add a cycle head to the end of the head list
|
|
112
|
+
void push_back(NodeRef head)
|
|
128
113
|
{
|
|
129
|
-
|
|
114
|
+
_heads.push_back(head);
|
|
130
115
|
}
|
|
131
116
|
|
|
132
|
-
/// \brief Begin iterator over the head of cycles
|
|
133
117
|
Iterator begin() const
|
|
134
118
|
{
|
|
135
|
-
return
|
|
119
|
+
return _heads.cbegin();
|
|
136
120
|
}
|
|
137
121
|
|
|
138
|
-
/// \brief End iterator over the head of cycles
|
|
139
122
|
Iterator end() const
|
|
140
123
|
{
|
|
141
|
-
return
|
|
124
|
+
return _heads.cend();
|
|
142
125
|
}
|
|
143
126
|
|
|
144
|
-
///
|
|
145
|
-
|
|
127
|
+
/// Convert the wto-cycle-depth to a string
|
|
128
|
+
std::string toString() const
|
|
146
129
|
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
130
|
+
std::string str;
|
|
131
|
+
std::stringstream rawstr(str);
|
|
132
|
+
rawstr << "[";
|
|
133
|
+
for (auto it = begin(), et = end(); it != et;)
|
|
151
134
|
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
else
|
|
135
|
+
rawstr << (*it)->getName().data();
|
|
136
|
+
++it;
|
|
137
|
+
if (it != et)
|
|
157
138
|
{
|
|
158
|
-
|
|
139
|
+
rawstr << ", ";
|
|
159
140
|
}
|
|
160
141
|
}
|
|
161
|
-
|
|
142
|
+
rawstr << "]";
|
|
143
|
+
return rawstr.str();
|
|
162
144
|
}
|
|
163
145
|
|
|
164
146
|
private:
|
|
165
|
-
///
|
|
166
|
-
int compare(const
|
|
147
|
+
/// Compare the given wto-cycle-depth
|
|
148
|
+
int compare(const WTOCycleDepth &other) const
|
|
167
149
|
{
|
|
168
150
|
if (this == &other)
|
|
169
151
|
{
|
|
170
|
-
return 0; // equals
|
|
152
|
+
return 0; // 0 - equals
|
|
171
153
|
}
|
|
172
154
|
|
|
173
155
|
auto this_it = begin();
|
|
@@ -176,7 +158,7 @@ private:
|
|
|
176
158
|
{
|
|
177
159
|
if (other_it == other.end())
|
|
178
160
|
{
|
|
179
|
-
return 1; // `this` is
|
|
161
|
+
return 1; // `this` is inside `other`
|
|
180
162
|
}
|
|
181
163
|
else if (*this_it == *other_it)
|
|
182
164
|
{
|
|
@@ -194,146 +176,189 @@ private:
|
|
|
194
176
|
}
|
|
195
177
|
else
|
|
196
178
|
{
|
|
197
|
-
return -1; // `other` is
|
|
179
|
+
return -1; // `other` is inside `this`
|
|
198
180
|
}
|
|
199
181
|
}
|
|
200
182
|
|
|
201
183
|
public:
|
|
202
|
-
|
|
184
|
+
|
|
185
|
+
/// Overloading operators
|
|
186
|
+
//@{
|
|
187
|
+
/// Return the common prefix of the given wto-cycle-depth
|
|
188
|
+
WTOCycleDepth operator^(const WTOCycleDepth &other) const
|
|
203
189
|
{
|
|
204
|
-
|
|
190
|
+
WTOCycleDepth res;
|
|
191
|
+
for (auto this_it = begin(), other_it = other.begin();
|
|
192
|
+
this_it != end() && other_it != other.end();
|
|
193
|
+
++this_it, ++other_it)
|
|
194
|
+
{
|
|
195
|
+
if (*this_it == *other_it)
|
|
196
|
+
{
|
|
197
|
+
res.push_back(*this_it);
|
|
198
|
+
}
|
|
199
|
+
else
|
|
200
|
+
{
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return res;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
/// Less than other's depth - `other` is inside `this`
|
|
208
|
+
bool operator<(const WTOCycleDepth &other) const
|
|
208
209
|
{
|
|
209
|
-
return compare(other)
|
|
210
|
+
return compare(other) == -1;
|
|
210
211
|
}
|
|
211
212
|
|
|
212
|
-
|
|
213
|
+
/// Less than or Equal with other's depth
|
|
214
|
+
bool operator<=(const WTOCycleDepth &other) const
|
|
213
215
|
{
|
|
214
|
-
return compare(other)
|
|
216
|
+
return compare(other) <= 0;
|
|
215
217
|
}
|
|
216
218
|
|
|
217
|
-
|
|
219
|
+
/// Equal with other's depth
|
|
220
|
+
bool operator==(const WTOCycleDepth &other) const
|
|
218
221
|
{
|
|
219
|
-
return
|
|
222
|
+
return compare(other) == 0;
|
|
220
223
|
}
|
|
221
224
|
|
|
222
|
-
|
|
225
|
+
/// Greater than other's depth - `this` is inside `other`
|
|
226
|
+
bool operator>(const WTOCycleDepth &other) const
|
|
223
227
|
{
|
|
224
228
|
return compare(other) == 1;
|
|
225
229
|
}
|
|
226
230
|
|
|
227
|
-
///
|
|
228
|
-
|
|
231
|
+
/// Greater than or Equal with other's depth
|
|
232
|
+
bool operator>=(const WTOCycleDepth &other) const
|
|
229
233
|
{
|
|
230
|
-
|
|
231
|
-
std::stringstream rawstr(str);
|
|
232
|
-
rawstr << "[";
|
|
233
|
-
for (auto it = begin(), et = end(); it != et;)
|
|
234
|
-
{
|
|
235
|
-
rawstr << (*it)->getName().data();
|
|
236
|
-
++it;
|
|
237
|
-
if (it != et)
|
|
238
|
-
{
|
|
239
|
-
rawstr << ", ";
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
rawstr << "]";
|
|
243
|
-
return rawstr.str();
|
|
234
|
+
return operator<=(other);
|
|
244
235
|
}
|
|
245
236
|
|
|
246
|
-
///
|
|
247
|
-
|
|
248
|
-
friend std::ostream &operator<<(std::ostream &o, const WtoNesting &wto)
|
|
237
|
+
/// Dump into CMD
|
|
238
|
+
friend std::ostream &operator<<(std::ostream &o, const WTOCycleDepth &CFBasicBlockGWTO)
|
|
249
239
|
{
|
|
250
|
-
o <<
|
|
240
|
+
o << CFBasicBlockGWTO.toString();
|
|
251
241
|
return o;
|
|
252
242
|
}
|
|
253
243
|
//@}
|
|
254
244
|
|
|
255
|
-
}; // end class
|
|
245
|
+
}; // end class WTOCycleDepth
|
|
246
|
+
|
|
247
|
+
/*!
|
|
248
|
+
* Weak topological order (WTO) visitor
|
|
249
|
+
*/
|
|
250
|
+
class WTOVisitor
|
|
251
|
+
{
|
|
252
|
+
|
|
253
|
+
public:
|
|
254
|
+
/// Default Constructor
|
|
255
|
+
WTOVisitor() = default;
|
|
256
|
+
|
|
257
|
+
/// Default Copy Constructor
|
|
258
|
+
WTOVisitor(const WTOVisitor &) noexcept = default;
|
|
259
|
+
|
|
260
|
+
/// Default Move Constructor
|
|
261
|
+
WTOVisitor(WTOVisitor &&) noexcept = default;
|
|
262
|
+
|
|
263
|
+
/// Default Copy Operator=
|
|
264
|
+
WTOVisitor &operator=(const WTOVisitor &) noexcept = default;
|
|
265
|
+
|
|
266
|
+
/// Default Move Operator=
|
|
267
|
+
WTOVisitor &operator=(WTOVisitor &&) noexcept = default;
|
|
268
|
+
|
|
269
|
+
/// Default Destructor
|
|
270
|
+
virtual ~WTOVisitor() = default;
|
|
271
|
+
|
|
272
|
+
/// Visit WTO Node
|
|
273
|
+
virtual void visit(const CFBasicBlockGWTONode &) = 0;
|
|
256
274
|
|
|
275
|
+
/// Visit WTO Cycle
|
|
276
|
+
virtual void visit(const CFBasicBlockGWTOCycle &) = 0;
|
|
257
277
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
class
|
|
278
|
+
}; // end class WTOVisitor
|
|
279
|
+
|
|
280
|
+
/*!
|
|
281
|
+
* Base class for a WTO component for CFBasicBlockG
|
|
282
|
+
*
|
|
283
|
+
* A WTO component can be either a node or cycle
|
|
284
|
+
*/
|
|
285
|
+
class CFBasicBlockGWTOComp
|
|
262
286
|
{
|
|
287
|
+
|
|
263
288
|
public:
|
|
264
|
-
/// Types of SVFIR statements
|
|
265
|
-
/// Gep represents (base + offset) for field sensitivity
|
|
266
|
-
/// ThreadFork/ThreadJoin is to model parameter passings between thread spawners and spawnees.
|
|
267
289
|
enum WtoCT
|
|
268
290
|
{
|
|
269
291
|
Node, Cycle
|
|
270
292
|
};
|
|
271
293
|
|
|
272
|
-
|
|
273
|
-
|
|
294
|
+
public:
|
|
295
|
+
/// Default Constructor
|
|
296
|
+
CFBasicBlockGWTOComp(WtoCT k) : _type(k) {};
|
|
274
297
|
|
|
275
|
-
///
|
|
276
|
-
|
|
298
|
+
/// Copy Constructor
|
|
299
|
+
CFBasicBlockGWTOComp(const CFBasicBlockGWTOComp &) noexcept = default;
|
|
277
300
|
|
|
278
|
-
///
|
|
279
|
-
|
|
301
|
+
/// Move Constructor
|
|
302
|
+
CFBasicBlockGWTOComp(CFBasicBlockGWTOComp &&) noexcept = default;
|
|
280
303
|
|
|
281
|
-
///
|
|
282
|
-
|
|
304
|
+
/// Copy Operator=
|
|
305
|
+
CFBasicBlockGWTOComp &operator=(const CFBasicBlockGWTOComp &) noexcept = default;
|
|
283
306
|
|
|
284
|
-
///
|
|
285
|
-
|
|
307
|
+
/// Move Operator=
|
|
308
|
+
CFBasicBlockGWTOComp &operator=(CFBasicBlockGWTOComp &&) noexcept = default;
|
|
286
309
|
|
|
287
|
-
///
|
|
288
|
-
virtual
|
|
310
|
+
/// Default Destructor
|
|
311
|
+
virtual ~CFBasicBlockGWTOComp() = default;
|
|
289
312
|
|
|
290
|
-
///
|
|
291
|
-
virtual
|
|
313
|
+
/// Accept a visitor
|
|
314
|
+
virtual void accept(WTOVisitor *) const = 0;
|
|
292
315
|
|
|
316
|
+
/// Return the WTO Kind (node or cycle)
|
|
293
317
|
inline WtoCT getKind() const
|
|
294
318
|
{
|
|
295
|
-
return
|
|
319
|
+
return _type;
|
|
296
320
|
}
|
|
297
321
|
|
|
298
322
|
virtual std::string toString() const = 0;
|
|
299
323
|
|
|
300
|
-
|
|
301
|
-
//@{
|
|
302
|
-
friend std::ostream &operator<<(std::ostream &o, const WtoComponent &wto)
|
|
324
|
+
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockGWTOComp &CFBasicBlockGWTO)
|
|
303
325
|
{
|
|
304
|
-
o <<
|
|
326
|
+
o << CFBasicBlockGWTO.toString();
|
|
305
327
|
return o;
|
|
306
328
|
}
|
|
307
|
-
//@}
|
|
308
329
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
330
|
+
private:
|
|
331
|
+
|
|
332
|
+
WtoCT _type;
|
|
333
|
+
|
|
334
|
+
}; // end class CFBasicBlockGWTOComp
|
|
312
335
|
|
|
313
336
|
|
|
314
|
-
|
|
315
|
-
|
|
337
|
+
/*!
|
|
338
|
+
* WTO node for CFBasicBlockG
|
|
339
|
+
*/
|
|
340
|
+
class CFBasicBlockGWTONode final : public CFBasicBlockGWTOComp
|
|
316
341
|
{
|
|
317
342
|
private:
|
|
318
|
-
const
|
|
343
|
+
const CFBasicBlockNode *_node;
|
|
319
344
|
|
|
320
345
|
public:
|
|
321
|
-
///
|
|
322
|
-
explicit
|
|
346
|
+
/// Constructor
|
|
347
|
+
explicit CFBasicBlockGWTONode(const CFBasicBlockNode *node) : CFBasicBlockGWTOComp(CFBasicBlockGWTOComp::Node), _node(node) {}
|
|
323
348
|
|
|
324
|
-
///
|
|
325
|
-
const
|
|
349
|
+
/// Return the graph node
|
|
350
|
+
const CFBasicBlockNode *node() const
|
|
326
351
|
{
|
|
327
352
|
return _node;
|
|
328
353
|
}
|
|
329
354
|
|
|
330
|
-
///
|
|
331
|
-
void accept(
|
|
355
|
+
/// Accept a visitor
|
|
356
|
+
void accept(WTOVisitor *v) const override
|
|
332
357
|
{
|
|
333
358
|
v->visit(*this);
|
|
334
359
|
}
|
|
335
360
|
|
|
336
|
-
///
|
|
361
|
+
/// Convert the node to string
|
|
337
362
|
std::string toString() const override
|
|
338
363
|
{
|
|
339
364
|
return std::string(_node->getName().data());
|
|
@@ -341,84 +366,76 @@ public:
|
|
|
341
366
|
|
|
342
367
|
/// ClassOf
|
|
343
368
|
//@{
|
|
344
|
-
static inline bool classof(const
|
|
369
|
+
static inline bool classof(const CFBasicBlockGWTONode *)
|
|
345
370
|
{
|
|
346
371
|
return true;
|
|
347
372
|
}
|
|
348
373
|
|
|
349
|
-
static inline bool classof(const
|
|
374
|
+
static inline bool classof(const CFBasicBlockGWTOComp *c)
|
|
350
375
|
{
|
|
351
|
-
return c->getKind() ==
|
|
376
|
+
return c->getKind() == CFBasicBlockGWTOComp::Node;
|
|
352
377
|
}
|
|
353
378
|
///@}
|
|
354
379
|
|
|
355
|
-
}; // end class
|
|
380
|
+
}; // end class CFBasicBlockGWTONode
|
|
356
381
|
|
|
357
382
|
|
|
358
|
-
|
|
359
|
-
|
|
383
|
+
/*!
|
|
384
|
+
* WTO cycle for CFBasicBlockG
|
|
385
|
+
*/
|
|
386
|
+
class CFBasicBlockGWTOCycle final : public CFBasicBlockGWTOComp
|
|
360
387
|
{
|
|
361
|
-
public:
|
|
362
|
-
typedef WtoComponent WtoComponentT;
|
|
363
|
-
|
|
364
388
|
private:
|
|
365
|
-
typedef const
|
|
366
|
-
typedef
|
|
367
|
-
|
|
368
|
-
public:
|
|
369
|
-
/// \brief Iterator over the components
|
|
370
|
-
typedef typename WtoComponentRefList::const_iterator Iterator;
|
|
389
|
+
typedef std::list<const CFBasicBlockGWTOComp *> WtoComponentRefList;
|
|
390
|
+
typedef WtoComponentRefList::const_iterator Iterator;
|
|
371
391
|
|
|
372
392
|
private:
|
|
373
|
-
///
|
|
374
|
-
const
|
|
393
|
+
/// Head of the cycle
|
|
394
|
+
const CFBasicBlockNode *_head;
|
|
375
395
|
|
|
376
|
-
///
|
|
396
|
+
/// List of components
|
|
377
397
|
WtoComponentRefList _components;
|
|
378
398
|
|
|
379
399
|
public:
|
|
380
|
-
///
|
|
381
|
-
|
|
382
|
-
:
|
|
400
|
+
/// Constructor
|
|
401
|
+
CFBasicBlockGWTOCycle(const CFBasicBlockNode *head, WtoComponentRefList components)
|
|
402
|
+
: CFBasicBlockGWTOComp(CFBasicBlockGWTOComp::Cycle), _head(head), _components(std::move(components)) {}
|
|
383
403
|
|
|
384
|
-
///
|
|
385
|
-
const
|
|
404
|
+
/// Return the head of the cycle
|
|
405
|
+
const CFBasicBlockNode *head() const
|
|
386
406
|
{
|
|
387
407
|
return _head;
|
|
388
408
|
}
|
|
389
409
|
|
|
390
|
-
/// \brief Begin iterator over the components
|
|
391
410
|
Iterator begin() const
|
|
392
411
|
{
|
|
393
412
|
return _components.cbegin();
|
|
394
413
|
}
|
|
395
414
|
|
|
396
|
-
/// \brief End iterator over the components
|
|
397
415
|
Iterator end() const
|
|
398
416
|
{
|
|
399
417
|
return _components.cend();
|
|
400
418
|
}
|
|
401
419
|
|
|
402
|
-
///
|
|
403
|
-
void accept(
|
|
420
|
+
/// Accept a visitor
|
|
421
|
+
void accept(WTOVisitor *v) const override
|
|
404
422
|
{
|
|
405
423
|
v->visit(*this);
|
|
406
424
|
}
|
|
407
425
|
|
|
408
426
|
/// ClassOf
|
|
409
427
|
//@{
|
|
410
|
-
static inline bool classof(const
|
|
428
|
+
static inline bool classof(const CFBasicBlockGWTOCycle *)
|
|
411
429
|
{
|
|
412
430
|
return true;
|
|
413
431
|
}
|
|
414
432
|
|
|
415
|
-
static inline bool classof(const
|
|
433
|
+
static inline bool classof(const CFBasicBlockGWTOComp *c)
|
|
416
434
|
{
|
|
417
|
-
return c->getKind() ==
|
|
435
|
+
return c->getKind() == CFBasicBlockGWTOComp::Cycle;
|
|
418
436
|
}
|
|
419
437
|
///@}
|
|
420
438
|
|
|
421
|
-
/// \brief Dump the cycle, for debugging purpose
|
|
422
439
|
std::string toString() const override
|
|
423
440
|
{
|
|
424
441
|
std::string str;
|
|
@@ -438,76 +455,61 @@ public:
|
|
|
438
455
|
return rawstr.str();
|
|
439
456
|
}
|
|
440
457
|
|
|
441
|
-
}; // end class
|
|
458
|
+
}; // end class CFBasicBlockGWTOCycle
|
|
442
459
|
|
|
443
460
|
|
|
444
|
-
|
|
445
|
-
|
|
461
|
+
/*!
|
|
462
|
+
* Weak topological order for CFBasicBlockG
|
|
463
|
+
*/
|
|
464
|
+
class CFBasicBlockGWTO
|
|
446
465
|
{
|
|
447
466
|
|
|
448
467
|
public:
|
|
449
|
-
typedef
|
|
450
|
-
typedef
|
|
451
|
-
typedef WtoVertex WtoVertexT;
|
|
452
|
-
typedef WtoCycle WtoCycleT;
|
|
453
|
-
typedef Set<const SVFBasicBlock *> NodeRefList;
|
|
468
|
+
typedef WTOCycleDepth<const CFBasicBlockNode*> CFBasicBlockGWTOCycleDepth;
|
|
469
|
+
typedef Set<const CFBasicBlockNode *> NodeRefSet;
|
|
454
470
|
|
|
455
471
|
protected:
|
|
456
|
-
typedef const
|
|
457
|
-
typedef
|
|
458
|
-
typedef
|
|
459
|
-
typedef Map<const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
typedef
|
|
463
|
-
typedef
|
|
464
|
-
typedef std::
|
|
465
|
-
typedef
|
|
466
|
-
typedef Map<const SVFBasicBlock *, WtoNestingPtr> NestingTable;
|
|
472
|
+
typedef std::list<const CFBasicBlockGWTOComp *> WTOCompRefList;
|
|
473
|
+
typedef Set <const CFBasicBlockGWTOComp *> WTOCompRefSet;
|
|
474
|
+
typedef Map<const CFBasicBlockNode *, const CFBasicBlockGWTOCycle *> NodeRefToWTOCycleMap;
|
|
475
|
+
typedef Map<const CFBasicBlockNode *, NodeRefSet> NodeRefToNodeRefSetMap;
|
|
476
|
+
|
|
477
|
+
typedef u32_t CycleDepthNumber;
|
|
478
|
+
typedef Map<const CFBasicBlockNode *, CycleDepthNumber> NodeRefToCycleDepthNumber;
|
|
479
|
+
typedef std::vector<const CFBasicBlockNode *> CFBasicBlockNodes;
|
|
480
|
+
typedef std::shared_ptr<CFBasicBlockGWTOCycleDepth> CFBasicBlockGWTOCycleDepthPtr;
|
|
481
|
+
typedef Map<const CFBasicBlockNode *, CFBasicBlockGWTOCycleDepthPtr> NodeRefToWTOCycleDepthPtr;
|
|
467
482
|
|
|
468
483
|
public:
|
|
469
|
-
|
|
470
|
-
typedef typename WtoComponentRefList::const_iterator Iterator;
|
|
484
|
+
typedef typename WTOCompRefList::const_iterator Iterator;
|
|
471
485
|
|
|
472
486
|
protected:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
487
|
+
WTOCompRefList _components;
|
|
488
|
+
WTOCompRefSet _allComponents;
|
|
489
|
+
NodeRefToWTOCycleMap _headToCycle;
|
|
490
|
+
NodeRefToNodeRefSetMap _headToTails;
|
|
491
|
+
NodeRefToWTOCycleDepthPtr _nodeToDepth;
|
|
492
|
+
NodeRefToCycleDepthNumber _nodeToCDN;
|
|
493
|
+
CycleDepthNumber _num;
|
|
494
|
+
CFBasicBlockNodes _stack;
|
|
481
495
|
|
|
482
496
|
public:
|
|
483
|
-
|
|
484
|
-
explicit Wto() : _num(0) {}
|
|
497
|
+
explicit CFBasicBlockGWTO() : _num(0) {}
|
|
485
498
|
|
|
486
|
-
|
|
487
|
-
explicit Wto(const SVFBasicBlock *entry) : _num(0)
|
|
499
|
+
explicit CFBasicBlockGWTO(const CFBasicBlockNode *entry) : _num(0)
|
|
488
500
|
{
|
|
489
|
-
|
|
490
|
-
//link_components(_components);
|
|
491
|
-
_dfn_table.clear();
|
|
492
|
-
_stack.clear();
|
|
493
|
-
build_nesting();
|
|
494
|
-
build_tails();
|
|
501
|
+
build(entry);
|
|
495
502
|
}
|
|
496
503
|
|
|
497
|
-
|
|
498
|
-
Wto(const Wto &other) = default;
|
|
504
|
+
CFBasicBlockGWTO(const CFBasicBlockGWTO &other) = default;
|
|
499
505
|
|
|
500
|
-
|
|
501
|
-
Wto(Wto &&other) = default;
|
|
506
|
+
CFBasicBlockGWTO(CFBasicBlockGWTO &&other) = default;
|
|
502
507
|
|
|
503
|
-
|
|
504
|
-
Wto &operator=(const Wto &other) = default;
|
|
508
|
+
CFBasicBlockGWTO &operator=(const CFBasicBlockGWTO &other) = default;
|
|
505
509
|
|
|
506
|
-
|
|
507
|
-
Wto &operator=(Wto &&other) = default;
|
|
510
|
+
CFBasicBlockGWTO &operator=(CFBasicBlockGWTO &&other) = default;
|
|
508
511
|
|
|
509
|
-
|
|
510
|
-
~Wto()
|
|
512
|
+
~CFBasicBlockGWTO()
|
|
511
513
|
{
|
|
512
514
|
for (const auto &component: _allComponents)
|
|
513
515
|
{
|
|
@@ -515,60 +517,56 @@ public:
|
|
|
515
517
|
}
|
|
516
518
|
}
|
|
517
519
|
|
|
518
|
-
/// \brief Begin iterator over the components
|
|
519
|
-
/// \brief Begin iterator over the components
|
|
520
520
|
Iterator begin() const
|
|
521
521
|
{
|
|
522
522
|
return _components.cbegin();
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
-
/// \brief End iterator over the components
|
|
526
525
|
Iterator end() const
|
|
527
526
|
{
|
|
528
527
|
return _components.cend();
|
|
529
528
|
}
|
|
530
529
|
|
|
531
|
-
bool isHead(const
|
|
530
|
+
bool isHead(const CFBasicBlockNode *node) const
|
|
532
531
|
{
|
|
533
|
-
return
|
|
532
|
+
return _headToCycle.find(node) != _headToCycle.end();
|
|
534
533
|
}
|
|
535
534
|
|
|
536
|
-
typename
|
|
535
|
+
typename NodeRefToWTOCycleMap::const_iterator headBegin() const
|
|
537
536
|
{
|
|
538
|
-
return
|
|
537
|
+
return _headToCycle.cbegin();
|
|
539
538
|
}
|
|
540
539
|
|
|
541
|
-
|
|
542
|
-
typename NodeRefToWtoCycleMap::const_iterator headEnd() const
|
|
540
|
+
typename NodeRefToWTOCycleMap::const_iterator headEnd() const
|
|
543
541
|
{
|
|
544
|
-
return
|
|
542
|
+
return _headToCycle.cend();
|
|
545
543
|
}
|
|
546
544
|
|
|
547
|
-
const
|
|
545
|
+
const NodeRefSet &getTails(const CFBasicBlockNode *node) const
|
|
548
546
|
{
|
|
549
|
-
auto it =
|
|
550
|
-
assert(it !=
|
|
547
|
+
auto it = _headToTails.find(node);
|
|
548
|
+
assert(it != _headToTails.end() && "node not found");
|
|
551
549
|
return it->second;
|
|
552
550
|
}
|
|
553
551
|
|
|
554
552
|
|
|
555
|
-
///
|
|
556
|
-
const
|
|
553
|
+
/// Get the wto-cycle-depth of the given node
|
|
554
|
+
const CFBasicBlockGWTOCycleDepth &getWTOCycleDepth(const CFBasicBlockNode *n) const
|
|
557
555
|
{
|
|
558
|
-
auto it =
|
|
559
|
-
assert(it !=
|
|
556
|
+
auto it = _nodeToDepth.find(n);
|
|
557
|
+
assert(it != _nodeToDepth.end() && "node not found");
|
|
560
558
|
return *(it->second);
|
|
561
559
|
}
|
|
562
560
|
|
|
563
|
-
///
|
|
564
|
-
inline bool
|
|
561
|
+
/// Whether the given node is in the node to cycle getCDN
|
|
562
|
+
inline bool inNodeToCycleDepth(const CFBasicBlockNode *n) const
|
|
565
563
|
{
|
|
566
|
-
auto it =
|
|
567
|
-
return it !=
|
|
564
|
+
auto it = _nodeToDepth.find(n);
|
|
565
|
+
return it != _nodeToDepth.end();
|
|
568
566
|
}
|
|
569
567
|
|
|
570
|
-
///
|
|
571
|
-
void accept(
|
|
568
|
+
/// Accept the given visitor
|
|
569
|
+
void accept(WTOVisitor* v)
|
|
572
570
|
{
|
|
573
571
|
for (const auto &c: _components)
|
|
574
572
|
{
|
|
@@ -576,7 +574,6 @@ public:
|
|
|
576
574
|
}
|
|
577
575
|
}
|
|
578
576
|
|
|
579
|
-
/// \brief Dump the order, for debugging purpose
|
|
580
577
|
std::string toString() const
|
|
581
578
|
{
|
|
582
579
|
std::string str;
|
|
@@ -595,69 +592,76 @@ public:
|
|
|
595
592
|
return rawstr.str();
|
|
596
593
|
}
|
|
597
594
|
|
|
598
|
-
|
|
599
|
-
//@{
|
|
600
|
-
friend std::ostream &operator<<(std::ostream &o, const Wto &wto)
|
|
595
|
+
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockGWTO &CFBasicBlockGWTO)
|
|
601
596
|
{
|
|
602
|
-
o <<
|
|
597
|
+
o << CFBasicBlockGWTO.toString();
|
|
603
598
|
return o;
|
|
604
599
|
}
|
|
605
|
-
//@}
|
|
606
600
|
|
|
607
601
|
protected:
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
602
|
+
|
|
603
|
+
inline void build(const CFBasicBlockNode *entry)
|
|
604
|
+
{
|
|
605
|
+
visit(entry, _components);
|
|
606
|
+
_nodeToCDN.clear();
|
|
607
|
+
_stack.clear();
|
|
608
|
+
buildNodeToWTOCycleDepth();
|
|
609
|
+
build_tails();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/// Visitor to build the WTO cycle getCDN of each node
|
|
613
|
+
class WTOCycleDepthBuilder final
|
|
614
|
+
: public WTOVisitor
|
|
611
615
|
{
|
|
612
616
|
private:
|
|
613
|
-
|
|
614
|
-
|
|
617
|
+
CFBasicBlockGWTOCycleDepthPtr _wtoCycleDepth;
|
|
618
|
+
NodeRefToWTOCycleDepthPtr &_nodeToWTOCycleDepth;
|
|
615
619
|
|
|
616
620
|
public:
|
|
617
|
-
explicit
|
|
618
|
-
:
|
|
619
|
-
|
|
621
|
+
explicit WTOCycleDepthBuilder(NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth)
|
|
622
|
+
: _wtoCycleDepth(std::make_shared<CFBasicBlockGWTOCycleDepth>()),
|
|
623
|
+
_nodeToWTOCycleDepth(nodeToWTOCycleDepth) {}
|
|
620
624
|
|
|
621
|
-
void visit(const
|
|
625
|
+
void visit(const CFBasicBlockGWTOCycle &cycle) override
|
|
622
626
|
{
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
627
|
+
const CFBasicBlockNode *head = cycle.head();
|
|
628
|
+
CFBasicBlockGWTOCycleDepthPtr previous_nesting = _wtoCycleDepth;
|
|
629
|
+
_nodeToWTOCycleDepth.insert(std::make_pair(head, _wtoCycleDepth));
|
|
630
|
+
_wtoCycleDepth = std::make_shared<CFBasicBlockGWTOCycleDepth>(*_wtoCycleDepth);
|
|
631
|
+
_wtoCycleDepth->push_back(head);
|
|
628
632
|
for (auto it = cycle.begin(), et = cycle.end(); it != et; ++it)
|
|
629
633
|
{
|
|
630
634
|
(*it)->accept(this);
|
|
631
635
|
}
|
|
632
|
-
|
|
636
|
+
_wtoCycleDepth = previous_nesting;
|
|
633
637
|
}
|
|
634
638
|
|
|
635
|
-
void visit(const
|
|
639
|
+
void visit(const CFBasicBlockGWTONode &node) override
|
|
636
640
|
{
|
|
637
|
-
|
|
638
|
-
std::make_pair(
|
|
641
|
+
_nodeToWTOCycleDepth.insert(
|
|
642
|
+
std::make_pair(node.node(), _wtoCycleDepth));
|
|
639
643
|
}
|
|
640
644
|
|
|
641
|
-
}; // end class
|
|
645
|
+
}; // end class WTOCycleDepthBuilder
|
|
642
646
|
|
|
643
|
-
///
|
|
644
|
-
class TailBuilder : public
|
|
647
|
+
/// Visitor to build the tails of each head/loop
|
|
648
|
+
class TailBuilder : public WTOVisitor
|
|
645
649
|
{
|
|
646
650
|
protected:
|
|
647
|
-
|
|
648
|
-
const
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
+
NodeRefSet &_tails;
|
|
652
|
+
const CFBasicBlockGWTOCycleDepth &_headWTOCycleDepth;
|
|
653
|
+
const CFBasicBlockNode *_head;
|
|
654
|
+
NodeRefToWTOCycleDepthPtr &_nodeToWTOCycleDepth;
|
|
651
655
|
|
|
652
656
|
public:
|
|
653
657
|
|
|
654
|
-
explicit TailBuilder(
|
|
655
|
-
const
|
|
656
|
-
|
|
658
|
+
explicit TailBuilder(NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth, NodeRefSet &tails, const CFBasicBlockNode *head,
|
|
659
|
+
const CFBasicBlockGWTOCycleDepth &headWTOCycleDepth) : _tails(tails), _headWTOCycleDepth(headWTOCycleDepth), _head(head), _nodeToWTOCycleDepth(
|
|
660
|
+
nodeToWTOCycleDepth)
|
|
657
661
|
{
|
|
658
662
|
}
|
|
659
663
|
|
|
660
|
-
void visit(const
|
|
664
|
+
void visit(const CFBasicBlockGWTOCycle &cycle) override
|
|
661
665
|
{
|
|
662
666
|
for (auto it = cycle.begin(), et = cycle.end(); it != et; ++it)
|
|
663
667
|
{
|
|
@@ -665,36 +669,36 @@ protected:
|
|
|
665
669
|
}
|
|
666
670
|
}
|
|
667
671
|
|
|
668
|
-
virtual void visit(const
|
|
672
|
+
virtual void visit(const CFBasicBlockGWTONode &node) override
|
|
669
673
|
{
|
|
670
|
-
for (const auto &
|
|
674
|
+
for (const auto &edge: node.node()->getOutEdges())
|
|
671
675
|
{
|
|
672
|
-
const
|
|
673
|
-
const
|
|
674
|
-
if (succ != _head && succNesting <=
|
|
676
|
+
const CFBasicBlockNode *succ = edge->getDstNode();
|
|
677
|
+
const CFBasicBlockGWTOCycleDepth &succNesting = getWTOCycleDepth(succ);
|
|
678
|
+
if (succ != _head && succNesting <= _headWTOCycleDepth)
|
|
675
679
|
{
|
|
676
|
-
_tails.insert(
|
|
680
|
+
_tails.insert(node.node());
|
|
677
681
|
}
|
|
678
682
|
}
|
|
679
683
|
}
|
|
680
684
|
|
|
681
685
|
protected:
|
|
682
|
-
///
|
|
683
|
-
const
|
|
686
|
+
/// Get the wto-cycle-depth of the given node
|
|
687
|
+
const CFBasicBlockGWTOCycleDepth &getWTOCycleDepth(const CFBasicBlockNode *n) const
|
|
684
688
|
{
|
|
685
|
-
auto it =
|
|
686
|
-
assert(it !=
|
|
689
|
+
auto it = _nodeToWTOCycleDepth.find(n);
|
|
690
|
+
assert(it != _nodeToWTOCycleDepth.end() && "node not found");
|
|
687
691
|
return *(it->second);
|
|
688
692
|
}
|
|
689
693
|
|
|
690
694
|
};
|
|
691
695
|
|
|
692
696
|
protected:
|
|
693
|
-
///
|
|
694
|
-
|
|
697
|
+
/// Get the cycle depth number of the given node
|
|
698
|
+
CycleDepthNumber getCDN(const CFBasicBlockNode *n) const
|
|
695
699
|
{
|
|
696
|
-
auto it =
|
|
697
|
-
if (it !=
|
|
700
|
+
auto it = _nodeToCDN.find(n);
|
|
701
|
+
if (it != _nodeToCDN.end())
|
|
698
702
|
{
|
|
699
703
|
return it->second;
|
|
700
704
|
}
|
|
@@ -704,81 +708,79 @@ protected:
|
|
|
704
708
|
}
|
|
705
709
|
}
|
|
706
710
|
|
|
707
|
-
///
|
|
708
|
-
void
|
|
711
|
+
/// Set the cycle depth number of the given node
|
|
712
|
+
void setCDN(const CFBasicBlockNode *n, const CycleDepthNumber &Depth)
|
|
709
713
|
{
|
|
710
|
-
auto res =
|
|
714
|
+
auto res = _nodeToCDN.insert(std::make_pair(n, Depth));
|
|
711
715
|
if (!res.second)
|
|
712
716
|
{
|
|
713
|
-
(res.first)->second =
|
|
717
|
+
(res.first)->second = Depth;
|
|
714
718
|
}
|
|
715
719
|
}
|
|
716
720
|
|
|
717
|
-
///
|
|
718
|
-
const
|
|
721
|
+
/// Pop a node from the stack
|
|
722
|
+
const CFBasicBlockNode *pop()
|
|
719
723
|
{
|
|
720
724
|
assert(!_stack.empty() && "empty stack");
|
|
721
|
-
const
|
|
725
|
+
const CFBasicBlockNode *top = _stack.back();
|
|
722
726
|
_stack.pop_back();
|
|
723
727
|
return top;
|
|
724
728
|
}
|
|
725
729
|
|
|
726
|
-
///
|
|
727
|
-
void push(const
|
|
730
|
+
/// Push a node on the stack
|
|
731
|
+
void push(const CFBasicBlockNode *n)
|
|
728
732
|
{
|
|
729
733
|
_stack.push_back(n);
|
|
730
734
|
}
|
|
731
735
|
|
|
732
|
-
const
|
|
736
|
+
const CFBasicBlockGWTONode *newNode(const CFBasicBlockNode *node)
|
|
733
737
|
{
|
|
734
|
-
const
|
|
738
|
+
const CFBasicBlockGWTONode *ptr = new CFBasicBlockGWTONode(node);
|
|
735
739
|
_allComponents.insert(ptr);
|
|
736
740
|
return ptr;
|
|
737
741
|
}
|
|
738
742
|
|
|
739
|
-
const
|
|
743
|
+
const CFBasicBlockGWTOCycle *newCycle(const CFBasicBlockNode *node, const WTOCompRefList &partition)
|
|
740
744
|
{
|
|
741
|
-
const
|
|
745
|
+
const CFBasicBlockGWTOCycle *ptr = new CFBasicBlockGWTOCycle(node, std::move(partition));
|
|
742
746
|
_allComponents.insert(ptr);
|
|
743
747
|
return ptr;
|
|
744
748
|
}
|
|
745
749
|
|
|
746
|
-
///
|
|
747
|
-
const
|
|
750
|
+
/// Create the cycle component for the given node
|
|
751
|
+
const CFBasicBlockGWTOCycle *component(const CFBasicBlockNode *node)
|
|
748
752
|
{
|
|
749
|
-
|
|
750
|
-
for (auto it =
|
|
753
|
+
WTOCompRefList partition;
|
|
754
|
+
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
|
|
751
755
|
{
|
|
752
|
-
const
|
|
753
|
-
if (
|
|
756
|
+
const CFBasicBlockNode *succ = (*it)->getDstNode();
|
|
757
|
+
if (getCDN(succ) == 0)
|
|
754
758
|
{
|
|
755
759
|
visit(succ, partition);
|
|
756
760
|
}
|
|
757
761
|
}
|
|
758
|
-
const
|
|
759
|
-
|
|
762
|
+
const CFBasicBlockGWTOCycle *ptr = newCycle(node, partition);
|
|
763
|
+
_headToCycle.emplace(node, ptr);
|
|
760
764
|
return ptr;
|
|
761
765
|
}
|
|
762
766
|
|
|
763
|
-
///
|
|
764
|
-
|
|
765
|
-
/// Algorithm to build a weak topological order of a graph
|
|
766
|
-
virtual Dfn visit(const SVFBasicBlock *vertex, WtoComponentRefList &partition)
|
|
767
|
+
/// Main algorithm to build WTO
|
|
768
|
+
virtual CycleDepthNumber visit(const CFBasicBlockNode *node, WTOCompRefList &partition)
|
|
767
769
|
{
|
|
768
|
-
|
|
769
|
-
|
|
770
|
+
CycleDepthNumber head(0);
|
|
771
|
+
CycleDepthNumber min(0);
|
|
770
772
|
bool loop;
|
|
771
773
|
|
|
772
|
-
push(
|
|
773
|
-
_num +=
|
|
774
|
+
push(node);
|
|
775
|
+
_num += CycleDepthNumber(1);
|
|
774
776
|
head = _num;
|
|
775
|
-
|
|
777
|
+
setCDN(node, head);
|
|
776
778
|
loop = false;
|
|
777
|
-
for (auto it =
|
|
779
|
+
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
|
|
778
780
|
{
|
|
779
|
-
const
|
|
780
|
-
|
|
781
|
-
if (succ_dfn ==
|
|
781
|
+
const CFBasicBlockNode *succ = (*it)->getDstNode();
|
|
782
|
+
CycleDepthNumber succ_dfn = getCDN(succ);
|
|
783
|
+
if (succ_dfn == CycleDepthNumber(0))
|
|
782
784
|
{
|
|
783
785
|
min = visit(succ, partition);
|
|
784
786
|
}
|
|
@@ -792,54 +794,53 @@ protected:
|
|
|
792
794
|
loop = true;
|
|
793
795
|
}
|
|
794
796
|
}
|
|
795
|
-
if (head ==
|
|
797
|
+
if (head == getCDN(node))
|
|
796
798
|
{
|
|
797
|
-
|
|
798
|
-
const
|
|
799
|
+
setCDN(node, UINT_MAX);
|
|
800
|
+
const CFBasicBlockNode *element = pop();
|
|
799
801
|
if (loop)
|
|
800
802
|
{
|
|
801
|
-
while (element !=
|
|
803
|
+
while (element != node)
|
|
802
804
|
{
|
|
803
|
-
|
|
805
|
+
setCDN(element, 0);
|
|
804
806
|
element = pop();
|
|
805
807
|
}
|
|
806
|
-
partition.push_front(component(
|
|
808
|
+
partition.push_front(component(node));
|
|
807
809
|
}
|
|
808
810
|
else
|
|
809
811
|
{
|
|
810
|
-
partition.push_front(
|
|
812
|
+
partition.push_front(newNode(node));
|
|
811
813
|
}
|
|
812
814
|
}
|
|
813
815
|
return head;
|
|
814
816
|
}
|
|
815
817
|
|
|
816
|
-
///
|
|
817
|
-
void
|
|
818
|
+
/// Build the node to WTO cycle depth table
|
|
819
|
+
void buildNodeToWTOCycleDepth()
|
|
818
820
|
{
|
|
819
|
-
|
|
821
|
+
WTOCycleDepthBuilder builder(_nodeToDepth);
|
|
820
822
|
for (auto it = begin(), et = end(); it != et; ++it)
|
|
821
823
|
{
|
|
822
824
|
(*it)->accept(&builder);
|
|
823
825
|
}
|
|
824
826
|
}
|
|
825
827
|
|
|
826
|
-
///
|
|
828
|
+
/// Build the tails for each cycle
|
|
827
829
|
virtual void build_tails()
|
|
828
830
|
{
|
|
829
|
-
for (const auto &head:
|
|
831
|
+
for (const auto &head: _headToCycle)
|
|
830
832
|
{
|
|
831
|
-
|
|
832
|
-
TailBuilder builder(
|
|
833
|
+
NodeRefSet tails;
|
|
834
|
+
TailBuilder builder(_nodeToDepth, tails, head.first, getWTOCycleDepth(head.first));
|
|
833
835
|
for (auto it = head.second->begin(), eit = head.second->end(); it != eit; ++it)
|
|
834
836
|
{
|
|
835
837
|
(*it)->accept(&builder);
|
|
836
838
|
}
|
|
837
|
-
|
|
839
|
+
_headToTails.emplace(head.first, tails);
|
|
838
840
|
}
|
|
839
841
|
}
|
|
840
842
|
|
|
841
|
-
}; // end class
|
|
842
|
-
|
|
843
|
-
}
|
|
843
|
+
}; // end class CFBasicBlockGWTO
|
|
844
844
|
|
|
845
|
-
|
|
845
|
+
} // end namespace SVF
|
|
846
|
+
#endif /* WTO_H_ */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
5
|
-
// Copyright (C) <2013
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
// This program is free software: you can redistribute it and/or modify
|
|
@@ -77,11 +77,20 @@ public:
|
|
|
77
77
|
|
|
78
78
|
virtual const std::string toString() const;
|
|
79
79
|
|
|
80
|
-
inline std::string getName() const
|
|
80
|
+
inline std::string getName() const
|
|
81
|
+
{
|
|
82
|
+
return _svfBasicBlock->getName();
|
|
83
|
+
}
|
|
81
84
|
|
|
82
|
-
inline const SVFBasicBlock *getSVFBasicBlock() const
|
|
85
|
+
inline const SVFBasicBlock *getSVFBasicBlock() const
|
|
86
|
+
{
|
|
87
|
+
return _svfBasicBlock;
|
|
88
|
+
}
|
|
83
89
|
|
|
84
|
-
inline const SVFFunction *getFunction() const
|
|
90
|
+
inline const SVFFunction *getFunction() const
|
|
91
|
+
{
|
|
92
|
+
return _svfBasicBlock->getFunction();
|
|
93
|
+
}
|
|
85
94
|
|
|
86
95
|
inline std::vector<const ICFGNode *>::const_iterator begin() const
|
|
87
96
|
{
|
|
@@ -124,11 +133,32 @@ public:
|
|
|
124
133
|
GraphPrinter::WriteGraphToFile(SVFUtil::outs(), filename, this);
|
|
125
134
|
}
|
|
126
135
|
|
|
127
|
-
inline CFBasicBlockNode *getCFBasicBlockNode(u32_t id) const
|
|
136
|
+
inline CFBasicBlockNode *getCFBasicBlockNode(u32_t id) const
|
|
137
|
+
{
|
|
138
|
+
if (!hasGNode(id)) return nullptr;
|
|
139
|
+
return getGNode(id);
|
|
140
|
+
}
|
|
128
141
|
|
|
129
|
-
inline CFBasicBlockNode *getCFBasicBlockNode(const SVFBasicBlock *bb) const
|
|
142
|
+
inline CFBasicBlockNode *getCFBasicBlockNode(const SVFBasicBlock *bb) const
|
|
143
|
+
{
|
|
144
|
+
auto it = _bbToNode.find(bb);
|
|
145
|
+
if (it == _bbToNode.end()) return nullptr;
|
|
146
|
+
return it->second;
|
|
147
|
+
}
|
|
130
148
|
|
|
131
|
-
inline bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
|
|
149
|
+
inline bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst) const
|
|
150
|
+
{
|
|
151
|
+
CFBasicBlockEdge edge(src, dst);
|
|
152
|
+
CFBasicBlockEdge *outEdge = src->hasOutgoingEdge(&edge);
|
|
153
|
+
CFBasicBlockEdge *inEdge = dst->hasIncomingEdge(&edge);
|
|
154
|
+
if (outEdge && inEdge)
|
|
155
|
+
{
|
|
156
|
+
assert(outEdge == inEdge && "edges not match");
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
else
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
132
162
|
|
|
133
163
|
CFBasicBlockEdge* getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst);
|
|
134
164
|
|
|
@@ -243,4 +273,4 @@ struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVF
|
|
|
243
273
|
};
|
|
244
274
|
|
|
245
275
|
} // End namespace SVF
|
|
246
|
-
#endif //SVF_CFBASICBLOCKG_H
|
|
276
|
+
#endif //SVF_CFBASICBLOCKG_H
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
5
|
-
// Copyright (C) <2013
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
// This program is free software: you can redistribute it and/or modify
|
|
@@ -55,48 +55,6 @@ const std::string CFBasicBlockNode::toString() const
|
|
|
55
55
|
return stringstream.str();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
std::string CFBasicBlockNode::getName() const
|
|
59
|
-
{
|
|
60
|
-
return _svfBasicBlock->getName();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const SVFBasicBlock* CFBasicBlockNode::getSVFBasicBlock() const
|
|
64
|
-
{
|
|
65
|
-
return _svfBasicBlock;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const SVFFunction* CFBasicBlockNode::getFunction() const
|
|
69
|
-
{
|
|
70
|
-
return _svfBasicBlock->getFunction();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
bool CFBasicBlockGraph::hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
|
|
74
|
-
{
|
|
75
|
-
CFBasicBlockEdge edge(src, dst);
|
|
76
|
-
CFBasicBlockEdge *outEdge = src->hasOutgoingEdge(&edge);
|
|
77
|
-
CFBasicBlockEdge *inEdge = dst->hasIncomingEdge(&edge);
|
|
78
|
-
if (outEdge && inEdge)
|
|
79
|
-
{
|
|
80
|
-
assert(outEdge == inEdge && "edges not match");
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
else
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(u32_t id) const
|
|
88
|
-
{
|
|
89
|
-
if (!hasGNode(id)) return nullptr;
|
|
90
|
-
return getGNode(id);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(const SVFBasicBlock *bb) const
|
|
94
|
-
{
|
|
95
|
-
auto it = _bbToNode.find(bb);
|
|
96
|
-
if (it == _bbToNode.end()) return nullptr;
|
|
97
|
-
return it->second;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
58
|
CFBasicBlockEdge* CFBasicBlockGraph::getCFBasicBlockEdge(const SVFBasicBlock *src, const SVFBasicBlock *dst)
|
|
101
59
|
{
|
|
102
60
|
return getCFBasicBlockEdge(getCFBasicBlockNode(src), getCFBasicBlockNode(dst));
|
|
@@ -155,5 +113,4 @@ void CFBasicBlockGBuilder::build()
|
|
|
155
113
|
}
|
|
156
114
|
}
|
|
157
115
|
}
|
|
158
|
-
}
|
|
159
|
-
|
|
116
|
+
}
|