exp.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002-2006 Mike Van Emmerik and Trent Waddington
00003  */
00004 /*==============================================================================
00005  * FILE:       exp.cpp
00006  * OVERVIEW:   Implementation of the Exp and related classes.
00007  *============================================================================*/
00008 /*
00009  * $Revision: 1.215 $   // 1.172.2.20
00010  * 05 Apr 02 - Mike: Created
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>      // For accumulate
00022 #include <algorithm>    // For std::max()
00023 #include <map>          // In decideType()
00024 #include <sstream>      // Need gcc 3.0 or better
00025 #include "types.h"
00026 #include "statement.h"
00027 #include "cfg.h"
00028 #include "exp.h"
00029 #include "register.h"
00030 #include "rtl.h"        // E.g. class ParamEntry in decideType()
00031 #include "proc.h"
00032 #include "signature.h"
00033 #include "prog.h"
00034 #include "operstrings.h"// Defines a large array of strings for the createDotFile etc. functions. Needs -I. to find it
00035 #include "util.h"
00036 #include "boomerang.h"
00037 //#include "transformer.h"
00038 #include "visitor.h"
00039 #include "log.h"
00040 #include <iomanip>          // For std::setw etc
00041 
00042 extern char debug_buffer[];      ///< For prints functions
00043 
00044 /*==============================================================================
00045  * FUNCTION:        Const::Const etc
00046  * OVERVIEW:        Constructors
00047  * PARAMETERS:      As required
00048  * RETURNS:         <nothing>
00049  *============================================================================*/
00050 
00051 // Derived class constructors
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 /// \remark This is bad. We need a way of constructing true unsigned constants
00059 Const::Const(ADDRESS a) : Exp(opIntConst),  conscript(0), type(new VoidType) {u.a = a;}
00060 
00061 // Copy constructor
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) {}      // Copy constructor
00066 
00067 Unary::Unary(OPER op)
00068     : Exp(op) {
00069     subExp1 = 0;        // Initialise the pointer
00070     //assert(op != opRegOf);
00071 }
00072 
00073 Unary::Unary(OPER op, Exp* e)
00074     : Exp(op) {
00075     subExp1 = e;        // Initialise the pointer
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;        // Initialise the 2nd pointer. The first pointer is initialised in the Unary constructor
00087 }
00088 Binary::Binary(OPER op, Exp* e1, Exp* e2)
00089     : Unary(op, e1)
00090 {
00091     subExp2 = e2;       // Initialise the 2nd pointer
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  * Create a new Location expression.
00142  * \param op Should be \opRegOf, opMemOf, opLocal, opGlobal, opParam or opTemp.
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         // eep.. this almost always causes problems
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  * FUNCTION:        Unary::~Unary etc
00180  * OVERVIEW:        Destructors.
00181  * PARAMETERS:      <none>
00182  * RETURNS:         <nothing>
00183  *============================================================================*/
00184 Unary::~Unary() {
00185     // Remember to ;//delete all children
00186     if (subExp1 != 0) ;//delete subExp1;
00187 }
00188 Binary::~Binary() {
00189     if (subExp2 != 0) ;//delete subExp2;
00190     // Note that the first pointer is destructed in the Exp1 destructor
00191 }
00192 Ternary::~Ternary() {
00193     if (subExp3 != 0) ;//delete subExp3;
00194 }
00195 FlagDef::~FlagDef() {
00196     ;//delete rtl;
00197 }
00198 TypeVal::~TypeVal() {
00199     ;//delete val;
00200 }
00201 
00202 /*==============================================================================
00203  * FUNCTION:        Unary::setSubExp1 etc
00204  * OVERVIEW:        Set requested subexpression; 1 is first
00205  * PARAMETERS:      Pointer to subexpression to set
00206  * NOTE:            If an expression already exists, it is ;//deleted
00207  * RETURNS:         <nothing>
00208  *============================================================================*/
00209 void Unary::setSubExp1(Exp* e) {
00210     if (subExp1 != 0) ;//delete subExp1;
00211     subExp1 = e;
00212     assert(subExp1);
00213 }
00214 void Binary::setSubExp2(Exp* e) {
00215     if (subExp2 != 0) ;//delete subExp2;
00216     subExp2 = e;
00217     assert(subExp1 && subExp2);
00218 }
00219 void Ternary::setSubExp3(Exp* e) {
00220     if (subExp3 != 0) ;//delete subExp3;
00221     subExp3 = e;
00222     assert(subExp1 && subExp2 && subExp3);
00223 }
00224 /*==============================================================================
00225  * FUNCTION:        Unary::getSubExp1 etc
00226  * OVERVIEW:        Get subexpression
00227  * PARAMETERS:      <none>
00228  * RETURNS:         Pointer to the requested subexpression
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 // This to satisfy the compiler (never gets called!)
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  * FUNCTION:        Binary::commute
00264  * OVERVIEW:        Swap the two subexpressions
00265  * PARAMETERS:      <none>
00266  * RETURNS:         <nothing>
00267  *============================================================================*/
00268 /// Swap the two subexpressions.
00269 void Binary::commute() {
00270     Exp* t = subExp1;
00271     subExp1 = subExp2;
00272     subExp2 = t;
00273     assert(subExp1 && subExp2);
00274 }
00275 
00276 /*==============================================================================
00277  * FUNCTION:        Const::clone etc
00278  * OVERVIEW:        Virtual function to make a clone of myself, i.e. to create
00279  *                   a new Exp with the same contents as myself, but not sharing
00280  *                   any memory. Deleting the clone will not affect this object.
00281  *                   Pointers to subexpressions are not copied, but also cloned.
00282  * PARAMETERS:      <none>
00283  * RETURNS:         Pointer to cloned object
00284  *============================================================================*/
00285 Exp* Const::clone() {
00286     // Note: not actually cloning the Type* type pointer. Probably doesn't matter with GC
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  * FUNCTION:        Const::operator==() etc
00335  * OVERVIEW:        Virtual function to compare myself for equality with
00336  *                  another Exp
00337  * PARAMETERS:      Ref to other Exp
00338  * RETURNS:         True if equal
00339  *============================================================================*/
00340 bool Const::operator==(const Exp& o) const {
00341     // Note: the casts of o to Const& are needed, else op is protected! Duh.
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) ||           // Wild matches anything
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     // This is the strict type version
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     // Allow a def of (Statement*)-1 as a wild card
00403     if ((int)def == -1) return true;
00404     // Allow a def of NULL to match a def of an implicit assignment
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  * FUNCTION:        Const::operator<() etc
00419  * OVERVIEW:        Virtual function to compare myself with another Exp
00420  * NOTE:            The test for a wildcard is only with this object, not the other object (o).
00421  *                  So when searching and there could be wildcards, use search == *this not *this == search
00422  * PARAMETERS:      Ref to other Exp
00423  * RETURNS:         True if equal
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 {        // Type insensitive
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 {        // Type sensitive
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     // Allow a wildcard def to match any
00494     if (def == (Statement*)-1) return false;    // Not less (equal)
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  * FUNCTION:        Const::operator*=() etc
00507  * OVERVIEW:        Virtual function to compare myself for equality with another Exp, *ignoring subscripts*
00508  * PARAMETERS:      Ref to other Exp
00509  * RETURNS:         True if equal
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     // This is the strict type version
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  * FUNCTION:        Const::print etc
00574  * OVERVIEW:        "Print" in infix notation the expression to a stream.
00575  *                  Mainly for debugging, or maybe some low level windows
00576  * PARAMETERS:      Ref to an output stream
00577  * RETURNS:         <nothing>
00578  *============================================================================*/
00579 
00580 //  //  //  //
00581 //  Const   //
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);      // FIXME: needs an intelligent printer
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 //  Binary  //
00624 //  //  //  //
00625 void Binary::printr(std::ostream& os, bool html) {
00626     assert(subExp1 && subExp2);
00627     // The "r" is for recursive: the idea is that we don't want parentheses at the outer level, but a subexpression
00628     // (recursed from a higher level), we want the parens (at least for standard infix operators)
00629     switch (op) {
00630         case opSize:
00631         case opList:        // Otherwise, you get (a, (b, (c, d)))
00632             // There may be others
00633             // These are the noparen cases
00634             print(os, html); return;
00635         default:
00636             break;
00637     }
00638     // Normal case: we want the parens
00639     // std::ostream::operator<< uses print(), which does not have the parens
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     // Special cases
00650     switch (op) {
00651         case opSize:
00652             // This can still be seen after decoding and before type analysis after m[...]
00653             // *size* is printed after the expression, even though it comes from the first subexpression
00654             p2->printr(os, html); os << "*"; p1->printr(os, html);
00655             os << "*";
00656             return;
00657         case opFlagCall:
00658             // The name of the flag function (e.g. ADDFLAGS) should be enough
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             // Because "," is the lowest precedence operator, we don't need printr here.
00673             // Also, same as UQBT, so easier to test
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     // Ordinary infix operators. Emit parens around the binary
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;   // Raising to power
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 << " &lt; "; else os << " < ";  break;
00725         case opGtr:     if (html) os << " &gt; "; else os << " > ";  break;
00726         case opLessEq:  if (html) os << " &lt;= "; else os << " <= "; break;
00727         case opGtrEq:   if (html) os << " &gt;= "; else os << " >= "; break;
00728         case opLessUns: if (html) os << " &lt;u "; else os << " <u "; break;
00729         case opGtrUns:  if (html) os << " &gt;u "; else os << " >u "; break;
00730         case opLessEqUns: if (html) os << " &lt;u "; else os<< " <=u ";break;
00731         case opGtrEqUns: if (html) os << " &gt;=u "; else os << " >=u ";break;
00732         case opUpper:   os << " GT "; break;
00733         case opLower:   os << " LT "; break;
00734         case opShiftL:  if (html) os << " &lt;&lt; "; else os << " << "; break;
00735         case opShiftR:  if (html) os << " &gt;&gt; "; else os << " >> "; break;
00736         case opShiftRA: if (html) os << " &gt;&gt;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 //   Terminal   //
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 //   Unary  //
00791 //  //  //  //
00792 void Unary::print(std::ostream& os, bool html) {
00793     Exp* p1 = ((Unary*)this)->getSubExp1();
00794     switch (op) {
00795         //  //  //  //  //  //  //
00796         //  x[ subexpression ]  //
00797         //  //  //  //  //  //  //
00798         case opRegOf:
00799             // Make a special case for the very common case of r[intConst]
00800             if (p1->isIntConst()) {
00801                 os << "r" << std::dec << ((Const*)p1)->getInt();
00802                 break;
00803             } else if (p1->isTemp()) {
00804                 // Just print the temp {   // balance }s
00805                 p1->print(os, html);
00806                 break;
00807             }
00808             // Else fall through
00809         case opMemOf: case opAddrOf:  case opVar: case opTypeOf: case opKindOf:
00810             switch (op) {
00811                 case opRegOf: os << "r["; break;    // e.g. r[r2]
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;     // Suppress compiler warning
00818             }
00819             if (op == opVar) ((Const*)p1)->printNoQuotes(os);
00820             // Use print, not printr, because this is effectively the top level again (because the [] act as
00821             // parentheses)
00822             else {
00823                 p1->print(os, html);
00824             }
00825             os << "]";
00826             break;
00827 
00828         //  //  //  //  //  //  //
00829         //    Unary operators   //
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 << "!";          // Operator after expression
00843             return;
00844 
00845         //  //  //  //  //  //  //  //
00846         //  Function-like operators //
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;         // For warning
00870             }
00871             p1->printr(os, html);
00872             os << ")";
00873             return;
00874 
00875         //  Misc    //
00876         case opSgnEx:      // Different because the operator appears last
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             // Temp: just print the string, no quotes
00888         case opGlobal:
00889         case opLocal:
00890         case opParam:
00891             // Print a more concise form than param["foo"] (just foo)
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 //  Ternary //
00922 //  //  //  //
00923 void Ternary::printr(std::ostream& os, bool html) {
00924     // The function-like operators don't need parentheses
00925     switch (op) {
00926         // The "function-like" ternaries
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             // No paren case
00932             print(os); return;
00933         default:
00934             break;
00935     }
00936     // All other cases, we use the parens
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         // The "function-like" ternaries
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;         // For warning
00962             }
00963             // Use print not printr here, since , has the lowest precendence of all.
00964             // Also it makes it the same as UQBT, so it's easier to test
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     // Else must be ?: or @ (traditional ternary operators)
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 << " : ";        // Need wide spacing here
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 // TypedExp //
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 //  RefExp  //
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 << "-";          // So you can tell the difference with {0}
01021     if (html)
01022         os << "</sub>";
01023     else
01024         os << "}";
01025 }
01026 
01027 //  //  //  //
01028 // TypeVal  //
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  * FUNCTION:        Exp::prints
01039  * OVERVIEW:        Print to a static string (for debugging)
01040  * PARAMETERS:      <none>
01041  * RETURNS:         Address of the static buffer
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  * FUNCTION:        Exp::createDotFile etc
01058  * OVERVIEW:        Create a dotty file (use dotty to display the file; search the web for "graphviz"). 
01059  *                  Mainly for debugging
01060  * PARAMETERS:      Name of the file to create
01061  * RETURNS:         <nothing>
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 //  Const   //
01078 //  //  //  //
01079 void Const::appendDotFile(std::ofstream& of) {
01080     // We define a unique name for each node as "e123456" if the address of "this" == 0x123456
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         // Might want to distinguish this better, e.g. "(func*)myProc"
01088         case opFuncConst: of << u.pp->getName(); break;
01089         default:
01090             break;
01091     }
01092     of << " }\"];\n";
01093 }
01094 
01095 //  //  //  //
01096 // Terminal //
01097 //  //  //  //
01098 void Terminal::appendDotFile(std::ofstream& of) {
01099     of << "e" << std::hex << (int)this << " [shape=parallelogram,label=\"";
01100     if (op == opWild)
01101         // Note: value is -1, so can't index array
01102         of << "WILD";
01103     else
01104         of << operStrings[op];
01105     of << "\\n0x" << std::hex << (int)this;
01106     of << "\"];\n";
01107 }
01108 
01109 //  //  //  //
01110 //  Unary   //
01111 //  //  //  //
01112 void Unary::appendDotFile(std::ofstream& of) {
01113     // First a node for this Unary object
01114     of << "e" << std::hex << (int)this << " [shape=record,label=\"{";
01115     // The (int) cast is to print the address, not the expression!
01116     of << operStrings[op] << "\\n0x" << std::hex << (int)this << " | ";
01117     of << "<p1>";
01118     of << " }\"];\n";
01119 
01120     // Now recurse to the subexpression.
01121     subExp1->appendDotFile(of);
01122 
01123     // Finally an edge for the subexpression
01124     of << "e" << std::hex << (int)this << "->e" << (int)subExp1 << ";\n";
01125 }
01126 
01127 //  //  //  //
01128 //  Binary  //
01129 //  //  //  //
01130 void Binary::appendDotFile(std::ofstream& of) {
01131     // First a node for this Binary object
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     // Now an edge for each subexpression
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 //  Ternary //
01145 //  //  //  //
01146 void Ternary::appendDotFile(std::ofstream& of) {
01147     // First a node for this Ternary object
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     // Now an edge for each subexpression
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 // TypedExp //
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     // Just display the C type for now
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 //  FlagDef //
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     // Display the RTL as "RTL <r1> <r2>..." vertically (curly brackets)
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  * FUNCTION:        Exp::isRegOfK
01191  * OVERVIEW:        Returns true if the expression is r[K] where K is int const
01192  * PARAMETERS:      <none>
01193  * RETURNS:         True if matches
01194  *============================================================================*/
01195 bool Exp::isRegOfK()
01196 {
01197     if (op != opRegOf) return false;
01198     return ((Unary*)this)->getSubExp1()->getOper() == opIntConst;
01199 }
01200 /*==============================================================================
01201  * FUNCTION:        Exp::isRegN
01202  * OVERVIEW:        Returns true if the expression is r[N] where N is the given int const
01203  * PARAMETERS:      N: the specific register to be tested for
01204  * RETURNS:         True if matches
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  * FUNCTION:        Exp::isAfpTerm
01214  * OVERVIEW:        Returns true if is %afp, %afp+k, %afp-k, or a[m[<any of these]]
01215  * PARAMETERS:      <none>
01216  * RETURNS:         True if found
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     // cur must be a Binary* now
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  * FUNCTION:        Exp::getVarIndex
01239  * OVERVIEW:        Returns the index for this var, e.g. if v[2], return 2
01240  * PARAMETERS:      <none>
01241  * RETURNS:         The index
01242  *============================================================================*/
01243 int Exp::getVarIndex() {
01244     assert (op == opVar);
01245     Exp* sub = ((Unary*)this)->getSubExp1();
01246     return ((Const*)sub)->getInt();
01247 }
01248 
01249 /*==============================================================================
01250  * FUNCTION:        Exp::getGuard
01251  * OVERVIEW:        Returns a ptr to the guard exression, or 0 if none
01252  * PARAMETERS:      <none>
01253  * RETURNS:         Ptr to the guard, or 0
01254  *============================================================================*/
01255 Exp* Exp::getGuard() {
01256     if (op == opGuard) return ((Unary*)this)->getSubExp1();
01257     return NULL;
01258 }
01259 
01260 /*==============================================================================
01261  * FUNCTION:        Exp::match
01262  * OVERVIEW:        Matches this expression to the given patten
01263  * PARAMETERS:      pattern to match
01264  * RETURNS:         list of variable bindings, or NULL if matching fails
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;        // must be agreement between LHS and RHS
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 //    if (r)
01320         return r;
01321 /*    r = subExp1->match(pattern);
01322     if (r) {
01323         bool change;
01324         r = r->searchReplaceAll(subExp1->clone(), this->clone(), change);
01325         return r;
01326     }
01327     return Exp::match(pattern); */
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 //#define DEBUG_MATCH
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  * FUNCTION:        Exp::match
01363  * OVERVIEW:        Matches this expression to the given patten
01364  * PARAMETERS:      pattern to match, map of bindings
01365  * RETURNS:         true if match, false otherwise
01366  *============================================================================*/
01367 bool Exp::match(const char *pattern, std::map<std::string, Exp*> &bindings)
01368 {
01369     // most obvious
01370     std::ostringstream ostr;
01371     this->print(ostr);
01372     if (ostr.str() == pattern)
01373         return true;
01374 
01375     // alright, is pattern an acceptable variable?
01376     if (ISVARIABLE(pattern)) {
01377         bindings[pattern] = this;
01378         return true;
01379     }
01380 
01381     // no, fail
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  * FUNCTION:        Exp::doSearch
01531  * OVERVIEW:        Search for the given subexpression
01532  * NOTE:            Caller must free the list li after use, but not the Exp objects that they point to
01533  * NOTE:            If the top level expression matches, li will contain search
01534  * NOTE:            Now a static function. Searches pSrc, not this
01535  * PARAMETERS:      search: ptr to Exp we are searching for 
01536  *                  pSrc: ref to ptr to Exp to search. Reason is that we can then overwrite that pointer
01537  *                  to effect a replacement. So we need to append &pSrc in the list. Can't append &this!
01538  *                  li: list of Exp** where pointers to the matches are found once: true if not all occurrences to be
01539  *                    found, false for all
01540  * RETURNS:         <nothing>
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);                // Success
01547         if (once)
01548             return;                         // No more to do
01549     }
01550     // Either want to find all occurrences, or did not match at this level
01551     // Recurse into children, unless a matching opSubscript
01552     if (!compare || pSrc->op != opSubscript)
01553         pSrc->doSearchChildren(search, li, once);
01554 }
01555 
01556 /*==============================================================================
01557  * FUNCTION:        Exp::doSearchChildren
01558  * OVERVIEW:        Search for the given subexpression in all children
01559  * NOTE:            Virtual function; different implementation for each subclass of Exp
01560  * NOTE:            Will recurse via doSearch
01561  * PARAMETERS:      search: ptr to Exp we are searching for
01562  *                  li: list of Exp** where pointers to the matches are found
01563  *                  once: true if not all occurrences to be found, false for all
01564  * RETURNS:         <nothing>
01565  *============================================================================*/
01566 void Exp::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01567     return;         // Const and Terminal do not override this
01568 }
01569 void Unary::doSearchChildren(Exp* search, std::list<Exp**>& li, bool once) {
01570     if (op != opInitValueOf)        // don't search child
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  * FUNCTION:        Exp::searchReplace
01590  * OVERVIEW:        Search for the given subexpression, and replace if found
01591  * NOTE:            If the top level expression matches, return val != this
01592  * PARAMETERS:      search:  ptr to Exp we are searching for
01593  *                  replace: ptr to Exp to replace it with
01594  *                  change: ref to boolean, set true if a change made (else cleared)
01595  * RETURNS:         True if a change made
01596  *============================================================================*/
01597 Exp* Exp::searchReplace(Exp* search, Exp* replace, bool& change)
01598 {
01599     return searchReplaceAll(search, replace, change, true);
01600 }
01601 
01602 /*==============================================================================
01603  * FUNCTION:        Exp::searchReplaceAll
01604  * OVERVIEW:        Search for the given subexpression, and replace wherever found
01605  * NOTE:            If the top level expression matches, something other than "this" will be returned
01606  * NOTE:            It is possible with wildcards that in very unusual circumstances a replacement will be made to
01607  *                  something that is already deleted.
01608  * NOTE:            Replacements are cloned. Caller to delete search and replace
01609  * PARAMETERS:      search:  ptr to ptr to Exp we are searching for
01610  *                  replace: ptr to Exp to replace it with
01611  *                  change: set true if a change made; cleared otherwise
01612  * NOTE:            change is ALWAYS assigned. No need to clear beforehand.
01613  * RETURNS:         the result (often this, but possibly changed)
01614  *============================================================================*/
01615 Exp* Exp::searchReplaceAll(Exp* search, Exp* replace, bool& change, bool once /* = false */ ) {
01616     std::list<Exp**> li;
01617     Exp* top = this;        // top may change; that's why we have to return it
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         //if (*pp) //delete *pp;         // Delete any existing
01623         *pp = replace->clone();     // Do the replacement
01624         if (once) {
01625             change = true;
01626             return top;
01627         }
01628     }
01629     change = (li.size() != 0);
01630     return top;
01631 }
01632 
01633 /*==============================================================================
01634  * FUNCTION:        Exp::search
01635  * OVERVIEW:        Search this expression for the given subexpression, and if found, return true and return a pointer
01636  *                    to the matched expression in result (useful when there are wildcards, e.g. search pattern is r[?]
01637  *                    result is r[2].
01638  * PARAMETERS:      search:  ptr to Exp we are searching for
01639  *                  result:  ref to ptr to Exp that matched
01640  * RETURNS:         True if a match was found
01641  *============================================================================*/
01642 bool Exp::search(Exp* search, Exp*& result)
01643 {
01644     std::list<Exp**> li;
01645     result = 0;             // In case it fails; don't leave it unassigned
01646     // The search requires a reference to a pointer to this object.
01647     // This isn't needed for searches, only for replacements, but we want to re-use the same search routine
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  * FUNCTION:        Exp::searchAll
01659  * OVERVIEW:        Search this expression for the given subexpression, and for each found, return a pointer to the
01660  *                    matched expression in result
01661  * PARAMETERS:      search:  ptr to Exp we are searching for
01662  *                  results:  ref to list of Exp that matched 
01663  * RETURNS:         True if a match was found
01664  *============================================================================*/
01665 bool Exp::searchAll(Exp* search, std::list<Exp*>& result)
01666 {
01667     std::list<Exp**> li;
01668     //result.clear();   // No! Useful when searching for more than one thing
01669                         // (add to the same list)
01670     // The search requires a reference to a pointer to this object.
01671     // This isn't needed for searches, only for replacements, but we want to re-use the same search routine
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         // li is list of Exp**; result is list of Exp*
01677         result.push_back(**it);
01678     }
01679     return li.size() != 0;
01680 }
01681 
01682 // These simplifying functions don't really belong in class Exp, but they know too much about how Exps work
01683 // They can't go into util.so, since then util.so and db.so would co-depend on each other for testing at least
01684 /*==============================================================================
01685  * FUNCTION:        Exp::partitionTerms
01686  * OVERVIEW:        Takes an expression consisting on only + and - operators and partitions its terms into positive
01687  *                  non-integer fixed terms, negative non-integer fixed terms and integer terms. For example, given:
01688  *                     %sp + 108 + n - %sp - 92
01689  *                  the resulting partition will be:
01690  *                     positives = { %sp, n }
01691  *                     negatives = { %sp }
01692  *                     integers  = { 108, -92 }
01693  * NOTE:            integers is a vector so we can use the accumulate func
01694  * NOTE:            Expressions are NOT cloned. Therefore, do not delete the expressions in positives or negatives
01695  * PARAMETERS:      positives - the list of positive terms
01696  *                  negatives - the list of negative terms
01697  *                  integers - the vector of integer terms
01698  *                  negate - determines whether or not to negate the whole expression, i.e. we are on the RHS of an
01699  *                  opMinus
01700  * RETURNS:         <nothing>
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             // These can be any other expression tree
01732             if (negate)
01733                 negatives.push_back(this);
01734             else
01735                 positives.push_back(this);
01736     }
01737 }
01738 
01739 /*==============================================================================
01740  * FUNCTION:        [Unary|Binary]::simplifyArith
01741  * OVERVIEW:        This method simplifies an expression consisting of + and - at the top level. For example,
01742  *                  (%sp + 100) - (%sp + 92) will be simplified to 8.
01743  * NOTE:            Any expression can be so simplified
01744  * NOTE:            User must ;//delete result
01745  * PARAMETERS:      <none>
01746  * RETURNS:         Ptr to the simplified expression
01747  *============================================================================*/
01748 Exp* Unary::simplifyArith()
01749 {
01750     if (op == opMemOf || op == opRegOf || op == opAddrOf || op == opSubscript) {
01751         // assume we want to simplify the subexpression
01752         subExp1 = subExp1->simplifyArith();
01753     }
01754     return this;            // Else, do nothing
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();     // FIXME: does this make sense?
01767     subExp2 = subExp2->simplifyArith();     // FIXME: ditto
01768     if ((op != opPlus) && (op != opMinus))
01769         return this;
01770 
01771     // Partition this expression into positive non-integer terms, negative
01772     // non-integer terms and integer terms.
01773     std::list<Exp*> positives;
01774     std::list<Exp*> negatives;
01775     std::vector<int> integers;
01776     partitionTerms(positives,negatives,integers,false);
01777 
01778     // Now reduce these lists by cancelling pairs
01779     // Note: can't improve this algorithm using multisets, since can't instantiate multisets of type Exp (only Exp*).
01780     // The Exp* in the multisets would be sorted by address, not by value of the expression.
01781     // So they would be unsorted, same as lists!
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                 // A positive and a negative that are equal; therefore they cancel
01789                 pp = positives.erase(pp);   // Erase the pointers, not the Exps
01790                 nn = negatives.erase(nn);
01791                 inc = false;                // Don't increment pp now
01792                 break;
01793             }
01794             nn++;
01795         }
01796         if (pp == positives.end()) break;
01797         if (inc) pp++;
01798     }
01799 
01800     // Summarise the set of integers to a single number.
01801     int sum = std::accumulate(integers.begin(),integers.end(),0);
01802 
01803     // Now put all these elements back together and return the result
01804     if (positives.size() == 0) {
01805         if (negatives.size() == 0) {
01806             return new Const(sum);
01807         } else
01808             // No positives, some negatives. sum - Acc
01809             return new Binary(opMinus, new Const(sum),
01810                 Exp::Accumulate(negatives));
01811     }
01812     if (negatives.size() == 0) {
01813         // Positives + sum
01814         if (sum == 0) {
01815             // Just positives
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     // Some positives, some negatives
01827     if (sum == 0) {
01828         // positives - negatives
01829         return new Binary(opMinus, Exp::Accumulate(positives),
01830             Exp::Accumulate(negatives));
01831     }
01832     // General case: some positives, some negatives, a sum
01833     OPER op = opPlus;
01834     if (sum < 0) {
01835         op = opMinus;       // Return (pos - negs) - sum
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  * FUNCTION:        Exp::Accumulate
01848  * OVERVIEW:        This method creates an expression that is the sum of all expressions in a list.
01849  *                  E.g. given the list <4,r[8],m[14]> the resulting expression is 4+r[8]+m[14].
01850  * NOTE:            static (non instance) function
01851  * NOTE:            Exps ARE cloned
01852  * PARAMETERS:      exprs - a list of expressions
01853  * RETURNS:         a new Exp with the accumulation
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  * FUNCTION:        Exp::simplify
01872  * OVERVIEW:        Apply various simplifications such as constant folding. Also canonicalise by putting iteger
01873  *                  constants on the right hand side of sums, adding of negative constants changed to subtracting
01874  *                  positive constants, etc.  Changes << k to a multiply
01875  * NOTE:            User must ;//delete result
01876  * NOTE:            Address simplification (a[ m[ x ]] == x) is done separately
01877  * PARAMETERS:      <none>
01878  * RETURNS:         Ptr to the simplified expression
01879  *
01880  * This code is so big, so weird and so lame it's not funny.  What this boils down to is the process of unification.
01881  * We're trying to do it with a simple iterative algorithm, but the algorithm keeps getting more and more complex.
01882  * Eventually I will replace this with a simple theorem prover and we'll have something powerful, but until then, dont
01883  * rely on this code to do anything critical. - trent 8/7/2002
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;                  // True if simplified at this or lower level
01891     Exp* res = this;
01892     //res = ExpTransformer::applyAllTo(res, bMod);
01893     //return res;
01894     do {
01895         bMod = false;
01896         //Exp *before = res->clone();
01897         res = res->polySimplify(bMod);// Call the polymorphic simplify
01898      /*   if (bMod) {
01899             LOG << "polySimplify hit: " << before << " to " << res << "\n";
01900             // polySimplify is now redundant, if you see this in the log you need to update one of the files in the
01901             // transformations directory to include a rule for the reported transform.
01902         } */
01903     } while (bMod);             // If modified at this (or a lower) level, redo
01904     // The below is still important. E.g. want to canonicalise sums, so we know that a + K + b is the same as a + b + K
01905     // No! This slows everything down, and it's slow enough as it is. Call only where needed:
01906     // res = res->simplifyArith();
01907 #if DEBUG_SIMP
01908     if (!(*res == *save)) std::cout << "simplified " << save << "  to  " << res << "\n";
01909     ;//delete save;
01910 #endif
01911     return res;
01912 }
01913 
01914 /*==============================================================================
01915  * FUNCTION:        Unary::polySimplify etc
01916  * OVERVIEW:        Do the work of simplification
01917  * NOTE:            User must ;//delete result
01918  * NOTE:            Address simplification (a[ m[ x ]] == x) is done separately
01919  * PARAMETERS:      <none>
01920  * RETURNS:         Ptr to the simplified expression
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                 // -k, ~k, or !k
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: /* No change required */ 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             // check for a[m[x]], becomes x
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             // The below IS bad now. It undoes the simplification of
02020             // m[r29 + -4] to m[r29 - 4]
02021             // If really needed, do another polySimplify, or swap the order
02022             //subExp1 = subExp1->simplifyArith();       // probably bad
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         // k1 op k2, where k1 and k2 are integer constants
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             ;//delete res;
02078             res = new Const(k1);
02079             bMod = true;
02080             return res;
02081         }
02082     }
02083 
02084     if (    ((op == opBitXor) || (op == opMinus)) &&
02085             (*subExp1 == *subExp2)) {
02086         // x ^ x or x - x: result is zero
02087         res = new Const(0);
02088         bMod = true;
02089         return res;
02090     }
02091         
02092     if (    ((op == opBitOr) || (op == opBitAnd)) &&
02093             (*subExp1 == *subExp2)) {
02094         // x | x or x & x: result is x
02095         res = subExp1;
02096         bMod = true;
02097         return res;
02098     }
02099         
02100     if (    op == opEquals &&
02101             *subExp1 == *subExp2) {
02102         // x == x: result is true
02103         ;//delete this;
02104         res = new Terminal(opTrue);
02105         bMod = true;
02106         return res;
02107     }
02108 
02109     // Might want to commute to put an integer constant on the RHS
02110     // Later simplifications can rely on this (ADD other ops as necessary)
02111     if (    opSub1 == opIntConst &&
02112             (op == opPlus || op == opMult || op == opMults || op == opBitOr || op == opBitAnd )) {
02113         commute();
02114         // Swap opSub1 and opSub2 as well
02115         OPER t = opSub1;
02116         opSub1 = opSub2;
02117         opSub2 = t;
02118         // This is not counted as a modification
02119     }
02120 
02121     // Similarly for boolean constants
02122     if (    subExp1->isBoolConst() &&
02123             !subExp2->isBoolConst() &&
02124             (op == opAnd || op == opOr)) {
02125         commute();
02126         // Swap opSub1 and opSub2 as well
02127         OPER t = opSub1;
02128         opSub1 = opSub2;
02129         opSub2 = t;
02130         // This is not counted as a modification
02131     }
02132 
02133     // Similarly for adding stuff to the addresses of globals
02134     if (subExp2->isAddrOf() && subExp2->getSubExp1()->isSubscript() &&
02135         subExp2->getSubExp1()->getSubExp1()->isGlobal() &&
02136         op == opPlus) {
02137         commute();
02138         // Swap opSub1 and opSub2 as well
02139         OPER t = opSub1;
02140         opSub1 = opSub2;
02141         opSub2 = t;
02142         // This is not counted as a modification
02143     }
02144 
02145     // check for (x + a) + b where a and b are constants, becomes x + a+b
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     // check for (x - a) + b where a and b are constants, becomes x + -a+b
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     // check for (x * k) - x, becomes x * (k-1)
02170     // same with +
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     // check for x + (x * k), becomes x * (k+1)
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     // Turn a + -K into a - K (K is int const > 0)
02191     // Also a - -K into a + K (K is int const > 0)
02192     // Does not count as a change
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     // Check for exp + 0  or  exp - 0  or  exp | 0
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     // Check for exp or false
02209     if (    op == opOr &&
02210             subExp2->isFalse()) {
02211         res = ((Binary*)res)->getSubExp1();
02212         bMod = true;
02213         return res;
02214     }
02215        
02216     // Check for exp * 0  or exp & 0
02217     if (    (op == opMult || op == opMults || op == opBitAnd) &&
02218             opSub2 == opIntConst &&
02219             ((Const*)subExp2)->getInt() == 0) {
02220         ;//delete res;
02221         res = new Const(0);
02222         bMod = true;
02223         return res;
02224     }
02225 
02226     // Check for exp and false
02227     if (    op == opAnd &&
02228             subExp2->isFalse()) {
02229         ;//delete res;
02230         res = new Terminal(opFalse);
02231         bMod = true;
02232         return res;
02233     }
02234 
02235     // Check for exp * 1
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     // Check for exp * x / x
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     // Check for exp / 1, becomes exp
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     // Check for exp % 1, becomes 0
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     // Check for exp * x % x, becomes 0
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     // Check for exp AND -1 (bitwise AND)
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     // Check for exp AND TRUE (logical AND)
02286     if (    (op == opAnd) &&
02287             // Is the below really needed?
02288             (opSub2 == opIntConst && ((Const*)subExp2)->getInt() != 0) || subExp2->isTrue()) {
02289         res = ((Unary*)res)->getSubExp1();
02290         bMod = true;
02291         return res;
02292     }
02293 
02294     // Check for exp OR TRUE (logical OR)
02295     if (    (op == opOr) &&
02296             (opSub2 == opIntConst &&
02297             ((Const*)subExp2)->getInt() != 0) || subExp2->isTrue()) {
02298         ;//delete res;
02299         res = new Terminal(opTrue);
02300         bMod = true;
02301         return res;
02302     }
02303 
02304     // Check for [exp] << k where k is a positive integer const
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     // Check for -x compare y, becomes x compare -y
02326     // doesn't count as a change
02327     if (    isComparison() &&
02328             opSub1 == opNeg) {
02329         Exp *e = subExp1;
02330         subExp1 = e->getSubExp1()->clone();
02331         ;//delete e;
02332         subExp2 = new Unary(opNeg, subExp2);
02333     }
02334 
02335     // Check for (x + y) compare 0, becomes x compare -y
02336     if (    isComparison() &&
02337             opSub2 == opIntConst && ((Const*)subExp2)->getInt() == 0 && 
02338             opSub1 == opPlus) {
02339         ;//delete subExp2;
02340         Binary *b = (Binary*)subExp1;
02341         subExp2 = b->subExp2;
02342         b->subExp2 = 0;
02343         subExp1 = b->subExp1;
02344         b->subExp1 = 0;
02345         ;//delete b;
02346         subExp2 = new Unary(opNeg, subExp2);
02347         bMod = true;
02348         return res;
02349     }
02350 */
02351     // Check for (x == y) == 1, becomes x == y
02352     if (    op == opEquals && opSub2 == opIntConst &&
02353             ((Const*)subExp2)->getInt() == 1 && opSub1 == opEquals) {
02354         ;//delete subExp2;
02355         Binary *b = (Binary*)subExp1;
02356         subExp2 = b->subExp2;
02357         b->subExp2 = 0;
02358         subExp1 = b->subExp1;
02359         b->subExp1 = 0;
02360         ;//delete b;
02361         bMod = true;
02362         return res;
02363     }
02364 
02365     // Check for x + -y == 0, becomes x == y
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             ;//delete subExp2;
02373             subExp2 = b->subExp2;
02374             ((Const*)subExp2)->setInt(-((Const*)subExp2)->getInt());
02375             b->subExp2 = 0;
02376             subExp1 = b->subExp1;
02377             b->subExp1 = 0;
02378             ;//delete b;
02379             bMod = true;
02380             return res;
02381         }
02382     }
02383 
02384     // Check for (x == y) == 0, becomes x != y
02385     if (    op == opEquals &&
02386             opSub2 == opIntConst &&
02387             ((Const*)subExp2)->getInt() == 0 && opSub1 == opEquals) {
02388         ;//delete subExp2;
02389         Binary *b = (Binary*)subExp1;
02390         subExp2 = b->subExp2;
02391         b->subExp2 = 0;
02392         subExp1 = b->subExp1;
02393         b->subExp1 = 0;
02394         ;//delete b;
02395         bMod = true;
02396         res->setOper(opNotEqual);
02397         return res;
02398     }
02399 
02400     // Check for (x == y) != 1, becomes x != y
02401     if (    op == opNotEqual && opSub2 == opIntConst &&
02402             ((Const*)subExp2)->getInt() == 1 && opSub1 == opEquals) {
02403         ;//delete subExp2;
02404         Binary *b = (Binary*)subExp1;
02405         subExp2 = b->subExp2;
02406         b->subExp2 = 0;
02407         subExp1 = b->subExp1;
02408         b->subExp1 = 0;
02409         ;//delete b;
02410         bMod = true;
02411         res->setOper(opNotEqual);
02412         return res;
02413     }
02414 
02415     // Check for (x == y) != 0, becomes x == y
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     // Check for (0 - x) != 0, becomes x != 0
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     // Check for (x > y) == 0, becomes x <= y
02436     if (    op == opEquals && opSub2 == opIntConst &&
02437             ((Const*)subExp2)->getInt() == 0 && opSub1 == opGtr) {
02438         ;//delete subExp2;
02439         Binary *b = (Binary*)subExp1;
02440         subExp2 = b->subExp2;
02441         b->subExp2 = 0;
02442         subExp1 = b->subExp1;
02443         b->subExp1 = 0;
02444         ;//delete b;
02445         bMod = true;
02446         res->setOper(opLessEq);
02447         return res;
02448     }
02449 
02450     // Check for (x >u y) == 0, becomes x <=u y
02451     if (    op == opEquals && opSub2 == opIntConst &&
02452             ((Const*)subExp2)->getInt() == 0 && opSub1 == opGtrUns) {
02453         ;//delete subExp2;
02454         Binary *b = (Binary*)subExp1;
02455         subExp2 = b->subExp2;
02456         b->subExp2 = 0;
02457         subExp1 = b->subExp1;
02458         b->subExp1 = 0;
02459         ;//delete b;
02460         bMod = true;
02461         res->setOper(opLessEqUns);
02462         return res;
02463     }
02464 
02465     Binary *b1 = (Binary*)subExp1;
02466     Binary *b2 = (Binary*)subExp2;
02467     // Check for (x <= y) || (x == y), becomes x <= y
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     // For (a || b) or (a && b) recurse on a and b
02479     if (op == opOr || op == opAnd) {
02480         subExp1 = subExp1->polySimplify(bMod);
02481         subExp2 = subExp2->polySimplify(bMod);
02482         return res;
02483     }
02484 
02485     // check for (x & x), becomes x
02486     if (    op == opBitAnd &&
02487             *subExp1 == *subExp2) {
02488         res = ((Binary*)res)->getSubExp1();
02489         bMod = true;
02490         return res;
02491     }
02492 
02493     // check for a + a*n, becomes a*(n+1) where n is an int
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     // check for a*n*m, becomes a*(n*m) where n and m are ints
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     // check for !(a == b) becomes a != b
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     // check for !(a != b) becomes a == b
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     // check for (exp + x) + n where exp is a pointer to a compound type becomes (exp + n) + x
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     // FIXME: suspect this was only needed for ADHOC TA
02552     // check for exp + n where exp is a pointer to a compound type
02553     // becomes &m[exp].m + r where m is the member at offset n and r is n - the offset to member m
02554     Type* ty = NULL;            // Type of subExp1
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                 //l->setType(c);
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     // check for exp + x where exp is a pointer to an array
02588     // becomes &exp[x / b] + (x % b) where b is the size of the base type in bytes
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     // check for ((x * a) + (y * b)) / c where a, b and c are all integers and a and b divide evenly by c
02669     // becomes: (x * a/c) + (y * b/c)
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     // check for ((x * a) + (y * b)) % c where a, b and c are all integers
02690     // becomes: (y * b) % c if a divides evenly by c
02691     // becomes: (x * a) % c if b divides evenly by c
02692     // becomes: 0           if both a and b divide evenly by c
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     // Check for 0 - (0 <u exp1) & exp2 => exp2
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     // Replace opSize(n, loc) with loc and set the type if needed
02738     if (    op == opSize &&
02739             subExp2->isLocation()) {
02740 #if 0       // FIXME: ADHOC TA assumed here
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     // p ? 1 : 0 -> p
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     // 1 ? x : y -> x
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     // 0 ? x : y -> y
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         // type cast on a reg of.. hmm.. let's remove this
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     /* This is a nasty hack.  We assume that %DF{0} is 0.  This happens when string instructions are used without first
02913      * clearing the direction flag.  By convention, the direction flag is assumed to be clear on entry to a procedure.
02914      */
02915     if (subExp1->getOper() == opDF && def == NULL) {
02916         res = new Const(0);
02917         bMod = true;
02918         return res;
02919     }
02920 
02921     // another hack, this time for aliasing
02922     // FIXME: do we really want this now? Pentium specific, and only handles ax/eax (not al or ah)
02923     if (subExp1->isRegN(0) &&                           // r0 (ax)
02924             def && def->isAssign() &&
02925             ((Assign*)def)->getLeft()->isRegN(24)) {    // r24 (eax)
02926         res = new TypedExp(new IntegerType(16), new RefExp(Location::regOf(24), def));
02927         bMod = true;
02928         return res;
02929     }
02930 
02931     // Was code here for bypassing phi statements that are now redundant
02932 
02933     return res;
02934 }
02935 
02936 /*==============================================================================
02937  * FUNCTION:        Exp::simplifyAddr
02938  * OVERVIEW:        Just do addressof simplification: a[ m[ any ]] == any, m[ a[ any ]] = any, and also
02939  *                    a[ size m[ any ]] == any
02940  * TODO:            Replace with a visitor some day
02941  * PARAMETERS:      <none>
02942  * RETURNS:         Ptr to the simplified expression
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         // Not a[ anything ]. Recurse
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             // Remove the a[
02963             Binary* b = (Binary*)getSubExp1();
02964             // Remove the size[
02965             Unary* u = (Unary*)b->getSubExp2();
02966             // Remove the m[
02967             return u->getSubExp1();
02968         }
02969     }
02970 
02971     // a[ something else ]. Still recurse, just in case
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  * FUNCTION:        Exp::printt
02993  * OVERVIEW:        Print an infix representation of the object to the given file stream, with its type in <angle
02994  *                    brackets>.
02995  * PARAMETERS:      Output stream to send the output to
02996  * RETURNS:         <nothing>
02997  *============================================================================*/
02998 void Exp::printt(std::ostream& os /*= cout*/)
02999 {
03000     print(os);
03001     if (op != opTypedExp) return;
03002     Type* t = ((TypedExp*)this)->getType();
03003     os << "<" << std::dec << t->getSize();
03004 /*    switch (t->getType()) {
03005         case INTEGER:
03006             if (t->getSigned())
03007                         os << "i";              // Integer
03008             else
03009                         os << "u"; break;       // Unsigned
03010         case FLOATP:    os << "f"; break;
03011         case DATA_ADDRESS: os << "pd"; break;   // Pointer to Data
03012         case FUNC_ADDRESS: os << "pc"; break;   // Pointer to Code
03013         case VARARGS:   os << "v"; break;
03014         case TBOOLEAN:   os << "b"; break;
03015         case UNKNOWN:   os << "?"; break;
03016         case TVOID:     break;
03017     } */
03018     os << ">";
03019 }
03020 
03021 /*==============================================================================
03022  * FUNCTION:        Exp::printAsHL
03023  * OVERVIEW:        Print an infix representation of the object to the given file stream, but convert r[10] to r10 and
03024  *                    v[5] to v5
03025  * NOTE:            Never modify this function to emit debugging info; the back ends rely on this being clean to emit
03026  *                    correct C.  If debugging is desired, use operator<<
03027  * PARAMETERS:      Output stream to send the output to
03028  * RETURNS:         <nothing>
03029  *============================================================================*/
03030 void Exp::printAsHL(std::ostream& os /*= cout*/)
03031 {
03032     std::ostringstream ost;
03033     ost << this;                    // Print to the string stream
03034     std::string s(ost.str());
03035     if ((s.length() >= 4) && (s[1] == '[')) {
03036         // r[nn]; change to rnn
03037         s.erase(1, 1);              // '['
03038         s.erase(s.length()-1);      // ']'
03039     }
03040     os << s;                        // Print to the output stream
03041 }
03042 
03043 /*==============================================================================
03044  * FUNCTION:        operator<<
03045  * OVERVIEW:        Output operator for Exp*
03046  * PARAMETERS:      os: output stream to send to
03047  *                  p: ptr to Exp to print to the stream
03048  * RETURNS:         copy of os (for concatenation)
03049  *============================================================================*/
03050 std::ostream& operator<<(std::ostream& os, Exp* p)
03051 {
03052 #if 1
03053     // Useful for debugging, but can clutter the output
03054     p->printt(os);
03055 #else
03056     p->print(os);
03057 #endif
03058     return os;
03059 }
03060 
03061 /*==============================================================================
03062  * FUNCTION:        Unary::fixSuccessor
03063  * OVERVIEW:        Replace succ(r[k]) by r[k+1]
03064  * NOTE:            Could change top level expression
03065  * PARAMETERS:      None
03066  * RETURNS:         Fixed expression
03067  *============================================================================*/
03068 Exp* Exp::fixSuccessor() {
03069     bool change;
03070     Exp* result;
03071     // Assume only one successor function in any 1 expression
03072     if (search(new Unary(opSuccessor,
03073                          Location::regOf(new Terminal(opWild))), result)) {
03074         // Result has the matching expression, i.e. succ(r[K])
03075         Exp* sub1 = ((Unary*)result)->getSubExp1();
03076         assert(sub1->getOper() == opRegOf);
03077         Exp* sub2 = ((Unary*)sub1)->getSubExp1();
03078         assert(sub2->getOper() == opIntConst);
03079         // result    sub1   sub2
03080         // succ(      r[   Const K  ])
03081         // Note: we need to clone the r[K] part, since it will be ;//deleted as
03082         // part of the searchReplace below
03083         Unary* replace = (Unary*)sub1->clone();
03084         Const* c = (Const*)replace->getSubExp1();
03085         c->setInt(c->getInt()+1);       // Do the increment
03086         Exp* res = searchReplace(result, replace, change);
03087         return res;
03088     }
03089     return this;
03090 }
03091     
03092 /*==============================================================================
03093  * FUNCTION:        Exp::killFill
03094  * OVERVIEW:        Remove size operations such as zero fill, sign extend
03095  * NOTE:            Could change top level expression
03096  * NOTE:            Does not handle truncation at present
03097  * PARAMETERS:      None
03098  * RETURNS:         Fixed expression
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         // Kill the sign extend bits
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     // Some old code has r[tmpb] instead of just tmpb
03121     Exp* sub = ((Unary*)this)->getSubExp1();
03122     return sub->op == opTemp;
03123 }
03124 
03125 // allZero is set if all subscripts in the whole expression are null or implicit; otherwise cleared
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()/*->clone()*/, change);
03141         }
03142     }
03143     return e;
03144 }
03145 
03146 
03147 
03148 // FIXME: if the wrapped expression does not convert to a location, the result is subscripted, which is probably not
03149 // what is wanted!
03150 Exp* Exp::fromSSAleft(UserProc* proc, Statement* d) {
03151     RefExp* r = new RefExp(this, d);       // "Wrap" in a ref
03152     return r->accept(new ExpSsaXformer(proc));
03153 }
03154 
03155 // A helper class for comparing Exp*'s sensibly
03156 bool lessExpStar::operator()(const Exp* x, const Exp* y) const {
03157     return (*x < *y);       // Compare the actual Exps
03158 }
03159 
03160 bool lessTI::operator()(const Exp* x, const Exp* y) const {
03161     return (*x << *y);      // Compare the actual Exps
03162 }
03163 
03164 //  //  //  //  //  //
03165 //  genConstraints  //
03166 //  //  //  //  //  //
03167 
03168 Exp* Exp::genConstraints(Exp* result) {
03169     // Default case, no constraints -> return true
03170     return new Terminal(opTrue);
03171 }
03172 
03173 Exp* Const::genConstraints(Exp* result) {
03174     if (result->isTypeVal()) {
03175         // result is a constant type, or possibly a partial type such as ptr(alpha)
03176         Type* t = ((TypeVal*)result)->getType();
03177         bool match = false;
03178         switch (op) {
03179             case opLongConst:
03180                 // An integer constant is compatible with any size of integer, as long is it is in the right range
03181                 // (no test yet) FIXME: is there an endianness issue here?
03182             case opIntConst:
03183                 match = t->isInteger();
03184                 // An integer constant can also match a pointer to something.  Assume values less than 0x100 can't be a
03185                 // pointer
03186                 if ((unsigned)u.i >= 0x100)
03187                     match |= t->isPointer();
03188                 // We can co-erce 32 bit constants to floats
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             // This constant may require a cast or a change of format. So we generate a constraint.
03205             // Don't clone 'this', so it can be co-erced after type analysis
03206             return new Binary(opEquals,
03207                 new Unary(opTypeOf, this),
03208                 result->clone());
03209         } else
03210             // Doesn't match
03211             return new Terminal(opFalse);
03212     }
03213     // result is a type variable, which is constrained by this constant
03214     Type* t;
03215     switch (op) {
03216         case opIntConst: {
03217             // We have something like local1 = 1234.  Either they are both integer, or both pointer
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                             // Note: don't clone 'this', so we can change the Const after type analysis!
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();    // size is not known. Assume double for now
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         // TODO: need to check for conflicts
03260         return new Terminal(opTrue);
03261     }
03262     
03263     switch (op) {
03264         case opRegOf:
03265         case opParam:       // Should be no params at constraint time
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             // Fall through
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             // result is a constant type, or possibly a partial type such as
03318             // ptr(alpha)
03319             Type* t = ((TypeVal*)result)->getType();
03320             // Compare broad types
03321             if (! (*retHasToBe *= *t))
03322                 return new Terminal(opFalse);
03323             // else just constrain the arg
03324         } else {
03325             // result is a type variable, constrained by this Ternary
03326             res = new Binary(opEquals,
03327                 result,
03328                 new TypeVal(retHasToBe));
03329         }
03330     }
03331     if (argHasToBe) {
03332         // Constrain the argument
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 // Return a constraint that my subexpressions have to be of type typeval1 and typeval2 respectively
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);  // Wild size (=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                 // Result can only be float
03383                 return new Terminal(opFalse);
03384 
03385             // MVE: what about sizes?
03386             FloatType* ft = new FloatType();
03387             TypeVal* ftv = new TypeVal(ft);
03388             res = constrainSub(ftv, ftv);
03389             if (!restrictTo)
03390                 // Also constrain the result
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                 // Result can only be integer
03402                 return new Terminal(opFalse);
03403 
03404             // MVE: What about sizes?
03405             IntegerType* it = new IntegerType();
03406             TypeVal* itv = new TypeVal(it);
03407             res = constrainSub(itv, itv);
03408             if (!restrictTo)
03409                 // Also constrain the result
03410                 res = new Binary(opAnd, res,
03411                     new Binary(opEquals, result->clone(), itv));
03412             return res;
03413             break;
03414         }
03415             
03416         case opPlus: {
03417             // A pointer to anything
03418             Type* ptrType = PointerType::newPtrAlpha();
03419             TypeVal ptrVal(ptrType);    // Type value of ptr to anything
03420             if (!restrictTo || restrictTo && restrictTo->isInteger()) {
03421                 // int + int -> int
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                 // ptr + int -> ptr
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                 // int + ptr -> ptr
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                 // int - int -> int
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                 // ptr - ptr -> int
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                 // ptr - int -> ptr
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             // This used to be considered obsolete, but now, it is used to carry the size of memOf's from the decoder to
03491             // here
03492             assert(subExp1->isIntConst());
03493             int sz = ((Const*)subExp1)->getInt();
03494             if (restrictTo) {
03495                 int rsz = restrictTo->getSize();
03496                 if (rsz == 0) {
03497                     // This is now restricted to the current restrictTo, but
03498                     // with a known size
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             // We constrain the size but not the basic type
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     // check for m[a[loc.x]] becomes loc.x
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     // This is a hack to fix aliasing (replace with something general)
03542     // FIXME! This is x86 specific too. Use -O for overlapped registers!
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                 // FIXME: ADHOC TA assumed
03567                 Type* t1 = NULL;    // ((TypeVal*)subExp1)->getType();
03568                 Type* t2 = NULL;    // ((TypeVal*)subExp2)->getType();
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 //     V i s i t i n g      //
03593 //                          //
03594 //  //  //  //  //  //  //  //
03595 bool Unary::accept(ExpVisitor* v) {
03596     bool override, ret = v->visit(this, override);
03597     if (override) return ret;   // Override the rest of the accept logic
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 // All the Unary derived accept functions look the same, but they have to be repeated because the particular visitor
03622 // function called each time is different for each class (because "this" is different each time)
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 // The following are similar, but don't have children that have to accept visitors
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 // FixProcVisitor class
03656 
03657 void Exp::fixLocationProc(UserProc* p) {
03658     // All locations are supposed to have a pointer to the enclosing UserProc that they are a location of. Sometimes,
03659     // you have an arbitrary expression that may not have all its procs set. This function fixes the procs for all
03660     // Location subexpresssions.
03661     FixProcVisitor fpv;
03662     fpv.setProc(p);
03663     accept(&fpv);
03664 }
03665 
03666 // GetProcVisitor class
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 // Strip size casts from an Exp
03681 Exp* Exp::stripSizes() {
03682     SizeStripper ss;
03683     return accept(&ss);
03684 }
03685 
03686 Exp* Unary::accept(ExpModifier* v) {
03687     // This Unary will be changed in *either* the pre or the post visit. If it's changed in the preVisit step, then
03688     // postVisit doesn't care about the type of ret. So let's call it a Unary, and the type system is happy
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     // This looks to be the same source code as Unary::accept, but the type of "this" is different, which is all
03714     // important here!  (it makes a call to a different visitor member function).
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     // This is important if we need to modify terminals
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 // Find the locations used by this expression. Use the UsedLocsFinder visitor class
03845 // If memOnly is true, only look inside m[...]
03846 void Exp::addUsedLocs(LocationSet& used, bool memOnly) {
03847     UsedLocsFinder ulf(used, memOnly);
03848     accept(&ulf);
03849 }
03850 
03851 // Subscript any occurrences of e with e{def} in this expression
03852 Exp* Exp::expSubscriptVar(Exp* e, Statement* def) {
03853     ExpSubscripter es(e, def);
03854     return accept(&es);
03855 }
03856 
03857 // Subscript any occurrences of e with e{-} in this expression Note: subscript with NULL, not implicit assignments as
03858 // above
03859 Exp* Exp::expSubscriptValNull(Exp* e) {
03860     return expSubscriptVar(e, NULL);
03861 }
03862 
03863 // Subscript all locations in this expression with their implicit assignments
03864 Exp* Exp::expSubscriptAllNull(/*Cfg* cfg*/) {
03865     return expSubscriptVar(new Terminal(opWild), NULL /* was NULL, NULL, cfg */);
03866 }
03867 
03868 Location* Location::local(const char *nam, UserProc *p) {
03869     return new Location(opLocal, new Const((char*)nam), p);
03870 }
03871 
03872 // Don't put in exp.h, as this would require statement.h including before exp.h
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 // Propagate all possible statements to this expression
03900 Exp* Exp::propagateAll() {
03901     ExpPropagator ep;
03902     return accept(&ep);
03903 }
03904 
03905 // Propagate all possible statements to this expression, and repeat until there is no further change
03906 Exp* Exp::propagateAllRpt(bool& changed) {
03907     ExpPropagator ep;
03908     changed = false;
03909     Exp* ret = this;
03910     while (true) {
03911         ep.clearChanged();          // Want to know if changed this *last* accept()
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 // Check if this expression contains a bare memof (no subscripts) or one that has no symbol (i.e. is not a local
03928 // variable or a parameter)
03929 bool Exp::containsBadMemof(UserProc* proc) {
03930     BadMemofFinder bmf(proc);
03931     accept(&bmf);
03932     return bmf.isFound();
03933 }
03934 
03935 // No longer used
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     // FIXME: not completed
03988     // TerminalMemo *m = dynamic_cast<TerminalMemo*>(mm);
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     // FIXME: not completed
04005     // UnaryMemo *m = dynamic_cast<UnaryMemo*>(mm);
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     // FIXME: not completed
04022     // BinaryMemo *m = dynamic_cast<BinaryMemo*>(mm);
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     // FIXME: not completed
04039     // TernaryMemo *m = dynamic_cast<TernaryMemo*>(mm);
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     // FIXME: not completed
04056     // TypedExpMemo *m = dynamic_cast<TypedExpMemo*>(mm);
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     // FIXME: not completed
04073     // FlagDefMemo *m = dynamic_cast<FlagDefMemo*>(mm);
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     // FIXME: not completed
04090     // RefExpMemo *m = dynamic_cast<RefExpMemo*>(mm);
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     // FIXME: not completed
04107     // TypeValMemo *m = dynamic_cast<TypeValMemo*>(mm);
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     // FIXME: not completed
04124     // LocationMemo *m = dynamic_cast<LocationMemo*>(mm);
04125 }
04126 #endif      // #ifdef USING_MEMO

Generated on Tue Sep 19 21:18:23 2006 for Boomerang by  doxygen 1.4.6