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