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  

fornode.cc

Go to the documentation of this file.
00001 // $Id: fornode.cc,v 1.3 2003/08/07 23:13:04 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 forNode::forNode(exprNode * init, exprNode * cond, exprNode * next,
00045                  stmtNode * body, const Coord coord)
00046   : loopNode(For, cond, body, coord),
00047     _init(init),
00048     _next(next)
00049 {}
00050 
00051 // ------------------------------------------------------------
00052 //  Walker
00053 // ------------------------------------------------------------
00054 
00055 void forNode::visit(Visitor * the_visitor) 
00056 {
00057   the_visitor->at_for(this);
00058 }
00059 
00060 void forNode::walk(Walker & the_walker)
00061 {
00062   Walker::Order ord = the_walker.order(); 
00063 
00064   if (ord == Walker::Preorder || ord == Walker::Both)
00065     the_walker.at_for(this, Walker::Preorder);
00066 
00067   if (the_walker.depth() == Walker::Subtree) {
00068     // -- Visit the children 
00069 
00070     if (init())
00071       init()->walk(the_walker);
00072 
00073     if (cond())
00074       cond()->walk(the_walker);
00075 
00076     if (next())
00077       next()->walk(the_walker);
00078 
00079     if (body())
00080       body()->walk(the_walker);
00081   }
00082 
00083   if (ord == Walker::Postorder || ord == Walker::Both)
00084     the_walker.at_for(this, Walker::Postorder);
00085 }
00086 
00087 // ------------------------------------------------------------
00088 // Dataflow
00089 // ------------------------------------------------------------
00090 
00091 void forNode::dataflow(FlowVal * v, FlowProblem & fp)
00092 {
00093   if (fp.forward()) {
00094     fp.flow_for(v, this, FlowProblem::Entry);
00095 
00096     if (init())
00097       if (fp.basicblocks()) {
00098         fp.flow_basicblock(v, init(), FlowProblem::Entry);
00099         fp.flow_basicblock(v, init(), FlowProblem::Exit);
00100       }
00101       else
00102         init()->dataflow(v, fp);
00103     
00104     // -- Get the values from the previous loop iteration
00105 
00106     v->meet(at_loop_head());
00107 
00108     if (cond())
00109       if (fp.basicblocks()) {
00110         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00111         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00112       }
00113       else
00114         cond()->dataflow(v, fp);
00115     
00116     // -- Dataflow the loop body (collect break values in at_exit and
00117     // continue values in at_loop_tail)
00118 
00119     FlowVal * bv = v->clone();
00120 
00121     if (body())
00122       body()->dataflow(bv, fp);
00123 
00124     // -- Get the collected continue values
00125 
00126     bv->meet(at_loop_tail());
00127 
00128     if (next())
00129       if (fp.basicblocks()) {
00130         fp.flow_basicblock(v, next(), FlowProblem::Entry);
00131         fp.flow_basicblock(v, next(), FlowProblem::Exit);
00132       }
00133       else
00134         next()->dataflow(v, fp);
00135     
00136     // -- Transfer values at the end of the loop to the loop head
00137 
00138     at_loop_head()->meet_and_diff(bv, fp);
00139     delete bv;
00140 
00141     // -- If there is no condition, then flow cannot go directly from
00142     // the cond to the exit.
00143 
00144     if (! cond())
00145       v->to_top();
00146 
00147     // -- Get the collected break values
00148 
00149     v->meet(at_exit());
00150 
00151     fp.flow_for(v, this, FlowProblem::Exit);
00152   }
00153   else {
00154     fp.flow_for(v, this, FlowProblem::Exit);
00155 
00156     // -- at_exit holds the values need by breaks
00157 
00158     at_exit()->meet_and_diff(v, fp);
00159 
00160     // -- Dataflow the loop
00161 
00162     FlowVal * bv = at_loop_head()->clone();
00163 
00164     if (next())
00165       if (fp.basicblocks()) {
00166         fp.flow_basicblock(v, next(), FlowProblem::Exit);
00167         fp.flow_basicblock(v, next(), FlowProblem::Entry);
00168       }
00169       else
00170         next()->dataflow(v, fp);
00171 
00172     // -- Save the loop_tail values needed by continue and break
00173 
00174     at_loop_tail()->meet_and_diff(bv, fp);
00175 
00176     // -- Dataflow the body (breaks and continues read values from
00177     // at_exit and at_loop_end, respectively).
00178 
00179     if (body())
00180       body()->dataflow(bv, fp);
00181 
00182     // -- If there is no condition, then flow cannot go directly from
00183     // the cond to the exit.
00184 
00185     if (! cond())
00186       v->to_top();
00187 
00188     // -- Merge in the loop body values
00189 
00190     v->meet(bv);
00191     delete bv;
00192 
00193     if (cond())
00194       if (fp.basicblocks()) {
00195         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00196         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00197       }
00198       else
00199         cond()->dataflow(v, fp);
00200 
00201     // -- Save the values for the next loop iteration
00202 
00203     at_loop_head()->meet_and_diff(v, fp);
00204 
00205     if (init())
00206       if (fp.basicblocks()) {
00207         fp.flow_basicblock(v, init(), FlowProblem::Exit);
00208         fp.flow_basicblock(v, init(), FlowProblem::Entry);
00209       }
00210       else
00211         init()->dataflow(v, fp);
00212 
00213     fp.flow_for(v, this, FlowProblem::Entry);
00214   }
00215 }
00216 
00217 // ------------------------------------------------------------
00218 // Output
00219 // ------------------------------------------------------------
00220 
00221 void forNode::output_stmt(output_context & ct, Node * parent)
00222 {
00223   ct << "for " << '(';
00224 
00225   if (init())
00226     init()->output(ct, this);
00227 
00228   ct.space();
00229   ct << ';';
00230   ct.space();
00231 
00232   if (cond())
00233     cond()->output(ct, this);
00234 
00235   ct.space();
00236   ct << ';';
00237   ct.space();
00238 
00239   if (next())
00240     next()->output(ct, this);
00241 
00242   ct.space();
00243   ct << ')';
00244   ct.space();
00245 
00246   if (body())
00247     body()->output(ct, this);
00248   else
00249     ct << ';';
00250 }
00251 
00252 // ------------------------------------------------------------
00253 //  Changer
00254 // ------------------------------------------------------------
00255 
00256 Node * forNode::change(Changer & the_changer, bool redispatch)
00257 {
00258   Changer::Order ord = the_changer.order(); 
00259   forNode * the_for = this;
00260 
00261   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00262     the_for = (forNode *) the_changer.at_for(the_for, Changer::Preorder);
00263 
00264   if (the_for) {
00265 
00266     if (the_for != this)
00267       return the_for->change(the_changer, true);
00268 
00269     exprNode * old_init = the_for->init();
00270     if (old_init) {
00271       exprNode * new_init = (exprNode *) old_init->change(the_changer);
00272       if (old_init != new_init) {
00273         //if (the_changer.delete_old())
00274           //delete old_init;
00275         the_for->init(new_init);
00276       }
00277     }
00278 
00279     exprNode * old_cond = the_for->cond();
00280     if (old_cond) {
00281       exprNode * new_cond = (exprNode *) old_cond->change(the_changer);
00282       if (old_cond != new_cond) {
00283         //if (the_changer.delete_old())
00284           //delete old_cond;
00285         the_for->cond(new_cond);
00286       }
00287     }
00288 
00289     exprNode * old_next = the_for->next();
00290     if (old_next) {
00291       exprNode * new_next = (exprNode *) old_next->change(the_changer);
00292       if (old_next != new_next) {
00293         //if (the_changer.delete_old())
00294           //delete old_next;
00295         the_for->next(new_next);
00296       }
00297     }
00298 
00299     blockNode * old_body = the_for->body();
00300     if (old_body) {
00301       blockNode * new_body = (blockNode *) old_body->change(the_changer);
00302       if (old_body != new_body) {
00303         //if (the_changer.delete_old())
00304           //delete old_body;
00305         the_for->body(new_body);
00306       }
00307     }
00308 
00309   }
00310 
00311   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00312     the_for = (forNode *) the_changer.at_for(the_for, Changer::Postorder);
00313 
00314   return the_for;
00315 }
00316 
00317 
00318 // ------------------------------------------------------------
00319 // Destructor
00320 // ------------------------------------------------------------
00321 
00322 forNode::~forNode()
00323 {
00324   //delete _init;
00325   //delete _next;
00326 }

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