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 <limits.h>
44#include <stack>
45
46#include "Graphs/GraphPrinter.h"
47#include "Util/GeneralType.h"
48#include "Util/WorkList.h"
49
50namespace SVF
51{
52
53class GNodeSCCInfo;
54
55template<class GraphType>
57{
58
59private:
62 typedef typename GTraits::NodeRef GNODE;
63 typedef typename GTraits::nodes_iterator node_iterator;
64 typedef typename GTraits::ChildIteratorType child_iterator;
65 typedef unsigned NodeID ;
66
67public:
68 typedef std::stack<NodeID> GNodeStack;
69
71 {
72 public:
74
75 inline bool visited(void) const
76 {
77 return _visited;
78 }
79 inline void visited(bool v)
80 {
81 _visited = v;
82 }
83 inline bool inSCC(void) const
84 {
85 return _inSCC;
86 }
87 inline void inSCC(bool v)
88 {
89 _inSCC = v;
90 }
91 inline NodeID rep(void)const
92 {
93 return _rep;
94 }
95 inline void rep(NodeID n)
96 {
97 _rep = n;
98 }
99 inline void addSubNodes(NodeID n)
100 {
101 _subNodes.set(n);
102 }
103 inline NodeBS& subNodes()
104 {
105 return _subNodes;
106 }
107 inline const NodeBS& subNodes() const
108 {
109 return _subNodes;
110 }
111 private:
113 bool _inSCC;
116 };
117
120
122 : _graph(GT),
123 _I(0)
124 {}
125
126
127 // Return a handle to the stack of nodes in topological
128 // order. This will be used to seed the initial solution
129 // and improve efficiency.
131 {
132 return _T;
133 }
134
135 inline const GNodeStack& topoNodeStack() const
136 {
137 return _T;
138 }
139
144 {
147 while(!topoOrder.empty())
148 {
149 NodeID nodeID = topoOrder.top();
150 topoOrder.pop();
151 revTopoOrder.push(nodeID);
152 }
153 return revTopoOrder;
154 }
155
156 const inline GNODESCCInfoMap &GNodeSCCInfo() const
157 {
158 return _NodeSCCAuxInfo;
159 }
160
162 inline NodeID repNode(NodeID n) const
163 {
164 typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n);
165 assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found");
166 NodeID rep = it->second.rep();
167 return rep!= UINT_MAX ? rep : n ;
168 }
169
170
172 inline bool isInCycle(NodeID n) const
173 {
174 NodeID rep = repNode(n);
175 // multi-node cycle
176 if (subNodes(rep).count() > 1)
177 {
178 return true;
179 }
180 // self-cycle
181 else
182 {
183 child_iterator EI = GTraits::direct_child_begin(Node(rep));
184 child_iterator EE = GTraits::direct_child_end(Node(rep));
185 for (; EI != EE; ++EI)
186 {
187 NodeID w = Node_Index(*EI);
188 if(w==rep)
189 return true;
190 }
191 return false;
192 }
193 }
194
196 inline const NodeBS& subNodes(NodeID n) const
197 {
198 typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n);
199 assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found");
200 return it->second.subNodes();
201 }
202
204 inline const NodeBS &getRepNodes() const
205 {
206 return repNodes;
207 }
208
209 const inline GraphType & graph()
210 {
211 return _graph;
212 }
213private:
214
216
223
224 inline bool visited(NodeID n)
225 {
226 return _NodeSCCAuxInfo[n].visited();
227 }
228 inline bool inSCC(NodeID n)
229 {
230 return _NodeSCCAuxInfo[n].inSCC();
231 }
232
233 inline void setVisited(NodeID n,bool v)
234 {
235 _NodeSCCAuxInfo[n].visited(v);
236 }
237 inline void setInSCC(NodeID n,bool v)
238 {
239 _NodeSCCAuxInfo[n].inSCC(v);
240 }
241 inline void rep(NodeID n, NodeID r)
242 {
243 _NodeSCCAuxInfo[n].rep(r);
244 _NodeSCCAuxInfo[r].addSubNodes(n);
245 if (n != r)
246 {
247 _NodeSCCAuxInfo[n].subNodes().clear();
249 repNodes.set(r);
250 }
251 }
252
254 {
255 return _NodeSCCAuxInfo[n].rep();
256 }
257 inline bool isInSCC(NodeID n)
258 {
259 return _NodeSCCAuxInfo[n].inSCC();
260 }
261
262 inline GNODE Node(NodeID id) const
263 {
264 return GTraits::getNode(_graph, id);
265 }
266
267 inline NodeID Node_Index(GNODE node) const
268 {
269 return GTraits::getNodeID(node);
270 }
271
273 {
274 // SVFUtil::outs() << "visit GNODE: " << Node_Index(v)<< "\n";
275 _I += 1;
276 _D[v] = _I;
277 this->rep(v,v);
278 this->setVisited(v,true);
279
280 child_iterator EI = GTraits::direct_child_begin(Node(v));
281 child_iterator EE = GTraits::direct_child_end(Node(v));
282
283 for (; EI != EE; ++EI)
284 {
285 NodeID w = Node_Index(*EI);
286
287 if (!this->visited(w))
288 visit(w);
289 if (!this->inSCC(w))
290 {
291 NodeID rep;
292 rep = _D[this->rep(v)] < _D[this->rep(w)] ?
293 this->rep(v) : this->rep(w);
294 this->rep(v,rep);
295 }
296 }
297 if (this->rep(v) == v)
298 {
299 this->setInSCC(v,true);
300 while (!_SS.empty())
301 {
302 NodeID w = _SS.top();
303 if (_D[w] <= _D[v])
304 break;
305 else
306 {
307 _SS.pop();
308 this->setInSCC(w,true);
309 this->rep(w,v);
310 }
311 }
312 _T.push(v);
313 }
314 else
315 _SS.push(v);
316 }
317
318 void clear()
319 {
320 _NodeSCCAuxInfo.clear();
321 _I = 0;
322 _D.clear();
323 repNodes.clear();
324 while(!_SS.empty())
325 _SS.pop();
326 while(!_T.empty())
327 _T.pop();
328 }
329public:
330
331 void find(void)
332 {
333 // Visit each unvisited root node. A root node is defined
334 // to be a node that has no incoming copy/skew edges
335 clear();
336 node_iterator I = GTraits::nodes_begin(_graph);
337 node_iterator E = GTraits::nodes_end(_graph);
338 for (; I != E; ++I)
339 {
340 NodeID node = Node_Index(*I);
341 if (!this->visited(node))
342 {
343 // We skip any nodes that have a representative other than
344 // themselves. Such nodes occur as a result of merging
345 // nodes either through unifying an ACC or other node
346 // merging optimizations. Any such node should have no
347 // outgoing edges and therefore should no longer be a member
348 // of an SCC.
349 if (this->rep(node) == UINT_MAX || this->rep(node) == node)
350 visit(node);
351 else
352 this->visited(node);
353 }
354 }
355 }
356
357 void find(NodeSet &candidates)
358 {
359 // This function is reloaded to only visit candidate NODES
360 clear();
361 for (NodeID node : candidates)
362 {
363 if (!this->visited(node))
364 {
365 if (this->rep(node) == UINT_MAX || this->rep(node) == node)
366 visit(node);
367 else
368 this->visited(node);
369 }
370 }
371 }
372
373};
374
375} // End namespace SVF
376
377#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:107
void addSubNodes(NodeID n)
Definition SCC.h:99
bool visited(void) const
Definition SCC.h:75
NodeID rep(void) const
Definition SCC.h:91
bool inSCC(void) const
Definition SCC.h:83
GNodeStack _T
Definition SCC.h:221
void rep(NodeID n, NodeID r)
Definition SCC.h:241
GNodeStack _SS
Definition SCC.h:220
void find(void)
Definition SCC.h:331
SCCDetection(const GraphType &GT)
Definition SCC.h:121
const GNodeStack & topoNodeStack() const
Definition SCC.h:135
void find(NodeSet &candidates)
Definition SCC.h:357
const GraphType & _graph
Definition SCC.h:217
NodeBS repNodes
Definition SCC.h:222
void clear()
Definition SCC.h:318
NodeID repNode(NodeID n) const
get the rep node if not found return itself
Definition SCC.h:162
unsigned NodeID
Definition SCC.h:65
GNODESCCInfoMap _NodeSCCAuxInfo
Definition SCC.h:215
Map< NodeID, GNodeSCCInfo > GNODESCCInfoMap
Definition SCC.h:118
NodeToNodeMap _D
Definition SCC.h:219
bool isInCycle(NodeID n) const
whether the node is in a cycle
Definition SCC.h:172
NodeID Node_Index(GNODE node) const
Definition SCC.h:267
bool inSCC(NodeID n)
Definition SCC.h:228
GNODE Node(NodeID id) const
Definition SCC.h:262
GTraits::NodeRef GNODE
Definition SCC.h:62
Map< NodeID, NodeID > NodeToNodeMap
Definition SCC.h:119
GNodeStack & topoNodeStack()
Definition SCC.h:130
std::stack< NodeID > GNodeStack
Definition SCC.h:68
SVF::GenericGraphTraits< GraphType > GTraits
Define the GTraits and node iterator for printing.
Definition SCC.h:61
NodeID _I
Definition SCC.h:218
FIFOWorkList< NodeID > revTopoNodeStack() const
Definition SCC.h:143
const NodeBS & getRepNodes() const
get all repNodeID
Definition SCC.h:204
bool visited(NodeID n)
Definition SCC.h:224
const NodeBS & subNodes(NodeID n) const
get all subnodes in one scc, if size is empty insert itself into the set
Definition SCC.h:196
void setInSCC(NodeID n, bool v)
Definition SCC.h:237
const GNODESCCInfoMap & GNodeSCCInfo() const
Definition SCC.h:156
GTraits::nodes_iterator node_iterator
Definition SCC.h:63
GTraits::ChildIteratorType child_iterator
Definition SCC.h:64
NodeID rep(NodeID n)
Definition SCC.h:253
void setVisited(NodeID n, bool v)
Definition SCC.h:233
const GraphType & graph()
Definition SCC.h:209
void visit(NodeID v)
Definition SCC.h:272
bool isInSCC(NodeID n)
Definition SCC.h:257
void set(unsigned Idx)
void reset(unsigned Idx)
for isBitcode
Definition BasicTypes.h:70
Set< NodeID > NodeSet
Definition GeneralType.h:87
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
typename GraphType::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:80