00001 #ifndef VIRTUAL_CFG_H
00002 #define VIRTUAL_CFG_H
00003
00004 #include <string>
00005 #include <vector>
00006 #include <assert.h>
00007
00008
00013 class SgNode;
00014 class SgExpression;
00015 class SgInitializedName;
00016 class SgLabelSymbol;
00017 class SgLabelRefExp;
00018 class SgStatement;
00019
00020 #ifndef _MSC_VER
00021 SgStatement* isSgStatement(SgNode* node);
00022 const SgStatement* isSgStatement(const SgNode* node);
00023 SgExpression* isSgExpression(SgNode* node);
00024 const SgExpression* isSgExpression(const SgNode* node);
00025 SgInitializedName* isSgInitializedName(SgNode* node);
00026 const SgInitializedName* isSgInitializedName(const SgNode* node);
00027 #endif
00028
00029 namespace VirtualCFG {
00030
00031 class CFGEdge;
00032
00040 enum EdgeConditionKind
00041 {
00042 eckUnconditional,
00043 eckTrue,
00044 eckFalse,
00045 eckCaseLabel,
00046 eckDefault,
00047 eckDoConditionPassed,
00048 eckDoConditionFailed,
00049 eckForallIndicesInRange,
00050 eckForallIndicesNotInRange,
00051 eckComputedGotoCaseLabel,
00052 eckArithmeticIfLess,
00053 eckArithmeticIfEqual,
00054 eckArithmeticIfGreater,
00055 eckInterprocedural
00056 };
00057
00060 class CFGNode {
00062 SgNode* node;
00063
00066 unsigned int index;
00067
00068 public:
00069 CFGNode(): node(0), index(0) {}
00070 CFGNode(SgNode* node, unsigned int index = 0);
00071
00073 std::string toString() const;
00075 std::string toStringForDebugging() const;
00077 std::string id() const;
00079 SgNode* getNode() const {return node;}
00081 unsigned int getIndex() const {return index;}
00083 std::vector<CFGEdge> outEdges() const;
00085 std::vector<CFGEdge> inEdges() const;
00090 bool isInteresting() const;
00092 bool operator==(const CFGNode& o) const {return node == o.node && index == o.index;}
00094 bool operator!=(const CFGNode& o) const {return !(*this == o);}
00096 bool operator<(const CFGNode& o) const {return node < o.node || (node == o.node && index < o.index);}
00097 };
00098
00101 class CFGEdge {
00102 CFGNode src, tgt;
00103 public:
00105 CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) {}
00106
00108 CFGEdge() {}
00109
00111 std::string toString() const;
00113 std::string toStringForDebugging() const;
00115 std::string id() const;
00117 CFGNode source() const {return src;}
00119 CFGNode target() const {return tgt;}
00121 EdgeConditionKind condition() const;
00123 SgExpression* caseLabel() const;
00125 unsigned int computedGotoCaseIndex() const;
00127 SgExpression* conditionBasedOn() const;
00129 std::vector<SgInitializedName*> scopesBeingExited() const;
00131 std::vector<SgInitializedName*> scopesBeingEntered() const;
00133 bool operator==(const CFGEdge& o) const {return src == o.src && tgt == o.tgt;}
00135 bool operator!=(const CFGEdge& o) const {return src != o.src || tgt != o.tgt;}
00136
00138 bool operator<(const CFGEdge& o) const {return src < o.src || (src == o.src && tgt < o.tgt);}
00139
00140 };
00141
00147 class CFGPath {
00148 std::vector<CFGEdge> edges;
00149 public:
00150
00151
00152 CFGPath(CFGEdge e): edges(1, e) {}
00153
00154 CFGPath(const CFGPath& a, const CFGPath& b): edges(a.edges) {
00155 assert (!a.edges.empty());
00156 assert (!b.edges.empty());
00157 assert (a.edges.back().target() == b.edges.front().source());
00158 edges.insert(edges.end(),b.edges.begin(),b.edges.end());
00159 }
00160
00161
00162 CFGPath()
00163 {
00164 }
00165
00166 std::string toString() const;
00167 std::string toStringForDebugging() const;
00168 std::string id() const;
00169
00170 CFGNode source() const {assert (!edges.empty()); return edges.front().source();}
00171
00172 CFGNode target() const {assert (!edges.empty()); return edges.back().target();}
00173
00174 EdgeConditionKind condition() const {
00175 for (unsigned int i = 0; i < edges.size(); ++i) {
00176 EdgeConditionKind kind = edges[i].condition();
00177 if (kind != eckUnconditional) return kind;
00178 }
00179 return eckUnconditional;
00180 }
00181
00182 SgExpression* caseLabel() const {
00183 for (unsigned int i = 0; i < edges.size(); ++i) {
00184 SgExpression* label = edges[i].caseLabel();
00185 if (label != NULL) return label;
00186 }
00187 return NULL;
00188 }
00189 SgExpression* conditionBasedOn() const {
00190 for (unsigned int i = 0; i < edges.size(); ++i) {
00191 SgExpression* base = edges[i].conditionBasedOn();
00192 if (base != NULL) return base;
00193 }
00194 return NULL;
00195 }
00196 std::vector<SgInitializedName*> scopesBeingExited() const {
00197 std::vector<SgInitializedName*> result;
00198 for (unsigned int i = 0; i < edges.size(); ++i) {
00199 std::vector<SgInitializedName*> s_i = edges[i].scopesBeingExited();
00200 result.insert(result.end(), s_i.begin(), s_i.end());
00201 }
00202 return result;
00203 }
00204 std::vector<SgInitializedName*> scopesBeingEntered() const {
00205 std::vector<SgInitializedName*> result;
00206 for (unsigned int i = 0; i < edges.size(); ++i) {
00207 std::vector<SgInitializedName*> s_i = edges[i].scopesBeingEntered();
00208 result.insert(result.end(), s_i.begin(), s_i.end());
00209 }
00210 return result;
00211 }
00212 bool operator==(const CFGPath& o) const {return edges == o.edges;}
00213 bool operator!=(const CFGPath& o) const {return edges != o.edges;}
00214
00216 bool operator<(const CFGPath& o) const {
00217 if (edges.size() != o.edges.size()) {
00218 return edges.size() < o.edges.size();
00219 }
00220 for (unsigned int i = 0; i < edges.size(); ++i) {
00221 if (edges[i] != o.edges[i]) {
00222 return edges[i] < o.edges[i];
00223 }
00224 }
00225 return false;
00226 }
00227
00229 const std::vector<CFGEdge>& getEdges() const
00230 {
00231 return edges;
00232 }
00233 };
00234
00236 inline CFGPath mergePaths(const CFGPath& hd, const CFGPath& tl) {
00237
00238 return CFGPath(hd, tl);
00239 }
00240
00242 inline CFGPath mergePathsReversed(const CFGPath& tl, const CFGPath& hd) {
00243 return mergePaths(hd, tl);
00244 }
00245
00248 inline CFGNode cfgBeginningOfConstruct(SgNode* c) {
00249 return CFGNode(c, 0);
00250 }
00251
00254 unsigned int cfgIndexForEndWrapper(SgNode* n);
00255
00259 inline CFGNode cfgEndOfConstruct(SgNode* c) {
00260 return CFGNode(c, cfgIndexForEndWrapper(c));
00261 }
00262
00264 inline CFGNode makeCfg(SgNode* start) {
00265 return cfgBeginningOfConstruct(start);
00266 }
00267
00269 class InterestingEdge;
00270
00271 class InterestingNode {
00272 CFGNode n;
00273
00274 public:
00275 InterestingNode(CFGNode n): n(n) {}
00276 std::string toString() const {return n.toString();}
00277 std::string toStringForDebugging() const {return n.toStringForDebugging();}
00278 std::string id() const {return n.id();}
00279 SgNode* getNode() const {return n.getNode();}
00280 const CFGNode& toNode() const { return n; }
00281 unsigned int getIndex() const {return n.getIndex();}
00282 std::vector<InterestingEdge> outEdges() const;
00283 std::vector<InterestingEdge> inEdges() const;
00284 bool isInteresting() const {return true;}
00285 bool operator==(const InterestingNode& o) const {return n == o.n;}
00286 bool operator!=(const InterestingNode& o) const {return !(*this == o);}
00287 bool operator<(const InterestingNode& o) const {return n < o.n;}
00288 };
00289
00290 class InterestingEdge {
00291 CFGPath p;
00292
00293 public:
00294 InterestingEdge(CFGPath p): p(p) {}
00295 std::string toString() const {return p.toString();}
00296 std::string toStringForDebugging() const {return p.toStringForDebugging();}
00297 std::string id() const {return p.id();}
00298 InterestingNode source() const {return InterestingNode(p.source());}
00299 InterestingNode target() const {return InterestingNode(p.target());}
00300 EdgeConditionKind condition() const {return p.condition();}
00301 SgExpression* caseLabel() const {return p.caseLabel();}
00302 SgExpression* conditionBasedOn() const {return p.conditionBasedOn();}
00303 std::vector<SgInitializedName*> scopesBeingExited() const {return p.scopesBeingExited();}
00304 std::vector<SgInitializedName*> scopesBeingEntered() const {return p.scopesBeingEntered();}
00305 bool operator==(const InterestingEdge& o) const {return p == o.p;}
00306 bool operator!=(const InterestingEdge& o) const {return p != o.p;}
00307 bool operator<(const InterestingEdge& o) const {return p < o.p;}
00308 };
00309
00310 inline InterestingNode makeInterestingCfg(SgNode* start) {
00311
00312 return InterestingNode(cfgBeginningOfConstruct(start));
00313 }
00314
00316 CFGNode getCFGTargetOfFortranLabelSymbol(SgLabelSymbol* sym);
00318 CFGNode getCFGTargetOfFortranLabelRef(SgLabelRefExp* lRef);
00319
00321 template <class Node1T, class Node2T, class EdgeT>
00322 void makeEdge(Node1T from, Node2T to, std::vector<EdgeT>& result);
00323
00324 }
00325
00326 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
00327 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
00328 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
00329
00330 #define SGFUNCTIONCALLEXP_INTERPROCEDURAL_INDEX 2
00331 #define SGCONSTRUCTORINITIALIZER_INTERPROCEDURAL_INDEX 1
00332 #define SGFUNCTIONDEFINITION_INTERPROCEDURAL_INDEX 2
00333
00335 template <class NodeT1, class NodeT2, class EdgeT>
00336 void makeEdge(NodeT1 from, NodeT2 to, std::vector<EdgeT>& result);
00337
00338 #endif // VIRTUAL_CFG_H