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  

whilenode.cc

Go to the documentation of this file.
00001 // $Id: whilenode.cc,v 1.3 2003/08/07 23:13:16 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 
00040 // --------------------------------------------------------------------
00041 // Constructors
00042 // --------------------------------------------------------------------
00043 
00044 whileNode::whileNode(exprNode * cond, stmtNode * body, const Coord coord)
00045   : loopNode(While, cond, body, coord)
00046 {}
00047 
00048 // ------------------------------------------------------------
00049 //  Walker
00050 // ------------------------------------------------------------
00051 
00052 void whileNode::visit(Visitor * the_visitor) 
00053 {
00054   the_visitor->at_while(this);
00055 }
00056 
00057 void whileNode::walk(Walker & the_walker)
00058 {
00059   Walker::Order ord = the_walker.order(); 
00060 
00061   if (ord == Walker::Preorder || ord == Walker::Both)
00062     the_walker.at_while(this, Walker::Preorder);
00063 
00064   if (the_walker.depth() == Walker::Subtree) {
00065     // -- Visit the children 
00066 
00067     if (cond())
00068       cond()->walk(the_walker);
00069 
00070     if (body())
00071       body()->walk(the_walker);
00072  }
00073 
00074   if (ord == Walker::Postorder || ord == Walker::Both)
00075     the_walker.at_while(this, Walker::Postorder);
00076 }
00077 
00078 // ------------------------------------------------------------
00079 //  Dataflow
00080 // ------------------------------------------------------------
00081 
00082 void whileNode::dataflow(FlowVal * v, FlowProblem & fp)
00083 {
00084   if (fp.forward()) {
00085     fp.flow_while(v, this, FlowProblem::Entry);
00086 
00087     // -- Get the values from the previous loop iteration
00088 
00089     v->meet(at_loop_head());
00090 
00091     if (cond())
00092       if (fp.basicblocks()) {
00093         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00094         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00095       }
00096       else
00097         cond()->dataflow(v, fp);
00098     
00099     // -- Dataflow the loop body (collect break values in at_exit and
00100     // continue values in at_loop_tail)
00101 
00102     FlowVal * bv = v->clone();
00103 
00104     if (body())
00105       body()->dataflow(bv, fp);
00106 
00107     // -- Get the collected continue values
00108 
00109     bv->meet(at_loop_tail());
00110 
00111     // -- Transfer values at the end of the loop to the loop head
00112 
00113     at_loop_head()->meet_and_diff(bv, fp);
00114     delete bv;
00115 
00116     // -- If there is no condition, then flow cannot go directly from
00117     // the cond to the exit.
00118 
00119     if (! cond())
00120       v->to_top();
00121 
00122     // -- Get the collected break values
00123 
00124     v->meet(at_exit());
00125 
00126     fp.flow_while(v, this, FlowProblem::Exit);
00127   }
00128   else {
00129     fp.flow_while(v, this, FlowProblem::Exit);
00130 
00131     // -- at_exit holds the values need by breaks
00132 
00133     at_exit()->meet_and_diff(v, fp);
00134 
00135     // -- Transfer values at loop head to the loop end
00136 
00137     at_loop_tail()->meet_and_diff(at_loop_head(), fp);
00138 
00139     // -- Dataflow the body (breaks and continues read values from
00140     // at_exit and at_loop_end, respectively).
00141 
00142     FlowVal * bv = at_loop_tail()->clone();
00143 
00144     if (body())
00145       body()->dataflow(bv, fp);
00146 
00147     // -- If there is no condition, then flow cannot go directly from
00148     // the cond to the exit.
00149 
00150     if (! cond())
00151       v->to_top();
00152 
00153     // -- Merge in the loop body values
00154 
00155     v->meet(bv);
00156     delete bv;
00157 
00158     if (cond())
00159       if (fp.basicblocks()) {
00160         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00161         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00162       }
00163       else
00164         cond()->dataflow(v, fp);
00165 
00166     // -- Save the values for the next loop iteration
00167 
00168     at_loop_head()->meet_and_diff(v, fp);
00169 
00170     fp.flow_while(v, this, FlowProblem::Entry);
00171   }
00172 }
00173 
00174 // ------------------------------------------------------------
00175 // Output
00176 // ------------------------------------------------------------
00177 
00178 void whileNode::output_stmt(output_context & ct, Node * parent)
00179 {
00180   ct << "while " << '(';
00181 
00182   if (cond())
00183     cond()->output(ct, this);
00184 
00185   ct << ')';
00186   ct.space();
00187 
00188   if (body())
00189     body()->output(ct, this);
00190   else
00191     ct << ';';
00192 }
00193 
00194 // ------------------------------------------------------------
00195 //  Changer
00196 // ------------------------------------------------------------
00197 
00198 Node * whileNode::change(Changer & the_changer, bool redispatch)
00199 {
00200   Changer::Order ord = the_changer.order(); 
00201   whileNode * the_while = this;
00202 
00203   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00204     the_while = (whileNode *) the_changer.at_while(the_while, Changer::Preorder);
00205 
00206   if (the_while) {
00207 
00208     if (the_while != this)
00209       return the_while->change(the_changer, true);
00210 
00211     exprNode * old_cond = the_while->cond();
00212     if (old_cond) {
00213       exprNode * new_cond = (exprNode *) old_cond->change(the_changer);
00214       if (old_cond != new_cond) {
00215         //if (the_changer.delete_old())
00216           //delete old_cond;
00217         the_while->cond(new_cond);
00218       }
00219     }
00220 
00221     blockNode * old_body = the_while->body();
00222     if (old_body) {
00223       blockNode * new_body = (blockNode *) old_body->change(the_changer);
00224       if (old_body != new_body) {
00225         //if (the_changer.delete_old())
00226           //delete old_body;
00227         the_while->body(new_body);
00228       }
00229     }
00230 
00231   }
00232 
00233   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00234     the_while = (whileNode *) the_changer.at_while(the_while, Changer::Postorder);
00235 
00236   return the_while;
00237 }
00238 
00239 
00240 // ------------------------------------------------------------
00241 // Destructor
00242 // ------------------------------------------------------------
00243 
00244 whileNode::~whileNode()
00245 {
00246 }

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