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
00039
00040
00041
00042 #include "c_breeze.h"
00043
00044 #include "bits.h"
00045 #include "reaching.h"
00046 #include "constprop.h"
00047 #include "dismantle.h"
00048
00051 exprNode *constantPropChanger::at_expr (exprNode *e) {
00052
00053
00054
00055
00056
00057 if(!e) return NULL;
00058 idNode *id;
00059 if(e->typ() == Operand) {
00060 operandNode *o = (operandNode*) e;
00061 if(o->addr()) return e;
00062 if(o->index()) {
00063 indexNode *index = (indexNode*) at_expr(o->index());
00064 if(index != o->index()) o->index(index);
00065
00066 indexNode *A = (indexNode*) at_expr(o->var());
00067 if(A != o->var()) {
00068 assert(A->typ() == Const && ((constNode*)A)->value().is_str());
00069 o->var(A);
00070 }
00071 return e;
00072 }
00073 if(! o->fields().empty()) return e;
00074 if(o->var()->typ() != Id) return e;
00075 id = (idNode*) o->var();
00076 } else if(e->typ() == Id)
00077 id = (idNode*) e;
00078 else return e;
00079
00080 NodeType typ = e->typ();
00081 constant value;
00082
00083
00084
00085 threeAddr_list defs = _udchain->defs(e);
00086
00087
00088
00089 if (defs.size() == 0) return e;
00090
00091
00092
00093 for (threeAddr_list::iterator d=defs.begin(); d!=defs.end(); d++) {
00094
00095 threeAddrNode *s = *d;
00096
00097 if (!s) return e;
00098
00099 assert (s->lhs());
00100
00101
00102 operandNode *lhs = s->lhs();
00103 if(lhs->star() || lhs->index() || ! lhs->fields().empty()) return e;
00104 if(lhs->var()->typ() != Id) return e;
00105 idNode *lhs_id = (idNode *) lhs->var();
00106 if (lhs_id->decl() != id->decl()) return e;
00107
00108 if(!s->rhs1() || s->rhs2()) return e;
00109
00110
00111 operandNode *rhs = s->rhs1();
00112 if(rhs->addr() || rhs->star() || !rhs->fields().empty() ||
00113 rhs->index()) return e;
00114 constant rhs_value;
00115 if(rhs->var()->typ() == Const) rhs_value = rhs->var()->value();
00116 else return e;
00117
00118 if(rhs->cast()) {
00119 if(rhs_value.is_zero() && rhs->cast()->typ() == Ptr) ;
00120 else {
00121 assert(rhs->cast()->typ() == Prim);
00122 rhs_value= constant::cast(((primNode*)rhs->cast())->basic(), rhs_value);
00123 }
00124 }
00125
00126
00127 if(s->op()) {
00128 int opid = s->op()->id();
00129 if(opid == Operator::UPLUS) ;
00130 else if(opid == Operator::UMINUS)
00131 rhs_value = constant::eval(s->op(), rhs_value);
00132 else return e;
00133 }
00134
00135 if ( d==defs.begin() ) {
00136 value = rhs_value;
00137 } else if (! value.is_equal_to (rhs_value))
00138 return e;
00139 }
00140
00141
00142
00143 _changed = true;
00144 if(typ == Id) return new constNode (value);
00145 return new operandNode(new constNode(value));
00146 }
00147
00148
00150 Node *constantPropChanger::at_threeAddr (threeAddrNode *t, Order) {
00151 if(t->rhs1()) {
00152 operandNode *v = (operandNode*) at_expr(t->rhs1());
00153 if(v != t->rhs1()) {
00154 v->cast( t->rhs1()->cast() );
00155 t->rhs1(v);
00156 }
00157 }
00158 if(t->rhs2()) {
00159 operandNode *v = (operandNode*) at_expr(t->rhs2());
00160 if(v != t->rhs2()) {
00161 v->cast( t->rhs2()->cast() );
00162 t->rhs2(v);
00163 }
00164 }
00165 if(t->lhs() && t->lhs()->index()) {
00166 indexNode *v = (indexNode*) at_expr(t->lhs()->index());
00167 if(v != t->lhs()->index()) t->lhs()->index(v);
00168 }
00169
00170 for(operand_list_p o=t->arg_list().begin(); o!=t->arg_list().end(); o++) {
00171 operandNode *v = (operandNode*) at_expr(*o);
00172 if(v != *o) {
00173 v->cast( (*o)->cast() );
00174 *o = v;
00175 }
00176 }
00177 return t;
00178 }
00179
00180
00182 Node *constantPropChanger::at_conditiongoto (conditiongotoNode *c, Order) {
00183 assert(c->left());
00184 exprNode *v = at_expr(c->left());
00185 if(v != c->left()) {
00186 assert(v->typ()==Id || v->typ()==Const);
00187 c->left((indexNode*) v);
00188 }
00189
00190 assert(c->right());
00191 v = at_expr(c->right());
00192 if(v != c->right()) {
00193 assert(v->typ()==Id || v->typ()==Const);
00194 c->right((indexNode*) v);
00195 }
00196 return c;
00197 }
00198
00200 Node *constantPropChanger::at_return (returnNode *r, Order) {
00201
00202
00203
00204 exprNode *v = at_expr(r->expr());
00205 if(v != r->expr()) r->expr(v);
00206 return r;
00207 }
00208
00210
00212 Node * constantFoldingChanger::at_threeAddr (threeAddrNode *t, Order ord) {
00213 if(!t->rhs1() || !t->op()) return t;
00214
00215 constNode *c1 = NULL, *c2 = NULL;
00216
00217 operandNode *o = t->rhs1();
00218 if(o->var()->typ() == Const && !o->star() && !o->addr() &&
00219 o->fields().empty() && !o->index())
00220 c1 = (constNode*) o->var();
00221
00222 o = t->rhs2();
00223 if(o && o->var()->typ() == Const && !o->star() && !o->addr() &&
00224 o->fields().empty() && !o->index())
00225 c2 = (constNode*) o->var();
00226
00227 if(c1 && !t->rhs2()) {
00228 switch(t->op()->id()) {
00229 case Operator::UMINUS:
00230 case '!':
00231
00232 t->rhs1()->var(new constNode(constant::eval(t->op(), c1->value())));
00233
00234 case Operator::UPLUS: t->op(NULL);
00235 }
00236 return t;
00237 }
00238
00239
00240
00241 if(!c1 && !c2) return t;
00242
00243
00244 switch (t->op()->id()) {
00245 case '*': case '/': case '%': case '+': case '-':
00246 case Operator::LS: case Operator::RS: case Operator::LE: case Operator::GE:
00247 case '<': case '>': case Operator::EQ: case Operator::NE:
00248
00249
00250 break;
00251 default:
00252 return t;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 if(c1 && c2) {
00265
00266 constant oper1 = c1->value();
00267 constant oper2 = c2->value();
00268
00269 #define cast_constant(cast_type, oper) \
00270 if(cast_type) { \
00271 assert(cast_type->typ() == Prim); \
00272 oper = constant::cast(((primNode*)cast_type)->basic(), oper); \
00273 }
00274 cast_constant(t->rhs1()->cast(), oper1)
00275 cast_constant(t->rhs2()->cast(), oper2)
00276
00277 if (oper1.basic() == oper2.basic()) {
00278 constant c = constant::eval (t->op(), oper1, oper2);
00279 if (c.no_val() == false) {
00280 _changed = true;
00281 t->rhs1()->var( new constNode (c) );
00282 if(t->rhs1()->cast() &&
00283 !(((primNode*)t->rhs1()->cast())->basic() == oper1.basic()))
00284 t->rhs1()->cast( new primNode(typeNode::NONE, oper1.basic()));
00285
00286 t->rhs2( NULL );
00287 t->op(NULL);
00288 }
00289 }
00290
00291 } else if(t->op()->id()=='+' || t->op()->id()=='-') {
00292 constNode *c = c1 ? c1 : c2;
00293 if(c->value().is_zero()) {
00294 if(c==c1)
00295 t->rhs1(t->rhs2());
00296 t->rhs2(NULL);
00297 if(t->op()->id()=='-' && c==c1)
00298 t->op( Operators::table[Operator::UMINUS] );
00299 else t->op( NULL );
00300 }
00301
00302 } else if(t->op()->id()=='*' || t->op()->id()=='/') {
00303 constNode *c = c1 ? c1 : c2;
00304 constant v = c->value();
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 if(v.Integer() == 1
00319
00320 ) {
00321 if(t->op()->id()=='/' && c==c1) ;
00322 else {
00323 if(c==c1)
00324 t->rhs1(t->rhs2());
00325 t->rhs2(NULL);
00326 t->op(NULL);
00327 }
00328 }
00329 }
00330
00331 return t;
00332 }
00333
00334
00335 Node * constantFoldingChanger::at_basicblock(basicblockNode *the_bb,
00336 Order ord) {
00337 return _current_block = the_bb;
00338 }
00339
00340
00341 Node * constantFoldingChanger::at_conditiongoto(conditiongotoNode *the_cg,
00342 Order ord) {
00343 bool is_constant = false;
00344 bool which_branch;
00345
00346
00347
00348
00349
00350 assert(the_cg->op());
00351 assert(the_cg->left());
00352 assert(the_cg->right());
00353
00354
00355 indexNode * left = the_cg->left();
00356 indexNode * right = the_cg->right();
00357
00358
00359 if(left->typ()==Const && right->typ() == Const) {
00360 constNode * l = (constNode *)left;
00361 constNode * r = (constNode *)right;
00362 constant lhs = l->value();
00363 constant rhs = r->value();
00364
00365
00366 constant result = constant::eval(the_cg->op(), lhs, rhs);
00367 if(! result.no_val()) {
00368 is_constant = true;
00369 which_branch = result.Boolean();
00370 }
00371 }
00372
00373
00374
00375 if (is_constant) {
00376 _changed = _cfg_changed = true;
00377
00378
00379
00380 #define label_of_block(B) \
00381 ((B && !(B)->stmts().empty() && (B)->stmts().front()->typ() == Label) ? \
00382 (labelNode*) (B)->stmts().front() : NULL)
00383
00384 #define erase_succ_pred(pred, succ) { \
00385 (pred)->succs().remove(succ); \
00386 (succ)->preds().remove(pred); \
00387
00388 \
00389 labelNode *l_succ = label_of_block(succ), \
00390 *l_pred = label_of_block(pred); \
00391 (pred)->comment() += " remove # "; \
00392 if(l_succ) (pred)->comment() += l_succ->name(); \
00393 (succ)->comment() += " remove # "; \
00394 if(l_pred) (succ)->comment() += l_pred->name(); \
00395 }
00396
00397 basicblock_list succs = _current_block->succs();
00398
00399 if(which_branch) {
00400 for(basicblock_list_p s=succs.begin(); s!=succs.end(); s++) {
00401 labelNode *label = label_of_block(*s);
00402 if(label != the_cg->label())
00403 erase_succ_pred (_current_block, *s)
00404 }
00405 return new gotoNode (the_cg->label());
00406 } else {
00407 for(basicblock_list_p s=succs.begin(); s!=succs.end(); s++) {
00408 labelNode *label = label_of_block(*s);
00409 if(label == the_cg->label()) {
00410 erase_succ_pred (_current_block, *s)
00411 break;
00412 }
00413 }
00414 return NULL;
00415 }
00416 }
00417
00418 return the_cg;
00419 }
00420
00421
00423
00424 void constantPropChanger::change() {
00425 for (unit_list_p n=CBZ::Program.begin(); n!=CBZ::Program.end(); n++)
00426 change(*n);
00427 }
00428
00429
00430 void constantPropChanger::change(unitNode *u) {
00431 if(!u) return;
00432 for(def_list_p d=u->defs().begin(); d!=u->defs().end(); d++)
00433 if((*d)->typ() == Proc) change((procNode*) *d);
00434 }
00435
00436 void constantPropChanger::change(procNode *p) {
00437 if(!p) return;
00438 udduChains *udchain = reachingDefinitionsWalker::analyze(p);
00439 constantPropChanger cpc(udchain);
00440 constantFoldingChanger cfc;
00441
00442 bool first_time = true;
00443 do {
00444 cpc.reset();
00445 p->change (cpc);
00446 if(! cpc._changed && !first_time)
00447 break;
00448 first_time = false;
00449
00450 cfc.reset();
00451 p->change (cfc);
00452 if(! cfc._changed) break;
00453 if(cfc._cfg_changed) {
00454 delete udchain;
00455 udchain = reachingDefinitionsWalker::analyze(p);
00456 cpc._udchain = udchain;
00457 }
00458 } while(true);
00459
00460 delete udchain;
00461 }
00462
00464
00465 void constantFoldingChanger::change() {
00466 for (unit_list_p n=CBZ::Program.begin(); n!=CBZ::Program.end(); n++)
00467 change(*n);
00468 }
00469
00470 void constantFoldingChanger::change(unitNode *u) {
00471 if(!u) return;
00472 for(def_list_p d=u->defs().begin(); d!=u->defs().end(); d++)
00473 if((*d)->typ() == Proc) change((procNode*) *d);
00474 }
00475
00476 void constantFoldingChanger::change(procNode *p) {
00477 if(!p) return;
00478 constantFoldingChanger cfc;
00479 p->change (cfc);
00480 }
00481
00483
00484 class constpropphase : public Phase {
00485 void run() {
00486 constantPropChanger::change();
00487 }
00488 };
00489 Phases constprop_phase("constprop", new constpropphase());
00490