00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027 #ifndef SHCTRLGRAPH_HPP
00028 #define SHCTRLGRAPH_HPP
00029
00030 #include <vector>
00031 #include <list>
00032 #include <iosfwd>
00033 #include "ShDllExport.hpp"
00034 #include "ShRefCount.hpp"
00035 #include "ShBasicBlock.hpp"
00036 #include "ShVariable.hpp"
00037 #include "ShBlock.hpp"
00038
00039 namespace SH {
00040
00041 class ShCtrlGraphNode;
00042
00043 struct
00044 SH_DLLEXPORT ShCtrlGraphBranch {
00045 ShCtrlGraphBranch(const ShPointer<ShCtrlGraphNode>& node,
00046 ShVariable cond);
00047
00048 ShPointer<ShCtrlGraphNode> node;
00049 ShVariable cond;
00050 };
00051
00062 class
00063 SH_DLLEXPORT ShCtrlGraphNode : public ShRefCountable {
00064 public:
00065 ShCtrlGraphNode();
00066 ~ShCtrlGraphNode();
00067
00068 ShBasicBlockPtr block;
00069 typedef std::vector<ShCtrlGraphBranch> SuccessorList;
00070 SuccessorList successors;
00071 ShPointer<ShCtrlGraphNode> follower;
00072
00073 typedef std::list<ShCtrlGraphNode*> ShPredList;
00074 ShPredList predecessors;
00075
00078 std::ostream& print(std::ostream& out, int indent) const;
00079
00082 std::ostream& graphvizDump(std::ostream& out) const;
00083
00085 void append(const ShPointer<ShCtrlGraphNode>& node);
00086
00088 void append(const ShPointer<ShCtrlGraphNode>& node,
00089 ShVariable cond);
00090
00104 ShPointer<ShCtrlGraphNode>
00105 split(ShBasicBlock::ShStmtList::iterator stmt);
00106
00109 bool marked() const;
00110
00111
00112
00113
00114 void mark() const;
00115 void clearMarked() const;
00116
00117
00118 template<typename F>
00119 void dfs(F& functor);
00120
00121 template<typename F>
00122 void dfs(F& functor) const;
00123
00124 private:
00125 template<typename F>
00126 void real_dfs(F& functor);
00127
00128 template<typename F>
00129 void real_dfs(F& functor) const;
00130
00131 mutable bool m_marked;
00132 };
00133
00134 typedef ShPointer<ShCtrlGraphNode> ShCtrlGraphNodePtr;
00135 typedef ShPointer<const ShCtrlGraphNode> ShCtrlGraphNodeCPtr;
00136
00140 class
00141 SH_DLLEXPORT ShCtrlGraph : public ShRefCountable {
00142 public:
00143 ShCtrlGraph(ShCtrlGraphNodePtr head, ShCtrlGraphNodePtr tail);
00144 ShCtrlGraph(ShBlockListPtr blocks);
00145 ~ShCtrlGraph();
00146
00147 std::ostream& print(std::ostream& out, int indent) const;
00148
00149 std::ostream& graphvizDump(std::ostream& out) const;
00150
00151 ShCtrlGraphNodePtr entry() const;
00152 ShCtrlGraphNodePtr exit() const;
00153
00155
00156 ShCtrlGraphNodePtr prependEntry();
00157
00159 ShCtrlGraphNodePtr appendExit();
00160
00161 template<typename F>
00162 void dfs(F& functor);
00163
00164 template<typename F>
00165 void dfs(F& functor) const;
00166
00168 void computePredecessors();
00169
00170
00171 void copy(ShCtrlGraphNodePtr& head, ShCtrlGraphNodePtr& tail) const;
00172
00173 private:
00174 ShCtrlGraphNodePtr m_entry;
00175 ShCtrlGraphNodePtr m_exit;
00176
00177
00178 };
00179
00180 typedef ShPointer<ShCtrlGraph> ShCtrlGraphPtr;
00181 typedef ShPointer<const ShCtrlGraph> ShCtrlGraphCPtr;
00182
00183 template<typename F>
00184 void ShCtrlGraphNode::real_dfs(F& functor)
00185 {
00186 if (this == 0) return;
00187 if (m_marked) return;
00188 mark();
00189 functor(this);
00190 for (std::vector<ShCtrlGraphBranch>::iterator I = successors.begin(); I != successors.end(); ++I) {
00191 I->node->real_dfs(functor);
00192 }
00193 if (follower) follower->real_dfs(functor);
00194 }
00195
00196 template<typename F>
00197 void ShCtrlGraphNode::real_dfs(F& functor) const
00198 {
00199 if (this == 0) return;
00200 if (m_marked) return;
00201 mark();
00202 functor(this);
00203 for (std::vector<ShCtrlGraphBranch>::const_iterator I = successors.begin();
00204 I != successors.end(); ++I) {
00205 I->node->real_dfs(functor);
00206 }
00207 if (follower) follower->real_dfs(functor);
00208 }
00209
00210 template<typename F>
00211 void ShCtrlGraphNode::dfs(F& functor)
00212 {
00213 clearMarked();
00214 real_dfs(functor);
00215 clearMarked();
00216 }
00217
00218 template<typename F>
00219 void ShCtrlGraphNode::dfs(F& functor) const
00220 {
00221 clearMarked();
00222 real_dfs(functor);
00223 clearMarked();
00224 }
00225
00226 template<typename F>
00227 void ShCtrlGraph::dfs(F& functor)
00228 {
00229 m_entry->dfs(functor);
00230 }
00231
00232 template<typename F>
00233 void ShCtrlGraph::dfs(F& functor) const
00234 {
00235 m_entry->dfs(functor);
00236 }
00237
00238 }
00239
00240 #endif