Static Value-Flow Analysis
Loading...
Searching...
No Matches
SCC.h
Go to the documentation of this file.
1//===- SCC.h -- SCC detection algorithm---------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <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 * SCC.h
25 *
26 * Esko Nuutila and Eljas Soisalon-Soininen, "On finding the
27 * strongly connected components in a directed graph".
28 * Inf. Process. Letters, 49(1):9-14, 1994.
29 *
30 * The implementation is derived from the pseudo code in the following paper:
31 * Pereira and Berlin, "Wave Propagation and Deep Propagation for Pointer Analysis",
32 * CGO 2009, 126-135, 2009.
33 *
34 * And influenced by implementation from Open64 compiler
35 *
36 * Created on: Jul 12, 2013
37 * Author: yusui
38 */
39
40#ifndef SCC_H_
41#define SCC_H_
42
43#include "SVFIR/SVFValue.h" // for NodeBS
44#include <limits.h>
45#include <stack>
46#include <map>
47
48namespace SVF
49{
50
51class GNodeSCCInfo;
52
53template<class GraphType>
55{
56
57private:
60 typedef typename GTraits::NodeRef GNODE;
61 typedef typename GTraits::nodes_iterator node_iterator;
62 typedef typename GTraits::ChildIteratorType child_iterator;
63 typedef unsigned NodeID ;
64
65public:
66 typedef std::stack<NodeID> GNodeStack;
67
69 {
70 public:
72
73 inline bool visited(void) const
74 {
75 return _visited;
76 }
77 inline void visited(bool v)
78 {
79 _visited = v;
80 }
81 inline bool inSCC(void) const
82 {
83 return _inSCC;
84 }
85 inline void inSCC(bool v)
86 {
87 _inSCC = v;
88 }
89 inline NodeID rep(void)const
90 {
91 return _rep;
92 }
93 inline void rep(NodeID n)
94 {
95 _rep = n;
96 }
97 inline void addSubNodes(NodeID n)
98 {
100 }
101 inline NodeBS& subNodes()
102 {
103 return _subNodes;
104 }
105 inline const NodeBS& subNodes() const
106 {
107 return _subNodes;
108 }
109 private:
111 bool _inSCC;
114 };
115
118
119 SCCDetection(const GraphType &GT)
120 : _graph(GT),
121 _I(0)
122 {}
123
124
125 // Return a handle to the stack of nodes in topological
126 // order. This will be used to seed the initial solution
127 // and improve efficiency.
129 {
130 return _T;
131 }
132
133 const inline GNODESCCInfoMap &GNodeSCCInfo() const
134 {
135 return _NodeSCCAuxInfo;
136 }
137
139 inline NodeID repNode(NodeID n) const
140 {
141 typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n);
142 assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found");
143 NodeID rep = it->second.rep();
144 return rep!= UINT_MAX ? rep : n ;
145 }
146
147
149 inline bool isInCycle(NodeID n) const
150 {
151 NodeID rep = repNode(n);
152 // multi-node cycle
153 if (subNodes(rep).count() > 1)
154 {
155 return true;
156 }
157 // self-cycle
158 else
159 {
160 child_iterator EI = GTraits::direct_child_begin(Node(rep));
161 child_iterator EE = GTraits::direct_child_end(Node(rep));
162 for (; EI != EE; ++EI)
163 {
164 NodeID w = Node_Index(*EI);
165 if(w==rep)
166 return true;
167 }
168 return false;
169 }
170 }
171
173 inline const NodeBS& subNodes(NodeID n) const
174 {
175 typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n);
176 assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found");
177 return it->second.subNodes();
178 }
179
181 inline const NodeBS &getRepNodes() const
182 {
183 return repNodes;
184 }
185
186 const inline GraphType & graph()
187 {
188 return _graph;
189 }
190private:
191
193
194 const GraphType & _graph;
200
201 inline bool visited(NodeID n)
202 {
203 return _NodeSCCAuxInfo[n].visited();
204 }
205 inline bool inSCC(NodeID n)
206 {
207 return _NodeSCCAuxInfo[n].inSCC();
208 }
209
210 inline void setVisited(NodeID n,bool v)
211 {
212 _NodeSCCAuxInfo[n].visited(v);
213 }
214 inline void setInSCC(NodeID n,bool v)
215 {
216 _NodeSCCAuxInfo[n].inSCC(v);
217 }
218 inline void rep(NodeID n, NodeID r)
219 {
220 _NodeSCCAuxInfo[n].rep(r);
221 _NodeSCCAuxInfo[r].addSubNodes(n);
222 if (n != r)
223 {
224 _NodeSCCAuxInfo[n].subNodes().clear();
226 repNodes.set(r);
227 }
228 }
229
231 {
232 return _NodeSCCAuxInfo[n].rep();
233 }
234 inline bool isInSCC(NodeID n)
235 {
236 return _NodeSCCAuxInfo[n].inSCC();
237 }
238
239 inline GNODE Node(NodeID id) const
240 {
241 return GTraits::getNode(_graph, id);
242 }
243
244 inline NodeID Node_Index(GNODE node) const
245 {
246 return GTraits::getNodeID(node);
247 }
248
250 {
251 // SVFUtil::outs() << "visit GNODE: " << Node_Index(v)<< "\n";
252 _I += 1;
253 _D[v] = _I;
254 this->rep(v,v);
255 this->setVisited(v,true);
256
257 child_iterator EI = GTraits::direct_child_begin(Node(v));
258 child_iterator EE = GTraits::direct_child_end(Node(v));
259
260 for (; EI != EE; ++EI)
261 {
262 NodeID w = Node_Index(*EI);
263
264 if (!this->visited(w))
265 visit(w);
266 if (!this->inSCC(w))
267 {
268 NodeID rep;
269 rep = _D[this->rep(v)] < _D[this->rep(w)] ?
270 this->rep(v) : this->rep(w);
271 this->rep(v,rep);
272 }
273 }
274 if (this->rep(v) == v)
275 {
276 this->setInSCC(v,true);
277 while (!_SS.empty())
278 {
279 NodeID w = _SS.top();
280 if (_D[w] <= _D[v])
281 break;
282 else
283 {
284 _SS.pop();
285 this->setInSCC(w,true);
286 this->rep(w,v);
287 }
288 }
289 _T.push(v);
290 }
291 else
292 _SS.push(v);
293 }
294
295 void clear()
296 {
297 _NodeSCCAuxInfo.clear();
298 _I = 0;
299 _D.clear();
300 repNodes.clear();
301 while(!_SS.empty())
302 _SS.pop();
303 while(!_T.empty())
304 _T.pop();
305 }
306public:
307
308 void find(void)
309 {
310 // Visit each unvisited root node. A root node is defined
311 // to be a node that has no incoming copy/skew edges
312 clear();
313 node_iterator I = GTraits::nodes_begin(_graph);
314 node_iterator E = GTraits::nodes_end(_graph);
315 for (; I != E; ++I)
316 {
317 NodeID node = Node_Index(*I);
318 if (!this->visited(node))
319 {
320 // We skip any nodes that have a representative other than
321 // themselves. Such nodes occur as a result of merging
322 // nodes either through unifying an ACC or other node
323 // merging optimizations. Any such node should have no
324 // outgoing edges and therefore should no longer be a member
325 // of an SCC.
326 if (this->rep(node) == UINT_MAX || this->rep(node) == node)
327 visit(node);
328 else
329 this->visited(node);
330 }
331 }
332 }
333
334 void find(NodeSet &candidates)
335 {
336 // This function is reloaded to only visit candidate NODES
337 clear();
338 for (NodeID node : candidates)
339 {
340 if (!this->visited(node))
341 {
342 if (this->rep(node) == UINT_MAX || this->rep(node) == node)
343 visit(node);
344 else
345 this->visited(node);
346 }
347 }
348 }
349
350};
351
352} // End namespace SVF
353
354#endif /* SCC_H_ */
#define false
Definition cJSON.cpp:70
cJSON * n
Definition cJSON.cpp:2558
int count
Definition cJSON.h:216
const NodeBS & subNodes() const
Definition SCC.h:105
void addSubNodes(NodeID n)
Definition SCC.h:97
bool visited(void) const
Definition SCC.h:73
NodeID rep(void) const
Definition SCC.h:89
bool inSCC(void) const
Definition SCC.h:81
GNodeStack _T
Definition SCC.h:198
void rep(NodeID n, NodeID r)
Definition SCC.h:218
GNodeStack _SS
Definition SCC.h:197
void find(void)
Definition SCC.h:308
SCCDetection(const GraphType &GT)
Definition SCC.h:119
void find(NodeSet &candidates)
Definition SCC.h:334
const GraphType & _graph
Definition SCC.h:194
NodeBS repNodes
Definition SCC.h:199
void clear()
Definition SCC.h:295
NodeID repNode(NodeID n) const
get the rep node if not found return itself
Definition SCC.h:139
unsigned NodeID
Definition SCC.h:63
GNODESCCInfoMap _NodeSCCAuxInfo
Definition SCC.h:192
Map< NodeID, GNodeSCCInfo > GNODESCCInfoMap
Definition SCC.h:116
NodeToNodeMap _D
Definition SCC.h:196
bool isInCycle(NodeID n) const
whether the node is in a cycle
Definition SCC.h:149
NodeID Node_Index(GNODE node) const
Definition SCC.h:244
bool inSCC(NodeID n)
Definition SCC.h:205
GNODE Node(NodeID id) const
Definition SCC.h:239
GTraits::NodeRef GNODE
Definition SCC.h:60
Map< NodeID, NodeID > NodeToNodeMap
Definition SCC.h:117
GNodeStack & topoNodeStack()
Definition SCC.h:128
std::stack< NodeID > GNodeStack
Definition SCC.h:66
SVF::GenericGraphTraits< GraphType > GTraits
Define the GTraits and node iterator for printing.
Definition SCC.h:59
NodeID _I
Definition SCC.h:195
const NodeBS & getRepNodes() const
get all repNodeID
Definition SCC.h:181
bool visited(NodeID n)
Definition SCC.h:201
const NodeBS & subNodes(NodeID n) const
get all subnodes in one scc, if size is empty insert itself into the set
Definition SCC.h:173
void setInSCC(NodeID n, bool v)
Definition SCC.h:214
const GNODESCCInfoMap & GNodeSCCInfo() const
Definition SCC.h:133
GTraits::nodes_iterator node_iterator
Definition SCC.h:61
GTraits::ChildIteratorType child_iterator
Definition SCC.h:62
NodeID rep(NodeID n)
Definition SCC.h:230
void setVisited(NodeID n, bool v)
Definition SCC.h:210
const GraphType & graph()
Definition SCC.h:186
void visit(NodeID v)
Definition SCC.h:249
bool isInSCC(NodeID n)
Definition SCC.h:234
void set(unsigned Idx)
void reset(unsigned Idx)
for isBitcode
Definition BasicTypes.h:68
Set< NodeID > NodeSet
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
typename GraphType::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:80