visitor.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2006, Mike Van Emmerik and Trent Waddington
00003  */
00004 /*==============================================================================
00005  * FILE:       visitor.h
00006  * OVERVIEW:   Provides the definition for the various visitor and modifier classes.
00007  *              These classes sometimes are associated with Statement and Exp classes, so they are here to avoid
00008  *              #include problems, to make exp.cpp and statement.cpp a little less huge.
00009  *              The main advantage is that they are quick and easy to implement (once you get used to them), and it
00010  *              avoids having to declare methods in every Statement or Exp subclass
00011  * TOP LEVEL
00012  * CLASSES:     ExpVisitor      (visit expressions)
00013  *              StmtVisitor     (visit statements)
00014  *              StmtExpVisitor  (visit expressions in statements)
00015  *              ExpModifier     (modify expressions)
00016  *              SimpExpModifier (simplifying expression modifier)
00017  *              StmtModifier    (modify expressions in statements; not abstract)
00018  *              StmtPartModifier (as above with special case for whole of LHS)
00019  *============================================================================*/
00020 /*
00021  * $Revision: 1.39 $    // 1.13.2.11
00022  *
00023  * 14 Jun 04 - Mike: Created, from work started by Trent in 2003
00024  *
00025  * There are separate Visitor and Modifier classes. Visitors are more suited for searching: they have the capability of
00026  * stopping the recursion, but can't change the class of a top level expression. Visitors can also override (prevent)
00027  * the usual recursing to child objects. Modifiers always recurse to the end, and the ExpModifiers' visit function
00028  * returns an Exp* so that the top level expression can change class (e.g. RefExp to Binary).
00029  * The accept() functions (in the target classes) are always the same for all visitors; they encapsulate where the
00030  *  visitable parts of a Statement or expression are.
00031  * The visit() functions contain the logic of the search/modify/whatever.  Often only a few visitor functions have to do
00032  *  anything. Unfortunately, the visit functions are members of the Visitor (or Modifier) classes, and so have to use
00033  *  public functions of the target classes.
00034  */
00035 
00036 #ifndef __VISITOR_H__
00037 #define __VISITOR_H__
00038 
00039 #ifndef NULL
00040 #define NULL 0              // Often defined in stdio.h
00041 #endif
00042 
00043 #include "exp.h"            // Needs to know class hierarchy, e.g. so that can convert Unary* to Exp* in return of
00044                             // ExpModifier::preVisit()
00045 
00046 class Statement;
00047 class Assignment;
00048 class Assign;
00049 class ImplicitAssign;
00050 class PhiAssign;
00051 class BoolAssign;
00052 class CaseStatement;
00053 class CallStatement;
00054 class ReturnStatement;
00055 class GotoStatement;
00056 class BranchStatement;
00057 class ImpRefStatement;
00058 
00059 class RTL;
00060 class UserProc;
00061 class Cfg;
00062 class Prog;
00063 class BasicBlock;
00064 typedef BasicBlock* PBB;
00065 
00066 class LocationSet;
00067 
00068 /*
00069  * The ExpVisitor class is used to iterate over all subexpressions in an expression. 
00070  */
00071 
00072 class ExpVisitor {
00073 
00074 public:
00075     ExpVisitor() { }
00076 virtual         ~ExpVisitor() { }
00077 
00078     // visitor functions return false to abandon iterating through the expression (terminate the search)
00079     // Set override true to not do the usual recursion into children
00080 virtual bool        visit(Unary *e,     bool& override) {override = false; return true;}
00081 virtual bool        visit(Binary *e,    bool& override) {override = false; return true;}
00082 virtual bool        visit(Ternary *e,   bool& override) {override = false; return true;}
00083 virtual bool        visit(TypedExp *e,  bool& override) {override = false; return true;}
00084 virtual bool        visit(FlagDef *e,   bool& override) {override = false; return true;}
00085 virtual bool        visit(RefExp *e,    bool& override) {override = false; return true;}
00086 virtual bool        visit(Location *e,  bool& override) {override = false; return true;}
00087 // These three have zero arity, so there is nothing to override
00088 virtual bool        visit(Const *e   ) {return true;}
00089 virtual bool        visit(Terminal *e) {return true;}
00090 virtual bool        visit(TypeVal *e ) {return true;}
00091 };
00092 
00093 // This class visits subexpressions, and if a location, sets the UserProc
00094 class FixProcVisitor : public ExpVisitor {
00095         // the enclosing UserProc (if a Location)
00096         UserProc*   proc;
00097 
00098 public:
00099         void        setProc(UserProc* p) { proc = p; }
00100 virtual bool        visit(Location *e, bool& override);
00101         // All other virtual functions inherit from ExpVisitor, i.e. they just visit their children recursively
00102 };
00103 
00104 // This class is more or less the opposite of the above. It finds a proc by visiting the whole expression if necessary
00105 class GetProcVisitor : public ExpVisitor {
00106         UserProc*   proc;           // The result (or NULL)
00107 
00108 public:
00109                     GetProcVisitor() {proc = NULL;} // Constructor
00110         UserProc*   getProc() {return proc;}
00111 virtual bool        visit(Location *e, bool& override);
00112     // All others inherit and visit their children
00113 };
00114 
00115 // This class visits subexpressions, and if a Const, sets or clears a new conscript
00116 class SetConscripts : public ExpVisitor {
00117         int         curConscript;
00118         bool        bInLocalGlobal;     // True when inside a local or global
00119         bool        bClear;             // True when clearing, not setting
00120 public:
00121                     SetConscripts(int n, bool bClear) : bInLocalGlobal(false), bClear(bClear) {curConscript = n;}
00122         int         getLast() {return curConscript;}
00123 virtual bool        visit(Const* e);
00124 virtual bool        visit(Location* e, bool& override);
00125 virtual bool        visit(Binary* b,    bool& override);
00126         // All other virtual functions inherit from ExpVisitor: return true
00127 };
00128 
00129 /*
00130  * The ExpModifier class is used to iterate over all subexpressions in an expression. It contains methods for each kind
00131  * of subexpression found in an and can be used to eliminate switch statements.
00132  * It is a little more expensive to use than ExpVisitor, but can make changes to the expression
00133  */
00134 class ExpModifier {
00135 protected:
00136         bool        mod;        // Set if there is any change. Don't have to implement
00137 public:
00138                     ExpModifier() {mod = false;}
00139 virtual             ~ExpModifier() { }
00140         bool        isMod() {return mod;}
00141         void        clearMod() {mod = false;}
00142 
00143         // visitor functions
00144         // Most times these won't be needed. You only need to override the ones that make a cange.
00145         // preVisit comes before modifications to the children (if any)
00146 virtual Exp*        preVisit(Unary      *e, bool& recur) {recur = true; return e;}
00147 virtual Exp*        preVisit(Binary     *e, bool& recur) {recur = true; return e;}
00148 virtual Exp*        preVisit(Ternary    *e, bool& recur) {recur = true; return e;}
00149 virtual Exp*        preVisit(TypedExp   *e, bool& recur) {recur = true; return e;}
00150 virtual Exp*        preVisit(FlagDef    *e, bool& recur) {recur = true; return e;}
00151 virtual Exp*        preVisit(RefExp     *e, bool& recur) {recur = true; return e;}
00152 virtual Exp*        preVisit(Location   *e, bool& recur) {recur = true; return e;}
00153 virtual Exp*        preVisit(Const      *e             ) {              return e;}
00154 virtual Exp*        preVisit(Terminal   *e             ) {              return e;}
00155 virtual Exp*        preVisit(TypeVal    *e             ) {              return e;}
00156 
00157         // postVisit comes after modifications to the children (if any)
00158 virtual Exp*        postVisit(Unary     *e) {return e;}
00159 virtual Exp*        postVisit(Binary    *e) {return e;}
00160 virtual Exp*        postVisit(Ternary   *e) {return e;}
00161 virtual Exp*        postVisit(TypedExp  *e) {return e;}
00162 virtual Exp*        postVisit(FlagDef   *e) {return e;}
00163 virtual Exp*        postVisit(RefExp    *e) {return e;}
00164 virtual Exp*        postVisit(Location  *e) {return e;}
00165 virtual Exp*        postVisit(Const     *e) {return e;}
00166 virtual Exp*        postVisit(Terminal  *e) {return e;}
00167 virtual Exp*        postVisit(TypeVal   *e) {return e;}
00168 };
00169 
00170 /* 
00171  * The StmtVisitor class is used for code that has to work with all the Statement classes. One advantage is that you
00172  * don't need to declare a function in every class derived from Statement: the accept methods already do that for you.
00173  * It does not automatically visit the expressions in the statement.
00174  */
00175 class StmtVisitor {
00176 public:
00177     StmtVisitor() { }
00178 virtual             ~StmtVisitor() { }
00179 
00180     // visitor functions, 
00181     // returns true to continue iterating the container
00182 virtual bool        visit(RTL               *rtl);  // By default, visits all statements
00183 virtual bool        visit(Assign            *stmt)  { return true;}
00184 virtual bool        visit(PhiAssign         *stmt)  { return true;}
00185 virtual bool        visit(ImplicitAssign    *stmt)  { return true;}
00186 virtual bool        visit(BoolAssign        *stmt)  { return true;}
00187 virtual bool        visit(GotoStatement     *stmt)  { return true;}
00188 virtual bool        visit(BranchStatement   *stmt)  { return true;}
00189 virtual bool        visit(CaseStatement     *stmt)  { return true;}
00190 virtual bool        visit(CallStatement     *stmt)  { return true;}
00191 virtual bool        visit(ReturnStatement   *stmt)  { return true;}
00192 virtual bool        visit(ImpRefStatement   *stmt)  { return true;}
00193 };
00194 
00195 class StmtConscriptSetter : public StmtVisitor {
00196         int         curConscript;
00197         bool        bClear;
00198 public:
00199                     StmtConscriptSetter(int n, bool bClear) : curConscript(n), bClear(bClear) {}
00200     int             getLast() {return curConscript;}
00201 
00202 virtual bool        visit(Assign *stmt);
00203 virtual bool        visit(PhiAssign *stmt);
00204 virtual bool        visit(ImplicitAssign *stmt);
00205 virtual bool        visit(BoolAssign *stmt);
00206 virtual bool        visit(CaseStatement *stmt);
00207 virtual bool        visit(CallStatement *stmt);
00208 virtual bool        visit(ReturnStatement *stmt);
00209 virtual bool        visit(BranchStatement *stmt);
00210 virtual bool        visit(ImpRefStatement   *stmt);
00211 };
00212 
00213 // StmtExpVisitor is a visitor of statements, and of expressions within those expressions. The visiting of expressions
00214 // (after the current node) is done by an ExpVisitor (i.e. this is a preorder traversal).
00215 class StmtExpVisitor {
00216         bool        ignoreCol;              // True if ignoring collectors
00217 public:
00218         ExpVisitor* ev;
00219                     StmtExpVisitor(ExpVisitor* v, bool ignoreCol = true) : ignoreCol(ignoreCol), ev(v) {}
00220 virtual             ~StmtExpVisitor() {}
00221 virtual bool        visit(         Assign *stmt, bool& override) {override = false; return true;}
00222 virtual bool        visit(      PhiAssign *stmt, bool& override) {override = false; return true;}
00223 virtual bool        visit( ImplicitAssign *stmt, bool& override) {override = false; return true;}
00224 virtual bool        visit(     BoolAssign *stmt, bool& override) {override = false; return true;}
00225 virtual bool        visit(  GotoStatement *stmt, bool& override) {override = false; return true;}
00226 virtual bool        visit(BranchStatement *stmt, bool& override) {override = false; return true;}
00227 virtual bool        visit(  CaseStatement *stmt, bool& override) {override = false; return true;}
00228 virtual bool        visit(  CallStatement *stmt, bool& override) {override = false; return true;}
00229 virtual bool        visit(ReturnStatement *stmt, bool& override) {override = false; return true;}
00230 virtual bool        visit(ImpRefStatement *stmt, bool& override) {override = false; return true;}
00231 
00232         bool        isIgnoreCol() {return ignoreCol;}
00233 };
00234 
00235 // StmtModifier is a class that for all expressions in this statement, makes a modification.
00236 // The modification is as a result of an ExpModifier; there is a pointer to such an ExpModifier in a StmtModifier.
00237 // Even the top level of the LHS of assignments are changed. This is useful e.g. when modifiying locations to locals
00238 // as a result of converting from SSA form, e.g. eax := ebx -> local1 := local2
00239 // Classes that derive from StmtModifier inherit the code (in the accept member functions) to modify all the expressions
00240 // in the various types of statement.
00241 // Because there is nothing specialised about a StmtModifier, it is not an abstract class (can be instantiated).
00242 class StmtModifier {
00243 protected:
00244         bool        ignoreCol;
00245 public:
00246         ExpModifier* mod;           // The expression modifier object
00247                     StmtModifier(ExpModifier* em, bool ic = false) : ignoreCol(ic), mod(em) {}  // Constructor
00248 virtual             ~StmtModifier() {}
00249         bool        ignoreCollector() {return ignoreCol;}
00250     // This class' visitor functions don't return anything. Maybe we'll need return values at a later stage.
00251 virtual void        visit(Assign *s,            bool& recur) {recur = true;}
00252 virtual void        visit(PhiAssign *s,         bool& recur) {recur = true;}
00253 virtual void        visit(ImplicitAssign *s,    bool& recur) {recur = true;}
00254 virtual void        visit(BoolAssign *s,        bool& recur) {recur = true;}
00255 virtual void        visit(GotoStatement *s,     bool& recur) {recur = true;}
00256 virtual void        visit(BranchStatement *s,   bool& recur) {recur = true;}
00257 virtual void        visit(CaseStatement *s,     bool& recur) {recur = true;}
00258 virtual void        visit(CallStatement *s,     bool& recur) {recur = true;}
00259 virtual void        visit(ReturnStatement *s,   bool& recur) {recur = true;}
00260 virtual void        visit(ImpRefStatement *s,   bool& recur) {recur = true;}
00261 };
00262 
00263 // As above, but specialised for propagating to. The top level of the lhs of assignment-like statements (including
00264 // arguments in calls) is not modified. So for example eax := ebx -> eax := local2, but in m[xxx] := rhs, the rhs and
00265 // xxx are modified, but not the m[xxx]
00266 class StmtPartModifier {
00267         bool        ignoreCol;
00268 public:
00269     ExpModifier* mod;           // The expression modifier object
00270                     StmtPartModifier(ExpModifier* em, bool ic = false) : ignoreCol(ic), mod(em) {}  // Constructor
00271 virtual             ~StmtPartModifier() {}
00272         bool        ignoreCollector() {return ignoreCol;}
00273     // This class' visitor functions don't return anything. Maybe we'll need return values at a later stage.
00274 virtual void        visit(Assign *s,            bool& recur) {recur = true;}
00275 virtual void        visit(PhiAssign *s,         bool& recur) {recur = true;}
00276 virtual void        visit(ImplicitAssign *s,    bool& recur) {recur = true;}
00277 virtual void        visit(BoolAssign *s,        bool& recur) {recur = true;}
00278 virtual void        visit(GotoStatement *s,     bool& recur) {recur = true;}
00279 virtual void        visit(BranchStatement *s,   bool& recur) {recur = true;}
00280 virtual void        visit(CaseStatement *s,     bool& recur) {recur = true;}
00281 virtual void        visit(CallStatement *s,     bool& recur) {recur = true;}
00282 virtual void        visit(ReturnStatement *s,   bool& recur) {recur = true;}
00283 virtual void        visit(ImpRefStatement *s,   bool& recur) {recur = true;}
00284 };
00285 
00286 class PhiStripper : public StmtModifier {
00287         bool        del;            // Set true if this statment is to be deleted
00288 public:
00289                     PhiStripper(ExpModifier* em) : StmtModifier(em) {del = false;} 
00290 virtual void        visit(PhiAssign* stmt, bool& recur);
00291         bool        getDelete() {return del;}
00292 };
00293 
00294 // A simplifying expression modifier. It does a simplification on the parent after a child has been modified
00295 class SimpExpModifier : public ExpModifier {
00296 protected:
00297         // These two provide 31 bits (or sizeof(int)-1) of information about whether the child is unchanged.
00298         // If the mask overflows, it goes to zero, and from then on the child is reported as always changing.
00299         // (That's why it's an "unchanged" set of flags, instead of a "changed" set).
00300         // This is used to avoid calling simplify in most cases where it is not necessary.
00301         unsigned    mask;
00302         unsigned    unchanged;
00303 public:
00304                     SimpExpModifier()   { mask = 1; unchanged = (unsigned)-1;}
00305         unsigned    getUnchanged()      { return unchanged;}
00306         bool        isTopChanged()      { return !(unchanged & mask);}
00307 virtual Exp*        preVisit(Unary      *e, bool& recur) { recur = true; mask <<= 1; return e;}
00308 virtual Exp*        preVisit(Binary     *e, bool& recur) { recur = true; mask <<= 1; return e;}
00309 virtual Exp*        preVisit(Ternary    *e, bool& recur) { recur = true; mask <<= 1; return e;}
00310 virtual Exp*        preVisit(TypedExp   *e, bool& recur) { recur = true; mask <<= 1; return e;}
00311 virtual Exp*        preVisit(FlagDef    *e, bool& recur) { recur = true; mask <<= 1; return e;}
00312 virtual Exp*        preVisit(RefExp     *e, bool& recur) { recur = true; mask <<= 1; return e;}
00313 virtual Exp*        preVisit(Location   *e, bool& recur) { recur = true; mask <<= 1; return e;}
00314 virtual Exp*        preVisit(Const      *e) { mask <<= 1; return e;}
00315 virtual Exp*        preVisit(Terminal   *e) { mask <<= 1; return e;}
00316 virtual Exp*        preVisit(TypeVal    *e) { mask <<= 1; return e;}
00317 
00318 virtual Exp*        postVisit(Unary *e);
00319 virtual Exp*        postVisit(Binary *e);
00320 virtual Exp*        postVisit(Ternary *e);
00321 virtual Exp*        postVisit(TypedExp *e);
00322 virtual Exp*        postVisit(FlagDef *e);
00323 virtual Exp*        postVisit(RefExp *e);
00324 virtual Exp*        postVisit(Location *e);
00325 virtual Exp*        postVisit(Const *e);
00326 virtual Exp*        postVisit(Terminal *e);
00327 virtual Exp*        postVisit(TypeVal *e);
00328 };
00329 
00330 // A modifying visitor to process all references in an expression, bypassing calls (and phi statements if they have been
00331 // replaced by copy assignments), and performing simplification on the direct parent of the expression that is modified.
00332 // NOTE: this is sometimes not enough! Consider changing (r+x)+K2) where x gets changed to K1. Now you have (r+K1)+K2,
00333 // but simplifying only the parent doesn't simplify the K1+K2.
00334 // Used to also propagate, but this became unwieldy with -l propagation limiting
00335 class CallBypasser : public SimpExpModifier {
00336         Statement*  enclosingStmt;      // Statement that is being modified at present, for debugging only
00337 public:
00338                     CallBypasser(Statement* enclosing) : enclosingStmt(enclosing) {}
00339 virtual Exp*        postVisit(RefExp *e);
00340 virtual Exp*        postVisit(Location *e);
00341 };
00342 
00343 class UsedLocsFinder : public ExpVisitor {
00344     LocationSet*    used;               // Set of Exps
00345     bool            memOnly;            // If true, only look inside m[...]
00346 public:
00347                     UsedLocsFinder(LocationSet& used, bool memOnly) : used(&used), memOnly(memOnly) {}
00348                     ~UsedLocsFinder() {}
00349 
00350         LocationSet* getLocSet() {return used;}
00351         void        setMemOnly(bool b) {memOnly = b;}
00352         bool        isMemOnly() {return memOnly;}
00353 
00354 virtual bool        visit(RefExp *e,    bool& override);
00355 virtual bool        visit(Location *e, bool& override);
00356 virtual bool        visit(Terminal* e);
00357 };
00358 
00359 // This class differs from the above in these ways:
00360 //  1) it counts locals implicitly referred to with (cast to pointer)(sp-K)
00361 //  2) it does not recurse inside the memof (thus finding the stack pointer as a local)
00362 //  3) only used after fromSSA, so no RefExps to visit
00363 class UsedLocalFinder : public ExpVisitor {
00364         LocationSet* used;          // Set of used locals' names
00365         UserProc*   proc;           // Enclosing proc
00366         bool        all;            // True if see opDefineAll
00367 public:
00368                     UsedLocalFinder(LocationSet& used, UserProc* proc) : used(&used), proc(proc), all(false) {}
00369                     ~UsedLocalFinder() {}
00370 
00371         LocationSet* getLocSet() {return used;}
00372         bool        wasAllFound() {return all;}
00373 
00374 virtual bool        visit(Location *e, bool& override);
00375 virtual bool        visit(TypedExp *e,  bool& override);
00376 virtual bool        visit(Terminal* e);
00377 };
00378 
00379 class UsedLocsVisitor : public StmtExpVisitor {
00380         bool        countCol;                   // True to count uses in collectors
00381 public:
00382                     UsedLocsVisitor(ExpVisitor* v, bool cc) : StmtExpVisitor(v), countCol(cc) {}
00383 virtual             ~UsedLocsVisitor() {}
00384         // Needs special attention because the lhs of an assignment isn't used (except where it's m[blah], when blah is
00385         // used)
00386 virtual bool        visit(         Assign *stmt, bool& override);
00387 virtual bool        visit(      PhiAssign *stmt, bool& override);
00388 virtual bool        visit(ImplicitAssign *stmt, bool& override);
00389         // A BoolAssign uses its condition expression, but not its destination (unless it's an m[x], in which case x is
00390         // used and not m[x])
00391 virtual bool        visit(BoolAssign *stmt, bool& override);
00392         // Returns aren't used (again, except where m[blah] where blah is used), and there is special logic for when the
00393         // pass is final
00394 virtual bool        visit(CallStatement *stmt, bool& override);
00395         // Only consider the first return when final
00396 virtual bool        visit(ReturnStatement *stmt, bool& override);
00397 };
00398 
00399 class ExpSubscripter : public ExpModifier {
00400         Exp*        search;
00401         Statement*  def;
00402 public:
00403                     ExpSubscripter(Exp* s, Statement* d) : search(s), def(d) { }
00404 virtual Exp*        preVisit(Location *e, bool& recur);
00405 virtual Exp*        preVisit(Binary *e, bool& recur);
00406 virtual Exp*        preVisit(Terminal *e);
00407 virtual Exp*        preVisit(RefExp *e,   bool& recur);
00408 };
00409 
00410 class StmtSubscripter : public StmtModifier {
00411 public:
00412                     StmtSubscripter(ExpSubscripter* es) : StmtModifier(es) {}
00413 virtual             ~StmtSubscripter() {}
00414 
00415 virtual void        visit(        Assign *s, bool& recur);
00416 virtual void        visit(     PhiAssign *s, bool& recur);
00417 virtual void        visit(ImplicitAssign *s, bool& recur);
00418 virtual void        visit(    BoolAssign *s, bool& recur);
00419 virtual void        visit( CallStatement *s, bool& recur);
00420 };
00421 
00422 class SizeStripper : public ExpModifier {
00423 public:
00424                     SizeStripper() {}
00425 virtual             ~SizeStripper() {}
00426 
00427 virtual Exp*        preVisit(Binary *b,   bool& recur);
00428 };
00429 
00430 class ExpConstCaster: public ExpModifier {
00431         int         num;
00432         Type*       ty;
00433         bool        changed;
00434 public:
00435                     ExpConstCaster(int num, Type* ty) : num(num), ty(ty), changed(false) {}
00436 virtual             ~ExpConstCaster() {}
00437         bool        isChanged() {return changed;}
00438 
00439 virtual Exp*        preVisit(Const *c);
00440 };
00441 
00442 class ConstFinder : public ExpVisitor {
00443         std::list<Const*>& lc;
00444 public:
00445                     ConstFinder(std::list<Const*>& lc) : lc(lc) {}
00446 virtual             ~ConstFinder() {}
00447 
00448 virtual bool        visit(Const *e);
00449 virtual bool        visit(Location *e, bool& override);
00450 };
00451 
00452 class StmtConstFinder : public StmtExpVisitor {
00453 public:
00454                     StmtConstFinder(ConstFinder* v) : StmtExpVisitor(v) {}
00455 };
00456 
00457 // This class is an ExpModifier because although most of the time it merely maps expressions to locals, in one case,
00458 // where sp-K is found, we replace it with a[m[sp-K]] so the back end emits it as &localX.
00459 // FIXME: this is probably no longer necessary, since the back end no longer maps anything!
00460 class DfaLocalMapper : public ExpModifier {
00461         UserProc*   proc;
00462         Prog*       prog;
00463         Signature*  sig;        // Look up once (from proc) for speed
00464         bool        processExp(Exp* e);     // Common processing here
00465 public:
00466         bool        change;     // True if changed this statement
00467 
00468                     DfaLocalMapper(UserProc* proc);
00469 
00470         Exp*        preVisit(Location* e, bool& recur);     // To process m[X]
00471 //      Exp*        preVisit(Unary* e, bool& recur);        // To process a[X]
00472         Exp*        preVisit(Binary* e, bool& recur);       // To look for sp -+ K
00473         Exp*        preVisit(TypedExp*  e, bool& recur);    // To prevent processing TypedExps more than once
00474 };
00475 
00476 #if 0   // FIXME: deleteme
00477 class StmtDfaLocalMapper : public StmtModifier {
00478 public:
00479                     StmtDfaLocalMapper(ExpModifier* em, bool ic = false) : StmtModifier(em, ic) {}
00480 
00481 virtual void        visit(         Assign *s, bool& recur);
00482 virtual void        visit(      PhiAssign *s, bool& recur);
00483 virtual void        visit( ImplicitAssign *s, bool& recur);
00484 virtual void        visit(     BoolAssign *s, bool& recur);
00485 virtual void        visit(  CallStatement *s, bool& recur);
00486 virtual void        visit(BranchStatement *s, bool& recur);
00487 virtual void        visit(ReturnStatement *s, bool& recur);
00488 virtual void        visit(ImpRefStatement *s, bool& recur);
00489 virtual void        visit(  CaseStatement *s, bool& recur);
00490 };
00491 #endif
00492 
00493 // Convert any exp{-} (with null definition) so that the definition points instead to an implicit assignment (exp{0})
00494 // Note it is important to process refs in a depth first manner, so that e.g. m[sp{-}-8]{-} -> m[sp{0}-8]{-} first, so
00495 // that there is never an implicit definition for m[sp{-}-8], only ever for m[sp{0}-8]
00496 class ImplicitConverter : public ExpModifier {
00497         Cfg*        cfg;
00498 public:
00499                     ImplicitConverter(Cfg* cfg) : cfg(cfg) { }
00500         Exp*        postVisit(RefExp* e);
00501 };
00502 
00503 class StmtImplicitConverter : public StmtModifier {
00504         Cfg*        cfg;
00505 public:
00506                     StmtImplicitConverter(ImplicitConverter* ic, Cfg* cfg)
00507                         : StmtModifier(ic, false),          // False to not ignore collectors (want to make sure that
00508                         cfg(cfg) { }                        //  collectors have valid expressions so you can ascendType)
00509 virtual void        visit(      PhiAssign *s, bool& recur);
00510 };
00511 
00512 class Localiser : public SimpExpModifier {
00513         CallStatement* call;                    // The call to localise to
00514 public:
00515                     Localiser(CallStatement* call) : call(call) { }
00516         Exp*        preVisit(RefExp* e, bool& recur);
00517         Exp*        preVisit(Location* e, bool& recur);
00518         Exp*        postVisit(Location* e);
00519         Exp*        postVisit(Terminal* e);
00520 };
00521 
00522 
00523 class ComplexityFinder : public ExpVisitor {
00524         int         count;
00525         UserProc*   proc;
00526 public:
00527                 ComplexityFinder(UserProc* p) : count(0), proc(p) {}
00528         int     getDepth() {return count;}
00529 
00530 virtual bool    visit(Unary *e,     bool& override);
00531 virtual bool    visit(Binary *e,    bool& override);
00532 virtual bool    visit(Ternary *e,   bool& override);
00533 virtual bool    visit(Location *e,  bool& override);
00534 
00535 };
00536 
00537 // Used by range analysis
00538 class MemDepthFinder : public ExpVisitor {
00539         int     depth;
00540 public:
00541                 MemDepthFinder() : depth(0) {}
00542 virtual bool    visit(Location *e,  bool& override);
00543         int     getDepth() {return depth;}
00544 };
00545 
00546 
00547 // A class to propagate everything, regardless, to this expression. Does not consider memory expressions and whether
00548 // the address expression is primitive. Use with caution; mostly Statement::propagateTo() should be used.
00549 class ExpPropagator : public SimpExpModifier {
00550         bool        change;
00551 public:
00552                     ExpPropagator() : change(false) { }
00553         bool        isChanged() {return change;}
00554         void        clearChanged() {change = false;}
00555         Exp*        postVisit(RefExp* e);
00556 };
00557 
00558 // Test an address expression (operand of a memOf) for primitiveness (i.e. if it is possible to SSA rename the memOf
00559 // without problems). Note that the PrimitiveTester is not used with the memOf expression, only its address expression
00560 class PrimitiveTester : public ExpVisitor {
00561         bool        result;
00562 public:
00563                     PrimitiveTester() : result(true) {}     // Initialise result true: need AND of all components
00564         bool        getResult() {return result;}
00565         bool        visit(Location *e, bool& override);
00566         bool        visit(RefExp *e, bool& override);
00567 };
00568 
00569 // Test if an expression (usually the RHS on an assignment) contains memory expressions. If so, it may not be safe to
00570 // propagate the assignment. NO LONGER USED.
00571 class ExpHasMemofTester : public ExpVisitor {
00572         bool        result;
00573         UserProc*   proc;
00574 public:
00575                     ExpHasMemofTester(UserProc* proc) : result(false), proc(proc) {}
00576         bool        getResult() {return result;}
00577         bool        visit(Location *e, bool& override);
00578 };
00579 
00580 class TempToLocalMapper : public ExpVisitor {
00581         UserProc*   proc;                                   // Proc object for storing the symbols
00582 public:
00583                     TempToLocalMapper(UserProc* p) : proc(p) {}
00584         bool        visit(Location *e, bool& override);
00585 };
00586 
00587 // Name registers and temporaries
00588 class ExpRegMapper : public ExpVisitor {
00589         UserProc*   proc;                                   // Proc object for storing the symbols
00590         Prog*       prog;
00591 public:
00592                     ExpRegMapper(UserProc* proc);
00593         bool        visit(RefExp *e, bool& override);
00594 };
00595 
00596 class StmtRegMapper : public StmtExpVisitor {
00597 public:
00598                     StmtRegMapper(ExpRegMapper* erm) : StmtExpVisitor(erm) {}
00599 virtual bool        common(    Assignment *stmt, bool& override);
00600 virtual bool        visit(         Assign *stmt, bool& override);
00601 virtual bool        visit(      PhiAssign *stmt, bool& override);
00602 virtual bool        visit( ImplicitAssign *stmt, bool& override);
00603 virtual bool        visit(     BoolAssign *stmt, bool& override);
00604 };
00605 
00606 class ConstGlobalConverter : public ExpModifier {
00607         Prog*       prog;                                   // Pointer to the Prog object, for reading memory
00608 public:
00609                     ConstGlobalConverter(Prog* pg) : prog(pg) {}
00610 virtual Exp*        preVisit(RefExp     *e, bool& recur);
00611 };
00612 
00613 // Count the number of times a reference expression is used. Increments the count multiple times if the same reference
00614 // expression appears multiple times (so can't use UsedLocsFinder for this)
00615 class ExpDestCounter : public ExpVisitor {
00616         std::map<Exp*, int, lessExpStar>& destCounts;
00617 public:
00618                     ExpDestCounter(std::map<Exp*, int, lessExpStar>& dc) : destCounts(dc) {}
00619         bool        visit(RefExp *e, bool& override);
00620 };
00621 
00622 // FIXME: do I need to count collectors? All the visitors and modifiers should be refactored to conditionally visit
00623 // or modify collectors, or not
00624 class StmtDestCounter : public StmtExpVisitor {
00625 public:
00626                     StmtDestCounter(ExpDestCounter* edc) : StmtExpVisitor(edc) {}
00627         bool        visit(      PhiAssign *stmt, bool& override);
00628 };
00629 
00630 // Search an expression for flags calls, e.g. SETFFLAGS(...) & 0x45
00631 class FlagsFinder : public ExpVisitor {
00632         bool        found;
00633 public:
00634                     FlagsFinder() : found(false) {}
00635         bool        isFound() {return found;}
00636 private:
00637 virtual bool        visit(Binary *e,    bool& override);
00638 
00639 };
00640 
00641 // Search an expression for a bad memof (non subscripted or not linked with a symbol, i.e. local or parameter)
00642 class BadMemofFinder : public ExpVisitor {
00643         bool        found;
00644         UserProc*   proc;
00645 public:
00646                     BadMemofFinder(UserProc* proc) : found(false), proc(proc) {}
00647         bool        isFound() {return found;}
00648 private:
00649 virtual bool        visit(Location *e,  bool& override);
00650 virtual bool        visit(RefExp *e,    bool& override);
00651 };
00652 
00653 class ExpCastInserter : public ExpModifier {
00654         UserProc*   proc;               // The enclising UserProc
00655 public:
00656                     ExpCastInserter(UserProc* proc) : proc(proc) {}
00657 static  void        checkMemofType(Exp* memof, Type* memofType);
00658 virtual Exp*        postVisit(RefExp *e);
00659 virtual Exp*        postVisit(Binary *e);
00660 virtual Exp*        postVisit(Const *e);
00661 virtual Exp*        preVisit(TypedExp   *e, bool& recur) {recur = false; return e;} // Don't consider if already cast
00662 };
00663 
00664 class StmtCastInserter : public StmtVisitor {
00665         ExpCastInserter* ema;
00666 public:
00667                     StmtCastInserter() {}
00668         bool        common(   Assignment *s);
00669 virtual bool        visit(        Assign *s);
00670 virtual bool        visit(     PhiAssign *s);
00671 virtual bool        visit(ImplicitAssign *s);
00672 virtual bool        visit(    BoolAssign *s);
00673 };
00674 
00675 // Transform an exp by applying mappings to the subscripts. This used to be done by many Exp::fromSSAform() functions.
00676 // Note that mappings have to be done depth first, so e.g. m[r28{0}-8]{22} -> m[esp-8]{22} first, otherwise there wil be
00677 // a second implicit definition for m[esp{0}-8] (original should be b[esp+8] by now)
00678 class ExpSsaXformer : public ExpModifier {
00679         UserProc*   proc;
00680 public:
00681                     ExpSsaXformer(UserProc* proc) : proc(proc) { }
00682         UserProc*   getProc() {return proc;}
00683 
00684 virtual Exp*        postVisit(RefExp *e);
00685 };
00686 
00687 class StmtSsaXformer : public StmtModifier {
00688         UserProc*   proc;
00689 public:
00690                     StmtSsaXformer(ExpSsaXformer* esx, UserProc* proc) : StmtModifier(esx), proc(proc) {}
00691 //virtual           ~StmtSsaXformer() {}
00692         void        commonLhs(Assignment* s);
00693 
00694 virtual void        visit(        Assign *s, bool& recur);
00695 virtual void        visit(     PhiAssign *s, bool& recur);
00696 virtual void        visit(ImplicitAssign *s, bool& recur);
00697 virtual void        visit(    BoolAssign *s, bool& recur);
00698 virtual void        visit( CallStatement *s, bool& recur);
00699 };
00700 
00701 #endif  // #ifndef __VISITOR_H__

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