ROSE 0.11.145.147
virtualCFG.h
1#ifndef VIRTUAL_CFG_H
2#define VIRTUAL_CFG_H
3
4#include <string>
5#include <vector>
6#include <assert.h>
7#include "rosedll.h"
8
9
14class SgNode;
15class SgExpression;
17class SgLabelSymbol;
18class SgLabelRefExp;
19class SgStatement;
20
21#ifndef _MSC_VER
23const SgStatement* isSgStatement(const SgNode* node);
24SgExpression* isSgExpression(SgNode* node);
25const SgExpression* isSgExpression(const SgNode* node);
26SgInitializedName* isSgInitializedName(SgNode* node);
27const SgInitializedName* isSgInitializedName(const SgNode* node);
28#endif
29
30// DQ (9/1/2012): Debugging code to trace haskell_port error.
31extern int abcd;
32
33namespace VirtualCFG {
34
35// DQ (9/1/2012): Debugging code to trace haskell_port error.
36extern int efgh;
37
38 class CFGEdge;
39
47 enum EdgeConditionKind
48 {
49 eckUnconditional,
50 eckTrue,
51 eckFalse,
52 eckCaseLabel,
53 eckDefault,
54 eckDoConditionPassed,
55 eckDoConditionFailed,
56 eckForallIndicesInRange,
57 eckForallIndicesNotInRange,
58 eckComputedGotoCaseLabel,
59 eckArithmeticIfLess,
60 eckArithmeticIfEqual,
61 eckArithmeticIfGreater,
62 eckInterprocedural,
63
64 // DQ (1/19/2018): Allow an error value to use for debugging.
65 eckError
66 };
67
70 class ROSE_DLL_API CFGNode {
72 SgNode* node; // Must be either a SgStatement, SgExpression, or SgInitializedName (FIXME: change this to just SgLocatedNode if SgInitializedName becomes a subclass of that)
73
76 unsigned int index;
77
78 public:
79 CFGNode(): node(0), index(0) {}
80 CFGNode(SgNode* node, unsigned int index = 0);
81
83 std::string toString() const;
85 std::string toStringForDebugging() const;
87 std::string id() const;
89 SgNode* getNode() const {return node;}
91 unsigned int getIndex() const {return index;}
93 std::vector<CFGEdge> outEdges() const;
95 std::vector<CFGEdge> inEdges() const;
100 bool isInteresting() const;
102 bool operator==(const CFGNode& o) const {return node == o.node && index == o.index;}
104 bool operator!=(const CFGNode& o) const {return !(*this == o);}
106 bool operator<(const CFGNode& o) const {return node < o.node || (node == o.node && index < o.index);}
107 }; // end class CFGNode
108
111 class ROSE_DLL_API CFGEdge {
112 CFGNode src, tgt;
113 public:
115 CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) { assert(src.getNode() != NULL && tgt.getNode() != NULL); }
116
119
121 std::string toString() const;
123 std::string toStringForDebugging() const;
125 std::string id() const;
127 CFGNode source() const {return src;}
129 CFGNode target() const {return tgt;}
131 EdgeConditionKind condition() const;
135 unsigned int computedGotoCaseIndex() const;
139 std::vector<SgInitializedName*> scopesBeingExited() const;
141 std::vector<SgInitializedName*> scopesBeingEntered() const;
143 bool operator==(const CFGEdge& o) const {return src == o.src && tgt == o.tgt;}
145 bool operator!=(const CFGEdge& o) const {return src != o.src || tgt != o.tgt;}
146
148 bool operator<(const CFGEdge& o) const {return src < o.src || (src == o.src && tgt < o.tgt);}
149
150 }; // end CFGEdge
151
157 class CFGPath {
158 std::vector<CFGEdge> edges;
159 public:
160 // DQ (8/28/2006): This constructor causes a bug to be brought out in ROSE
161 // (in compiling this file using ROSE) see test2006_124.C for a smaller example.
162 CFGPath(CFGEdge e): edges(1, e) {}
163 // Merge two CFG paths
164 CFGPath(const CFGPath& a, const CFGPath& b): edges(a.edges) {
165 assert (!a.edges.empty());
166 assert (!b.edges.empty());
167 assert (a.edges.back().target() == b.edges.front().source());
168 edges.insert(edges.end(),b.edges.begin(),b.edges.end());
169 }
170
171 //George Vulov 12/1/2010: We need a default constructor
172 CFGPath()
173 {
174 }
175
176 std::string toString() const;
177 std::string toStringForDebugging() const;
178 std::string id() const;
179 // Get the head CFG node of the path
180 CFGNode source() const {assert (!edges.empty()); return edges.front().source();}
181 // Get the tail CFG node of the path
182 CFGNode target() const {assert (!edges.empty()); return edges.back().target();}
183 //Return the first non-unconditional edge's condition
184 EdgeConditionKind condition() const {
185 for (unsigned int i = 0; i < edges.size(); ++i) {
186 EdgeConditionKind kind = edges[i].condition();
187 if (kind != eckUnconditional) return kind;
188 }
189 return eckUnconditional;
190 }
191 // Return the case label of its first edge representing a case
192 SgExpression* caseLabel() const {
193 for (unsigned int i = 0; i < edges.size(); ++i) {
194 SgExpression* label = edges[i].caseLabel();
195 if (label != NULL) return label;
196 }
197 return NULL;
198 }
199 SgExpression* conditionBasedOn() const {
200 for (unsigned int i = 0; i < edges.size(); ++i) {
201 SgExpression* base = edges[i].conditionBasedOn();
202 if (base != NULL) return base;
203 }
204 return NULL;
205 }
206 std::vector<SgInitializedName*> scopesBeingExited() const {
207 std::vector<SgInitializedName*> result;
208 for (unsigned int i = 0; i < edges.size(); ++i) {
209 std::vector<SgInitializedName*> s_i = edges[i].scopesBeingExited();
210 result.insert(result.end(), s_i.begin(), s_i.end());
211 }
212 return result;
213 }
214 std::vector<SgInitializedName*> scopesBeingEntered() const {
215 std::vector<SgInitializedName*> result;
216 for (unsigned int i = 0; i < edges.size(); ++i) {
217 std::vector<SgInitializedName*> s_i = edges[i].scopesBeingEntered();
218 result.insert(result.end(), s_i.begin(), s_i.end());
219 }
220 return result;
221 }
222 bool operator==(const CFGPath& o) const {return edges == o.edges;}
223 bool operator!=(const CFGPath& o) const {return edges != o.edges;}
224
226 bool operator<(const CFGPath& o) const {
227 if (edges.size() != o.edges.size()) {
228 return edges.size() < o.edges.size();
229 }
230 for (unsigned int i = 0; i < edges.size(); ++i) {
231 if (edges[i] != o.edges[i]) {
232 return edges[i] < o.edges[i];
233 }
234 }
235 return false;
236 }
237
239 const std::vector<CFGEdge>& getEdges() const
240 {
241 return edges;
242 }
243 }; // end CFGPath
244
246 inline CFGPath mergePaths(const CFGPath& hd, const CFGPath& tl) {
247 // Assumes the edges don't do anything too complicated with scopes
248 return CFGPath(hd, tl);
249 }
250
252 inline CFGPath mergePathsReversed(const CFGPath& tl, const CFGPath& hd) {
253 return mergePaths(hd, tl);
254 }
255
258 inline CFGNode cfgBeginningOfConstruct(SgNode* c) {
259 return CFGNode(c, 0);
260 }
261
264 unsigned int cfgIndexForEndWrapper(SgNode* n);
265
269 inline CFGNode cfgEndOfConstruct(SgNode* c) {
270 return CFGNode(c, cfgIndexForEndWrapper(c));
271 }
272
274 inline CFGNode makeCfg(SgNode* start) {
275 return cfgBeginningOfConstruct(start);
276 }
277
279 class InterestingEdge;
280
282 CFGNode n;
283
284 public:
285 InterestingNode(CFGNode n): n(n) {}
286 std::string toString() const {return n.toString();}
287 std::string toStringForDebugging() const {return n.toStringForDebugging();}
288 std::string id() const {return n.id();}
289 SgNode* getNode() const {return n.getNode();}
290 const CFGNode& toNode() const { return n; }
291 unsigned int getIndex() const {return n.getIndex();}
292 std::vector<InterestingEdge> outEdges() const;
293 std::vector<InterestingEdge> inEdges() const;
294 bool isInteresting() const {return true;}
295 bool operator==(const InterestingNode& o) const {return n == o.n;}
296 bool operator!=(const InterestingNode& o) const {return !(*this == o);}
297 bool operator<(const InterestingNode& o) const {return n < o.n;}
298 };
299
301 CFGPath p;
302
303 public:
304 InterestingEdge(CFGPath p): p(p) {}
305 std::string toString() const {return p.toString();}
306 std::string toStringForDebugging() const {return p.toStringForDebugging();}
307 std::string id() const {return p.id();}
308 InterestingNode source() const {return InterestingNode(p.source());}
309 InterestingNode target() const {return InterestingNode(p.target());}
310 EdgeConditionKind condition() const {return p.condition();}
311 SgExpression* caseLabel() const {return p.caseLabel();}
312 SgExpression* conditionBasedOn() const {return p.conditionBasedOn();}
313 std::vector<SgInitializedName*> scopesBeingExited() const {return p.scopesBeingExited();}
314 std::vector<SgInitializedName*> scopesBeingEntered() const {return p.scopesBeingEntered();}
315 bool operator==(const InterestingEdge& o) const {return p == o.p;}
316 bool operator!=(const InterestingEdge& o) const {return p != o.p;}
317 bool operator<(const InterestingEdge& o) const {return p < o.p;}
318 };
319
320 inline InterestingNode makeInterestingCfg(SgNode* start) {
321 // Returns CFG node for just before start
322 return InterestingNode(cfgBeginningOfConstruct(start));
323 }
324
326 CFGNode getCFGTargetOfFortranLabelSymbol(SgLabelSymbol* sym);
328 CFGNode getCFGTargetOfFortranLabelRef(SgLabelRefExp* lRef);
329
331 template <class Node1T, class Node2T, class EdgeT>
332 void makeEdge(Node1T from, Node2T to, std::vector<EdgeT>& result);
333
334} // end namespace VirtualCFG
335
336#define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
337#define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
338#define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
339
340#define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
341#define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
342#define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
343
345template <class NodeT1, class NodeT2, class EdgeT>
346void makeEdge(NodeT1 from, NodeT2 to, std::vector<EdgeT>& result);
347
348#endif // VIRTUAL_CFG_H
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes,...
This class represents the notion of a declared variable.
This class represents the base class for all IR nodes within Sage III.
This class represents the notion of a statement.
ROSE_DLL_API friend SgStatement * isSgStatement(SgNode *s)
Casts pointer from base class to derived class.
A control flow edge connecting two CFG nodes, with an edge condition to indicate edge types.
Definition virtualCFG.h:111
SgExpression * caseLabel() const
The label of the case represented by an eckCaseLabel edge.
SgExpression * conditionBasedOn() const
The test or case key that is tested as a condition of this control flow edge.
CFGEdge()
Default constructor. Used for compatibility with containers.
Definition virtualCFG.h:118
std::string toString() const
Pretty string for Dot node labels, etc.
std::string id() const
ID to use for Dot, etc.
CFGNode source() const
The source (beginning) CFG node.
Definition virtualCFG.h:127
std::vector< SgInitializedName * > scopesBeingEntered() const
Variables coming into scope across this edge (not extensively tested)
bool operator==(const CFGEdge &o) const
Compare equality of edges.
Definition virtualCFG.h:143
std::string toStringForDebugging() const
String for debugging graphs.
bool operator<(const CFGEdge &o) const
operator<() has an arbitrary ordering, but allows these objects to be used with std::set and std::map
Definition virtualCFG.h:148
EdgeConditionKind condition() const
The control flow condition that enables this edge.
unsigned int computedGotoCaseIndex() const
The expression of the computed goto represented by the eckArithmeticIf* conditions.
bool operator!=(const CFGEdge &o) const
Compare disequality of edges.
Definition virtualCFG.h:145
CFGEdge(CFGNode src, CFGNode tgt)
Constructor.
Definition virtualCFG.h:115
std::vector< SgInitializedName * > scopesBeingExited() const
Variables going out of scope across this edge (not extensively tested)
CFGNode target() const
The target (ending) CFG node.
Definition virtualCFG.h:129
A node in the control flow graph.
Definition virtualCFG.h:70
bool operator==(const CFGNode &o) const
Equality operator.
Definition virtualCFG.h:102
SgNode * getNode() const
The underlying AST node.
Definition virtualCFG.h:89
std::string toString() const
Pretty string for Dot node labels, etc.
bool operator<(const CFGNode &o) const
Less-than operator.
Definition virtualCFG.h:106
bool isInteresting() const
Test whether this node satisfies a (fairly arbitrary) standard for "interestingness".
std::vector< CFGEdge > inEdges() const
Incoming control flow edges to this node.
unsigned int getIndex() const
An identifying index within the AST node given by getNode()
Definition virtualCFG.h:91
std::vector< CFGEdge > outEdges() const
Outgoing control flow edges from this node.
std::string id() const
ID to use for Dot, etc.
std::string toStringForDebugging() const
String for debugging graphs.
bool operator!=(const CFGNode &o) const
Disequality operator.
Definition virtualCFG.h:104
const std::vector< CFGEdge > & getEdges() const
Returns the edges in the path, starting at the source and ending at the target.
Definition virtualCFG.h:239
bool operator<(const CFGPath &o) const
An arbitrary order, so we can use this in std::set and std::map.
Definition virtualCFG.h:226