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  

dismantle-flatten.cc

Go to the documentation of this file.
00001 // $Id: dismantle-flatten.cc,v 1.13 2003/08/07 23:13:43 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 //  Adam Brown
00013 // 
00014 //  Permission is hereby granted, free of charge, to any person
00015 //  obtaining a copy of this software and associated documentation
00016 //  files (the "Software"), to deal in the Software without
00017 //  restriction, including without limitation the rights to use, copy,
00018 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00019 //  of the Software, and to permit persons to whom the Software is
00020 //  furnished to do so, subject to the following conditions:
00021 //  
00022 //  The above copyright notice and this permission notice shall be
00023 //  included in all copies or substantial portions of the Software.
00024 //  
00025 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00026 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00027 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00028 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00029 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00030 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00031 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00032 //  THE SOFTWARE.
00033 //
00034 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00035 //  Computer Science for inspiring parts of the C-Breeze design.
00036 //
00037 // ----------------------------------------------------------------------
00038 //
00039 // dismantle-flatten.cc
00040 //
00041 
00042 #include "c_breeze.h"
00043 #include "dismantle.h"
00044 #include <sstream>
00045 
00046 FlattenDismantle::FlattenDismantle(void):
00047   Changer(Both, Subtree, false),
00048   _new_body(NULL),
00049   _last_stmt(NULL),
00050   _vars()
00051 {}
00052 
00053 Node * FlattenDismantle::at_proc(procNode * the_proc, Order ord) {
00054   if ( ord == Preorder ) {
00055     _new_body = new blockNode(NULL, NULL);
00056     _last_stmt = NULL;
00057     assert(the_proc->decl()->type()->typ() == Func);
00058     decl_list & args = ((funcNode *) the_proc->decl()->type())->args();
00059     for ( decl_list_p arg_decl = args.begin(); arg_decl != args.end();
00060           arg_decl++ ) {
00061       _vars.insert((*arg_decl)->name());
00062     }
00063   } else { // ord == Postorder
00064     // remove sections of code that are a label followed by a goto
00065     stmt_list_p next = _new_body->stmts().begin();
00066     stmtNode *prev = NULL;
00067     while ( next != _new_body->stmts().end() ) {
00068       stmt_list_p curr = next;
00069       next++;
00070       if ( next != _new_body->stmts().end()
00071            && (*curr)->typ() == Label
00072            && (*next)->typ() == Goto ) {
00073         labelNode * the_label = (labelNode *) *curr;
00074         labelNode * new_label = ((gotoNode *) *next)->label();
00075         goto_list_p next_goto = the_label->references().begin();
00076         while ( next_goto != the_label->references().end() ) {
00077           gotoNode * curr_goto = *next_goto;
00078           next_goto++;
00079           curr_goto->label(new_label);
00080         }
00081         _new_body->stmts().erase(curr);  // the Label
00082         curr = next;
00083         next++;
00084         if(prev && prev->typ() != Goto) {
00085           // keep the Goto.
00086           prev = *curr;
00087         } else {
00088           _new_body->stmts().erase(curr);  // the Goto
00089           // prev remains unchanged.
00090         }
00091       } else
00092         prev = *curr;
00093     }
00094     the_proc->body(_new_body);
00095   }
00096   return the_proc;
00097 }
00098 
00099 Node * FlattenDismantle::at_decl(declNode * the_decl, Order ord) {
00100   if ( ord == Preorder ) {
00101     if ( the_decl->decl_location() == declNode::BLOCK ) {
00102       int next_num = 0;
00103       string base_name(the_decl->name());
00104       bool changed_name = false;
00105       // ensure that we don't have another variable by this name in this proc
00106       while ( _vars.find(the_decl->name()) != _vars.end() ) {
00107         ostringstream ost;
00108         ost << base_name << next_num;
00109         the_decl->name(ost.str());
00110         next_num++;
00111         changed_name = true;
00112       }
00113       if ( changed_name ) {
00114         // update all the idNodes that point to this decl
00115         for ( id_list_p p = the_decl->ref_list().begin();
00116               p != the_decl->ref_list().end();
00117               p++ ) {
00118           (*p)->name(the_decl->name());
00119         }
00120       }
00121       _vars.insert(the_decl->name());
00122       _new_body->decls().push_back(the_decl);
00123     }
00124   }
00125   return the_decl;
00126 }
00127 
00128 Node * FlattenDismantle::at_label(labelNode * the_label, Order ord) {
00129   // we only want to keep the label if some goto points to it
00130   if ( ord == Preorder 
00131        && the_label->references().size() > 0 )
00132     if ( _last_stmt && _last_stmt->typ() == Label ) {
00133       // if the last statment seen was also a label, just update all of the
00134       // gotoNode's that point to the_label to point to the last label
00135       goto_list_p next = the_label->references().begin();
00136       while ( next != the_label->references().end() ) {
00137         gotoNode * curr = *next;
00138         next++;
00139         curr->label((labelNode *) _last_stmt);
00140       }
00141     } else {
00142       int next_num = 0;
00143       string base_name(the_label->name());
00144       bool changed_name = false;
00145       // ensure that we don't have another label with this same name
00146       while ( _labels.find(the_label->name()) != _labels.end() ) {
00147         ostringstream ost;
00148         ost << base_name << next_num;
00149         the_label->name(ost.str());
00150         next_num++;
00151         changed_name = true;
00152       }
00153       if (changed_name ) {
00154         // update all gotoNodes that point to this labelNode
00155         for ( goto_list_p p = the_label->references().begin();
00156               p != the_label->references().end();
00157               p++ ) {
00158           (*p)->name(the_label->name());
00159         }
00160       }
00161 
00162       _labels.insert(the_label->name());
00163       _new_body->stmts().push_back(the_label);
00164       _last_stmt = the_label;
00165     }
00166   return the_label;
00167 }
00168 
00169 Node * FlattenDismantle::at_threeAddr(threeAddrNode * the_3addr,
00170                                                Order ord) {
00171   if ( ord == Preorder ) {
00172     _new_body->stmts().push_back(the_3addr);
00173     _last_stmt = the_3addr;
00174   }
00175   return the_3addr;
00176 }
00177 
00178 // This also captures conditiongotoNodes.
00179 Node * FlattenDismantle::at_goto(gotoNode * the_goto, Order ord) {
00180   if ( ord == Preorder ) {
00181     // the second unconditional goto is unreachable, so remove it here
00182     if ( ! (_last_stmt && _last_stmt->typ() == Goto) ) {
00183       _new_body->stmts().push_back(the_goto);
00184       _last_stmt = the_goto;
00185     }
00186   }
00187   return the_goto;
00188 }
00189 
00190 Node * FlattenDismantle::at_return(returnNode * the_return, 
00191                                             Order ord) {
00192   if ( ord == Preorder ) {
00193     _new_body->stmts().push_back(the_return);
00194     _last_stmt = the_return;
00195   }
00196   return the_return;
00197 }
00198 
00199 Node * FlattenDismantle::at_exprstmt(exprstmtNode * the_exprstmt,
00200                                               Order ord) {
00201   if ( ord == Preorder ) {
00202     if ( the_exprstmt->expr() ) {
00203       _new_body->stmts().push_back(the_exprstmt);
00204       _last_stmt = the_exprstmt;
00205     }
00206   }
00207   return the_exprstmt;
00208 }

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