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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef CBZ_LOOPS_H
00038 #define CBZ_LOOPS_H
00039
00040 #include <set>
00041
00042 typedef set< basicblockNode * > basicblock_set;
00043 typedef basicblock_set::iterator basicblock_set_p;
00044
00045 typedef map< basicblockNode *, basicblock_set > edge_map;
00046 typedef edge_map::iterator edge_map_p;
00047
00048 typedef map< basicblockNode *, basicblock_set > basicblock_set_map;
00049 typedef basicblock_set_map::iterator basicblock_set_map_p;
00050
00051 typedef map< basicblockNode *, int > basicblock_int_map;
00052 typedef basicblock_int_map::iterator basicblock_int_map_p;
00053
00054 class loopTreeNode;
00055
00056 typedef list< loopTreeNode * > loop_list;
00057 typedef loop_list::iterator loop_list_p;
00058
00059 typedef set< loopTreeNode * > loop_set;
00060 typedef loop_set::iterator loop_set_p;
00061
00062 class loopTreeNode
00063 {
00064 public:
00065
00068 typedef enum { SingleEntry, MultipleEntry, Top } LoopKind;
00069
00070 private:
00071
00074 LoopKind _kind;
00075
00078 int _depth;
00079
00082 basicblockNode * _header;
00083
00086 basicblockNode * _preheader;
00087
00090 loopTreeNode * _parentLoop;
00091
00094 loop_set _nestedLoops;
00095
00098 basicblock_set _blocks;
00099
00100 public:
00101
00104 loopTreeNode(LoopKind kind, basicblockNode * header);
00105
00108 inline void addBlock(basicblockNode * block) { _blocks.insert(block); }
00109
00112 inline void addNestedLoop(loopTreeNode * nest){ _nestedLoops.insert(nest); }
00113
00116 inline LoopKind kind() const { return _kind; }
00117
00118 inline int depth() const { return _depth; }
00119 inline void depth(int d) { _depth = d; }
00120
00121 inline basicblockNode * header() const { return _header; }
00122
00123 inline basicblockNode * preheader() const { return _preheader; }
00124
00125 inline loopTreeNode * parentLoop() const { return _parentLoop; }
00126 inline void parentLoop(loopTreeNode * parent) { _parentLoop = parent; }
00127
00128 inline loop_set & nestedLoops() { return _nestedLoops; }
00129
00130 inline basicblock_set & blocks() { return _blocks; }
00131
00134 void report();
00135 };
00136
00137 typedef map< basicblockNode *, loopTreeNode * > blockloop_map;
00138 typedef blockloop_map::iterator blockloop_map_p;
00139
00140 class loopTree
00141 {
00142 public:
00143
00144 typedef enum { TreeEdge, BackEdge, ForwardEdge, CrossEdge } EdgeKind;
00145
00146 private:
00147
00150 procNode * _procedure;
00151
00154 loopTreeNode * _top;
00155
00158 loop_list _loops;
00159
00162 blockloop_map _containedIn;
00163
00170 edge_map _backEdges;
00171
00176 edge_map _forwardEdges;
00177
00182 edge_map _crossEdges;
00183
00186 basicblock_int_map _preOrder;
00187
00190 basicblock_int_map _rpostOrder;
00191
00192 public:
00193
00196 loopTree(procNode * procedure);
00197
00203 ~loopTree();
00204
00207 inline procNode * procedure() const { return _procedure; }
00208
00214 inline loopTreeNode * topLoop() const { return _top; }
00215
00220 loopTreeNode * whichLoop(basicblockNode * block);
00221
00224 loopTreeNode * loopAncestor(loopTreeNode * loop);
00225
00232 EdgeKind classifyEdge(basicblockNode * source,
00233 basicblockNode * target);
00234
00237 void report();
00238
00239 private:
00240
00243 void findLoop(basicblockNode * candidate,
00244 basicblock_set_map & generators_map);
00245
00248 void findBody(basicblockNode * head,
00249 basicblock_set & generators,
00250 loopTreeNode::LoopKind kind);
00251
00254 basicblockNode * commonDominator(basicblockNode * first,
00255 basicblockNode * second);
00256
00264 void classifyEdges(basicblock_list & post_order);
00265
00268 void depthFirstSearch(basicblockNode * cur,
00269 basicblock_list & post_order,
00270 int & pre_order_number,
00271 int & post_order_number);
00272
00275 void setDepths(loopTreeNode * cur, int depth);
00276
00279 void report(loopTreeNode * cur, int level);
00280
00281 };
00282
00283 #endif // CBZ_LOOPS_H
00284