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 
00040 
00041 
00042 
00043 
00044 doNode::doNode(stmtNode * body, exprNode * cond, const Coord coord,
00045                const Coord while_coord)
00046   : loopNode(Do, cond, body, coord),
00047     _while_coord(while_coord)
00048 {}
00049 
00050 
00051 
00052 
00053 
00054 void doNode::visit(Visitor * the_visitor) 
00055 {
00056   the_visitor->at_do(this);
00057 }
00058 
00059 void doNode::walk(Walker & the_walker)
00060 {
00061   Walker::Order ord = the_walker.order(); 
00062 
00063   if (ord == Walker::Preorder || ord == Walker::Both)
00064     the_walker.at_do(this, Walker::Preorder);
00065 
00066   if (the_walker.depth() == Walker::Subtree) {
00067     
00068 
00069     if (body())
00070       body()->walk(the_walker);
00071 
00072     if (cond())
00073       cond()->walk(the_walker);
00074   }
00075 
00076   if (ord == Walker::Postorder || ord == Walker::Both)
00077     the_walker.at_do(this, Walker::Postorder);
00078 }
00079 
00080 
00081 
00082 
00083 
00084 void doNode::dataflow(FlowVal * v, FlowProblem & fp)
00085 {
00086   if (fp.forward()) {
00087     fp.flow_do(v, this, FlowProblem::Entry);
00088 
00089     
00090 
00091     v->meet(at_loop_head());
00092 
00093     
00094     
00095 
00096     if (body())
00097       body()->dataflow(v, fp);
00098 
00099     
00100 
00101     v->meet(at_loop_tail());
00102 
00103     if (cond())
00104       if (fp.basicblocks()) {
00105         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00106         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00107       }
00108       else
00109         cond()->dataflow(v, fp);
00110     
00111     
00112 
00113     at_loop_head()->meet_and_diff(v, fp);
00114 
00115     
00116     
00117 
00118     if (! cond())
00119       v->to_top();
00120 
00121     
00122 
00123     v->meet(at_exit());
00124 
00125     fp.flow_do(v, this, FlowProblem::Exit);
00126   }
00127   else {
00128     fp.flow_do(v, this, FlowProblem::Exit);
00129 
00130     
00131 
00132     at_exit()->meet_and_diff(v, fp);
00133 
00134     
00135 
00136     at_loop_tail()->meet_and_diff(at_loop_head(), fp);
00137 
00138     
00139     
00140 
00141     if (! cond())
00142       v->to_top();
00143 
00144     
00145 
00146     v->meet(at_loop_tail());
00147 
00148     if (cond())
00149       if (fp.basicblocks()) {
00150         fp.flow_basicblock(v, cond(), FlowProblem::Exit);
00151         fp.flow_basicblock(v, cond(), FlowProblem::Entry);
00152       }
00153       else
00154         cond()->dataflow(v, fp);
00155 
00156     
00157     
00158 
00159     if (body())
00160       body()->dataflow(v, fp);
00161 
00162     
00163 
00164     at_loop_head()->meet_and_diff(v, fp);
00165 
00166     fp.flow_do(v, this, FlowProblem::Entry);
00167   }
00168 }
00169 
00170 
00171 
00172 
00173 
00174 void doNode::output_stmt(output_context & ct, Node * parent)
00175 {
00176   ct << "do";
00177   ct.space();
00178 
00179   if (body())
00180     body()->output(ct, this);
00181   else
00182     ct << ';';
00183 
00184   ct.space();
00185   ct << "while " << '(' ;
00186 
00187   if (cond())
00188     cond()->output(ct, this);
00189 
00190   ct << ')' << ';' ;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 Node * doNode::change(Changer & the_changer, bool redispatch)
00198 {
00199   Changer::Order ord = the_changer.order(); 
00200   doNode * the_do = this;
00201 
00202   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00203     the_do = (doNode *) the_changer.at_do(the_do, Changer::Preorder);
00204 
00205   if (the_do) {
00206 
00207     if (the_do != this)
00208       return the_do->change(the_changer, true);
00209 
00210     blockNode * old_body = the_do->body();
00211     if (old_body) {
00212       blockNode * new_body = (blockNode *) old_body->change(the_changer);
00213       if (old_body != new_body) {
00214         
00215           
00216         the_do->body(new_body);
00217       }
00218     }
00219 
00220     exprNode * old_cond = the_do->cond();
00221     if (old_cond) {
00222       exprNode * new_cond = (exprNode *) old_cond->change(the_changer);
00223       if (old_cond != new_cond) {
00224         
00225           
00226         the_do->cond(new_cond);
00227       }
00228     }
00229 
00230   }
00231 
00232   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00233     the_do = (doNode *) the_changer.at_do(the_do, Changer::Postorder);
00234 
00235   return the_do;
00236 }
00237 
00238 
00239 
00240 
00241 
00242 
00243 doNode::~doNode()
00244 {
00245 }