00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <assert.h>
00014 #if defined(_MSC_VER) && _MSC_VER <= 1200
00015 #pragma warning(disable:4786)
00016 #endif
00017 #if defined(_MSC_VER) && _MSC_VER >= 1400
00018 #pragma warning(disable:4996) // Warnings about e.g. _strdup deprecated in VS 2005
00019 #endif
00020
00021 #include <numeric>
00022 #include <algorithm>
00023 #include <map>
00024 #include <sstream>
00025 #include "types.h"
00026 #include "statement.h"
00027 #include "cfg.h"
00028 #include "exp.h"
00029 #include "register.h"
00030 #include "rtl.h"
00031 #include "proc.h"
00032 #include "signature.h"
00033 #include "prog.h"
00034 #include "operstrings.h"
00035 #include "util.h"
00036 #include "boomerang.h"
00037
00038 #include "visitor.h"
00039 #include "log.h"
00040 #include <iomanip>
00041
00042 extern char debug_buffer[];
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 Const::Const(int i) : Exp(opIntConst), conscript(0), type(new VoidType) {u.i = i;}
00054 Const::Const(QWord ll) : Exp(opLongConst), conscript(0), type(new VoidType) {u.ll= ll;}
00055 Const::Const(double d) : Exp(opFltConst), conscript(0), type(new VoidType) {u.d = d;}
00056 Const::Const(char* p) : Exp(opStrConst), conscript(0), type(new VoidType) {u.p = p;}
00057 Const::Const(Proc* p) : Exp(opFuncConst), conscript(0), type(new VoidType) {u.pp = p;}
00058
00059 Const::Const(ADDRESS a) : Exp(opIntConst), conscript(0), type(new VoidType) {u.a = a;}
00060
00061
00062 Const::Const(Const& o) : Exp(o.op) {u = o.u; conscript = o.conscript; type = o.type;}
00063
00064 Terminal::Terminal(OPER op) : Exp(op) {}
00065 Terminal::Terminal(Terminal& o) : Exp(o.op) {}
00066
00067 Unary::Unary(OPER op)
00068 : Exp(op) {
00069 subExp1 = 0;
00070
00071 }
00072
00073 Unary::Unary(OPER op, Exp* e)
00074 : Exp(op) {
00075 subExp1 = e;
00076 assert(subExp1);
00077 }
00078 Unary::Unary(Unary& o)
00079 : Exp(o.op) {
00080 subExp1 = o.subExp1->clone();
00081 assert(subExp1);
00082 }
00083
00084 Binary::Binary(OPER op)
00085 : Unary(op) {
00086 subExp2 = 0;
00087 }
00088 Binary::Binary(OPER op, Exp* e1, Exp* e2)
00089 : Unary(op, e1)
00090 {
00091 subExp2 = e2;
00092 assert(subExp1 && subExp2);
00093 }
00094 Binary::Binary(Binary& o)
00095 : Unary(op)
00096 {
00097 setSubExp1( subExp1->clone());
00098 subExp2 = o.subExp2->clone();
00099 assert(subExp1 && subExp2);
00100 }
00101
00102 Ternary::Ternary(OPER op)
00103 : Binary(op)
00104 {
00105 subExp3 = 0;
00106 }
00107 Ternary::Ternary(OPER op, Exp* e1, Exp* e2, Exp* e3)
00108 : Binary(op, e1, e2)
00109 {
00110 subExp3 = e3;
00111 assert(subExp1 && subExp2 && subExp3);
00112 }
00113 Ternary::Ternary(Ternary& o)
00114 : Binary(o.op)
00115 {
00116 subExp1 = o.subExp1->clone();
00117 subExp2 = o.subExp2->clone();
00118 subExp3 = o.subExp3->clone();
00119 assert(subExp1 && subExp2 && subExp3);
00120 }
00121
00122 TypedExp::TypedExp() : Unary(opTypedExp), type(NULL) { }
00123 TypedExp::TypedExp(Exp* e1) : Unary(opTypedExp, e1), type(NULL) { }
00124 TypedExp::TypedExp(Type* ty, Exp* e1) : Unary(opTypedExp, e1), type(ty) { }
00125 TypedExp::TypedExp(TypedExp& o) : Unary(opTypedExp)
00126 {
00127 subExp1 = o.subExp1->clone();
00128 type = o.type->clone();
00129 }
00130
00131 FlagDef::FlagDef(Exp* params, RTL* rtl)
00132 : Unary(opFlagDef, params), rtl(rtl) {}
00133
00134 RefExp::RefExp(Exp* e, Statement* d) : Unary(opSubscript, e), def(d) {
00135 assert(e);
00136 }
00137
00138 TypeVal::TypeVal(Type* ty) : Terminal(opTypeVal), val(ty) { }
00139
00140
00141
00142
00143
00144 Location::Location(OPER op, Exp *exp, UserProc *proc) : Unary(op, exp), proc(proc) {
00145 assert(op == opRegOf || op == opMemOf || op == opLocal || op == opGlobal || op == opParam || op == opTemp);
00146 if (proc == NULL) {
00147
00148 Exp *e = exp;
00149 if (e) {
00150 bool giveUp = false;
00151 while (this->proc == NULL && !giveUp) {
00152 switch(e->getOper()) {
00153 case opRegOf:
00154 case opMemOf:
00155 case opTemp:
00156 case opLocal:
00157 case opGlobal:
00158 case opParam:
00159 this->proc = ((Location*)e)->getProc();
00160 giveUp = true;
00161 break;
00162 case opSubscript:
00163 e = e->getSubExp1();
00164 break;
00165 default:
00166 giveUp = true;
00167 break;
00168 }
00169 }
00170 }
00171 }
00172 }
00173
00174 Location::Location(Location& o) : Unary(o.op, o.subExp1->clone()), proc(o.proc)
00175 {
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 Unary::~Unary() {
00185
00186 if (subExp1 != 0) ;
00187 }
00188 Binary::~Binary() {
00189 if (subExp2 != 0) ;
00190
00191 }
00192 Ternary::~Ternary() {
00193 if (subExp3 != 0) ;
00194 }
00195 FlagDef::~FlagDef() {
00196 ;
00197 }
00198 TypeVal::~TypeVal() {
00199 ;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 void Unary::setSubExp1(Exp* e) {
00210 if (subExp1 != 0) ;
00211 subExp1 = e;
00212 assert(subExp1);
00213 }
00214 void Binary::setSubExp2(Exp* e) {
00215 if (subExp2 != 0) ;
00216 subExp2 = e;
00217 assert(subExp1 && subExp2);
00218 }
00219 void Ternary::setSubExp3(Exp* e) {
00220 if (subExp3 != 0) ;
00221 subExp3 = e;
00222 assert(subExp1 && subExp2 && subExp3);
00223 }
00224
00225
00226
00227
00228
00229
00230 Exp* Unary::getSubExp1() {
00231 assert(subExp1);
00232 return subExp1;
00233 }
00234 Exp*& Unary::refSubExp1() {
00235 assert(subExp1);
00236 return subExp1;
00237 }
00238 Exp* Binary::getSubExp2() {
00239 assert(subExp1 && subExp2);
00240 return subExp2;
00241 }
00242 Exp*& Binary::refSubExp2() {
00243 assert(subExp1 && subExp2);
00244 return subExp2;
00245 }
00246 Exp* Ternary::getSubExp3() {
00247 assert(subExp1 && subExp2 && subExp3);
00248 return subExp3;
00249 }
00250 Exp*& Ternary::refSubExp3() {
00251 assert(subExp1 && subExp2 && subExp3);
00252 return subExp3;
00253 }
00254
00255
00256 Exp* dummy;
00257 Exp*& Exp::refSubExp1() {return dummy;}
00258 Exp*& Exp::refSubExp2() {return dummy;}
00259 Exp*& Exp::refSubExp3() {return dummy;}
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 void Binary::commute() {
00270 Exp* t = subExp1;
00271 subExp1 = subExp2;
00272 subExp2 = t;
00273 assert(subExp1 && subExp2);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 Exp* Const::clone() {
00286
00287 return new Const(*this);
00288 }
00289 Exp* Terminal::clone() {
00290 return new Terminal(*this);
00291 }
00292 Exp* Unary::clone() {
00293 assert(subExp1);
00294 Unary* c = new Unary(op);
00295 c->subExp1 = subExp1->clone();
00296 return c;
00297 }
00298 Exp* Binary::clone() {
00299 assert(subExp1 && subExp2);
00300 Binary* c = new Binary(op);
00301 c->subExp1 = subExp1->clone();
00302 c->subExp2 = subExp2->clone();
00303 return c;
00304 }
00305
00306 Exp* Ternary::clone() {
00307 assert(subExp1 && subExp2 && subExp3);
00308 Ternary* c = new Ternary(op);
00309 c->subExp1 = subExp1->clone();
00310 c->subExp2 = subExp2->clone();
00311 c->subExp3 = subExp3->clone();
00312 return c;
00313 }
00314 Exp* TypedExp::clone() {
00315 TypedExp* c = new TypedExp(type, subExp1->clone());
00316 return c;
00317 }
00318 Exp* RefExp::clone() {
00319 RefExp* c = new RefExp(subExp1->clone(), def);
00320 return c;
00321 }
00322
00323 Exp* TypeVal::clone() {
00324 TypeVal* c = new TypeVal(val->clone());
00325 return c;
00326 }
00327
00328 Exp* Location::clone() {
00329 Location* c = new Location(op, subExp1->clone(), proc);
00330 return c;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340 bool Const::operator==(const Exp& o) const {
00341
00342 if (((Const&)o).op == opWild) return true;
00343 if (((Const&)o).op == opWildIntConst && op == opIntConst) return true;
00344 if (((Const&)o).op == opWildStrConst && op == opStrConst) return true;
00345 if (op != ((Const&)o).op) return false;
00346 if (conscript && conscript != ((Const&)o).conscript || ((Const&)o).conscript)
00347 return false;
00348 switch (op) {
00349 case opIntConst: return u.i == ((Const&)o).u.i;
00350 case opFltConst: return u.d == ((Const&)o).u.d;
00351 case opStrConst: return (strcmp(u.p, ((Const&)o).u.p) == 0);
00352 default: LOG << "Operator== invalid operator " << operStrings[op] << "\n";
00353 assert(0);
00354 }
00355 return false;
00356 }
00357 bool Unary::operator==(const Exp& o) const {
00358 if (((Unary&)o).op == opWild) return true;
00359 if (((Unary&)o).op == opWildRegOf && op == opRegOf) return true;
00360 if (((Unary&)o).op == opWildMemOf && op == opMemOf) return true;
00361 if (((Unary&)o).op == opWildAddrOf && op == opAddrOf) return true;
00362 if (op != ((Unary&)o).op) return false;
00363 return *subExp1 == *((Unary&)o).getSubExp1();
00364 }
00365 bool Binary::operator==(const Exp& o) const {
00366 assert(subExp1 && subExp2);
00367 if (((Binary&)o).op == opWild) return true;
00368 if (op != ((Binary&)o).op) return false;
00369 if (!( *subExp1 == *((Binary&)o).getSubExp1())) return false;
00370 return *subExp2 == *((Binary&)o).getSubExp2();
00371 }
00372
00373 bool Ternary::operator==(const Exp& o) const {
00374 if (((Ternary&)o).op == opWild) return true;
00375 if (op != ((Ternary&)o).op) return false;
00376 if (!( *subExp1 == *((Ternary&)o).getSubExp1())) return false;
00377 if (!( *subExp2 == *((Ternary&)o).getSubExp2())) return false;
00378 return *subExp3 == *((Ternary&)o).getSubExp3();
00379 }
00380 bool Terminal::operator==(const Exp& o) const {
00381 if (op == opWildIntConst) return ((Terminal&)o).op == opIntConst;
00382 if (op == opWildStrConst) return ((Terminal&)o).op == opStrConst;
00383 if (op == opWildMemOf) return ((Terminal&)o).op == opMemOf;
00384 if (op == opWildRegOf) return ((Terminal&)o).op == opRegOf;
00385 if (op == opWildAddrOf) return ((Terminal&)o).op == opAddrOf;
00386 return ((op == opWild) ||
00387 (((Terminal&)o).op == opWild) ||
00388 (op == ((Terminal&)o).op));
00389 }
00390 bool TypedExp::operator==(const Exp& o) const {
00391 if (((TypedExp&)o).op == opWild) return true;
00392 if (((TypedExp&)o).op != opTypedExp) return false;
00393
00394 if (*type != *((TypedExp&)o).type) return false;
00395 return *((Unary*)this)->getSubExp1() == *((Unary&)o).getSubExp1();
00396 }
00397
00398 bool RefExp::operator==(const Exp& o) const {
00399 if (((RefExp&)o).op == opWild) return true;
00400 if (((RefExp&)o).op != opSubscript) return false;
00401 if (!( *subExp1 == *((RefExp&)o).subExp1)) return false;
00402
00403 if ((int)def == -1) return true;
00404
00405 if ((int)((RefExp&)o).def == -1) return true;
00406 if (def == NULL && ((RefExp&)o).isImplicitDef()) return true;
00407 if (((RefExp&)o).def == NULL && def && def->isImplicit()) return true;
00408 return def == ((RefExp&)o).def;
00409 }
00410
00411 bool TypeVal::operator==(const Exp& o) const {
00412 if (((TypeVal&)o).op == opWild) return true;
00413 if (((TypeVal&)o).op != opTypeVal) return false;
00414 return *val == *((TypeVal&)o).val;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 bool Const::operator< (const Exp& o) const {
00426 if (op < o.getOper()) return true;
00427 if (op > o.getOper()) return false;
00428 if (conscript) {
00429 if (conscript < ((Const&)o).conscript) return true;
00430 if (conscript > ((Const&)o).conscript) return false;
00431 } else
00432 if (((Const&)o).conscript) return true;
00433 switch (op) {
00434 case opIntConst:
00435 return u.i < ((Const&)o).u.i;
00436 case opFltConst:
00437 return u.d < ((Const&)o).u.d;
00438 case opStrConst:
00439 return strcmp(u.p, ((Const&)o).u.p) < 0;
00440 default: LOG << "Operator< invalid operator " << operStrings[op] << "\n";
00441 assert(0);
00442 }
00443 return false;
00444 }
00445 bool Terminal::operator< (const Exp& o) const {
00446 return (op < o.getOper());
00447 }
00448
00449 bool Unary::operator< (const Exp& o) const {
00450 if (op < o.getOper()) return true;
00451 if (op > o.getOper()) return false;
00452 return *subExp1 < *((Unary&)o).getSubExp1();
00453 }
00454
00455 bool Binary::operator< (const Exp& o) const {
00456 assert(subExp1 && subExp2);
00457 if (op < o.getOper()) return true;
00458 if (op > o.getOper()) return false;
00459 if (*subExp1 < *((Binary&)o).getSubExp1()) return true;
00460 if (*((Binary&)o).getSubExp1() < *subExp1) return false;
00461 return *subExp2 < *((Binary&)o).getSubExp2();
00462 }
00463
00464 bool Ternary::operator< (const Exp& o) const {
00465 if (op < o.getOper()) return true;
00466 if (op > o.getOper()) return false;
00467 if (*subExp1 < *((Ternary&)o).getSubExp1()) return true;
00468 if (*((Ternary&)o).getSubExp1() < *subExp1) return false;
00469 if (*subExp2 < *((Ternary&)o).getSubExp2()) return true;
00470 if (*((Ternary&)o).getSubExp2() < *subExp2) return false;
00471 return *subExp3 < *((Ternary&)o).getSubExp3();
00472 }
00473
00474 bool TypedExp::operator<< (const Exp& o) const {
00475 if (op < o.getOper()) return true;
00476 if (op > o.getOper()) return false;
00477 return *subExp1 << *((Unary&)o).getSubExp1();
00478 }
00479
00480 bool TypedExp::operator< (const Exp& o) const {
00481 if (op < o.getOper()) return true;
00482 if (op > o.getOper()) return false;
00483 if (*type < *((TypedExp&)o).type) return true;
00484 if (*((TypedExp&)o).type < *type) return false;
00485 return *subExp1 < *((Unary&)o).getSubExp1();
00486 }
00487
00488 bool RefExp::operator< (const Exp& o) const {
00489 if (opSubscript < o.getOper()) return true;
00490 if (opSubscript > o.getOper()) return false;
00491 if (*subExp1 < *((Unary&)o).getSubExp1()) return true;
00492 if (*((Unary&)o).getSubExp1() < *subExp1) return false;
00493
00494 if (def == (Statement*)-1) return false;
00495 if (((RefExp&)o).def == (Statement*)-1) return false;
00496 return def < ((RefExp&)o).def;
00497 }
00498
00499 bool TypeVal::operator< (const Exp& o) const {
00500 if (opTypeVal < o.getOper()) return true;
00501 if (opTypeVal > o.getOper()) return false;
00502 return *val < *((TypeVal&)o).val;
00503 }
00504
00505
00506
00507
00508
00509
00510
00511 bool Const::operator*=(Exp& o) {
00512 Exp* other = &o;
00513 if (o.getOper() == opSubscript) other = o.getSubExp1();
00514 return *this == *other;
00515 }
00516 bool Unary::operator*=(Exp& o) {
00517 Exp* other = &o;
00518 if (o.getOper() == opSubscript) other = o.getSubExp1();
00519 if (((Unary*)other)->op == opWild) return true;
00520 if (((Unary*)other)->op == opWildRegOf && op == opRegOf) return true;
00521 if (((Unary*)other)->op == opWildMemOf && op == opMemOf) return true;
00522 if (((Unary*)other)->op == opWildAddrOf && op == opAddrOf) return true;
00523 if (op != ((Unary*)other)->op) return false;
00524 return *subExp1 *= *((Unary*)other)->getSubExp1();
00525 }
00526 bool Binary::operator*=(Exp& o) {
00527 assert(subExp1 && subExp2);
00528 Exp* other = &o;
00529 if (o.getOper() == opSubscript) other = o.getSubExp1();
00530 if (((Binary*)other)->op == opWild) return true;
00531 if (op != ((Binary*)other)->op) return false;
00532 if (!( *subExp1 *= *((Binary*)other)->getSubExp1())) return false;
00533 return *subExp2 *= *((Binary*)other)->getSubExp2();
00534 }
00535
00536 bool Ternary::operator*=(Exp& o) {
00537 Exp* other = &o;
00538 if (o.getOper() == opSubscript) other = o.getSubExp1();
00539 if (((Ternary*)other)->op == opWild) return true;
00540 if (op != ((Ternary*)other)->op) return false;
00541 if (!( *subExp1 *= *((Ternary*)other)->getSubExp1())) return false;
00542 if (!( *subExp2 *= *((Ternary*)other)->getSubExp2())) return false;
00543 return *subExp3 *= *((Ternary*)other)->getSubExp3();
00544 }
00545 bool Terminal::operator*=(Exp& o) {
00546 Exp* other = &o;
00547 if (o.getOper() == opSubscript) other = o.getSubExp1();
00548 return *this == *other;
00549 }
00550 bool TypedExp::operator*=(Exp& o) {
00551 Exp* other = &o;
00552 if (o.getOper() == opSubscript) other = o.getSubExp1();
00553 if (((TypedExp*)other)->op == opWild) return true;
00554 if (((TypedExp*)other)->op != opTypedExp) return false;
00555
00556 if (*type != *((TypedExp*)other)->type) return false;
00557 return *((Unary*)this)->getSubExp1() *= *((Unary*)other)->getSubExp1();
00558 }
00559
00560 bool RefExp::operator*=(Exp& o) {
00561 Exp* other = &o;
00562 if (o.getOper() == opSubscript) other = o.getSubExp1();
00563 return *subExp1 *= *other;
00564 }
00565
00566 bool TypeVal::operator*=(Exp& o) {
00567 Exp* other = &o;
00568 if (o.getOper() == opSubscript) other = o.getSubExp1();
00569 return *this == *other;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 void Const::print(std::ostream& os, bool html) {
00584 setLexBegin(os.tellp());
00585 switch (op) {
00586 case opIntConst:
00587 if (u.i < -1000 || u.i > 1000)
00588 os << "0x" << std::hex << u.i << std::dec;
00589 else
00590 os << std::dec << u.i;
00591 break;
00592 case opLongConst:
00593 if ((long long)u.ll < -1000LL || (long long)u.ll > 1000LL)
00594 os << "0x" << std::hex << u.ll << std::dec << "LL";
00595 else
00596 os << std::dec << u.ll << "LL";
00597 break;
00598 case opFltConst:
00599 char buf[64];
00600 sprintf(buf, "%.4f", u.d);
00601 os << buf;
00602 break;
00603 case opStrConst:
00604 os << "\"" << u.p << "\"";
00605 break;
00606 default:
00607 LOG << "Const::print invalid operator " << operStrings[op] << "\n";
00608 assert(0);
00609 }
00610 if (conscript)
00611 os << "\\" << std::dec << conscript << "\\";
00612 setLexEnd(os.tellp());
00613 }
00614
00615 void Const::printNoQuotes(std::ostream& os) {
00616 if (op == opStrConst)
00617 os << u.p;
00618 else
00619 print(os);
00620 }
00621
00622
00623
00624
00625 void Binary::printr(std::ostream& os, bool html) {
00626 assert(subExp1 && subExp2);
00627
00628
00629 switch (op) {
00630 case opSize:
00631 case opList:
00632
00633
00634 print(os, html); return;
00635 default:
00636 break;
00637 }
00638
00639
00640 os << "(";
00641 this->print(os, html);
00642 os << ")";
00643 }
00644
00645 void Binary::print(std::ostream& os, bool html) {
00646 assert(subExp1 && subExp2);
00647 Exp* p1 = ((Binary*)this)->getSubExp1();
00648 Exp* p2 = ((Binary*)this)->getSubExp2();
00649
00650 switch (op) {
00651 case opSize:
00652
00653
00654 p2->printr(os, html); os << "*"; p1->printr(os, html);
00655 os << "*";
00656 return;
00657 case opFlagCall:
00658
00659 ((Const*)p1)->printNoQuotes(os);
00660 os << "( "; p2->printr(os, html); os << " )";
00661 return;
00662 case opExpTable:
00663 case opNameTable:
00664 if (op == opExpTable)
00665 os << "exptable(";
00666 else
00667 os << "nametable(";
00668 os << p1 << ", " << p2 << ")";
00669 return;
00670
00671 case opList:
00672
00673
00674 p1->print(os, html);
00675 if (!p2->isNil())
00676 os << ", ";
00677 p2->print(os, html);
00678 return;
00679
00680 case opMemberAccess:
00681 p1->print(os, html);
00682 os << ".";
00683 ((Const*)p2)->printNoQuotes(os);
00684 return;
00685
00686 case opArrayIndex:
00687 p1->print(os, html);
00688 os << "[";
00689 p2->print(os, html);
00690 os << "]";
00691 return;
00692
00693 default:
00694 break;
00695 }
00696
00697
00698 if (p1 == NULL)
00699 os << "<NULL>";
00700 else
00701 p1->printr(os, html);
00702 switch (op) {
00703 case opPlus: os << " + "; break;
00704 case opMinus: os << " - "; break;
00705 case opMult: os << " * "; break;
00706 case opMults: os << " *! "; break;
00707 case opDiv: os << " / "; break;
00708 case opDivs: os << " /! "; break;
00709 case opMod: os << " % "; break;
00710 case opMods: os << " %! "; break;
00711 case opFPlus: os << " +f "; break;
00712 case opFMinus: os << " -f "; break;
00713 case opFMult: os << " *f "; break;
00714 case opFDiv: os << " /f "; break;
00715 case opPow: os << " pow "; break;
00716
00717 case opAnd: os << " and ";break;
00718 case opOr: os << " or "; break;
00719 case opBitAnd: os << " & "; break;
00720 case opBitOr : os << " | "; break;
00721 case opBitXor: os << " ^ "; break;
00722 case opEquals: os << " = "; break;
00723 case opNotEqual:os << " ~= "; break;
00724 case opLess: if (html) os << " < "; else os << " < "; break;
00725 case opGtr: if (html) os << " > "; else os << " > "; break;
00726 case opLessEq: if (html) os << " <= "; else os << " <= "; break;
00727 case opGtrEq: if (html) os << " >= "; else os << " >= "; break;
00728 case opLessUns: if (html) os << " <u "; else os << " <u "; break;
00729 case opGtrUns: if (html) os << " >u "; else os << " >u "; break;
00730 case opLessEqUns: if (html) os << " <u "; else os<< " <=u ";break;
00731 case opGtrEqUns: if (html) os << " >=u "; else os << " >=u ";break;
00732 case opUpper: os << " GT "; break;
00733 case opLower: os << " LT "; break;
00734 case opShiftL: if (html) os << " << "; else os << " << "; break;
00735 case opShiftR: if (html) os << " >> "; else os << " >> "; break;
00736 case opShiftRA: if (html) os << " >>A "; else os << " >>A "; break;
00737 case opRotateL: os << " rl "; break;
00738 case opRotateR: os << " rr "; break;
00739 case opRotateLC:os << " rlc "; break;
00740 case opRotateRC:os << " rrc "; break;
00741
00742 default:
00743 LOG << "Binary::print invalid operator " << operStrings[op] << "\n";
00744 assert(0);
00745 }
00746
00747 if (p2 == NULL)
00748 os << "<NULL>";
00749 else
00750 p2->printr(os, html);
00751
00752 }
00753
00754
00755
00756
00757
00758 void Terminal::print(std::ostream& os, bool html) {
00759 switch (op) {
00760 case opPC: os << "%pc"; break;
00761 case opFlags: os << "%flags"; break;
00762 case opFflags: os << "%fflags"; break;
00763 case opCF: os << "%CF"; break;
00764 case opZF: os << "%ZF"; break;
00765 case opOF: os << "%OF"; break;
00766 case opNF: os << "%NF"; break;
00767 case opDF: os << "%DF"; break;
00768 case opAFP: os << "%afp"; break;
00769 case opAGP: os << "%agp"; break;
00770 case opWild: os << "WILD"; break;
00771 case opAnull: os << "%anul"; break;
00772 case opFpush: os << "FPUSH"; break;
00773 case opFpop: os << "FPOP"; break;
00774 case opWildMemOf:os<< "m[WILD]"; break;
00775 case opWildRegOf:os<< "r[WILD]"; break;
00776 case opWildAddrOf:os<< "a[WILD]"; break;
00777 case opWildIntConst:os<<"WILDINT"; break;
00778 case opWildStrConst:os<<"WILDSTR"; break;
00779 case opNil: break;
00780 case opTrue: os << "true"; break;
00781 case opFalse: os << "false"; break;
00782 case opDefineAll: os << "<all>"; break;
00783 default:
00784 LOG << "Terminal::print invalid operator " << operStrings[op] << "\n";
00785 assert(0);
00786 }
00787 }
00788
00789
00790
00791
00792 void Unary::print(std::ostream& os, bool html) {
00793 Exp* p1 = ((Unary*)this)->getSubExp1();
00794 switch (op) {
00795
00796
00797
00798 case opRegOf:
00799
00800 if (p1->isIntConst()) {
00801 os << "r" << std::dec << ((Const*)p1)->getInt();
00802 break;
00803 } else if (p1->isTemp()) {
00804
00805 p1->print(os, html);
00806 break;
00807 }
00808
00809 case opMemOf: case opAddrOf: case opVar: case opTypeOf: case opKindOf:
00810 switch (op) {
00811 case opRegOf: os << "r["; break;
00812 case opMemOf: os << "m["; break;
00813 case opAddrOf:os << "a["; break;
00814 case opVar: os << "v["; break;
00815 case opTypeOf:os << "T["; break;
00816 case opKindOf:os << "K["; break;
00817 default: break;
00818 }
00819 if (op == opVar) ((Const*)p1)->printNoQuotes(os);
00820
00821
00822 else {
00823 p1->print(os, html);
00824 }
00825 os << "]";
00826 break;
00827
00828
00829
00830
00831
00832 case opNot: case opLNot: case opNeg: case opFNeg:
00833 if (op == opNot) os << "~";
00834 else if (op == opLNot) os << "L~";
00835 else if (op == opFNeg) os << "~f ";
00836 else os << "-";
00837 p1->printr(os, html);
00838 return;
00839
00840 case opSignExt:
00841 p1->printr(os, html);
00842 os << "!";
00843 return;
00844
00845
00846
00847
00848
00849 case opSQRTs: case opSQRTd: case opSQRTq:
00850 case opSqrt: case opSin: case opCos:
00851 case opTan: case opArcTan: case opLog2:
00852 case opLog10: case opLoge: case opPow:
00853 case opMachFtr: case opSuccessor:
00854 switch (op) {
00855 case opSQRTs: os << "SQRTs("; break;
00856 case opSQRTd: os << "SQRTd("; break;
00857 case opSQRTq: os << "SQRTq("; break;
00858 case opSqrt: os << "sqrt("; break;
00859 case opSin: os << "sin("; break;
00860 case opCos: os << "cos("; break;
00861 case opTan: os << "tan("; break;
00862 case opArcTan:os << "arctan("; break;
00863 case opLog2: os << "log2("; break;
00864 case opLog10: os << "log10("; break;
00865 case opLoge: os << "loge("; break;
00866 case opExecute:os<< "execute("; break;
00867 case opMachFtr:os << "machine("; break;
00868 case opSuccessor: os << "succ("; break;
00869 default: break;
00870 }
00871 p1->printr(os, html);
00872 os << ")";
00873 return;
00874
00875
00876 case opSgnEx:
00877 p1->printr(os, html);
00878 os << "! ";
00879 return;
00880 case opTemp:
00881 if (p1->getOper() == opWildStrConst) {
00882 os << "t[";
00883 ((Const*)p1)->printNoQuotes(os);
00884 os << "]";
00885 return;
00886 }
00887
00888 case opGlobal:
00889 case opLocal:
00890 case opParam:
00891
00892 ((Const*)p1)->printNoQuotes(os);
00893 return;
00894 case opInitValueOf:
00895 p1->printr(os, html);
00896 os << "'";
00897 return;
00898 case opPhi:
00899 os << "phi(";
00900 p1->print(os, html);
00901 os << ")";
00902 return;
00903 case opFtrunc:
00904 os << "ftrunc(";
00905 p1->print(os, html);
00906 os << ")";
00907 return;
00908 case opFabs:
00909 os << "fabs(";
00910 p1->print(os, html);
00911 os << ")";
00912 return;
00913 default:
00914 LOG << "Unary::print invalid operator " << operStrings[op] <<
00915 "\n";
00916 assert(0);
00917 }
00918 }
00919
00920
00921
00922
00923 void Ternary::printr(std::ostream& os, bool html) {
00924
00925 switch (op) {
00926
00927 case opTruncu: case opTruncs: case opZfill:
00928 case opSgnEx: case opFsize: case opItof:
00929 case opFtoi: case opFround: case opFtrunc:
00930 case opOpTable:
00931
00932 print(os); return;
00933 default:
00934 break;
00935 }
00936
00937 os << "(" << this << ")";
00938 }
00939
00940 void Ternary::print(std::ostream& os, bool html) {
00941 Exp* p1 = ((Ternary*)this)->getSubExp1();
00942 Exp* p2 = ((Ternary*)this)->getSubExp2();
00943 Exp* p3 = ((Ternary*)this)->getSubExp3();
00944 switch (op) {
00945
00946 case opTruncu: case opTruncs: case opZfill:
00947 case opSgnEx: case opFsize: case opItof:
00948 case opFtoi: case opFround: case opFtrunc:
00949 case opOpTable:
00950 switch (op) {
00951 case opTruncu: os << "truncu("; break;
00952 case opTruncs: os << "truncs("; break;
00953 case opZfill: os << "zfill("; break;
00954 case opSgnEx: os << "sgnex("; break;
00955 case opFsize: os << "fsize("; break;
00956 case opItof: os << "itof("; break;
00957 case opFtoi: os << "ftoi("; break;
00958 case opFround: os << "fround("; break;
00959 case opFtrunc: os << "ftrunc("; break;
00960 case opOpTable: os << "optable("; break;
00961 default: break;
00962 }
00963
00964
00965 if (p1) p1->print(os, html); else os << "<NULL>"; os << ",";
00966 if (p2) p2->print(os, html); else os << "<NULL>"; os << ",";
00967 if (p3) p3->print(os, html); else os << "<NULL>"; os << ")";
00968 return;
00969 default:
00970 break;
00971 }
00972
00973 if (p1) p1->printr(os, html); else os << "<NULL>";
00974 if (op == opTern) {
00975 os << " ? ";
00976 if (p2) p2->printr(os, html); else os << "<NULL>";
00977 os << " : ";
00978 if (p3) p3->print(os, html); else os << "<NULL>";
00979 }
00980 else if (op == opAt) {
00981 os << "@";
00982 if (p2) p2->printr(os, html); else os << "NULL>";
00983 os << ":";
00984 if (p3) p3->printr(os, html); else os << "NULL>";
00985 } else {
00986 LOG << "Ternary::print invalid operator " << operStrings[op] << "\n";
00987 assert(0);
00988 }
00989 }
00990
00991
00992
00993
00994 void TypedExp::print(std::ostream& os, bool html) {
00995 os << " ";
00996 type->starPrint(os);
00997 Exp* p1 = ((Ternary*)this)->getSubExp1();
00998 p1->print(os, html);
00999 }
01000
01001
01002
01003
01004
01005 void RefExp::print(std::ostream& os, bool html) {
01006 if (subExp1) subExp1->print(os, html);
01007 else os << "<NULL>";
01008 if (html)
01009 os << "<sub>";
01010 else
01011 os << "{";
01012 if (def == (Statement*)-1) os << "WILD";
01013 else if (def) {
01014 if (html)
01015 os << "<a href=\"#stmt" << std::dec << def->getNumber() << "\">";
01016 def->printNum(os);
01017 if (html)
01018 os << "</a>";
01019 } else
01020 os << "-";
01021 if (html)
01022 os << "</sub>";
01023 else
01024 os << "}";
01025 }
01026
01027
01028
01029
01030 void TypeVal::print(std::ostream& os, bool html) {
01031 if (val)
01032 os << "<" << val->getCtype() << ">";
01033 else
01034 os << "<NULL>";
01035 }
01036
01037
01038
01039
01040
01041
01042
01043 char* Exp::prints() {
01044 std::ostringstream ost;
01045 print(ost);
01046 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
01047 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
01048 return debug_buffer;
01049 }
01050
01051 void Exp::dump() {
01052 print(std::cerr);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 void Exp::createDotFile(char* name) {
01064 std::ofstream of;
01065 of.open(name);
01066 if (!of) {
01067 LOG << "Could not open " << name << " to write dotty file\n";
01068 return;
01069 }
01070 of << "digraph Exp {\n";
01071 appendDotFile(of);
01072 of << "}";
01073 of.close();
01074 }
01075
01076
01077
01078
01079 void Const::appendDotFile(std::ofstream& of) {
01080
01081 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01082 of << operStrings[op] << "\\n0x" << std::hex << (int)this << " | ";
01083 switch (op) {
01084 case opIntConst: of << std::dec << u.i; break;
01085 case opFltConst: of << u.d; break;
01086 case opStrConst: of << "\\\"" << u.p << "\\\""; break;
01087
01088 case opFuncConst: of << u.pp->getName(); break;
01089 default:
01090 break;
01091 }
01092 of << " }\"];\n";
01093 }
01094
01095
01096
01097
01098 void Terminal::appendDotFile(std::ofstream& of) {
01099 of << "e" << std::hex << (int)this << " [shape=parallelogram,label=\"";
01100 if (op == opWild)
01101
01102 of << "WILD";
01103 else
01104 of << operStrings[op];
01105 of << "\\n0x" << std::hex << (int)this;
01106 of << "\"];\n";
01107 }
01108
01109
01110
01111
01112 void Unary::appendDotFile(std::ofstream& of) {
01113
01114 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01115
01116 of << operStrings[op] << "\\n0x" << std::hex << (int)this << " | ";
01117 of << "<p1>";
01118 of << " }\"];\n";
01119
01120
01121 subExp1->appendDotFile(of);
01122
01123
01124 of << "e" << std::hex << (int)this << "->e" << (int)subExp1 << ";\n";
01125 }
01126
01127
01128
01129
01130 void Binary::appendDotFile(std::ofstream& of) {
01131
01132 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01133 of << operStrings[op] << "\\n0x" << std::hex << (int)this << " | ";
01134 of << "{<p1> | <p2>}";
01135 of << " }\"];\n";
01136 subExp1->appendDotFile(of);
01137 subExp2->appendDotFile(of);
01138
01139 of << "e" << std::hex << (int)this << ":p1->e" << (int)subExp1 << ";\n";
01140 of << "e" << std::hex << (int)this << ":p2->e" << (int)subExp2 << ";\n";
01141 }
01142
01143
01144
01145
01146 void Ternary::appendDotFile(std::ofstream& of) {
01147
01148 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01149 of << operStrings[op] << "\\n0x" << std::hex << (int)this << " | ";
01150 of << "{<p1> | <p2> | <p3>}";
01151 of << " }\"];\n";
01152 subExp1->appendDotFile(of);
01153 subExp2->appendDotFile(of);
01154 subExp3->appendDotFile(of);
01155
01156 of << "e" << std::hex << (int)this << ":p1->e" << (int)subExp1 << ";\n";
01157 of << "e" << std::hex << (int)this << ":p2->e" << (int)subExp2 << ";\n";
01158 of << "e" << std::hex << (int)this << ":p3->e" << (int)subExp3 << ";\n";
01159 }
01160
01161
01162
01163 void TypedExp::appendDotFile(std::ofstream& of) {
01164 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01165 of << "opTypedExp\\n0x" << std::hex << (int)this << " | ";
01166
01167 of << type->getCtype() << " | <p1>";
01168 of << " }\"];\n";
01169 subExp1->appendDotFile(of);
01170 of << "e" << std::hex << (int)this << ":p1->e" << (int)subExp1 << ";\n";
01171 }
01172
01173
01174
01175
01176 void FlagDef::appendDotFile(std::ofstream& of) {
01177 of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01178 of << "opFlagDef \\n0x" << std::hex << (int)this << "| ";
01179
01180 of << "{ RTL ";
01181 int n = rtl->getNumStmt();
01182 for (int i=0; i < n; i++)
01183 of << "| <r" << std::dec << i << "> ";
01184 of << "} | <p1> }\"];\n";
01185 subExp1->appendDotFile(of);
01186 of << "e" << std::hex << (int)this << ":p1->e" << (int)subExp1 << ";\n";
01187 }
01188
01189
01190
01191
01192
01193
01194
01195 bool Exp::isRegOfK()
01196 {
01197 if (op != opRegOf) return false;
01198 return ((Unary*)this)->getSubExp1()->getOper() == opIntConst;
01199 }
01200
01201
01202
01203
01204
01205
01206 bool Exp::isRegN(int N)
01207 {
01208 if (op != opRegOf) return false;
01209 Exp* sub = ((Unary*)this)->getSubExp1();
01210 return (sub->getOper() == opIntConst && ((Const*)sub)->getInt() == N);
01211 }
01212
01213
01214
01215
01216
01217
01218 bool Exp::isAfpTerm()
01219 {
01220 Exp* cur = this;
01221 if (op == opTypedExp)
01222 cur = ((Unary*)this)->getSubExp1();
01223 Exp* p;
01224 if ((cur->getOper() == opAddrOf) && ((p = ((Unary*)cur)->getSubExp1()), p->getOper() == opMemOf))
01225 cur =((Unary*)p )->getSubExp1();
01226
01227 OPER curOp = cur->getOper();
01228 if (curOp == opAFP) return true;
01229 if ((curOp != opPlus) && (curOp != opMinus)) return false;
01230
01231 OPER subOp1 = ((Binary*)cur)->getSubExp1()->getOper();
01232 OPER subOp2 = ((Binary*)cur)->getSubExp2()->getOper();
01233 return ((subOp1 == opAFP) && (subOp2 == opIntConst));
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243 int Exp::getVarIndex() {
01244 assert (op == opVar);
01245 Exp* sub = ((Unary*)this)->getSubExp1();
01246 return ((Const*)sub)->getInt();
01247 }
01248
01249
01250
01251
01252
01253
01254
01255 Exp* Exp::getGuard() {
01256 if (op == opGuard) return ((Unary*)this)->getSubExp1();
01257 return NULL;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266 Exp* Exp::match(Exp *pattern) {
01267 if (*this == *pattern)
01268 return new Terminal(opNil);
01269 if (pattern->getOper() == opVar) {
01270 return new Binary(opList,
01271 new Binary(opEquals, pattern->clone(), this->clone()),
01272 new Terminal(opNil));
01273 }
01274 return NULL;
01275 }
01276 Exp* Unary::match(Exp *pattern) {
01277 assert(subExp1);
01278 if (op == pattern->getOper()) {
01279 return subExp1->match(pattern->getSubExp1());
01280 }
01281 return Exp::match(pattern);
01282 }
01283 Exp* Binary::match(Exp *pattern) {
01284 assert(subExp1 && subExp2);
01285 if (op == pattern->getOper()) {
01286 Exp *b_lhs = subExp1->match(pattern->getSubExp1());
01287 if (b_lhs == NULL)
01288 return NULL;
01289 Exp *b_rhs = subExp2->match(pattern->getSubExp2());
01290 if (b_rhs == NULL)
01291 return NULL;
01292 if (b_lhs->getOper() == opNil)
01293 return b_rhs;
01294 if (b_rhs->getOper() == opNil)
01295 return b_lhs;
01296 #if 0
01297 LOG << "got lhs list " << b_lhs << " and rhs list " << b_rhs << "\n";
01298 #endif
01299 Exp *result = new Terminal(opNil);
01300 for (Exp *l = b_lhs; l->getOper() != opNil; l = l->getSubExp2())
01301 for (Exp *r = b_rhs; r->getOper() != opNil; r = r->getSubExp2())
01302 if (*l->getSubExp1()->getSubExp1() == *r->getSubExp1()->getSubExp1() &&
01303 !(*l->getSubExp1()->getSubExp2() == *r->getSubExp1()->getSubExp2())) {
01304 #if 0
01305 LOG << "disagreement in match: " << l->getSubExp1()->getSubExp2() << " != " <<
01306 r->getSubExp1()->getSubExp2() << "\n";
01307 #endif
01308 return NULL;
01309 } else
01310 result = new Binary(opList, l->getSubExp1()->clone(), result);
01311 for (Exp *r = b_rhs; r->getOper() != opNil; r = r->getSubExp2())
01312 result = new Binary(opList, r->getSubExp1()->clone(), result);
01313 return result;
01314 }
01315 return Exp::match(pattern);
01316 }
01317 Exp* RefExp::match(Exp *pattern) {
01318 Exp *r = Unary::match(pattern);
01319
01320 return r;
01321
01322
01323
01324
01325
01326
01327
01328 }
01329 #if 0 // Suspect ADHOC TA only
01330 Exp* TypeVal::match(Exp *pattern) {
01331 if (op == pattern->getOper()) {
01332 return val->match(pattern->getType());
01333 }
01334 return Exp::match(pattern);
01335 }
01336 #endif
01337
01338 #define ISVARIABLE(x) (strspn((x), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") == strlen((x)))
01339
01340
01341 const char *tlstrchr(const char *str, char ch)
01342 {
01343 while (str && *str) {
01344 if (*str == ch)
01345 return str;
01346 if (*str == '[' || *str == '{' || *str == '(') {
01347 char close = ']';
01348 if (*str == '{')
01349 close = '}';
01350 if (*str == '(')
01351 close = ')';
01352 while (*str && *str != close)
01353 str++;
01354 }
01355 if (*str)
01356 str++;
01357 }
01358 return NULL;
01359 }
01360
01361
01362
01363
01364
01365
01366
01367 bool Exp::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01368 {
01369
01370 std::ostringstream ostr;
01371 this->print(ostr);
01372 if (ostr.str() == pattern)
01373 return true;
01374
01375
01376 if (ISVARIABLE(pattern)) {
01377 bindings[pattern] = this;
01378 return true;
01379 }
01380
01381
01382 return false;
01383 }
01384 bool Unary::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01385 {
01386 if (Exp::match(pattern, bindings))
01387 return true;
01388 #ifdef DEBUG_MATCH
01389 LOG << "unary::match " << this << " to " << pattern << ".\n";
01390 #endif
01391 if (op == opAddrOf && pattern[0] == 'a' && pattern[1] == '[' &&
01392 pattern[strlen(pattern)-1] == ']') {
01393 char *sub1 = strdup(pattern+2);
01394 sub1[strlen(sub1)-1] = 0;
01395 return subExp1->match(sub1, bindings);
01396 }
01397 return false;
01398 }
01399 bool Binary::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01400 {
01401 if (Exp::match(pattern, bindings))
01402 return true;
01403 #ifdef DEBUG_MATCH
01404 LOG << "binary::match " << this << " to " << pattern << ".\n";
01405 #endif
01406 if (op == opMemberAccess && tlstrchr(pattern, '.')) {
01407 char *sub1 = strdup(pattern);
01408 char *sub2 = (char*)tlstrchr(sub1, '.');
01409 *sub2++ = 0;
01410 if (subExp1->match(sub1, bindings)) {
01411 assert(subExp2->isStrConst());
01412 if (!strcmp(sub2, ((Const*)subExp2)->getStr()))
01413 return true;
01414 if (ISVARIABLE(sub2)) {
01415 bindings[sub2] = subExp2;
01416 return true;
01417 }
01418 }
01419 }
01420 if (op == opArrayIndex) {
01421 if (pattern[strlen(pattern)-1] != ']')
01422 return false;
01423 char *sub1 = strdup(pattern);
01424 char *sub2 = strrchr(sub1, '[');
01425 *sub2++ = 0;
01426 sub2[strlen(sub2)-1] = 0;
01427 if (subExp1->match(sub1, bindings) && subExp2->match(sub2, bindings))
01428 return true;
01429 }
01430 if (op == opPlus && tlstrchr(pattern, '+')) {
01431 char *sub1 = strdup(pattern);
01432 char *sub2 = (char*)tlstrchr(sub1, '+');
01433 *sub2++ = 0;
01434 while (*sub2 == ' ')
01435 sub2++;
01436 while (sub1[strlen(sub1)-1] == ' ')
01437 sub1[strlen(sub1)-1] = 0;
01438 if (subExp1->match(sub1, bindings) && subExp2->match(sub2, bindings))
01439 return true;
01440 }
01441 if (op == opMinus && tlstrchr(pattern, '-')) {
01442 char *sub1 = strdup(pattern);
01443 char *sub2 = (char*)tlstrchr(sub1, '-');
01444 *sub2++ = 0;
01445 while (*sub2 == ' ')
01446 sub2++;
01447 while (sub1[strlen(sub1)-1] == ' ')
01448 sub1[strlen(sub1)-1] = 0;
01449 if (subExp1->match(sub1, bindings) && subExp2->match(sub2, bindings))
01450 return true;
01451 }
01452 return false;
01453 }
01454 bool Ternary::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01455 {
01456 if (Exp::match(pattern, bindings))
01457 return true;
01458 #ifdef DEBUG_MATCH
01459 LOG << "ternary::match " << this << " to " << pattern << ".\n";
01460 #endif
01461 return false;
01462 }
01463 bool RefExp::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01464 {
01465 if (Exp::match(pattern, bindings))
01466 return true;
01467 #ifdef DEBUG_MATCH
01468 LOG << "refexp::match " << this << " to " << pattern << ".\n";
01469 #endif
01470 const char *end = pattern + strlen(pattern) - 1;
01471 if (end > pattern && *end == '}') {
01472 end--;
01473 if (*end == '-' && def == NULL) {
01474 char *sub = strdup(pattern);
01475 *(sub + (end - 1 - pattern)) = 0;
01476 return subExp1->match(sub, bindings);
01477 }
01478 end = strrchr(end, '{');
01479 if (end) {
01480 if (atoi(end + 1) == def->getNumber()) {
01481 char *sub = strdup(pattern);
01482 *(sub + (end - pattern)) = 0;
01483 return subExp1->match(sub, bindings);
01484 }
01485 }
01486 }
01487 return false;
01488 }
01489 bool Const::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01490 {
01491 if (Exp::match(pattern, bindings))
01492 return true;
01493 #ifdef DEBUG_MATCH
01494 LOG << "const::match " << this << " to " << pattern << ".\n";
01495 #endif
01496 return false;
01497 }
01498 bool Terminal::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01499 {
01500 if (Exp::match(pattern, bindings))
01501 return true;
01502 #ifdef DEBUG_MATCH
01503 LOG << "terminal::match " << this << " to " << pattern << ".\n";
01504 #endif
01505 return false;
01506 }
01507 bool Location::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01508 {
01509 if (Exp::match(pattern, bindings))
01510 return true;
01511 #ifdef DEBUG_MATCH
01512 LOG << "location::match " << this << " to " << pattern << ".\n";
01513 #endif
01514 if (op == opMemOf || op == opRegOf) {
01515 char ch = 'm';
01516 if (op == opRegOf)
01517 ch = 'r';
01518 if (pattern[0] != ch || pattern[1] != '[')
01519 return false;
01520 if (pattern[strlen(pattern)-1] != ']')
01521 return false;
01522 char *sub = strdup(pattern + 2);
01523 *(sub + strlen(sub) - 1) = 0;
01524 return subExp1->match(sub, bindings);
01525 }
01526 return false;
01527 }
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542 void Exp::doSearch(Exp* search, Exp*& pSrc, std::list<Exp**>& li, bool once) {
01543 bool compare;
01544 compare = (*search == *pSrc);
01545 if (compare) {
01546 li.push_back(&pSrc);
01547 if (once)
01548 return;
01549 }
01550
01551
01552 if (!compare || pSrc->op != opSubscript)
01553 pSrc->doSearchChildren(search, li, once);
01554 }
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566 void Exp::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01567 return;
01568 }
01569 void Unary::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01570 if (op != opInitValueOf)
01571 doSearch(search, subExp1, li, once);
01572 }
01573 void Binary::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01574 assert(subExp1 && subExp2);
01575 doSearch(search, subExp1, li, once);
01576 if (once && li.size()) return;
01577 doSearch(search, subExp2, li, once);
01578 }
01579 void Ternary::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01580 doSearch(search, subExp1, li, once);
01581 if (once && li.size()) return;
01582 doSearch(search, subExp2, li, once);
01583 if (once && li.size()) return;
01584 doSearch(search, subExp3, li, once);
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597 Exp* Exp::searchReplace(Exp* search, Exp* replace, bool& change)
01598 {
01599 return searchReplaceAll(search, replace, change, true);
01600 }
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615 Exp* Exp::searchReplaceAll(Exp* search, Exp* replace, bool& change, bool once ) {
01616 std::list<Exp**> li;
01617 Exp* top = this;
01618 doSearch(search, top, li, false);
01619 std::list<Exp**>::iterator it;
01620 for (it = li.begin(); it != li.end(); it++) {
01621 Exp** pp = *it;
01622
01623 *pp = replace->clone();
01624 if (once) {
01625 change = true;
01626 return top;
01627 }
01628 }
01629 change = (li.size() != 0);
01630 return top;
01631 }
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642 bool Exp::search(Exp* search, Exp*& result)
01643 {
01644 std::list<Exp**> li;
01645 result = 0;
01646
01647
01648 Exp* top = this;
01649 doSearch(search, top, li, false);
01650 if (li.size()) {
01651 result = *li.front();
01652 return true;
01653 }
01654 return false;
01655 }
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665 bool Exp::searchAll(Exp* search, std::list<Exp*>& result)
01666 {
01667 std::list<Exp**> li;
01668
01669
01670
01671
01672 Exp* pSrc = this;
01673 doSearch(search, pSrc, li, false);
01674 std::list<Exp**>::iterator it;
01675 for (it = li.begin(); it != li.end(); it++) {
01676
01677 result.push_back(**it);
01678 }
01679 return li.size() != 0;
01680 }
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702 void Exp::partitionTerms(std::list<Exp*>& positives, std::list<Exp*>& negatives,
01703 std::vector<int>& integers, bool negate) {
01704 Exp* p1, *p2;
01705 switch (op) {
01706 case opPlus:
01707 p1 = ((Binary*)this)->getSubExp1();
01708 p2 = ((Binary*)this)->getSubExp2();
01709 p1->partitionTerms(positives, negatives, integers, negate);
01710 p2->partitionTerms(positives, negatives, integers, negate);
01711 break;
01712 case opMinus:
01713 p1 = ((Binary*)this)->getSubExp1();
01714 p2 = ((Binary*)this)->getSubExp2();
01715 p1->partitionTerms(positives, negatives, integers, negate);
01716 p2->partitionTerms(positives, negatives, integers, !negate);
01717 break;
01718 case opTypedExp:
01719 p1 = ((Binary*)this)->getSubExp1();
01720 p1->partitionTerms(positives, negatives, integers, negate);
01721 break;
01722 case opIntConst: {
01723 int k = ((Const*)this)->getInt();
01724 if (negate)
01725 integers.push_back(-k);
01726 else
01727 integers.push_back(k);
01728 break;
01729 }
01730 default:
01731
01732 if (negate)
01733 negatives.push_back(this);
01734 else
01735 positives.push_back(this);
01736 }
01737 }
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 Exp* Unary::simplifyArith()
01749 {
01750 if (op == opMemOf || op == opRegOf || op == opAddrOf || op == opSubscript) {
01751
01752 subExp1 = subExp1->simplifyArith();
01753 }
01754 return this;
01755 }
01756
01757 Exp* Ternary::simplifyArith() {
01758 subExp1 = subExp1->simplifyArith();
01759 subExp2 = subExp2->simplifyArith();
01760 subExp3 = subExp3->simplifyArith();
01761 return this;
01762 }
01763
01764 Exp* Binary::simplifyArith() {
01765 assert(subExp1 && subExp2);
01766 subExp1 = subExp1->simplifyArith();
01767 subExp2 = subExp2->simplifyArith();
01768 if ((op != opPlus) && (op != opMinus))
01769 return this;
01770
01771
01772
01773 std::list<Exp*> positives;
01774 std::list<Exp*> negatives;
01775 std::vector<int> integers;
01776 partitionTerms(positives,negatives,integers,false);
01777
01778
01779
01780
01781
01782 std::list<Exp*>::iterator pp = positives.begin();
01783 std::list<Exp*>::iterator nn = negatives.begin();
01784 while (pp != positives.end()) {
01785 bool inc = true;
01786 while (nn != negatives.end()) {
01787 if (**pp == **nn) {
01788
01789 pp = positives.erase(pp);
01790 nn = negatives.erase(nn);
01791 inc = false;
01792 break;
01793 }
01794 nn++;
01795 }
01796 if (pp == positives.end()) break;
01797 if (inc) pp++;
01798 }
01799
01800
01801 int sum = std::accumulate(integers.begin(),integers.end(),0);
01802
01803
01804 if (positives.size() == 0) {
01805 if (negatives.size() == 0) {
01806 return new Const(sum);
01807 } else
01808
01809 return new Binary(opMinus, new Const(sum),
01810 Exp::Accumulate(negatives));
01811 }
01812 if (negatives.size() == 0) {
01813
01814 if (sum == 0) {
01815
01816 return Exp::Accumulate(positives);
01817 } else {
01818 OPER op = opPlus;
01819 if (sum < 0) {
01820 op = opMinus;
01821 sum = -sum;
01822 }
01823 return new Binary(op, Exp::Accumulate(positives), new Const(sum));
01824 }
01825 }
01826
01827 if (sum == 0) {
01828
01829 return new Binary(opMinus, Exp::Accumulate(positives),
01830 Exp::Accumulate(negatives));
01831 }
01832
01833 OPER op = opPlus;
01834 if (sum < 0) {
01835 op = opMinus;
01836 sum = -sum;
01837 }
01838 return new Binary(op,
01839 new Binary(opMinus,
01840 Exp::Accumulate(positives),
01841 Exp::Accumulate(negatives)),
01842 new Const(sum));
01843
01844 }
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855 Exp* Exp::Accumulate(std::list<Exp*> exprs)
01856 {
01857 int n = exprs.size();
01858 if (n == 0)
01859 return new Const(0);
01860 if (n == 1)
01861 return exprs.front()->clone();
01862
01863 Exp *first = exprs.front()->clone();
01864 exprs.pop_front();
01865 Binary *res = new Binary(opPlus, first, Accumulate(exprs));
01866 exprs.push_front(first);
01867 return res;
01868 }
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885 #define DEBUG_SIMP 0 // Set to 1 to print every change
01886 Exp* Exp::simplify() {
01887 #if DEBUG_SIMP
01888 Exp* save = clone();
01889 #endif
01890 bool bMod = false;
01891 Exp* res = this;
01892
01893
01894 do {
01895 bMod = false;
01896
01897 res = res->polySimplify(bMod);
01898
01899
01900
01901
01902
01903 } while (bMod);
01904
01905
01906
01907 #if DEBUG_SIMP
01908 if (!(*res == *save)) std::cout << "simplified " << save << " to " << res << "\n";
01909 ;
01910 #endif
01911 return res;
01912 }
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 Exp* Unary::polySimplify(bool& bMod) {
01923 Exp* res = this;
01924 subExp1 = subExp1->polySimplify(bMod);
01925
01926 if (op == opNot || op == opLNot) {
01927 switch(subExp1->getOper()) {
01928 case opEquals:
01929 res = ((Unary*)res)->getSubExp1();
01930 res->setOper(opNotEqual);
01931 bMod = true;
01932 return res;
01933 case opNotEqual:
01934 res = ((Unary*)res)->getSubExp1();
01935 res->setOper(opEquals);
01936 bMod = true;
01937 return res;
01938 case opLess:
01939 res = ((Unary*)res)->getSubExp1();
01940 res->setOper(opGtrEq);
01941 bMod = true;
01942 return res;
01943 case opLessEq:
01944 res = ((Unary*)res)->getSubExp1();
01945 res->setOper(opGtr);
01946 bMod = true;
01947 return res;
01948 case opGtr:
01949 res = ((Unary*)res)->getSubExp1();
01950 res->setOper(opLessEq);
01951 bMod = true;
01952 return res;
01953 case opGtrEq:
01954 res = ((Unary*)res)->getSubExp1();
01955 res->setOper(opLess);
01956 bMod = true;
01957 return res;
01958 case opLessUns:
01959 res = ((Unary*)res)->getSubExp1();
01960 res->setOper(opGtrEqUns);
01961 bMod = true;
01962 return res;
01963 case opLessEqUns:
01964 res = ((Unary*)res)->getSubExp1();
01965 res->setOper(opGtrUns);
01966 bMod = true;
01967 return res;
01968 case opGtrUns:
01969 res = ((Unary*)res)->getSubExp1();
01970 res->setOper(opLessEqUns);
01971 bMod = true;
01972 return res;
01973 case opGtrEqUns:
01974 res = ((Unary*)res)->getSubExp1();
01975 res->setOper(opLessUns);
01976 bMod = true;
01977 return res;
01978 default:
01979 break;
01980 }
01981 }
01982
01983 switch (op) {
01984 case opNeg: case opNot: case opLNot: case opSize: {
01985 OPER subOP = subExp1->getOper();
01986 if (subOP == opIntConst) {
01987
01988 OPER op2 = op;
01989 res = ((Unary*)res)->getSubExp1();
01990 int k = ((Const*)res)->getInt();
01991 switch (op2) {
01992 case opNeg: k = -k; break;
01993 case opNot: k = ~k; break;
01994 case opLNot:k = !k; break;
01995 case opSize: break;
01996 default: break;
01997 }
01998 ((Const*)res)->setInt(k);
01999 bMod = true;
02000 } else if (op == subOP) {
02001 res = ((Unary*)res)->getSubExp1();
02002 res = ((Unary*)res)->getSubExp1();
02003 bMod = true;
02004 break;
02005 }
02006 }
02007 break;
02008 case opAddrOf:
02009
02010 if (subExp1->getOper() == opMemOf) {
02011 res = ((Unary*)res)->getSubExp1();
02012 res = ((Unary*)res)->getSubExp1();
02013 bMod = true;
02014 return res;
02015 }
02016 break;
02017 case opMemOf: case opRegOf: {
02018 subExp1 = subExp1->polySimplify(bMod);
02019
02020
02021
02022
02023 }
02024 break;
02025 default:
02026 break;
02027 }
02028
02029 return res;
02030 }
02031
02032 Exp* Binary::polySimplify(bool& bMod) {
02033 assert(subExp1 && subExp2);
02034
02035 Exp* res = this;
02036
02037 subExp1 = subExp1->polySimplify(bMod);
02038 subExp2 = subExp2->polySimplify(bMod);
02039
02040 OPER opSub1 = subExp1->getOper();
02041 OPER opSub2 = subExp2->getOper();
02042
02043 if ( (opSub1 == opIntConst) &&
02044 (opSub2 == opIntConst)) {
02045
02046 int k1 = ((Const*)subExp1)->getInt();
02047 int k2 = ((Const*)subExp2)->getInt();
02048 bool change = true;
02049 switch (op) {
02050 case opPlus: k1 = k1 + k2; break;
02051 case opMinus: k1 = k1 - k2; break;
02052 case opDiv: k1 = (int) ((unsigned)k1 / (unsigned)k2); break;
02053 case opDivs: k1 = k1 / k2; break;
02054 case opMod: k1 = (int) ((unsigned)k1 % (unsigned)k2); break;
02055 case opMods: k1 = k1 % k2; break;
02056 case opMult: k1 = (int) ((unsigned)k1 * (unsigned)k2); break;
02057 case opMults: k1 = k1 * k2; break;
02058 case opShiftL: k1 = k1 << k2; break;
02059 case opShiftR: k1 = k1 >> k2; break;
02060 case opShiftRA: k1 = (k1 >> k2) | (((1 << k2) -1) << (32 - k2)); break;
02061 case opBitOr: k1 = k1 | k2; break;
02062 case opBitAnd: k1 = k1 & k2; break;
02063 case opBitXor: k1 = k1 ^ k2; break;
02064 case opEquals: k1 = (k1 == k2); break;
02065 case opNotEqual:k1 = (k1 != k2); break;
02066 case opLess: k1 = (k1 < k2); break;
02067 case opGtr: k1 = (k1 > k2); break;
02068 case opLessEq: k1 = (k1 <= k2); break;
02069 case opGtrEq: k1 = (k1 >= k2); break;
02070 case opLessUns: k1 = ((unsigned)k1 < (unsigned)k2); break;
02071 case opGtrUns: k1 = ((unsigned)k1 > (unsigned)k2); break;
02072 case opLessEqUns:k1 = ((unsigned)k1 <=(unsigned)k2); break;
02073 case opGtrEqUns:k1 = ((unsigned)k1 >=(unsigned)k2); break;
02074 default: change = false;
02075 }
02076 if (change) {
02077 ;
02078 res = new Const(k1);
02079 bMod = true;
02080 return res;
02081 }
02082 }
02083
02084 if ( ((op == opBitXor) || (op == opMinus)) &&
02085 (*subExp1 == *subExp2)) {
02086
02087 res = new Const(0);
02088 bMod = true;
02089 return res;
02090 }
02091
02092 if ( ((op == opBitOr) || (op == opBitAnd)) &&
02093 (*subExp1 == *subExp2)) {
02094
02095 res = subExp1;
02096 bMod = true;
02097 return res;
02098 }
02099
02100 if ( op == opEquals &&
02101 *subExp1 == *subExp2) {
02102
02103 ;
02104 res = new Terminal(opTrue);
02105 bMod = true;
02106 return res;
02107 }
02108
02109
02110
02111 if ( opSub1 == opIntConst &&
02112 (op == opPlus || op == opMult || op == opMults || op == opBitOr || op == opBitAnd )) {
02113 commute();
02114
02115 OPER t = opSub1;
02116 opSub1 = opSub2;
02117 opSub2 = t;
02118
02119 }
02120
02121
02122 if ( subExp1->isBoolConst() &&
02123 !subExp2->isBoolConst() &&
02124 (op == opAnd || op == opOr)) {
02125 commute();
02126
02127 OPER t = opSub1;
02128 opSub1 = opSub2;
02129 opSub2 = t;
02130
02131 }
02132
02133
02134 if (subExp2->isAddrOf() && subExp2->getSubExp1()->isSubscript() &&
02135 subExp2->getSubExp1()->getSubExp1()->isGlobal() &&
02136 op == opPlus) {
02137 commute();
02138
02139 OPER t = opSub1;
02140 opSub1 = opSub2;
02141 opSub2 = t;
02142
02143 }
02144
02145
02146 if ( op == opPlus &&
02147 opSub1 == opPlus &&
02148 opSub2 == opIntConst &&
02149 subExp1->getSubExp2()->getOper() == opIntConst) {
02150 int n = ((Const*)subExp2)->getInt();
02151 res = ((Binary*)res)->getSubExp1();
02152 ((Const*)res->getSubExp2())->setInt(((Const*)res->getSubExp2())->getInt() + n);
02153 bMod = true;
02154 return res;
02155 }
02156
02157
02158 if ( op == opPlus &&
02159 opSub1 == opMinus && opSub2 == opIntConst &&
02160 subExp1->getSubExp2()->getOper() == opIntConst) {
02161 int n = ((Const*)subExp2)->getInt();
02162 res = ((Binary*)res)->getSubExp1();
02163 res->setOper(opPlus);
02164 ((Const*)res->getSubExp2())->setInt((-((Const*)res->getSubExp2())->getInt()) + n);
02165 bMod = true;
02166 return res;
02167 }
02168
02169
02170
02171 if ( (op == opMinus || op == opPlus) &&
02172 (opSub1 == opMults || opSub1 == opMult) &&
02173 *subExp2 == *subExp1->getSubExp1()) {
02174 res = ((Binary*)res)->getSubExp1();
02175 res->setSubExp2(new Binary(op, res->getSubExp2(), new Const(1)));
02176 bMod = true;
02177 return res;
02178 }
02179
02180
02181 if ( op == opPlus &&
02182 (opSub2 == opMults || opSub2 == opMult) &&
02183 *subExp1 == *subExp2->getSubExp1()) {
02184 res = ((Binary*)res)->getSubExp2();
02185 res->setSubExp2(new Binary(opPlus, res->getSubExp2(), new Const(1)));
02186 bMod = true;
02187 return res;
02188 }
02189
02190
02191
02192
02193 if ( (op == opPlus || op == opMinus) &&
02194 opSub2 == opIntConst &&
02195 ((Const*)subExp2)->getInt() < 0) {
02196 ((Const*)subExp2)->setInt(-((Const*)subExp2)->getInt());
02197 op = op == opPlus ? opMinus : opPlus;
02198 }
02199
02200
02201 if ( (op == opPlus || op == opMinus || op == opBitOr) &&
02202 opSub2 == opIntConst && ((Const*)subExp2)->getInt() == 0) {
02203 res = ((Binary*)res)->getSubExp1();
02204 bMod = true;
02205 return res;
02206 }
02207
02208
02209 if ( op == opOr &&
02210 subExp2->isFalse()) {
02211 res = ((Binary*)res)->getSubExp1();
02212 bMod = true;
02213 return res;
02214 }
02215
02216
02217 if ( (op == opMult || op == opMults || op == opBitAnd) &&
02218 opSub2 == opIntConst &&
02219 ((Const*)subExp2)->getInt() == 0) {
02220 ;
02221 res = new Const(0);
02222 bMod = true;
02223 return res;
02224 }
02225
02226
02227 if ( op == opAnd &&
02228 subExp2->isFalse()) {
02229 ;
02230 res = new Terminal(opFalse);
02231 bMod = true;
02232 return res;
02233 }
02234
02235
02236 if ( (op == opMult || op == opMults) &&
02237 opSub2 == opIntConst &&
02238 ((Const*)subExp2)->getInt() == 1) {
02239 res = ((Unary*)res)->getSubExp1();
02240 bMod = true;
02241 return res;
02242 }
02243
02244
02245 if ( (op == opDiv || op == opDivs) && (opSub1 == opMult || opSub1 == opMults) &&
02246 *subExp2 == *subExp1->getSubExp2()) {
02247 res = ((Unary*)res)->getSubExp1();
02248 res = ((Unary*)res)->getSubExp1();
02249 bMod = true;
02250 return res;
02251 }
02252
02253
02254 if ( (op == opDiv || op == opDivs) &&
02255 opSub2 == opIntConst && ((Const*)subExp2)->getInt() == 1) {
02256 res = ((Binary*)res)->getSubExp1();
02257 bMod = true;
02258 return res;
02259 }
02260
02261
02262 if ( (op == opMod || op == opMods) &&
02263 opSub2 == opIntConst && ((Const*)subExp2)->getInt() == 1) {
02264 res = new Const(0);
02265 bMod = true;
02266 return res;
02267 }
02268
02269
02270 if ( (op == opMod || op == opMods) && (opSub1 == opMult || opSub1 == opMults) &&
02271 *subExp2 == *subExp1->getSubExp2()) {
02272 res = new Const(0);
02273 bMod = true;
02274 return res;
02275 }
02276
02277
02278 if ( (op == opBitAnd) &&
02279 opSub2 == opIntConst && ((Const*)subExp2)->getInt() == -1) {
02280 res = ((Unary*)res)->getSubExp1();
02281 bMod = true;
02282 return res;
02283 }
02284
02285
02286 if ( (op == opAnd) &&
02287
02288 (opSub2 == opIntConst && ((Const*)subExp2)->getInt() != 0) || subExp2->isTrue()) {
02289 res = ((Unary*)res)->getSubExp1();
02290 bMod = true;
02291 return res;
02292 }
02293
02294
02295 if ( (op == opOr) &&
02296 (opSub2 == opIntConst &&
02297 ((Const*)subExp2)->getInt() != 0) || subExp2->isTrue()) {
02298 ;
02299 res = new Terminal(opTrue);
02300 bMod = true;
02301 return res;
02302 }
02303
02304
02305 int k;
02306 if ( op == opShiftL &&
02307 opSub2 == opIntConst &&
02308 ((k = ((Const*)subExp2)->getInt(), (k >= 0 && k < 32)))) {
02309 res->setOper(opMult);
02310 ((Const*)subExp2)->setInt(1 << k);
02311 bMod = true;
02312 return res;
02313 }
02314
02315 if ( op == opShiftR &&
02316 opSub2 == opIntConst &&
02317 ((k = ((Const*)subExp2)->getInt(), (k >= 0 && k < 32)))) {
02318 res->setOper(opDiv);
02319 ((Const*)subExp2)->setInt(1 << k);
02320 bMod = true;
02321 return res;
02322 }
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352 if ( op == opEquals && opSub2 == opIntConst &&
02353 ((Const*)subExp2)->getInt() == 1 && opSub1 == opEquals) {
02354 ;
02355 Binary *b = (Binary*)subExp1;
02356 subExp2 = b->subExp2;
02357 b->subExp2 = 0;
02358 subExp1 = b->subExp1;
02359 b->subExp1 = 0;
02360 ;
02361 bMod = true;
02362 return res;
02363 }
02364
02365
02366 if ( op == opEquals && opSub2 == opIntConst &&
02367 ((Const*)subExp2)->getInt() == 0 && opSub1 == opPlus &&
02368 ((Binary*)subExp1)->subExp2->getOper() == opIntConst) {
02369 Binary *b = (Binary*)subExp1;
02370 int n = ((Const*)b->subExp2)->getInt();
02371 if (n < 0) {
02372 ;
02373 subExp2 = b->subExp2;
02374 ((Const*)subExp2)->setInt(-((Const*)subExp2)->getInt());
02375 b->subExp2 = 0;
02376 subExp1 = b->subExp1;
02377 b->subExp1 = 0;
02378 ;
02379 bMod = true;
02380 return res;
02381 }
02382 }
02383
02384
02385 if ( op == opEquals &&
02386 opSub2 == opIntConst &&
02387 ((Const*)subExp2)->getInt() == 0 && opSub1 == opEquals) {
02388 ;
02389 Binary *b = (Binary*)subExp1;
02390 subExp2 = b->subExp2;
02391 b->subExp2 = 0;
02392 subExp1 = b->subExp1;
02393 b->subExp1 = 0;
02394 ;
02395 bMod = true;
02396 res->setOper(opNotEqual);
02397 return res;
02398 }
02399
02400
02401 if ( op == opNotEqual && opSub2 == opIntConst &&
02402 ((Const*)subExp2)->getInt() == 1 && opSub1 == opEquals) {
02403 ;
02404 Binary *b = (Binary*)subExp1;
02405 subExp2 = b->subExp2;
02406 b->subExp2 = 0;
02407 subExp1 = b->subExp1;
02408 b->subExp1 = 0;
02409 ;
02410 bMod = true;
02411 res->setOper(opNotEqual);
02412 return res;
02413 }
02414
02415
02416 if ( op == opNotEqual &&
02417 opSub2 == opIntConst &&
02418 ((Const*)subExp2)->getInt() == 0 && opSub1 == opEquals) {
02419 res = ((Binary*)res)->getSubExp1();
02420 bMod = true;
02421 return res;
02422 }
02423
02424
02425 if ( op == opNotEqual &&
02426 opSub2 == opIntConst &&
02427 ((Const*)subExp2)->getInt() == 0 && opSub1 == opMinus &&
02428 subExp1->getSubExp1()->isIntConst() &&
02429 ((Const*)subExp1->getSubExp1())->getInt() == 0) {
02430 res = new Binary(opNotEqual, subExp1->getSubExp2()->clone(), subExp2->clone());
02431 bMod = true;
02432 return res;
02433 }
02434
02435
02436 if ( op == opEquals && opSub2 == opIntConst &&
02437 ((Const*)subExp2)->getInt() == 0 && opSub1 == opGtr) {
02438 ;
02439 Binary *b = (Binary*)subExp1;
02440 subExp2 = b->subExp2;
02441 b->subExp2 = 0;
02442 subExp1 = b->subExp1;
02443 b->subExp1 = 0;
02444 ;
02445 bMod = true;
02446 res->setOper(opLessEq);
02447 return res;
02448 }
02449
02450
02451 if ( op == opEquals && opSub2 == opIntConst &&
02452 ((Const*)subExp2)->getInt() == 0 && opSub1 == opGtrUns) {
02453 ;
02454 Binary *b = (Binary*)subExp1;
02455 subExp2 = b->subExp2;
02456 b->subExp2 = 0;
02457 subExp1 = b->subExp1;
02458 b->subExp1 = 0;
02459 ;
02460 bMod = true;
02461 res->setOper(opLessEqUns);
02462 return res;
02463 }
02464
02465 Binary *b1 = (Binary*)subExp1;
02466 Binary *b2 = (Binary*)subExp2;
02467
02468 if ( op == opOr && opSub2 == opEquals &&
02469 (opSub1 == opGtrEq || opSub1 == opLessEq || opSub1 == opGtrEqUns || opSub1 == opLessEqUns) &&
02470 ((*b1->subExp1 == *b2->subExp1 &&
02471 *b1->subExp2 == *b2->subExp2) || (*b1->subExp1 == *b2->subExp2 &&
02472 *b1->subExp2 == *b2->subExp1))) {
02473 res = ((Binary*)res)->getSubExp1();
02474 bMod = true;
02475 return res;
02476 }
02477
02478
02479 if (op == opOr || op == opAnd) {
02480 subExp1 = subExp1->polySimplify(bMod);
02481 subExp2 = subExp2->polySimplify(bMod);
02482 return res;
02483 }
02484
02485
02486 if ( op == opBitAnd &&
02487 *subExp1 == *subExp2) {
02488 res = ((Binary*)res)->getSubExp1();
02489 bMod = true;
02490 return res;
02491 }
02492
02493
02494 if ( op == opPlus &&
02495 opSub2 == opMult &&
02496 *subExp1 == *subExp2->getSubExp1() &&
02497 subExp2->getSubExp2()->getOper() == opIntConst) {
02498 res = ((Binary*)res)->getSubExp2();
02499 ((Const*)res->getSubExp2())->setInt(((Const*)res->getSubExp2())->getInt()+1);
02500 bMod = true;
02501 return res;
02502 }
02503
02504
02505 if ( op == opMult &&
02506 opSub1 == opMult &&
02507 opSub2 == opIntConst &&
02508 subExp1->getSubExp2()->getOper() == opIntConst) {
02509 int m = ((Const*)subExp2)->getInt();
02510 res = ((Binary*)res)->getSubExp1();
02511 ((Const*)res->getSubExp2())->setInt(((Const*)res->getSubExp2())->getInt()*m);
02512 bMod = true;
02513 return res;
02514 }
02515
02516
02517 if ( op == opLNot &&
02518 opSub1 == opEquals) {
02519 res = ((Unary*)res)->getSubExp1();
02520 res->setOper(opNotEqual);
02521 bMod = true;
02522 return res;
02523 }
02524
02525
02526 if ( op == opLNot &&
02527 opSub1 == opNotEqual) {
02528 res = ((Unary*)res)->getSubExp1();
02529 res->setOper(opEquals);
02530 bMod = true;
02531 return res;
02532 }
02533
02534 #if 0 // FIXME! ADHOC TA assumed!
02535
02536 if ( op == opPlus &&
02537 subExp1->getOper() == opPlus &&
02538 subExp1->getSubExp1()->getType() &&
02539 subExp2->getOper() == opIntConst) {
02540 Type *ty = subExp1->getSubExp1()->getType();
02541 if (ty->resolvesToPointer() &&
02542 ty->asPointer()->getPointsTo()->resolvesToCompound()) {
02543 res = new Binary(opPlus, subExp1->getSubExp1(), subExp2);
02544 res = new Binary(opPlus, res, subExp1->getSubExp2());
02545 bMod = true;
02546 return res;
02547 }
02548 }
02549 #endif
02550
02551
02552
02553
02554 Type* ty = NULL;
02555 if (subExp1->isSubscript()) {
02556 Statement* def = ((RefExp*)subExp1)->getDef();
02557 if (def)
02558 ty = def->getTypeFor(((RefExp*)subExp1)->getSubExp1());
02559 }
02560 if ( op == opPlus &&
02561 ty && ty->resolvesToPointer() && ty->asPointer()->getPointsTo()->resolvesToCompound() &&
02562 opSub2 == opIntConst) {
02563 unsigned n = (unsigned)((Const*)subExp2)->getInt();
02564 CompoundType *c = ty->asPointer()->getPointsTo()->asCompound();
02565 if (n*8 < c->getSize()) {
02566 unsigned r = c->getOffsetRemainder(n*8);
02567 assert((r % 8) == 0);
02568 const char *nam = c->getNameAtOffset(n*8);
02569 if (nam != NULL && std::string("pad") != nam) {
02570 Location *l = Location::memOf(subExp1);
02571
02572 res = new Binary(opPlus,
02573 new Unary(opAddrOf,
02574 new Binary(opMemberAccess,
02575 l,
02576 new Const(strdup(nam)))),
02577 new Const(r / 8));
02578 if (VERBOSE)
02579 LOG << "(trans1) replacing " << this << " with " << res << "\n";
02580 bMod = true;
02581 return res;
02582 }
02583 }
02584 }
02585
02586 #if 0 // FIXME: ADHOC TA assumed
02587
02588
02589 if ( op == opPlus &&
02590 subExp1->getType()) {
02591 Exp *x = subExp2;
02592 Exp *l = subExp1;
02593 Type *ty = l->getType();
02594 if ( ty && ty->resolvesToPointer() &&
02595 ty->asPointer()->getPointsTo()->resolvesToArray()) {
02596 ArrayType *a = ty->asPointer()->getPointsTo()->asArray();
02597 int b = a->getBaseType()->getSize() / 8;
02598 int br = a->getBaseType()->getSize() % 8;
02599 assert(br == 0);
02600 if (x->getOper() != opIntConst || ((Const*)x)->getInt() >= b || a->getBaseType()->isArray()) {
02601 res = new Binary(opPlus,
02602 new Unary(opAddrOf,
02603 new Binary(opArrayIndex,
02604 Location::memOf(l->clone()),
02605 new Binary(opDiv, x->clone(), new Const(b)))),
02606 new Binary(opMod, x->clone(), new Const(b)));
02607 if (VERBOSE)
02608 LOG << "replacing " << this << " with " << res << "\n";
02609 if (l->getOper() == opSubscript) {
02610 RefExp *r = (RefExp*)l;
02611 if (r->getDef() && r->getDef()->isPhi()) {
02612 PhiAssign *pa = (PhiAssign*)r->getDef();
02613 LOG << "argh: " << pa->getStmtAt(1) << "\n";
02614 }
02615 }
02616 bMod = true;
02617 return res;
02618 }
02619 }
02620 }
02621 #endif
02622
02623 if ( op == opFMinus &&
02624 subExp1->getOper() == opFltConst &&
02625 ((Const*)subExp1)->getFlt() == 0.0) {
02626 res = new Unary(opFNeg, subExp2);
02627 bMod = true;
02628 return res;
02629 }
02630
02631 if ( (op == opPlus || op == opMinus) &&
02632 (subExp1->getOper() == opMults || subExp1->getOper() == opMult) &&
02633 subExp2->getOper() == opIntConst &&
02634 subExp1->getSubExp2()->getOper() == opIntConst) {
02635 int n1 = ((Const*)subExp2)->getInt();
02636 int n2 = ((Const*)subExp1->getSubExp2())->getInt();
02637 if (n1 == n2) {
02638 res = new Binary(subExp1->getOper(),
02639 new Binary(op,
02640 subExp1->getSubExp1()->clone(),
02641 new Const(1)),
02642 new Const(n1));
02643 bMod = true;
02644 return res;
02645 }
02646 }
02647
02648 if ( (op == opPlus || op == opMinus) &&
02649 subExp1->getOper() == opPlus &&
02650 subExp2->getOper() == opIntConst &&
02651 (subExp1->getSubExp2()->getOper() == opMults || subExp1->getSubExp2()->getOper() == opMult) &&
02652 subExp1->getSubExp2()->getSubExp2()->getOper() == opIntConst) {
02653 int n1 = ((Const*)subExp2)->getInt();
02654 int n2 = ((Const*)subExp1->getSubExp2()->getSubExp2())->getInt();
02655 if (n1 == n2) {
02656 res = new Binary(opPlus,
02657 subExp1->getSubExp1(),
02658 new Binary(subExp1->getSubExp2()->getOper(),
02659 new Binary(op,
02660 subExp1->getSubExp2()->getSubExp1()->clone(),
02661 new Const(1)),
02662 new Const(n1)));
02663 bMod = true;
02664 return res;
02665 }
02666 }
02667
02668
02669
02670 if ( op == opDiv &&
02671 subExp1->getOper() == opPlus &&
02672 subExp2->getOper() == opIntConst &&
02673 subExp1->getSubExp1()->getOper() == opMult &&
02674 subExp1->getSubExp2()->getOper() == opMult &&
02675 subExp1->getSubExp1()->getSubExp2()->getOper() == opIntConst &&
02676 subExp1->getSubExp2()->getSubExp2()->getOper() == opIntConst) {
02677 int a = ((Const*)subExp1->getSubExp1()->getSubExp2())->getInt();
02678 int b = ((Const*)subExp1->getSubExp2()->getSubExp2())->getInt();
02679 int c = ((Const*)subExp2)->getInt();
02680 if ((a%c) == 0 && (b%c) == 0) {
02681 res = new Binary(opPlus,
02682 new Binary(opMult, subExp1->getSubExp1()->getSubExp1(), new Const(a/c)),
02683 new Binary(opMult, subExp1->getSubExp2()->getSubExp1(), new Const(b/c)));
02684 bMod = true;
02685 return res;
02686 }
02687 }
02688
02689
02690
02691
02692
02693 if ( op == opMod && subExp1->getOper() == opPlus &&
02694 subExp2->getOper() == opIntConst &&
02695 subExp1->getSubExp1()->getOper() == opMult &&
02696 subExp1->getSubExp2()->getOper() == opMult &&
02697 subExp1->getSubExp1()->getSubExp2()->getOper() == opIntConst &&
02698 subExp1->getSubExp2()->getSubExp2()->getOper() == opIntConst) {
02699 int a = ((Const*)subExp1->getSubExp1()->getSubExp2())->getInt();
02700 int b = ((Const*)subExp1->getSubExp2()->getSubExp2())->getInt();
02701 int c = ((Const*)subExp2)->getInt();
02702 if ((a%c) == 0 && (b%c) == 0) {
02703 res = new Const(0);
02704 bMod = true;
02705 return res;
02706 }
02707 if ((a%c) == 0) {
02708 res = new Binary(opMod, subExp1->getSubExp2()->clone(), new Const(c));
02709 bMod = true;
02710 return res;
02711 }
02712 if ((b%c) == 0) {
02713 res = new Binary(opMod, subExp1->getSubExp1()->clone(), new Const(c));
02714 bMod = true;
02715 return res;
02716 }
02717 }
02718
02719
02720 if ( op == opBitAnd &&
02721 opSub1 == opMinus) {
02722 Exp* leftOfMinus = ((Binary*)subExp1)->getSubExp1();
02723 if (leftOfMinus->isIntConst() && ((Const*)leftOfMinus)->getInt() == 0) {
02724 Exp* rightOfMinus = ((Binary*)subExp1)->getSubExp2();
02725 if (rightOfMinus->getOper() == opLessUns) {
02726 Exp* leftOfLess = ((Binary*)rightOfMinus)->getSubExp1();
02727 if (leftOfLess->isIntConst() &&
02728 ((Const*)leftOfLess)->getInt() == 0) {
02729 res = getSubExp2();
02730 bMod = true;
02731 return res;
02732 }
02733 }
02734 }
02735 }
02736
02737
02738 if ( op == opSize &&
02739 subExp2->isLocation()) {
02740 #if 0
02741 Location *loc = (Location*)subExp2;
02742 unsigned n = (unsigned)((Const*)subExp1)->getInt();
02743 Type *ty = loc->getType();
02744 if (ty == NULL)
02745 loc->setType(new SizeType(n));
02746 else if (ty->getSize() != n)
02747 ty->setSize(n);
02748 #endif
02749 res = ((Binary*)res)->getSubExp2();
02750 bMod = true;
02751 return res;
02752 }
02753
02754 return res;
02755 }
02756
02757 Exp* Ternary::polySimplify(bool& bMod) {
02758 Exp *res = this;
02759
02760 subExp1 = subExp1->polySimplify(bMod);
02761 subExp2 = subExp2->polySimplify(bMod);
02762 subExp3 = subExp3->polySimplify(bMod);
02763
02764
02765 if ( op == opTern &&
02766 subExp2->getOper() == opIntConst &&
02767 subExp3->getOper() == opIntConst) {
02768 Const *s2 = (Const*)subExp2;
02769 Const *s3 = (Const*)subExp3;
02770
02771 if (s2->getInt() == 1 && s3->getInt() == 0) {
02772 res = this->getSubExp1();
02773 bMod = true;
02774 return res;
02775 }
02776 }
02777
02778
02779 if ( op == opTern &&
02780 subExp1->getOper() == opIntConst &&
02781 ((Const*)subExp1)->getInt() == 1) {
02782 res = this->getSubExp2();
02783 bMod = true;
02784 return res;
02785 }
02786
02787
02788 if ( op == opTern &&
02789 subExp1->getOper() == opIntConst &&
02790 ((Const*)subExp1)->getInt() == 0) {
02791 res = this->getSubExp3();
02792 bMod = true;
02793 return res;
02794 }
02795
02796 if ( (op == opSgnEx || op == opZfill) &&
02797 subExp3->getOper() == opIntConst) {
02798 res = this->getSubExp3();
02799 bMod = true;
02800 return res;
02801 }
02802
02803 if ( op == opFsize &&
02804 subExp3->getOper() == opItof &&
02805 *subExp1 == *subExp3->getSubExp2() &&
02806 *subExp2 == *subExp3->getSubExp1()) {
02807 res = this->getSubExp3();
02808 bMod = true;
02809 return res;
02810 }
02811
02812 if ( op == opFsize &&
02813 subExp3->getOper() == opFltConst) {
02814 res = this->getSubExp3();
02815 bMod = true;
02816 return res;
02817 }
02818
02819 if ( op == opItof &&
02820 subExp3->getOper() == opIntConst &&
02821 subExp2->getOper() == opIntConst &&
02822 ((Const*)subExp2)->getInt() == 32) {
02823 unsigned n = ((Const*)subExp3)->getInt();
02824 res = new Const(*(float*)&n);
02825 bMod = true;
02826 return res;
02827 }
02828
02829 if ( op == opFsize &&
02830 subExp3->getOper() == opMemOf &&
02831 subExp3->getSubExp1()->getOper() == opIntConst) {
02832 unsigned u = ((Const*)subExp3->getSubExp1())->getInt();
02833 Location *l = dynamic_cast<Location*>(subExp3);
02834 UserProc *p = l->getProc();
02835 if (p) {
02836 Prog *prog = p->getProg();
02837 bool ok;
02838 double d = prog->getFloatConstant(u, ok, ((Const*)subExp1)->getInt());
02839 if (ok) {
02840 if (VERBOSE)
02841 LOG << "replacing " << subExp3 << " with " << d << " in " << this << "\n";
02842 subExp3 = new Const(d);
02843 bMod = true;
02844 return res;
02845 }
02846 }
02847 }
02848
02849 if (op == opTruncu && subExp3->isIntConst()) {
02850 int from = ((Const*)subExp1)->getInt();
02851 int to = ((Const*)subExp2)->getInt();
02852 unsigned int val = ((Const*)subExp3)->getInt();
02853 if (from == 32) {
02854 if (to == 16) {
02855 res = new Const(val & 0xffff);
02856 bMod = true;
02857 return res;
02858 }
02859 if (to == 8) {
02860 res = new Const(val & 0xff);
02861 bMod = true;
02862 return res;
02863 }
02864 }
02865 }
02866
02867 if (op == opTruncs && subExp3->isIntConst()) {
02868 int from = ((Const*)subExp1)->getInt();
02869 int to = ((Const*)subExp2)->getInt();
02870 int val = ((Const*)subExp3)->getInt();
02871 if (from == 32) {
02872 if (to == 16) {
02873 res = new Const(val & 0xffff);
02874 bMod = true;
02875 return res;
02876 }
02877 if (to == 8) {
02878 res = new Const(val & 0xff);
02879 bMod = true;
02880 return res;
02881 }
02882 }
02883 }
02884
02885 return res;
02886 }
02887
02888 Exp* TypedExp::polySimplify(bool& bMod) {
02889 Exp *res = this;
02890
02891 if (subExp1->getOper() == opRegOf) {
02892
02893 res = ((Unary*)res)->getSubExp1();
02894 bMod = true;
02895 return res;
02896 }
02897
02898 subExp1 = subExp1->simplify();
02899 return res;
02900 }
02901
02902 Exp* RefExp::polySimplify(bool& bMod) {
02903 Exp *res = this;
02904
02905
02906 Exp *tmp = subExp1->polySimplify(bMod);
02907 if (bMod) {
02908 subExp1 = tmp;
02909 return res;
02910 }
02911
02912
02913
02914
02915 if (subExp1->getOper() == opDF && def == NULL) {
02916 res = new Const(0);
02917 bMod = true;
02918 return res;
02919 }
02920
02921
02922
02923 if (subExp1->isRegN(0) &&
02924 def && def->isAssign() &&
02925 ((Assign*)def)->getLeft()->isRegN(24)) {
02926 res = new TypedExp(new IntegerType(16), new RefExp(Location::regOf(24), def));
02927 bMod = true;
02928 return res;
02929 }
02930
02931
02932
02933 return res;
02934 }
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944 Exp* Unary::simplifyAddr() {
02945 Exp* sub;
02946 if (op == opMemOf && subExp1->isAddrOf()) {
02947 Unary* s = (Unary*)getSubExp1();
02948 return s->getSubExp1();
02949 }
02950 if (op != opAddrOf) {
02951
02952 subExp1 = subExp1->simplifyAddr();
02953 return this;
02954 }
02955 if (subExp1->getOper() == opMemOf) {
02956 Unary* s = (Unary*)getSubExp1();
02957 return s->getSubExp1();
02958 }
02959 if (subExp1->getOper() == opSize) {
02960 sub = subExp1->getSubExp2();
02961 if (sub->getOper() == opMemOf) {
02962
02963 Binary* b = (Binary*)getSubExp1();
02964
02965 Unary* u = (Unary*)b->getSubExp2();
02966
02967 return u->getSubExp1();
02968 }
02969 }
02970
02971
02972 subExp1 = subExp1->simplifyAddr();
02973 return this;
02974 }
02975
02976 Exp* Binary::simplifyAddr() {
02977 assert(subExp1 && subExp2);
02978
02979 subExp1 = subExp1->simplifyAddr();
02980 subExp2 = subExp2->simplifyAddr();
02981 return this;
02982 }
02983
02984 Exp* Ternary::simplifyAddr() {
02985 subExp1 = subExp1->simplifyAddr();
02986 subExp2 = subExp2->simplifyAddr();
02987 subExp3 = subExp3->simplifyAddr();
02988 return this;
02989 }
02990
02991
02992
02993
02994
02995
02996
02997
02998 void Exp::printt(std::ostream& os )
02999 {
03000 print(os);
03001 if (op != opTypedExp) return;
03002 Type* t = ((TypedExp*)this)->getType();
03003 os << "<" << std::dec << t->getSize();
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018 os << ">";
03019 }
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030 void Exp::printAsHL(std::ostream& os )
03031 {
03032 std::ostringstream ost;
03033 ost << this;
03034 std::string s(ost.str());
03035 if ((s.length() >= 4) && (s[1] == '[')) {
03036
03037 s.erase(1, 1);
03038 s.erase(s.length()-1);
03039 }
03040 os << s;
03041 }
03042
03043
03044
03045
03046
03047
03048
03049
03050 std::ostream& operator<<(std::ostream& os, Exp* p)
03051 {
03052 #if 1
03053
03054 p->printt(os);
03055 #else
03056 p->print(os);
03057 #endif
03058 return os;
03059 }
03060
03061
03062
03063
03064
03065
03066
03067
03068 Exp* Exp::fixSuccessor() {
03069 bool change;
03070 Exp* result;
03071
03072 if (search(new Unary(opSuccessor,
03073 Location::regOf(new Terminal(opWild))), result)) {
03074
03075 Exp* sub1 = ((Unary*)result)->getSubExp1();
03076 assert(sub1->getOper() == opRegOf);
03077 Exp* sub2 = ((Unary*)sub1)->getSubExp1();
03078 assert(sub2->getOper() == opIntConst);
03079
03080
03081
03082
03083 Unary* replace = (Unary*)sub1->clone();
03084 Const* c = (Const*)replace->getSubExp1();
03085 c->setInt(c->getInt()+1);
03086 Exp* res = searchReplace(result, replace, change);
03087 return res;
03088 }
03089 return this;
03090 }
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100 static Ternary srch1(opZfill, new Terminal(opWild), new Terminal(opWild),
03101 new Terminal(opWild));
03102 static Ternary srch2(opSgnEx, new Terminal(opWild), new Terminal(opWild),
03103 new Terminal(opWild));
03104 Exp* Exp::killFill() {
03105 Exp* res = this;
03106 std::list<Exp**> result;
03107 doSearch(&srch1, res, result, false);
03108 doSearch(&srch2, res, result, false);
03109 std::list<Exp**>::iterator it;
03110 for (it = result.begin(); it != result.end(); it++) {
03111
03112 **it = ((Ternary*)(**it))->getSubExp3();
03113 }
03114 return res;
03115 }
03116
03117 bool Exp::isTemp() {
03118 if (op == opTemp) return true;
03119 if (op != opRegOf) return false;
03120
03121 Exp* sub = ((Unary*)this)->getSubExp1();
03122 return sub->op == opTemp;
03123 }
03124
03125
03126 Exp *Exp::removeSubscripts(bool& allZero) {
03127 Exp *e = this;
03128 LocationSet locs;
03129 e->addUsedLocs(locs);
03130 LocationSet::iterator xx;
03131 allZero = true;
03132 for (xx = locs.begin(); xx != locs.end(); xx++) {
03133 if ((*xx)->getOper() == opSubscript) {
03134 RefExp *r1 = (RefExp*)*xx;
03135 Statement* def = r1->getDef();
03136 if (!(def == NULL || def->getNumber() == 0)) {
03137 allZero = false;
03138 }
03139 bool change;
03140 e = e->searchReplaceAll(*xx, r1->getSubExp1(), change);
03141 }
03142 }
03143 return e;
03144 }
03145
03146
03147
03148
03149
03150 Exp* Exp::fromSSAleft(UserProc* proc, Statement* d) {
03151 RefExp* r = new RefExp(this, d);
03152 return r->accept(new ExpSsaXformer(proc));
03153 }
03154
03155
03156 bool lessExpStar::operator()(const Exp* x, const Exp* y) const {
03157 return (*x < *y);
03158 }
03159
03160 bool lessTI::operator()(const Exp* x, const Exp* y) const {
03161 return (*x << *y);
03162 }
03163
03164
03165
03166
03167
03168 Exp* Exp::genConstraints(Exp* result) {
03169
03170 return new Terminal(opTrue);
03171 }
03172
03173 Exp* Const::genConstraints(Exp* result) {
03174 if (result->isTypeVal()) {
03175
03176 Type* t = ((TypeVal*)result)->getType();
03177 bool match = false;
03178 switch (op) {
03179 case opLongConst:
03180
03181
03182 case opIntConst:
03183 match = t->isInteger();
03184
03185
03186 if ((unsigned)u.i >= 0x100)
03187 match |= t->isPointer();
03188
03189 match |= t->isFloat();
03190 break;
03191 case opStrConst:
03192 match = (t->isPointer()) && (
03193 ((PointerType*)t)->getPointsTo()->isChar() ||
03194 (((PointerType*)t)->getPointsTo()->isArray() &&
03195 ((ArrayType*)((PointerType*)t)->getPointsTo())->getBaseType()->isChar()));
03196 break;
03197 case opFltConst:
03198 match = t->isFloat();
03199 break;
03200 default:
03201 break;
03202 }
03203 if (match) {
03204
03205
03206 return new Binary(opEquals,
03207 new Unary(opTypeOf, this),
03208 result->clone());
03209 } else
03210
03211 return new Terminal(opFalse);
03212 }
03213
03214 Type* t;
03215 switch (op) {
03216 case opIntConst: {
03217
03218 Type* intt = new IntegerType(0);
03219 Type* alph = PointerType::newPtrAlpha();
03220 return new Binary(opOr,
03221 new Binary(opAnd,
03222 new Binary(opEquals,
03223 result->clone(),
03224 new TypeVal(intt)),
03225 new Binary(opEquals,
03226 new Unary(opTypeOf,
03227
03228 this),
03229 new TypeVal(intt))),
03230 new Binary(opAnd,
03231 new Binary(opEquals,
03232 result->clone(),
03233 new TypeVal(alph)),
03234 new Binary(opEquals,
03235 new Unary(opTypeOf,
03236 this),
03237 new TypeVal(alph))));
03238 break;
03239 }
03240 case opLongConst:
03241 t = new IntegerType(64);
03242 break;
03243 case opStrConst:
03244 t = new PointerType(new CharType());
03245 break;
03246 case opFltConst:
03247 t = new FloatType();
03248 break;
03249 default:
03250 return false;
03251 }
03252 TypeVal* tv = new TypeVal(t);
03253 Exp* e = new Binary(opEquals, result->clone(), tv);
03254 return e;
03255 }
03256
03257 Exp* Unary::genConstraints(Exp* result) {
03258 if (result->isTypeVal()) {
03259
03260 return new Terminal(opTrue);
03261 }
03262
03263 switch (op) {
03264 case opRegOf:
03265 case opParam:
03266 case opGlobal:
03267 case opLocal:
03268 return new Binary(opEquals,
03269 new Unary(opTypeOf, this->clone()),
03270 result->clone());
03271 default:
03272 break;
03273 }
03274 return new Terminal(opTrue);
03275 }
03276
03277 Exp* Ternary::genConstraints(Exp* result) {
03278 Type* argHasToBe = NULL;
03279 Type* retHasToBe = NULL;
03280 switch (op) {
03281 case opFsize:
03282 case opItof:
03283 case opFtoi:
03284 case opSgnEx: {
03285 assert(subExp1->isIntConst());
03286 assert(subExp2->isIntConst());
03287 int fromSize = ((Const*)subExp1)->getInt();
03288 int toSize = ((Const*)subExp2)->getInt();
03289
03290 switch (op) {
03291 case opFsize:
03292 argHasToBe = new FloatType(fromSize);
03293 retHasToBe = new FloatType(toSize);
03294 break;
03295 case opItof:
03296 argHasToBe = new IntegerType(fromSize);
03297 retHasToBe = new FloatType(toSize);
03298 break;
03299 case opFtoi:
03300 argHasToBe = new FloatType(fromSize);
03301 retHasToBe = new IntegerType(toSize);
03302 break;
03303 case opSgnEx:
03304 argHasToBe = new IntegerType(fromSize);
03305 retHasToBe = new IntegerType(toSize);
03306 break;
03307 default:
03308 break;
03309 }
03310 }
03311 default:
03312 break;
03313 }
03314 Exp* res = NULL;
03315 if (retHasToBe) {
03316 if (result->isTypeVal()) {
03317
03318
03319 Type* t = ((TypeVal*)result)->getType();
03320
03321 if (! (*retHasToBe *= *t))
03322 return new Terminal(opFalse);
03323
03324 } else {
03325
03326 res = new Binary(opEquals,
03327 result,
03328 new TypeVal(retHasToBe));
03329 }
03330 }
03331 if (argHasToBe) {
03332
03333 Exp* con = subExp3->genConstraints(new TypeVal(argHasToBe));
03334 if (res) res = new Binary(opAnd, res, con);
03335 else res = con;
03336 }
03337 if (res == NULL)
03338 return new Terminal(opTrue);
03339 return res;
03340 }
03341
03342 Exp* RefExp::genConstraints(Exp* result) {
03343 OPER subOp = subExp1->getOper();
03344 switch (subOp) {
03345 case opRegOf:
03346 case opParam:
03347 case opGlobal:
03348 case opLocal:
03349 return new Binary(opEquals,
03350 new Unary(opTypeOf, this->clone()),
03351 result->clone());
03352 default:
03353 break;
03354 }
03355 return new Terminal(opTrue);
03356 }
03357
03358
03359 Exp* Binary::constrainSub(TypeVal* typeVal1, TypeVal* typeVal2) {
03360 assert(subExp1 && subExp2);
03361
03362 Exp* con1 = subExp1->genConstraints(typeVal1);
03363 Exp* con2 = subExp2->genConstraints(typeVal2);
03364 return new Binary(opAnd, con1, con2);
03365 }
03366
03367 Exp* Binary::genConstraints(Exp* result) {
03368 assert(subExp1 && subExp2);
03369
03370 Type* restrictTo = NULL;
03371 if (result->isTypeVal())
03372 restrictTo = ((TypeVal*)result)->getType();
03373 Exp* res = NULL;
03374 IntegerType* intType = new IntegerType(0);
03375 TypeVal intVal(intType);
03376 switch (op) {
03377 case opFPlus:
03378 case opFMinus:
03379 case opFMult:
03380 case opFDiv: {
03381 if (restrictTo && !restrictTo->isFloat())
03382
03383 return new Terminal(opFalse);
03384
03385
03386 FloatType* ft = new FloatType();
03387 TypeVal* ftv = new TypeVal(ft);
03388 res = constrainSub(ftv, ftv);
03389 if (!restrictTo)
03390
03391 res = new Binary(opAnd, res,
03392 new Binary(opEquals, result->clone(), ftv));
03393 return res;
03394 break;
03395 }
03396
03397 case opBitAnd:
03398 case opBitOr:
03399 case opBitXor: {
03400 if (restrictTo && !restrictTo->isInteger())
03401
03402 return new Terminal(opFalse);
03403
03404
03405 IntegerType* it = new IntegerType();
03406 TypeVal* itv = new TypeVal(it);
03407 res = constrainSub(itv, itv);
03408 if (!restrictTo)
03409
03410 res = new Binary(opAnd, res,
03411 new Binary(opEquals, result->clone(), itv));
03412 return res;
03413 break;
03414 }
03415
03416 case opPlus: {
03417
03418 Type* ptrType = PointerType::newPtrAlpha();
03419 TypeVal ptrVal(ptrType);
03420 if (!restrictTo || restrictTo && restrictTo->isInteger()) {
03421
03422 res = constrainSub(&intVal, &intVal);
03423 if (!restrictTo)
03424 res = new Binary(opAnd, res,
03425 new Binary(opEquals, result->clone(),
03426 intVal.clone()));
03427 }
03428
03429 if (!restrictTo || restrictTo && restrictTo->isPointer()) {
03430
03431 Exp* res2 = constrainSub(&ptrVal, &intVal);
03432 if (!restrictTo)
03433 res2 = new Binary(opAnd, res2,
03434 new Binary(opEquals, result->clone(),
03435 ptrVal.clone()));
03436 if (res) res = new Binary(opOr, res, res2);
03437 else res = res2;
03438
03439
03440 res2 = constrainSub(&intVal, &ptrVal);
03441 if (!restrictTo)
03442 res2 = new Binary(opAnd, res2,
03443 new Binary(opEquals, result->clone(),
03444 ptrVal.clone()));
03445 if (res) res = new Binary(opOr, res, res2);
03446 else res = res2;
03447 }
03448
03449 if (res) return res->simplify();
03450 else return new Terminal(opFalse);
03451 }
03452
03453 case opMinus: {
03454 Type* ptrType = PointerType::newPtrAlpha();
03455 TypeVal ptrVal(ptrType);
03456 if (!restrictTo || restrictTo && restrictTo->isInteger()) {
03457
03458 res = constrainSub(&intVal, &intVal);
03459 if (!restrictTo)
03460 res = new Binary(opAnd, res,
03461 new Binary(opEquals, result->clone(),
03462 intVal.clone()));
03463
03464
03465 Exp* res2 = constrainSub(&ptrVal, &ptrVal);
03466 if (!restrictTo)
03467 res2 = new Binary(opAnd, res2,
03468 new Binary(opEquals, result->clone(),
03469 intVal.clone()));
03470 if (res) res = new Binary(opOr, res, res2);
03471 else res = res2;
03472 }
03473
03474 if (!restrictTo || restrictTo && restrictTo->isPointer()) {
03475
03476 Exp* res2 = constrainSub(&ptrVal, &intVal);
03477 if (!restrictTo)
03478 res2 = new Binary(opAnd, res2,
03479 new Binary(opEquals, result->clone(),
03480 ptrVal.clone()));
03481 if (res) res = new Binary(opOr, res, res2);
03482 else res = res2;
03483 }
03484
03485 if (res) return res->simplify();
03486 else return new Terminal(opFalse);
03487 }
03488
03489 case opSize: {
03490
03491
03492 assert(subExp1->isIntConst());
03493 int sz = ((Const*)subExp1)->getInt();
03494 if (restrictTo) {
03495 int rsz = restrictTo->getSize();
03496 if (rsz == 0) {
03497
03498
03499 Type* it = restrictTo->clone();
03500 it->setSize(sz);
03501 return new Binary(opEquals,
03502 new Unary(opTypeOf, subExp2),
03503 new TypeVal(it));
03504 }
03505 return new Terminal(
03506 (rsz == sz) ? opTrue : opFalse);
03507 }
03508
03509 return new Binary(opEquals, result->clone(), new TypeVal(new SizeType(sz)));
03510 }
03511
03512 default:
03513 break;
03514 }
03515 return new Terminal(opTrue);
03516 }
03517
03518 Exp* Location::polySimplify(bool& bMod) {
03519 Exp *res = Unary::polySimplify(bMod);
03520
03521 if (res->getOper() == opMemOf && res->getSubExp1()->getOper() == opAddrOf) {
03522 if (VERBOSE)
03523 LOG << "polySimplify " << res << "\n";
03524 res = res->getSubExp1()->getSubExp1();
03525 bMod = true;
03526 return res;
03527 }
03528
03529
03530 if (res->getOper() == opMemOf && res->getSubExp1()->getOper() == opAddrOf &&
03531 res->getSubExp1()->getSubExp1()->getOper() == opMemberAccess) {
03532 res = subExp1->getSubExp1();
03533 bMod = true;
03534 return res;
03535 }
03536
03537 return res;
03538 }
03539
03540 void Location::getDefinitions(LocationSet& defs) {
03541
03542
03543 if (op == opRegOf && ((Const*)subExp1)->getInt() == 24) {
03544 defs.insert(Location::regOf(0));
03545 }
03546 }
03547
03548
03549 const char* Const::getFuncName() {
03550 return u.pp->getName();
03551 }
03552
03553 Exp* Unary::simplifyConstraint() {
03554 subExp1 = subExp1->simplifyConstraint();
03555 return this;
03556 }
03557
03558 Exp* Binary::simplifyConstraint() {
03559 assert(subExp1 && subExp2);
03560
03561 subExp1 = subExp1->simplifyConstraint();
03562 subExp2 = subExp2->simplifyConstraint();
03563 switch (op) {
03564 case opEquals: {
03565 if (subExp1->isTypeVal() && subExp2->isTypeVal()) {
03566
03567 Type* t1 = NULL;
03568 Type* t2 = NULL;
03569 if (!t1->isPointerToAlpha() && !t2->isPointerToAlpha()) {
03570 delete this;
03571 if (*t1 == *t2)
03572 return new Terminal(opTrue);
03573 else
03574 return new Terminal(opFalse);
03575 }
03576 }
03577 break;
03578 }
03579
03580 case opOr:
03581 case opAnd:
03582 case opNot:
03583 return simplify();
03584 default:
03585 break;
03586 }
03587 return this;
03588 }
03589
03590
03591
03592
03593
03594
03595 bool Unary::accept(ExpVisitor* v) {
03596 bool override, ret = v->visit(this, override);
03597 if (override) return ret;
03598 if (ret) ret = subExp1->accept(v);
03599 return ret;
03600 }
03601
03602 bool Binary::accept(ExpVisitor* v) {
03603 assert(subExp1 && subExp2);
03604
03605 bool override, ret = v->visit(this, override);
03606 if (override) return ret;
03607 if (ret) ret = subExp1->accept(v);
03608 if (ret) ret = subExp2->accept(v);
03609 return ret;
03610 }
03611
03612 bool Ternary::accept(ExpVisitor* v) {
03613 bool override, ret = v->visit(this, override);
03614 if (override) return ret;
03615 if (ret) ret = subExp1->accept(v);
03616 if (ret) ret = subExp2->accept(v);
03617 if (ret) ret = subExp3->accept(v);
03618 return ret;
03619 }
03620
03621
03622
03623 bool TypedExp::accept(ExpVisitor* v) {
03624 bool override, ret = v->visit(this, override);
03625 if (override) return ret;
03626 if (ret) ret = subExp1->accept(v);
03627 return ret;
03628 }
03629 bool FlagDef::accept(ExpVisitor* v) {
03630 bool override, ret = v->visit(this, override);
03631 if (override) return ret;
03632 if (ret) ret = subExp1->accept(v);
03633 return ret;
03634 }
03635 bool RefExp::accept(ExpVisitor* v) {
03636 bool override, ret = v->visit(this, override);
03637 if (override) return ret;
03638 if (ret) ret = subExp1->accept(v);
03639 return ret;
03640 }
03641 bool Location::accept(ExpVisitor* v) {
03642 bool override = false, ret = v->visit(this, override);
03643 if (override) return ret;
03644 if (ret) ret &= subExp1->accept(v);
03645 return ret;
03646 }
03647
03648
03649 bool Terminal::accept(ExpVisitor* v) {return v->visit(this);}
03650 bool Const::accept(ExpVisitor* v) {return v->visit(this);}
03651 bool TypeVal::accept(ExpVisitor* v) {return v->visit(this);}
03652
03653
03654
03655
03656
03657 void Exp::fixLocationProc(UserProc* p) {
03658
03659
03660
03661 FixProcVisitor fpv;
03662 fpv.setProc(p);
03663 accept(&fpv);
03664 }
03665
03666
03667
03668 UserProc* Exp::findProc() {
03669 GetProcVisitor gpv;
03670 accept(&gpv);
03671 return gpv.getProc();
03672 }
03673
03674 void Exp::setConscripts(int n, bool bClear) {
03675 SetConscripts sc(n, bClear);
03676 accept(&sc);
03677 }
03678
03679
03680
03681 Exp* Exp::stripSizes() {
03682 SizeStripper ss;
03683 return accept(&ss);
03684 }
03685
03686 Exp* Unary::accept(ExpModifier* v) {
03687
03688
03689 bool recur;
03690 Unary* ret = (Unary*)v->preVisit(this, recur);
03691 if (recur) subExp1 = subExp1->accept(v);
03692 return v->postVisit(ret);
03693 }
03694 Exp* Binary::accept(ExpModifier* v) {
03695 assert(subExp1 && subExp2);
03696
03697 bool recur;
03698 Binary* ret = (Binary*)v->preVisit(this, recur);
03699 if (recur) subExp1 = subExp1->accept(v);
03700 if (recur) subExp2 = subExp2->accept(v);
03701 return v->postVisit(ret);
03702 }
03703 Exp* Ternary::accept(ExpModifier* v) {
03704 bool recur;
03705 Ternary* ret = (Ternary*)v->preVisit(this, recur);
03706 if (recur) subExp1 = subExp1->accept(v);
03707 if (recur) subExp2 = subExp2->accept(v);
03708 if (recur) subExp3 = subExp3->accept(v);
03709 return v->postVisit(ret);
03710 }
03711
03712 Exp* Location::accept(ExpModifier* v) {
03713
03714
03715 bool recur;
03716 Location* ret = (Location*)v->preVisit(this, recur);
03717 if (recur) subExp1 = subExp1->accept(v);
03718 return v->postVisit(ret);
03719 }
03720
03721 Exp* RefExp::accept(ExpModifier* v) {
03722 bool recur;
03723 RefExp* ret = (RefExp*)v->preVisit(this, recur);
03724 if (recur) subExp1 = subExp1->accept(v);
03725 return v->postVisit(ret);
03726 }
03727
03728 Exp* FlagDef::accept(ExpModifier* v) {
03729 bool recur;
03730 FlagDef* ret = (FlagDef*)v->preVisit(this, recur);
03731 if (recur) subExp1 = subExp1->accept(v);
03732 return v->postVisit(ret);
03733 }
03734
03735 Exp* TypedExp::accept(ExpModifier* v) {
03736 bool recur;
03737 TypedExp* ret = (TypedExp*)v->preVisit(this, recur);
03738 if (recur) subExp1 = subExp1->accept(v);
03739 return v->postVisit(ret);
03740 }
03741
03742 Exp* Terminal::accept(ExpModifier* v) {
03743
03744 return v->postVisit((Terminal*)v->preVisit(this));
03745 }
03746
03747 Exp* Const::accept(ExpModifier* v) {
03748 return v->postVisit((Const*)v->preVisit(this));
03749 }
03750
03751 Exp* TypeVal::accept(ExpModifier* v) {
03752 return v->postVisit((TypeVal*)v->preVisit(this));
03753 }
03754
03755 void child(Exp* e, int ind) {
03756 if (e == NULL) {
03757 std::cerr << std::setw(ind+4) << " " << "<NULL>\n" << std::flush;
03758 return;
03759 }
03760 void* vt = *(void**)e;
03761 if (vt == NULL) {
03762 std::cerr << std::setw(ind+4) << " " << "<NULL VT>\n" << std::flush;
03763 return;
03764 }
03765 e->printx(ind+4);
03766 }
03767
03768 void Unary::printx(int ind) {
03769 std::cerr << std::setw(ind) << " " << operStrings[op] << "\n" << std::flush;
03770 child(subExp1, ind);
03771 }
03772
03773 void Binary::printx(int ind) {
03774 assert(subExp1 && subExp2);
03775
03776 std::cerr << std::setw(ind) << " " << operStrings[op] << "\n" << std::flush;
03777 child(subExp1, ind);
03778 child(subExp2, ind);
03779 }
03780
03781 void Ternary::printx(int ind) {
03782 std::cerr << std::setw(ind) << " " << operStrings[op] << "\n" << std::flush;
03783 child(subExp1, ind);
03784 child(subExp2, ind);
03785 child(subExp3, ind);
03786 }
03787
03788 void Const::printx(int ind) {
03789 std::cerr << std::setw(ind) << " " << operStrings[op] << " ";
03790 switch (op) {
03791 case opIntConst:
03792 std::cerr << std::dec << u.i; break;
03793 case opStrConst:
03794 std::cerr << "\"" << u.p << "\""; break;
03795 case opFltConst:
03796 std::cerr << u.d; break;
03797 case opFuncConst:
03798 std::cerr << u.pp->getName(); break;
03799 default:
03800 std::cerr << std::hex << "?" << (int)op << "?";
03801 }
03802 if (conscript)
03803 std::cerr << " \\" << std::dec << conscript << "\\";
03804 std::cerr << std::flush << "\n";
03805 }
03806
03807 void TypeVal::printx(int ind) {
03808 std::cerr << std::setw(ind) << " " << operStrings[op] << " ";
03809 std::cerr << val->getCtype() << std::flush << "\n";
03810 }
03811
03812 void TypedExp::printx(int ind) {
03813 std::cerr << std::setw(ind) << " " << operStrings[op] << " ";
03814 std::cerr << type->getCtype() << std::flush << "\n";
03815 child(subExp1, ind);
03816 }
03817
03818 void Terminal::printx(int ind) {
03819 std::cerr << std::setw(ind) << " " << operStrings[op] << "\n" << std::flush;
03820 }
03821
03822 void RefExp::printx(int ind) {
03823 std::cerr << std::setw(ind) << " " << operStrings[op] << " ";
03824 std::cerr << "{";
03825 if (def == 0) std::cerr << "NULL";
03826 else std::cerr << std::hex << (unsigned)def << "=" << std::dec << def->getNumber();
03827 std::cerr << "}\n" << std::flush;
03828 child(subExp1, ind);
03829 }
03830
03831 char* Exp::getAnyStrConst() {
03832 Exp* e = this;
03833 if (op == opAddrOf) {
03834 e = ((Location*)this)->getSubExp1();
03835 if (e->op == opSubscript)
03836 e = ((Unary*)e)->getSubExp1();
03837 if (e->op == opMemOf)
03838 e = ((Location*)e)->getSubExp1();
03839 }
03840 if (e->op != opStrConst) return NULL;
03841 return ((Const*)e)->getStr();
03842 }
03843
03844
03845
03846 void Exp::addUsedLocs(LocationSet& used, bool memOnly) {
03847 UsedLocsFinder ulf(used, memOnly);
03848 accept(&ulf);
03849 }
03850
03851
03852 Exp* Exp::expSubscriptVar(Exp* e, Statement* def) {
03853 ExpSubscripter es(e, def);
03854 return accept(&es);
03855 }
03856
03857
03858
03859 Exp* Exp::expSubscriptValNull(Exp* e) {
03860 return expSubscriptVar(e, NULL);
03861 }
03862
03863
03864 Exp* Exp::expSubscriptAllNull() {
03865 return expSubscriptVar(new Terminal(opWild), NULL );
03866 }
03867
03868 Location* Location::local(const char *nam, UserProc *p) {
03869 return new Location(opLocal, new Const((char*)nam), p);
03870 }
03871
03872
03873 bool RefExp::isImplicitDef() {
03874 return def == NULL || def->getKind() == STMT_IMPASSIGN;
03875 }
03876
03877 Exp* Exp::bypass() {
03878 CallBypasser cb(NULL);
03879 return accept(&cb);
03880 }
03881
03882 void Exp::bypassComp() {
03883 if (op != opMemOf) return;
03884 ((Location*)this)->setSubExp1(((Location*)this)->getSubExp1()->bypass());
03885 }
03886
03887 int Exp::getComplexityDepth(UserProc* proc) {
03888 ComplexityFinder cf(proc);
03889 accept(&cf);
03890 return cf.getDepth();
03891 }
03892
03893 int Exp::getMemDepth() {
03894 MemDepthFinder mdf;
03895 accept(&mdf);
03896 return mdf.getDepth();
03897 }
03898
03899
03900 Exp* Exp::propagateAll() {
03901 ExpPropagator ep;
03902 return accept(&ep);
03903 }
03904
03905
03906 Exp* Exp::propagateAllRpt(bool& changed) {
03907 ExpPropagator ep;
03908 changed = false;
03909 Exp* ret = this;
03910 while (true) {
03911 ep.clearChanged();
03912 ret = ret->accept(&ep);
03913 if (ep.isChanged())
03914 changed = true;
03915 else
03916 break;
03917 }
03918 return ret;
03919 }
03920
03921 bool Exp::containsFlags() {
03922 FlagsFinder ff;
03923 accept(&ff);
03924 return ff.isFound();
03925 }
03926
03927
03928
03929 bool Exp::containsBadMemof(UserProc* proc) {
03930 BadMemofFinder bmf(proc);
03931 accept(&bmf);
03932 return bmf.isFound();
03933 }
03934
03935
03936 bool Exp::containsMemof(UserProc* proc) {
03937 ExpHasMemofTester ehmt(proc);
03938 accept(&ehmt);
03939 return ehmt.getResult();
03940 }
03941
03942
03943 #ifdef USING_MEMO
03944 class ConstMemo : public Memo {
03945 public:
03946 ConstMemo(int m) : Memo(m) { }
03947
03948 union {
03949 int i;
03950 ADDRESS a;
03951 QWord ll;
03952 double d;
03953 char* p;
03954 Proc* pp;
03955 } u;
03956 int conscript;
03957 };
03958
03959 Memo *Const::makeMemo(int mId)
03960 {
03961 ConstMemo *m = new ConstMemo(mId);
03962 memcpy(&m->u, &u, sizeof(u));
03963 m->conscript = conscript;
03964 return m;
03965 }
03966
03967 void Const::readMemo(Memo *mm, bool dec)
03968 {
03969 ConstMemo *m = dynamic_cast<ConstMemo*>(mm);
03970 memcpy(&u, &m->u, sizeof(u));
03971 conscript = m->conscript;
03972 }
03973
03974 class TerminalMemo : public Memo {
03975 public:
03976 TerminalMemo(int m) : Memo(m) { }
03977 };
03978
03979 Memo *Terminal::makeMemo(int mId)
03980 {
03981 TerminalMemo *m = new TerminalMemo(mId);
03982 return m;
03983 }
03984
03985 void Terminal::readMemo(Memo *mm, bool dec)
03986 {
03987
03988
03989 }
03990
03991 class UnaryMemo : public Memo {
03992 public:
03993 UnaryMemo(int m) : Memo(m) { }
03994 };
03995
03996 Memo *Unary::makeMemo(int mId)
03997 {
03998 UnaryMemo *m = new UnaryMemo(mId);
03999 return m;
04000 }
04001
04002 void Unary::readMemo(Memo *mm, bool dec)
04003 {
04004
04005
04006 }
04007
04008 class BinaryMemo : public Memo {
04009 public:
04010 BinaryMemo(int m) : Memo(m) { }
04011 };
04012
04013 Memo *Binary::makeMemo(int mId)
04014 {
04015 BinaryMemo *m = new BinaryMemo(mId);
04016 return m;
04017 }
04018
04019 void Binary::readMemo(Memo *mm, bool dec)
04020 {
04021
04022
04023 }
04024
04025 class TernaryMemo : public Memo {
04026 public:
04027 TernaryMemo(int m) : Memo(m) { }
04028 };
04029
04030 Memo *Ternary::makeMemo(int mId)
04031 {
04032 TernaryMemo *m = new TernaryMemo(mId);
04033 return m;
04034 }
04035
04036 void Ternary::readMemo(Memo *mm, bool dec)
04037 {
04038
04039
04040 }
04041
04042 class TypedExpMemo : public Memo {
04043 public:
04044 TypedExpMemo(int m) : Memo(m) { }
04045 };
04046
04047 Memo *TypedExp::makeMemo(int mId)
04048 {
04049 TypedExpMemo *m = new TypedExpMemo(mId);
04050 return m;
04051 }
04052
04053 void TypedExp::readMemo(Memo *mm, bool dec)
04054 {
04055
04056
04057 }
04058
04059 class FlagDefMemo : public Memo {
04060 public:
04061 FlagDefMemo(int m) : Memo(m) { }
04062 };
04063
04064 Memo *FlagDef::makeMemo(int mId)
04065 {
04066 FlagDefMemo *m = new FlagDefMemo(mId);
04067 return m;
04068 }
04069
04070 void FlagDef::readMemo(Memo *mm, bool dec)
04071 {
04072
04073
04074 }
04075
04076 class RefExpMemo : public Memo {
04077 public:
04078 RefExpMemo(int m) : Memo(m) { }
04079 };
04080
04081 Memo *RefExp::makeMemo(int mId)
04082 {
04083 RefExpMemo *m = new RefExpMemo(mId);
04084 return m;
04085 }
04086
04087 void RefExp::readMemo(Memo *mm, bool dec)
04088 {
04089
04090
04091 }
04092
04093 class TypeValMemo : public Memo {
04094 public:
04095 TypeValMemo(int m) : Memo(m) { }
04096 };
04097
04098 Memo *TypeVal::makeMemo(int mId)
04099 {
04100 TypeValMemo *m = new TypeValMemo(mId);
04101 return m;
04102 }
04103
04104 void TypeVal::readMemo(Memo *mm, bool dec)
04105 {
04106
04107
04108 }
04109
04110 class LocationMemo : public Memo {
04111 public:
04112 LocationMemo(int m) : Memo(m) { }
04113 };
04114
04115 Memo *Location::makeMemo(int mId)
04116 {
04117 LocationMemo *m = new LocationMemo(mId);
04118 return m;
04119 }
04120
04121 void Location::readMemo(Memo *mm, bool dec)
04122 {
04123
04124
04125 }
04126 #endif // #ifdef USING_MEMO