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