C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

dominators.cc

Go to the documentation of this file.
00001 // $Id: dominators.cc,v 1.10 2003/08/07 23:14:13 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
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   // --- Make sure there aren't too many basic blocks for the bitset
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   // --- Make sure the "None" node has been created
00058 
00059   if (1 || None == 0) { // Stuff inside None can become stale, so 
00060                         // we always re-make it -- djimenez
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   // --- Compute
00071 
00072   dominator_tree();
00073 
00074   // print();
00075 
00076   int size = df_vec.size();
00077 
00078   // --- Remove all the dominator_info structures
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 // Fast version (Muchnick)
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   // --- Initialize the data structures
00118   
00119   _index = 0;
00120   depth_first_search(_root, None);
00121 
00122   // --- Main loop
00123 
00124   num_nodes = df_vec.size() - 1;
00125 
00126   for (int i = num_nodes; i > 1; i--) {
00127     // cout << "[" << i << "] ---------- " << endl;
00128 
00129     // --- Retrieve the current node
00130 
00131     basicblockNode * w = df_vec[i];
00132 
00133     // cout << "Dfn = " << w->dfn() << " parent = " << Parent(w)->dfn() << endl;
00134 
00135     // --- For all predecessors, 
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         // cout << "Eval(" << v->dfn() << ") = ";
00146         basicblockNode * u = eval(v);
00147         // cout << u->dfn() << endl;
00148         
00149         // cout << "Test Sdno(" << Dfn(u) << ") = " << Sdno(u) << " < "
00150         //  "Test Sdno(" << Dfn(w) << ") = " << Sdno(w) << endl;
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     // cout << "Add " << i << " to bucket of " << Dfn(semi_dom) << endl;
00159     link(Parent(w), w);
00160 
00161     // print();
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         //      cout << " in bucket : " << Dfn(v) << endl;
00169 
00170         // cout << "Test Sdno(" << Dfn(u) << ") = " << Sdno(u) << " < "
00171         //  "Test Sdno(" << Dfn(v) << ") = " << Sdno(v) << endl;
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     // --- Add to the children pointer
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     // --- Check the ordering:
00208     //       _forward = true  --> successors   --> dominators
00209     //       _forward = false --> predecessors --> post-dominators
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     // com << " Sdno = " << Sdno(curblock);
00300 
00301     // Also show the CFG
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 // --- Test to see if A dominates B : return true if A is in the chain
00330 // of immediate dominators starting at B.
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 

Generated on August 27, 2003
Back to the C-Breeze home page