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 whileNode::whileNode(exprNode * cond, stmtNode * body, const Coord coord)
00045 : loopNode(While, cond, body, coord)
00046 {}
00047
00048
00049
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
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
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
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
00100
00101
00102 FlowVal * bv = v->clone();
00103
00104 if (body())
00105 body()->dataflow(bv, fp);
00106
00107
00108
00109 bv->meet(at_loop_tail());
00110
00111
00112
00113 at_loop_head()->meet_and_diff(bv, fp);
00114 delete bv;
00115
00116
00117
00118
00119 if (! cond())
00120 v->to_top();
00121
00122
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
00132
00133 at_exit()->meet_and_diff(v, fp);
00134
00135
00136
00137 at_loop_tail()->meet_and_diff(at_loop_head(), fp);
00138
00139
00140
00141
00142 FlowVal * bv = at_loop_tail()->clone();
00143
00144 if (body())
00145 body()->dataflow(bv, fp);
00146
00147
00148
00149
00150 if (! cond())
00151 v->to_top();
00152
00153
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
00167
00168 at_loop_head()->meet_and_diff(v, fp);
00169
00170 fp.flow_while(v, this, FlowProblem::Entry);
00171 }
00172 }
00173
00174
00175
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
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
00216
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
00226
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
00242
00243
00244 whileNode::~whileNode()
00245 {
00246 }