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
00038 #include "c_breeze.h"
00039 #include "dominators.h"
00040
00041 basicblockNode * Dominators::None = 0;
00042
00043 Dominators::Dominators(procNode * proc, bool forward)
00044 : _proc(proc),
00045 _root(0),
00046 _forward(forward),
00047 _index(0)
00048 {
00049
00050
00051 if (proc->body()->stmts().size() > BASICBLOCK_BITSET_SIZE) {
00052 cerr << "INTERNAL ERROR: trying to compute dominators for \"" << proc->decl()->name() << "\"" << endl;
00053 cerr << " Too many basic blocks (" << proc->body()->stmts().size() << "); limit is " << BASICBLOCK_BITSET_SIZE << endl;
00054 return;
00055 }
00056
00057
00058
00059 if (1 || None == 0) {
00060
00061 None = new basicblockNode(0,0);
00062 None->info(new dominator_info(None, 0));
00063 }
00064
00065 if (forward)
00066 _root = proc->entry();
00067 else
00068 _root = proc->exit();
00069
00070
00071
00072 dominator_tree();
00073
00074
00075
00076 int size = df_vec.size();
00077
00078
00079
00080 for (int i = 1; i < size; i++) {
00081 basicblockNode * curblock = df_vec[i];
00082
00083 if (curblock->info())
00084 delete curblock->info();
00085
00086 curblock->info(0);
00087 }
00088 }
00089
00090
00091
00092
00093 #define Label(n) ((dominator_info *)(n)->info())->label
00094 #define Parent(n) ((dominator_info *)(n)->info())->parent
00095 #define Ancestor(n) ((dominator_info *)(n)->info())->ancestor
00096 #define Child(n) ((dominator_info *)(n)->info())->child
00097 #define Sdno(n) ((dominator_info *)(n)->info())->sdno
00098 #define Size(n) ((dominator_info *)(n)->info())->size
00099 #define Bucket(n) ((dominator_info *)(n)->info())->bucket
00100
00101 dominator_info::dominator_info(basicblockNode * node, int depth_first_num)
00102 : label(node),
00103 parent(Dominators::None),
00104 ancestor(Dominators::None),
00105 child(Dominators::None),
00106 sdno(depth_first_num),
00107 size(1),
00108 bucket()
00109 {}
00110
00111 void Dominators::dominator_tree()
00112 {
00113 int num_nodes;
00114
00115 df_vec.push_back(None);
00116
00117
00118
00119 _index = 0;
00120 depth_first_search(_root, None);
00121
00122
00123
00124 num_nodes = df_vec.size() - 1;
00125
00126 for (int i = num_nodes; i > 1; i--) {
00127
00128
00129
00130
00131 basicblockNode * w = df_vec[i];
00132
00133
00134
00135
00136
00137 basicblock_list & bbl = (_forward) ? w->preds() : w->succs();
00138
00139 for (basicblock_list_p p = bbl.begin();
00140 p != bbl.end();
00141 ++p)
00142 {
00143 basicblockNode * v = *p;
00144
00145
00146 basicblockNode * u = eval(v);
00147
00148
00149
00150
00151
00152 if (Sdno(u) < Sdno(w))
00153 Sdno(w) = Sdno(u);
00154 }
00155
00156 basicblockNode * semi_dom = df_vec[Sdno(w)];
00157 Bucket(semi_dom).set(i);
00158
00159 link(Parent(w), w);
00160
00161
00162
00163 for (int j = 1; j <= num_nodes; j++) {
00164 if (Bucket(Parent(w)).test(j) != 0) {
00165 basicblockNode * v = df_vec[j];
00166 basicblockNode * u = eval(v);
00167
00168
00169
00170
00171
00172
00173 if (Sdno(u) < Sdno(v))
00174 v->parent(u);
00175 else
00176 v->parent(Parent(w));
00177 }
00178 }
00179 }
00180
00181 for (int i = 2; i <= num_nodes; i++) {
00182 basicblockNode * w = df_vec[i];
00183 basicblockNode * semi_dom = df_vec[Sdno(w)];
00184
00185 if (w->parent() != semi_dom)
00186 w->parent(w->parent()->parent());
00187
00188
00189
00190 w->parent()->children().push_back(w);
00191 }
00192 }
00193
00194 void Dominators::depth_first_search(basicblockNode * node,
00195 basicblockNode * par)
00196 {
00197 if (node->info() == 0) {
00198 ++_index;
00199
00200 node->info(new dominator_info(node, _index));
00201 node->dfn(_index);
00202 node_index[node] = _index;
00203 df_vec.push_back(node);
00204
00205 Parent(node) = par;
00206
00207
00208
00209
00210
00211 basicblock_list & bbl = (_forward) ? node->succs() : node->preds();
00212
00213 for (basicblock_list_p p = bbl.begin();
00214 p != bbl.end();
00215 ++p)
00216 {
00217 basicblockNode * curblock = *p;
00218 depth_first_search(curblock, node);
00219 }
00220 }
00221 }
00222
00223 void Dominators::compress(basicblockNode * v)
00224 {
00225 basicblockNode * anc = Ancestor(v);
00226
00227 if (Ancestor(Ancestor(v)) != None) {
00228 compress(Ancestor(v));
00229
00230 if (Sdno(Label(Ancestor(v))) < Sdno(Label(v)))
00231 Label(v) = Label(Ancestor(v));
00232
00233 Ancestor(v) = Ancestor(Ancestor(v));
00234 }
00235 }
00236
00237 basicblockNode * Dominators::eval(basicblockNode * v)
00238 {
00239 if (Ancestor(v) == None)
00240 return Label(v);
00241 else {
00242 compress(v);
00243
00244 if (Sdno(Label(Ancestor(v))) >= Sdno(Label(v)))
00245 return Label(v);
00246 else
00247 return Label(Ancestor(v));
00248 }
00249 }
00250
00251 void Dominators::link(basicblockNode * v, basicblockNode * w)
00252 {
00253 basicblockNode * s = w;
00254
00255 while (Sdno(Label(w)) < Sdno(Label(Child(s)))) {
00256
00257 if (((Size(s) + Size(Child(Child(s))))) >=
00258 2 * (Size(Child(s)))) {
00259 Ancestor(Child(s)) = s;
00260 Child(s) = Child(Child(s));
00261 }
00262 else {
00263 Size(Child(s)) = Size(s);
00264 s = Ancestor(s) = Child(s);
00265 }
00266 }
00267
00268 Label(s) = Label(w);
00269 Size(v) += Size(w);
00270
00271 if (Size(v) < 2 * (Size(w))) {
00272 basicblockNode * tmp = s;
00273 s = Child(v);
00274 Child(v) = tmp;
00275 }
00276
00277 while (s != None) {
00278 Ancestor(s) = v;
00279 s = Child(s);
00280 }
00281 }
00282
00283 void Dominators::print()
00284 {
00285 output_context out(cout);
00286 int size = df_vec.size();
00287
00288 for (int i = 1; i < size; i++) {
00289 basicblockNode * curblock = df_vec[i];
00290 basicblockNode * parent = curblock->parent();
00291
00292 ostringstream com;
00293
00294 com << "BB " << curblock->dfn() << " idom = ";
00295 if (parent)
00296 com << curblock->parent()->dfn();
00297 else
00298 com << "(no idom)";
00299
00300
00301
00302
00303 com << "\tPreds: ";
00304 if (curblock->preds().empty())
00305 com << "(none)";
00306
00307 for (basicblock_list_p l = curblock->preds().begin();
00308 l != curblock->preds().end(); l++)
00309 com << (*l)->dfn() << " ";
00310
00311 com << "\tSuccs: ";
00312 if (curblock->succs().empty())
00313 com << "(none)";
00314
00315 for (basicblock_list_p l = curblock->succs().begin();
00316 l != curblock->succs().end(); l++)
00317 com << (*l)->dfn() << " ";
00318
00319 curblock->comment() = com.str();
00320
00321 cout << com.str() << endl;
00322 }
00323 }
00324
00325 Dominators::~Dominators()
00326 {
00327 }
00328
00329
00330
00331
00332 bool Dominators::dominates(basicblockNode * A, basicblockNode * B)
00333 {
00334 basicblockNode * par = B;
00335
00336 if ((A == 0) || (B == 0))
00337 return false;
00338
00339 if (A == B)
00340 return true;
00341
00342 do
00343 par = par->parent();
00344 while (par && (par != A));
00345
00346 return (par == A);
00347 }
00348
00349