statement.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002, Trent Waddington
00003  *
00004  * See the file "LICENSE.TERMS" for information on usage and
00005  * redistribution of this file, and for a DISCLAIMER OF ALL
00006  * WARRANTIES.
00007  *
00008  */
00009 
00010 /*==============================================================================
00011  * FILE:       statement.h
00012  * OVERVIEW:   The Statement and related classes (was dataflow.h)
00013  *============================================================================*/
00014 
00015 /*
00016  * $Revision: 1.107 $   // 1.76.2.30
00017  * 25 Nov 02 - Trent: appropriated for use by new dataflow.
00018  * 3 July 02 - Trent: created.
00019  * 03 Feb 03 - Mike: cached dataflow (uses and usedBy)
00020  * 03 Apr 03 - Mike: Added StatementSet
00021  * 25 Jul 03 - Mike: Changed dataflow.h to statement.h
00022  * 15 Jul 04 - Mike: New Assignment hierarchy
00023  * 11 Aug 04 - Mike: BoolStatement -> BoolAssign
00024  * 17 Sep 04 - Mike: PhiExp in ordinary assignment replaced by PhiAssign statement
00025  * 27 Oct 04 - Mike: PhiAssign has vector of PhiInfo now; needed because a statement pointer alone does not uniquely
00026  *                      define what is defined. It is now possible for all parameters of a phi to have different exps
00027  * 15 Mar 05 - Mike: Removed implicit arguments; replaced with DefCollector
00028  * 11 Apr 05 - Mike: Added RetStatement, DefineAll
00029  * 26 Apr 05 - Mike: Moved class Return here from signature.h
00030  * 12 Aug 05 - Mike: Added ImpRefStatement
00031  */
00032 
00033 #ifndef _STATEMENT_H_
00034 #define _STATEMENT_H_
00035 
00036 /* Class hierarchy:   Statement@            (@ = abstract)
00037                     __/   |   \________________________
00038                    /      |            \               \
00039        GotoStatement  TypingStatement@  ReturnStatement JunctionStatement
00040  BranchStatement_/     /          \ 
00041  CaseStatement__/  Assignment@   ImpRefStatement
00042  CallStatement_/  /   /    \ \________
00043        PhiAssign_/ Assign  BoolAssign \_ImplicitAssign
00044 */
00045 
00046 #include <vector>
00047 #include <set>
00048 #include <list>
00049 #include <map>
00050 #include <ostream>
00051 #include <iostream>     // For std::cerr
00052 #include <assert.h>
00053 //#include "exp.h"      // No! This is (almost) the bottom of the #include hierarchy
00054 #include "memo.h"
00055 #include "exphelp.h"    // For lessExpStar, lessAssignment etc
00056 #include "types.h"
00057 #include "managed.h"
00058 #include "dataflow.h"   // For embedded objects DefCollector and UseCollector
00059 #include "boomerang.h"  // For USE_DOMINANCE_NUMS etc
00060 
00061 class BasicBlock;
00062 typedef BasicBlock *PBB;
00063 class Prog;
00064 class Proc;
00065 class UserProc;
00066 class Exp;
00067 class Const;
00068 class RefExp;
00069 class Cfg;
00070 class Type;
00071 class Statement;
00072 class Signature;
00073 class StmtVisitor;
00074 class StmtExpVisitor;
00075 class StmtModifier;
00076 class StmtPartModifier;
00077 class HLLCode;
00078 class Assign;
00079 class RTL;
00080 class XMLProgParser;
00081 class ReturnStatement;
00082 
00083 typedef std::set<UserProc*> CycleSet;
00084 
00085 /*==============================================================================
00086  * Kinds of Statements, or high-level register transfer lists.
00087  * changing the order of these will result in save files not working - trent
00088  *============================================================================*/
00089 enum STMT_KIND {
00090     STMT_ASSIGN = 0,
00091     STMT_PHIASSIGN,
00092     STMT_IMPASSIGN,
00093     STMT_BOOLASSIGN,            // For "setCC" instructions that set destination
00094                                 // to 1 or 0 depending on the condition codes.
00095     STMT_CALL,
00096     STMT_RET,
00097     STMT_BRANCH,
00098     STMT_GOTO,
00099     STMT_CASE,                  // Represent  a switch statement
00100     STMT_IMPREF,
00101     STMT_JUNCTION
00102 };
00103 
00104 /*==============================================================================
00105  * BRANCH_TYPE: These values indicate what kind of conditional jump or
00106  * conditonal assign is being performed.
00107  * Changing the order of these will result in save files not working - trent
00108  *============================================================================*/
00109 enum BRANCH_TYPE {
00110     BRANCH_JE = 0,          // Jump if equals
00111     BRANCH_JNE,             // Jump if not equals
00112     BRANCH_JSL,             // Jump if signed less
00113     BRANCH_JSLE,            // Jump if signed less or equal
00114     BRANCH_JSGE,            // Jump if signed greater or equal
00115     BRANCH_JSG,             // Jump if signed greater
00116     BRANCH_JUL,             // Jump if unsigned less
00117     BRANCH_JULE,            // Jump if unsigned less or equal
00118     BRANCH_JUGE,            // Jump if unsigned greater or equal
00119     BRANCH_JUG,             // Jump if unsigned greater
00120     BRANCH_JMI,             // Jump if result is minus
00121     BRANCH_JPOS,            // Jump if result is positive
00122     BRANCH_JOF,             // Jump if overflow
00123     BRANCH_JNOF,            // Jump if no overflow
00124     BRANCH_JPAR             // Jump if parity even (Intel only)
00125 };
00126 
00127 //  //  //  //  //  //  //  //  //  //  //  //  //  //
00128 //
00129 //  A b s t r a c t   C l a s s   S t a t e m e n t //
00130 //
00131 //  //  //  //  //  //  //  //  //  //  //  //  //  //
00132 
00133 /* Statements define values that are used in expressions.
00134  * They are akin to "definition" in the Dragon Book.
00135  */
00136 class Statement {
00137 protected:
00138         PBB         pbb;            // contains a pointer to the enclosing BB
00139         UserProc    *proc;          // procedure containing this statement
00140         int         number;         // Statement number for printing
00141 #if     USE_DOMINANCE_NUMS
00142         int         dominanceNum;   // Like a statement number, but has dominance properties
00143 public:
00144         int         getDomNumber() {return dominanceNum;}
00145         void        setDomNumber(int dn) {dominanceNum = dn;}
00146 protected:
00147 #endif
00148         STMT_KIND   kind;           // Statement kind (e.g. STMT_BRANCH)
00149         Statement   *parent;        // The statement that contains this one
00150         RangeMap    ranges;         // overestimation of ranges of locations
00151         RangeMap    savedInputRanges;  // saved overestimation of ranges of locations
00152 
00153         unsigned int lexBegin, lexEnd;
00154 
00155 public:
00156 
00157                     Statement() : pbb(NULL), proc(NULL), number(0), parent(NULL) { }
00158 virtual             ~Statement() { }
00159 
00160         // get/set the enclosing BB, etc
00161         PBB         getBB() { return pbb; }
00162         void        setBB(PBB bb) {pbb = bb; }
00163 
00164 //      bool        operator==(Statement& o);
00165         // Get and set *enclosing* proc (not destination proc)
00166         void        setProc(UserProc *p);
00167         UserProc*   getProc() {return proc;}
00168 
00169         int         getNumber() {return number;}
00170 virtual void        setNumber(int num) {number = num;}      // Overridden for calls (and maybe later returns)
00171 
00172         STMT_KIND   getKind() { return kind;}
00173         void        setKind(STMT_KIND k) {kind = k;}
00174 
00175         void        setParent(Statement* par) {parent = par;}
00176         Statement*  getParent() {return parent;}
00177 
00178         RangeMap &getRanges() { return ranges; }
00179         void      clearRanges() { ranges.clear(); }
00180 
00181 virtual Statement*  clone() = 0;               // Make copy of self
00182 
00183         // Accept a visitor (of various kinds) to this Statement. Return true to continue visiting
00184 virtual bool        accept(StmtVisitor* visitor) = 0;
00185 virtual bool        accept(StmtExpVisitor* visitor) = 0;
00186 virtual bool        accept(StmtModifier* visitor) = 0;
00187 virtual bool        accept(StmtPartModifier* visitor) = 0;
00188 
00189         void        setLexBegin(unsigned int n) { lexBegin = n; }
00190         void        setLexEnd(unsigned int n) { lexEnd = n; }
00191         unsigned    int getLexBegin() { return lexBegin; }
00192         unsigned    int getLexEnd() { return lexEnd; }
00193         Exp         *getExpAtLex(unsigned int begin, unsigned int end);
00194 
00195 
00196         // returns true if this statement defines anything
00197 virtual bool        isDefinition() = 0;
00198 
00199         // true if is a null statement
00200         bool        isNullStatement();
00201 
00202 virtual bool        isTyping() {return false;}      // Return true if a TypingStatement
00203         // true if this statement is a standard assign
00204         bool        isAssign() {return kind == STMT_ASSIGN;}
00205         // true if this statement is a any kind of assignment
00206         bool        isAssignment() {return kind == STMT_ASSIGN || kind == STMT_PHIASSIGN ||
00207                         kind == STMT_IMPASSIGN || kind == STMT_BOOLASSIGN;}
00208         // true if this statement is a phi assignment
00209         bool        isPhi() {return kind == STMT_PHIASSIGN; }
00210         // true if this statement is an implicit assignment
00211         bool        isImplicit() {return kind == STMT_IMPASSIGN;}
00212         // true if this statment is a flags assignment
00213         bool        isFlagAssgn();
00214         // true of this statement is an implicit reference
00215         bool        isImpRef() {return kind == STMT_IMPREF;}
00216 
00217 virtual bool        isGoto() { return kind == STMT_GOTO; }
00218 virtual bool        isBranch() { return kind == STMT_BRANCH; }
00219 
00220         // true if this statement is a junction
00221         bool        isJunction() { return kind == STMT_JUNCTION; }
00222 
00223         // true if this statement is a call
00224         bool        isCall() { return kind == STMT_CALL; }
00225 
00226         // true if this statement is a BoolAssign
00227         bool        isBool() { return kind == STMT_BOOLASSIGN; }
00228 
00229         // true if this statement is a ReturnStatement
00230         bool        isReturn() { return kind == STMT_RET; }
00231 
00232         // true if this statement is a decoded ICT.
00233         // NOTE: for now, it only represents decoded indirect jump instructions
00234         bool        isHL_ICT() {return kind == STMT_CASE; }
00235 
00236         bool        isCase() {return kind == STMT_CASE; }
00237 
00238         // true if this is a fpush/fpop
00239         bool        isFpush();
00240         bool        isFpop();
00241 
00242         // returns a set of locations defined by this statement
00243         // Classes with no definitions (e.g. GotoStatement and children) don't override this
00244 virtual void        getDefinitions(LocationSet &def) {}
00245 
00246         // set the left for forExp to newExp
00247 virtual void        setLeftFor(Exp* forExp, Exp* newExp) {assert(0);}
00248 virtual bool        definesLoc(Exp* loc) {return false;}            // True if this Statement defines loc
00249 
00250     // returns true if this statement uses the given expression
00251 virtual bool        usesExp(Exp *e) = 0;
00252 
00253     // statements should be printable (for debugging)
00254 virtual void        print(std::ostream &os, bool html = false) = 0;
00255         void        printAsUse(std::ostream &os)   {os << std::dec << number;}
00256         void        printAsUseBy(std::ostream &os) {os << std::dec << number;}
00257         void        printNum(std::ostream &os)     {os << std::dec << number;}
00258         char*       prints();       // For logging, was also for debugging
00259         void        dump();         // For debugging
00260 
00261         // general search
00262 virtual bool        search(Exp *search, Exp *&result) = 0;
00263 virtual bool        searchAll(Exp* search, std::list<Exp*>& result) = 0;
00264 
00265         // general search and replace. Set cc true to change collectors as well. Return true if any change
00266 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false) = 0;
00267 
00268         // True if can propagate to expression e in this Statement.
00269 static  bool        canPropagateToExp(Exp* e);
00270         // Propagate to this statement. Return true if a change
00271         // destCounts is a map that indicates how may times a statement's definition is used
00272         // dnp is a StatementSet with statements that should not be propagated
00273         // Set convert if an indirect call is changed to direct (otherwise, no change)
00274         // Set force to true to propagate even memofs (for switch analysis)
00275         bool        propagateTo(bool& convert, std::map<Exp*, int, lessExpStar>* destCounts = NULL,
00276                         LocationSet* usedByDomPhi = NULL, bool force = false);
00277         bool        propagateFlagsTo();
00278 
00279         // code generation
00280 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) = 0;
00281 
00282         // simpify internal expressions
00283 virtual void        simplify() = 0;
00284 
00285         // simplify internal address expressions (a[m[x]] -> x) etc
00286         // Only Assignments override at present
00287 virtual void        simplifyAddr() {}
00288 
00289         // map registers and temporaries to local variables
00290         void        mapRegistersToLocals();
00291 
00292         // The last part of the fromSSA logic: replace subscripted locations with suitable local variables
00293         void        replaceSubscriptsWithLocals();
00294 
00295         // insert casts where needed, since fromSSA will erase type information
00296         void        insertCasts();
00297 
00298         // fixSuccessor
00299         // Only Assign overrides at present
00300 virtual void        fixSuccessor() {}
00301 
00302         // Generate constraints (for constraint based type analysis)
00303 virtual void        genConstraints(LocationSet& cons) {}
00304 
00305         // Data flow based type analysis
00306 virtual void        dfaTypeAnalysis(bool& ch) {}            // Use the type information in this Statement
00307         Type*       meetWithFor(Type* ty, Exp* e, bool& ch);// Meet the type associated with e with ty
00308 
00309         // Range analysis
00310 protected:
00311         void        updateRanges(RangeMap &output, std::list<Statement*> &execution_paths, bool notTaken = false);
00312 public:
00313         RangeMap    &getSavedInputRanges() { return savedInputRanges; }
00314         RangeMap    getInputRanges();
00315 virtual void        rangeAnalysis(std::list<Statement*> &execution_paths);
00316 
00317         // helper functions
00318         bool        isFirstStatementInBB();
00319         bool        isLastStatementInBB();
00320         Statement*  getNextStatementInBB();
00321         Statement*  getPreviousStatementInBB();
00322 
00323 
00324 //  //  //  //  //  //  //  //  //  //
00325 //                                  //
00326 //  Statement visitation functions  //
00327 //                                  //
00328 //  //  //  //  //  //  //  //  //  //
00329 
00330         // Adds (inserts) all locations (registers or memory etc) used by this statement
00331         // Set cc to true to count the uses in collectors
00332         void        addUsedLocs(LocationSet& used, bool cc = false, bool memOnly = false);
00333         // Special version of the above for finding used locations. Returns true if defineAll was found
00334         bool        addUsedLocals(LocationSet& used);
00335         // Bypass calls for references in this statement
00336         void        bypass();
00337 
00338 
00339         // replaces a use in this statement with an expression from an ordinary assignment
00340         // Internal use only
00341         bool        replaceRef(Exp* e, Assign *def, bool& convert);
00342 
00343         // Find all constants in this statement
00344         void        findConstants(std::list<Const*>& lc);
00345 
00346         // Set or clear the constant subscripts (using a visitor)
00347         int         setConscripts(int n);
00348         void        clearConscripts();
00349 
00350         // Strip all size casts
00351         void        stripSizes();
00352 
00353         // For all expressions in this Statement, replace all e with e{def}
00354         void        subscriptVar(Exp* e, Statement* def /*, Cfg* cfg */);
00355 
00356         // Cast the constant num to type ty. If a change was made, return true
00357         bool        castConst(int num, Type* ty);
00358 
00359         // Map expressions to locals
00360         void        dfaMapLocals();
00361 
00362         // End Statement visitation functions
00363 
00364 
00365         // Get the type for the definition, if any, for expression e in this statement 
00366         // Overridden only by Assignment and CallStatement, and ReturnStatement.
00367 virtual Type*       getTypeFor(Exp* e) { return NULL;}
00368         // Set the type for the definition of e in this Statement
00369 virtual void        setTypeFor(Exp* e, Type* ty) {assert(0);}
00370 
00371 //virtual   Type*   getType() {return NULL;}            // Assignment, ReturnStatement and
00372 //virtual   void    setType(Type* t) {assert(0);}       // CallStatement override
00373 
00374         bool        doPropagateTo(Exp* e, Assign* def, bool& convert);
00375         bool        calcMayAlias(Exp *e1, Exp *e2, int size);
00376         bool        mayAlias(Exp *e1, Exp *e2, int size);
00377 
00378     friend class XMLProgParser;
00379 };      // class Statement
00380 
00381 // Print the Statement (etc) poited to by p
00382 std::ostream& operator<<(std::ostream& os, Statement* p);
00383 std::ostream& operator<<(std::ostream& os, StatementSet* p);
00384 std::ostream& operator<<(std::ostream& os, LocationSet* p);
00385 
00386 /*==============================================================================
00387  * TypingStatement is an abstract subclass of Statement. It has a type, representing the type of a reference or an
00388  * assignment
00389  *============================================================================*/
00390 class TypingStatement : public Statement {
00391 protected:
00392         Type*       type;       // The type for this assignment or reference
00393 public:
00394                     TypingStatement(Type* ty);      // Constructor
00395 
00396         // Get and set the type.
00397         Type*       getType() {return type;}
00398         void        setType(Type* ty) {type = ty;}
00399 
00400 virtual bool        isTyping() {return true;}
00401 };
00402 
00403 /*==========================================================================
00404  * Assignment is an abstract subclass of TypingStatement, holding a location
00405  *==========================================================================*/
00406 class Assignment : public TypingStatement {
00407 protected:
00408         Exp*        lhs;        // The left hand side
00409 public:
00410         // Constructor, subexpression
00411                     Assignment(Exp* lhs);
00412         // Constructor, type, and subexpression
00413                     Assignment(Type* ty, Exp* lhs);
00414         // Destructor
00415 virtual             ~Assignment();
00416 
00417         // Clone
00418 virtual Statement* clone() = 0;
00419 
00420         // We also want operator< for assignments. For example, we want ReturnStatement to contain a set of (pointers
00421         // to) Assignments, so we can automatically make sure that existing assignments are not duplicated
00422         // Assume that we won't want sets of assignments differing by anything other than LHSs
00423         bool        operator<(const Assignment& o) {return lhs < o.lhs;}
00424 
00425         // Accept a visitor to this Statement
00426 virtual bool        accept(StmtVisitor* visitor) = 0;
00427 virtual bool        accept(StmtExpVisitor* visitor) = 0;
00428 virtual bool        accept(StmtModifier* visitor) = 0;
00429 virtual bool        accept(StmtPartModifier* visitor) = 0;
00430 
00431 virtual void        print(std::ostream& os, bool html = false);
00432 virtual void        printCompact(std::ostream& os, bool html = false) = 0;  // Without statement number
00433 
00434 virtual Type*       getTypeFor(Exp* e);                 // Get the type for this assignment. It should define e
00435 virtual void        setTypeFor(Exp* e, Type* ty);       // Set the type for this assignment. It should define e
00436 
00437 virtual bool        usesExp(Exp *e);       // PhiAssign and ImplicitAssign don't override
00438 
00439 virtual bool        isDefinition() { return true; }
00440 virtual void        getDefinitions(LocationSet &defs);
00441 virtual bool        definesLoc(Exp* loc);                   // True if this Statement defines loc
00442         
00443         // get how to access this lvalue
00444 virtual Exp*        getLeft() { return lhs; }       // Note: now only defined for Assignments, not all Statements
00445 virtual void        setLeftFor(Exp* forExp, Exp* newExp) {lhs = newExp; }
00446 
00447         // set the lhs to something new
00448         void        setLeft(Exp* e)  { lhs = e; }
00449 
00450         // memory depth
00451         int         getMemDepth();
00452 
00453         // general search
00454 virtual bool        search(Exp *search, Exp *&result) = 0;
00455 virtual bool        searchAll(Exp* search, std::list<Exp*>& result) = 0;
00456 
00457         // general search and replace
00458 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false) = 0;
00459 
00460         void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {}
00461 
00462         // simpify internal expressions
00463 virtual void        simplify() = 0;
00464 
00465     // simplify address expressions
00466 virtual void        simplifyAddr();
00467 
00468         // generate Constraints
00469 virtual void        genConstraints(LocationSet& cons);
00470 
00471         // Data flow based type analysis
00472         void        dfaTypeAnalysis(bool& ch);
00473 
00474         friend class XMLProgParser;
00475 };      // class Assignment
00476 
00477 
00478 // Assign: an ordinary assignment with left and right sides
00479 class Assign : public Assignment {
00480         Exp*        rhs;
00481         Exp*        guard;
00482 
00483 public:
00484         // Constructor, subexpressions
00485                     Assign(Exp* lhs, Exp* rhs, Exp* guard = NULL);
00486         // Constructor, type and subexpressions
00487                     Assign(Type* ty, Exp* lhs, Exp* rhs, Exp* guard = NULL);
00488         // Default constructor, for XML parser
00489                     Assign() : Assignment(NULL), rhs(NULL), guard(NULL) {}
00490         // Copy constructor
00491                     Assign(Assign& o);
00492         // Destructor
00493                     ~Assign() {}
00494 
00495     // Clone
00496 virtual Statement*  clone();
00497 
00498     // get how to replace this statement in a use
00499 virtual Exp*        getRight() { return rhs; }
00500         Exp*&       getRightRef() { return rhs; }
00501 
00502         // set the rhs to something new
00503         void        setRight(Exp* e) { rhs = e; }
00504 
00505 
00506 
00507         // Accept a visitor to this Statement
00508 virtual bool        accept(StmtVisitor* visitor);
00509 virtual bool        accept(StmtExpVisitor* visitor);
00510 virtual bool        accept(StmtModifier* visitor);
00511 virtual bool        accept(StmtPartModifier* visitor);
00512 
00513 virtual void        printCompact(std::ostream& os, bool html = false);  // Without statement number
00514 
00515         // Guard
00516         void        setGuard(Exp* g) {guard = g;}
00517         Exp*        getGuard() {return guard;}
00518         bool        isGuarded() {return guard != NULL;}
00519 
00520 virtual bool        usesExp(Exp *e);
00521 virtual bool        isDefinition() { return true; }
00522         
00523         // general search
00524 virtual bool        search(Exp* search, Exp*& result);
00525 virtual bool        searchAll(Exp* search, std::list<Exp*>& result);
00526 
00527         // general search and replace
00528 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false);
00529  
00530         // memory depth
00531         int         getMemDepth();
00532 
00533         // Generate code
00534 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
00535 
00536         // simpify internal expressions
00537 virtual void        simplify();
00538 
00539         // simplify address expressions
00540 virtual void        simplifyAddr();
00541 
00542         // fixSuccessor (succ(r2) -> r3)
00543 virtual void        fixSuccessor();
00544 
00545         // generate Constraints
00546 virtual void        genConstraints(LocationSet& cons);
00547 
00548         // Data flow based type analysis
00549         void        dfaTypeAnalysis(bool& ch);
00550 
00551         // Range analysis
00552         void        rangeAnalysis(std::list<Statement*> &execution_paths);
00553 
00554         // FIXME: I suspect that this was only used by adhoc TA, and can be deleted
00555         bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00556 
00557     friend class XMLProgParser;
00558 };  // class Assign
00559 
00560 /*==============================================================================
00561  * PhiAssign is a subclass of Assignment, having a left hand side, and a StatementVec with the references.
00562  * Example:
00563  * m[1000] := phi{3 7 10}   m[1000] is defined at statements 3, 7, and 10
00564  * m[r28{3}+4] := phi{2 8}  the memof is defined at 2 and 8, and
00565  * the r28 is defined at 3. The integers are really pointers to statements,
00566  * printed as the statement number for compactness
00567  * NOTE: Although the left hand side is nearly always redundant, it is essential in at least one circumstance: when
00568  * finding locations used by some statement, and the reference is to a CallStatement returning multiple locations.
00569  *============================================================================*/
00570 // The below could almost be a RefExp. But we could not at one stage #include exp.h as part of statement,h; that's since
00571 // changed so it is now possible, and arguably desirable.  However, it's convenient to have these members public
00572 struct PhiInfo {
00573         // A default constructor is required because CFG changes (?) can cause access to elements of the vector that
00574         // are beyond the current end, creating gaps which have to be initialised to zeroes so that they can be skipped
00575         PhiInfo() : def(0), e(0) {}
00576         Statement*  def;        // The defining statement
00577         Exp*        e;          // The expression for the thing being defined (never subscripted)
00578 };
00579 class PhiAssign : public Assignment {
00580 public:
00581         typedef     std::vector<PhiInfo> Definitions;
00582         typedef     Definitions::iterator iterator;
00583 private:
00584         Definitions defVec;     // A vector of information about definitions
00585 public:
00586         // Constructor, subexpression
00587                     PhiAssign(Exp* lhs)
00588                         : Assignment(lhs) {kind = STMT_PHIASSIGN;}
00589         // Constructor, type and subexpression
00590                     PhiAssign(Type* ty, Exp* lhs)
00591                       : Assignment(ty, lhs) {kind = STMT_PHIASSIGN;}
00592         // Copy constructor (not currently used or implemented)
00593                     PhiAssign(Assign& o);
00594         // Destructor
00595 virtual             ~PhiAssign() {}
00596 
00597         // Clone
00598 virtual Statement*  clone();
00599 
00600         // get how to replace this statement in a use
00601 virtual Exp*        getRight() { return NULL; }
00602 
00603         // Accept a visitor to this Statement
00604 virtual bool        accept(StmtVisitor* visitor);
00605 virtual bool        accept(StmtExpVisitor* visitor);
00606 virtual bool        accept(StmtModifier* visitor);
00607 virtual bool        accept(StmtPartModifier* visitor);
00608 
00609 virtual void        printCompact(std::ostream& os, bool html = false);
00610 
00611         // general search
00612 virtual bool        search(Exp* search, Exp*& result);
00613 virtual bool        searchAll(Exp* search, std::list<Exp*>& result);
00614 
00615         // general search and replace
00616 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false);
00617  
00618         // simplify all the uses/defs in this Statement
00619 virtual void        simplify();
00620 
00621         // Generate constraints
00622 virtual void        genConstraints(LocationSet& cons);
00623 
00624         // Data flow based type analysis
00625         void        dfaTypeAnalysis(bool& ch);
00626 
00627 //
00628 //  Phi specific functions
00629 //
00630 
00631         // Get or put the statement at index idx
00632         Statement*  getStmtAt(int idx) {return defVec[idx].def;}
00633         PhiInfo&    getAt(int idx) {return defVec[idx];}
00634         void        putAt(int idx, Statement* d, Exp* e);
00635         void        simplifyRefs();
00636 virtual int         getNumDefs() {return defVec.size();}
00637         Definitions& getDefs() {return defVec;}
00638         // A hack. Check MVE
00639         bool        hasGlobalFuncParam();
00640 
00641         iterator    begin() {return defVec.begin();}
00642         iterator    end()   {return defVec.end();}
00643         iterator    erase(iterator it)  {return defVec.erase(it);}
00644 
00645         // Convert this phi assignment to an ordinary assignment
00646         void        convertToAssign(Exp* rhs);
00647 
00648         // Generate a list of references for the parameters
00649         void        enumerateParams(std::list<Exp*>& le);
00650 
00651 protected:
00652         friend class XMLProgParser;
00653 };      // class PhiAssign
00654 
00655 // An implicit assignment has only a left hand side. It is a placeholder for storing the types of parameters and
00656 // globals.  That way, you can always find the type of a subscripted variable by looking in its defining Assignment
00657 class ImplicitAssign : public Assignment {
00658 public:
00659         // Constructor, subexpression
00660                     ImplicitAssign(Exp* lhs);
00661         // Constructor, type, and subexpression
00662                     ImplicitAssign(Type* ty, Exp* lhs);
00663         // Copy constructor
00664                     ImplicitAssign(ImplicitAssign& o);
00665         // Destructor
00666 virtual             ~ImplicitAssign();
00667 
00668         // Clone
00669 virtual Statement*  clone();
00670 
00671         // Data flow based type analysis
00672         void        dfaTypeAnalysis(bool& ch);
00673 
00674         // general search
00675 virtual bool        search(Exp* search, Exp*& result);
00676 virtual bool        searchAll(Exp* search, std::list<Exp*>& result);
00677 
00678         // general search and replace
00679 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false);
00680  
00681 virtual void        printCompact(std::ostream& os, bool html = false);
00682 
00683         // Statement and Assignment functions
00684 virtual Exp*        getRight() { return NULL; }
00685 virtual void        simplify() {}
00686 
00687         // Visitation
00688 virtual bool        accept(StmtVisitor* visitor);
00689 virtual bool        accept(StmtExpVisitor* visitor);
00690 virtual bool        accept(StmtModifier* visitor);
00691 virtual bool        accept(StmtPartModifier* visitor);
00692 
00693 };      // class ImplicitAssign
00694 
00695 /*==============================================================================
00696  * BoolAssign represents "setCC" type instructions, where some destination is set (to 1 or 0) depending on the
00697  * condition codes. It has a condition Exp, similar to the BranchStatement class.
00698  * *==========================================================================*/
00699 class BoolAssign: public Assignment {
00700         BRANCH_TYPE jtCond;     // the condition for setting true
00701         Exp*        pCond;      // Exp representation of the high level
00702                                 // condition: e.g. r[8] == 5
00703         bool        bFloat;     // True if condition uses floating point CC
00704         int         size;       // The size of the dest
00705 public:
00706                     BoolAssign(int size);
00707 virtual             ~BoolAssign();
00708 
00709         // Make a deep copy, and make the copy a derived object if needed.
00710 virtual Statement*  clone();
00711 
00712         // Accept a visitor to this Statement
00713 virtual bool        accept(StmtVisitor* visitor);
00714 virtual bool        accept(StmtExpVisitor* visitor);
00715 virtual bool        accept(StmtModifier* visitor);
00716 virtual bool        accept(StmtPartModifier* visitor);
00717 
00718         // Set and return the BRANCH_TYPE of this scond as well as whether the
00719         // floating point condition codes are used.
00720         void        setCondType(BRANCH_TYPE cond, bool usesFloat = false);
00721         BRANCH_TYPE getCond(){return jtCond;}
00722         bool        isFloat(){return bFloat;}
00723         void        setFloat(bool b) { bFloat = b; }
00724 
00725         // Set and return the Exp representing the HL condition
00726         Exp*        getCondExpr();
00727         void        setCondExpr(Exp* pss);
00728         // As above, no delete (for subscripting)
00729         void        setCondExprND(Exp* e) { pCond = e; }
00730 
00731         int         getSize() {return size;}    // Return the size of the assignment
00732         void        makeSigned();
00733 
00734 virtual void        printCompact(std::ostream& os = std::cout, bool html = false);
00735 
00736         // code generation
00737 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
00738 
00739         // simplify all the uses/defs in this Statement
00740 virtual void        simplify();
00741 
00742         // Statement functions
00743 virtual bool        isDefinition() { return true; }
00744 virtual void        getDefinitions(LocationSet &def);
00745 virtual Exp*        getRight() { return getCondExpr(); }
00746 virtual bool        usesExp(Exp *e);
00747 virtual bool        search(Exp *search, Exp *&result);
00748 virtual bool        searchAll(Exp* search, std::list<Exp*>& result);
00749 virtual bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false);
00750         // a hack for the SETS macro
00751         void        setLeftFromList(std::list<Statement*>* stmts);
00752 
00753 virtual void        dfaTypeAnalysis(bool& ch);
00754 
00755         friend class XMLProgParser;
00756 };  // class BoolAssign
00757 
00758 // An implicit reference has only an expression. It holds the type information that results from taking the address
00759 // of a location. Note that dataflow can't decide which local variable (in the decompiled output) is being taken,
00760 // if there is more than one local variable sharing the same memory address (separated then by type).
00761 class ImpRefStatement : public TypingStatement {
00762         Exp*        addressExp;         // The expression representing the address of the location referenced
00763 public:
00764         // Constructor, subexpression
00765                     ImpRefStatement(Type* ty, Exp* a) : TypingStatement(ty), addressExp(a) {
00766                         kind = STMT_IMPREF;
00767                     }
00768         Exp*        getAddressExp() {return addressExp;}
00769         Type*       getType() {return type;}
00770         void        meetWith(Type* ty, bool& ch);       // Meet the internal type with ty. Set ch if a change
00771 
00772         // Virtuals
00773 virtual Statement*  clone();
00774 virtual bool        accept(StmtVisitor*);
00775 virtual bool        accept(StmtExpVisitor*);
00776 virtual bool        accept(StmtModifier*);
00777 virtual bool        accept(StmtPartModifier*);
00778 virtual bool        isDefinition() {return false;}
00779 virtual bool        usesExp(Exp*) {return false;}
00780 virtual bool        search(Exp*, Exp*&);
00781 virtual bool        searchAll(Exp*, std::list<Exp*, std::allocator<Exp*> >&);
00782 virtual bool        searchAndReplace(Exp*, Exp*, bool cc = false);
00783 virtual void        generateCode(HLLCode*, BasicBlock*, int) {}
00784 virtual void        simplify();
00785 virtual void        print(std::ostream& os, bool html = false);
00786 
00787 };  // class ImpRefStatement
00788 
00789 
00790 /*=============================================================================
00791  * GotoStatement has just one member variable, an expression representing the
00792  * jump's destination (an integer constant for direct jumps; an expression
00793  * for register jumps). An instance of this class will never represent a
00794  * return or computed call as these are distinguised by the decoder and are
00795  * instantiated as CallStatements and ReturnStatements respecitvely.
00796  * This class also represents unconditional jumps with a fixed offset
00797  * (e.g BN, Ba on SPARC).
00798  *===========================================================================*/
00799 class GotoStatement: public Statement {
00800 protected:
00801         Exp*        pDest;          // Destination of a jump or call. This is the absolute destination for both static
00802                                     // and dynamic CTIs.
00803         bool        m_isComputed;   // True if this is a CTI with a computed destination address.
00804                                     // NOTE: This should be removed, once CaseStatement and HLNwayCall are implemented
00805                                     // properly.
00806 public:
00807                     GotoStatement();
00808                     GotoStatement(ADDRESS jumpDest);
00809 virtual             ~GotoStatement();
00810 
00811         // Make a deep copy, and make the copy a derived object if needed.
00812 virtual Statement*  clone();
00813 
00814         // Accept a visitor to this Statement
00815 virtual bool        accept(StmtVisitor* visitor);
00816 virtual bool        accept(StmtExpVisitor* visitor);
00817 virtual bool        accept(StmtModifier* visitor);
00818 virtual bool        accept(StmtPartModifier* visitor);
00819 
00820         // Set and return the destination of the jump. The destination is either an Exp, or an ADDRESS that is
00821         // converted to a Exp.
00822         void        setDest(Exp* pd);
00823         void        setDest(ADDRESS addr);
00824 virtual Exp*        getDest();
00825 
00826         // Return the fixed destination of this CTI. For dynamic CTIs, returns -1.
00827         ADDRESS     getFixedDest();
00828 
00829         // Adjust the fixed destination by a given amount. Invalid for dynamic CTIs.
00830         void        adjustFixedDest(int delta);
00831     
00832         // Set and return whether the destination of this CTI is computed.
00833         // NOTE: These should really be removed, once CaseStatement and HLNwayCall are implemented properly.
00834         void        setIsComputed(bool b = true);
00835         bool        isComputed();
00836 
00837 virtual void        print(std::ostream& os = std::cout, bool html = false);
00838 
00839         // general search
00840 virtual bool        search(Exp*, Exp*&);
00841 
00842         // Replace all instances of "search" with "replace".
00843 virtual bool        searchAndReplace(Exp* search, Exp* replace, bool cc = false);
00844     
00845         // Searches for all instances of a given subexpression within this
00846         // expression and adds them to a given list in reverse nesting order.    
00847 virtual bool        searchAll(Exp* search, std::list<Exp*> &result);
00848 
00849         // code generation
00850 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
00851 
00852         // simplify all the uses/defs in this Statement
00853 virtual void        simplify();
00854 
00855         // Statement virtual functions
00856 virtual bool        isDefinition() { return false;}
00857 virtual bool        usesExp(Exp*);
00858 
00859         friend class XMLProgParser;
00860 };      // class GotoStatement
00861 
00862 class JunctionStatement: public Statement {
00863 public:
00864     JunctionStatement() { kind = STMT_JUNCTION; }
00865 
00866     Statement*  clone() { return new JunctionStatement(); }
00867 
00868     // Accept a visitor (of various kinds) to this Statement. Return true to continue visiting
00869     bool        accept(StmtVisitor* visitor);
00870     bool        accept(StmtExpVisitor* visitor);
00871     bool        accept(StmtModifier* visitor);
00872     bool        accept(StmtPartModifier* visitor);
00873 
00874         // returns true if this statement defines anything
00875     bool        isDefinition() { return false; }
00876 
00877     bool        usesExp(Exp *e) { return false; }
00878 
00879     void        print(std::ostream &os, bool html = false);
00880 
00881         // general search
00882     bool        search(Exp *search, Exp *&result) { return false; }
00883     bool        searchAll(Exp* search, std::list<Exp*>& result) { return false; }
00884 
00885         // general search and replace. Set cc true to change collectors as well. Return true if any change
00886     bool        searchAndReplace(Exp *search, Exp *replace, bool cc = false) { return false; }
00887 
00888         // code generation
00889     void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) { }
00890 
00891         // simpify internal expressions
00892     void        simplify() { }
00893 
00894     void        rangeAnalysis(std::list<Statement*> &execution_paths);
00895     bool        isLoopJunction();
00896 };
00897 
00898 /*================================================================================
00899  * BranchStatement has a condition Exp in addition to the destination of the jump.
00900  *==============================================================================*/
00901 class BranchStatement: public GotoStatement {
00902         BRANCH_TYPE jtCond;         // The condition for jumping
00903         Exp*        pCond;          // The Exp representation of the high level condition: e.g., r[8] == 5
00904         bool        bFloat;         // True if uses floating point CC
00905         // jtCond seems to be mainly needed for the Pentium weirdness.
00906         // Perhaps bFloat, jtCond, and size could one day be merged into a type
00907         int         size;           // Size of the operands, in bits
00908         RangeMap    ranges2;        // ranges for the not taken edge
00909 
00910 public:
00911                     BranchStatement();
00912 virtual             ~BranchStatement();
00913 
00914     // Make a deep copy, and make the copy a derived object if needed.
00915 virtual Statement* clone();
00916 
00917     // Accept a visitor to this Statement
00918 virtual bool        accept(StmtVisitor* visitor);
00919 virtual bool        accept(StmtExpVisitor* visitor);
00920 virtual bool        accept(StmtModifier* visitor);
00921 virtual bool        accept(StmtPartModifier* visitor);
00922 
00923         // Set and return the BRANCH_TYPE of this jcond as well as whether the
00924         // floating point condition codes are used.
00925         void        setCondType(BRANCH_TYPE cond, bool usesFloat = false);
00926         BRANCH_TYPE getCond(){ return jtCond; }
00927         bool        isFloat(){ return bFloat; }
00928         void        setFloat(bool b)      { bFloat = b; }
00929 
00930         // Set and return the Exp representing the HL condition
00931         Exp*        getCondExpr();
00932         void        setCondExpr(Exp* pe);
00933         // As above, no delete (for subscripting)
00934         void        setCondExprND(Exp* e) { pCond = e; }
00935 
00936         PBB         getFallBB();
00937         PBB         getTakenBB();
00938         void        setFallBB(PBB bb);
00939         void        setTakenBB(PBB bb);
00940         
00941         // Probably only used in front386.cc: convert this from an unsigned to a
00942         // signed conditional branch
00943         void        makeSigned();
00944 
00945 virtual void        print(std::ostream& os = std::cout, bool html = false);
00946 
00947         // general search
00948 virtual bool        search(Exp *search, Exp *&result);
00949 
00950         // Replace all instances of "search" with "replace".
00951 virtual bool        searchAndReplace(Exp* search, Exp* replace, bool cc = false);
00952     
00953         // Searches for all instances of a given subexpression within this
00954         // expression and adds them to a given list in reverse nesting order.
00955 virtual bool        searchAll(Exp* search, std::list<Exp*> &result);
00956 
00957         // code generation
00958 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
00959 
00960         // dataflow analysis
00961 virtual bool        usesExp(Exp *e);
00962 
00963         // Range analysis
00964         void        rangeAnalysis(std::list<Statement*> &execution_paths);
00965         RangeMap    &getRangesForOutEdgeTo(PBB out);
00966         RangeMap    &getRanges2Ref() { return ranges2; }
00967         void        setRanges2(RangeMap &r) { ranges2 = r; }
00968         void        limitOutputWithCondition(RangeMap &output, Exp *e);
00969 
00970         // simplify all the uses/defs in this Statememt
00971 virtual void        simplify();
00972 
00973         // Generate constraints
00974 virtual void        genConstraints(LocationSet& cons);
00975 
00976         // Data flow based type analysis
00977         void        dfaTypeAnalysis(bool& ch);
00978 
00979         friend class XMLProgParser;
00980 };      // class BranchStatement
00981 
00982 /*==============================================================================
00983  * CaseStatement is derived from GotoStatement. In addition to the destination
00984  * of the jump, it has a switch variable Exp.
00985  *============================================================================*/
00986 struct SWITCH_INFO {
00987         Exp*        pSwitchVar;     // Ptr to Exp repres switch var, e.g. v[7]
00988         char        chForm;         // Switch form: 'A', 'O', 'R', 'H', or 'F' etc
00989         int         iLower;         // Lower bound of the switch variable
00990         int         iUpper;         // Upper bound for the switch variable
00991         ADDRESS     uTable;         // Native address of the table, or ptr to array of values for form F
00992         int         iNumTable;      // Number of entries in the table (form H only)
00993         int         iOffset;        // Distance from jump to table (form R only)
00994         //int       delta;          // Host address - Native address
00995 };
00996 
00997 class CaseStatement: public GotoStatement {
00998         SWITCH_INFO* pSwitchInfo;   // Ptr to struct with info about the switch
00999 public:
01000                     CaseStatement();
01001 virtual             ~CaseStatement();
01002 
01003     // Make a deep copy, and make the copy a derived object if needed.
01004 virtual Statement*  clone();
01005 
01006     // Accept a visitor to this Statememt
01007 virtual bool        accept(StmtVisitor* visitor);
01008 virtual bool        accept(StmtExpVisitor* visitor);
01009 virtual bool        accept(StmtModifier* visitor);
01010 virtual bool        accept(StmtPartModifier* visitor);
01011 
01012         // Set and return the Exp representing the switch variable
01013         SWITCH_INFO* getSwitchInfo(); 
01014         void        setSwitchInfo(SWITCH_INFO* pss);
01015     
01016 virtual void        print(std::ostream& os = std::cout, bool html = false);
01017 
01018         // Replace all instances of "search" with "replace".
01019 virtual bool    searchAndReplace(Exp* search, Exp* replace, bool cc = false);
01020     
01021         // Searches for all instances of a given subexpression within this
01022         // expression and adds them to a given list in reverse nesting order.
01023 virtual bool        searchAll(Exp* search, std::list<Exp*> &result);
01024     
01025         // code generation
01026 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
01027     
01028         // dataflow analysis
01029 virtual bool        usesExp(Exp *e);
01030 public:
01031 
01032         // simplify all the uses/defs in this Statement
01033 virtual void        simplify();
01034 
01035         friend class XMLProgParser;
01036 };      // class CaseStatement
01037 
01038 /*==============================================================================
01039  * CallStatement: represents a high level call. Information about parameters and the like are stored here.
01040  *============================================================================*/
01041 class CallStatement: public GotoStatement {
01042         bool        returnAfterCall;// True if call is effectively followed by a return.
01043     
01044         // The list of arguments passed by this call, actually a list of Assign statements (location := expr)
01045         StatementList arguments;
01046 
01047         // The list of defines for this call, a list of ImplicitAssigns (used to be called returns).
01048         // Essentially a localised copy of the modifies of the callee, so the callee could be deleted. Stores types and
01049         // locations.  Note that not necessarily all of the defines end up being declared as results.
01050         StatementList defines;
01051 
01052         // Destination of call. In the case of an analysed indirect call, this will be ONE target's return statement.
01053         // For an unanalysed indirect call, or a call whose callee is not yet sufficiently decompiled due to recursion,
01054         // this will be NULL
01055         Proc*       procDest;
01056 
01057         // The signature for this call. NOTE: this used to be stored in the Proc, but this does not make sense when
01058         // the proc happens to have varargs
01059         Signature*  signature;
01060 
01061         // A UseCollector object to collect the live variables at this call. Used as part of the calculation of
01062         // results
01063         UseCollector useCol;
01064 
01065         // A DefCollector object to collect the reaching definitions; used for bypassAndPropagate/localiseExp etc; also
01066         // the basis for arguments if this is an unanlysed indirect call
01067         DefCollector defCol;
01068 
01069         // Pointer to the callee ReturnStatement. If the callee is unanlysed, this will be a special ReturnStatement
01070         // with ImplicitAssigns. Callee could be unanalysed because of an unanalysed indirect call, or a "recursion
01071         // break".
01072         ReturnStatement* calleeReturn;
01073 
01074 public:
01075                     CallStatement();
01076 virtual             ~CallStatement();
01077 
01078 virtual void        setNumber(int num);
01079         // Make a deep copy, and make the copy a derived object if needed.
01080 virtual Statement*  clone();
01081 
01082         // Accept a visitor to this stmt
01083 virtual bool        accept(StmtVisitor* visitor);
01084 virtual bool        accept(StmtExpVisitor* visitor);
01085 virtual bool        accept(StmtModifier* visitor);
01086 virtual bool        accept(StmtPartModifier* visitor);
01087 
01088         void        setArguments(StatementList& args);
01089         // Set implicit arguments: so far, for testing only:
01090         //void      setImpArguments(std::vector<Exp*>& arguments);
01091 //      void        setReturns(std::vector<Exp*>& returns);// Set call's return locs
01092         void        setSigArguments();              // Set arguments based on signature
01093         StatementList& getArguments() {return arguments;}   // Return call's arguments
01094         void        updateArguments();              // Update the arguments based on a callee change
01095         //Exp       *getDefineExp(int i);
01096         int         findDefine(Exp *e);             // Still needed temporarily for ad hoc type analysis
01097         void        removeDefine(Exp *e);
01098         void        addDefine(ImplicitAssign* as);  // For testing
01099         //void      ignoreReturn(Exp *e);
01100         //void      ignoreReturn(int n);
01101         //void      addReturn(Exp *e, Type* ty = NULL);
01102         void        updateDefines();                // Update the defines based on a callee change
01103         StatementList* calcResults();               // Calculate defines(this) isect live(this)
01104         ReturnStatement* getCalleeReturn() {return calleeReturn; }
01105         void        setCalleeReturn(ReturnStatement* ret) {calleeReturn = ret;}
01106         bool        isChildless();
01107         Exp         *getProven(Exp *e);
01108         Signature*  getSignature() {return signature;}
01109         // Localise the various components of expression e with reaching definitions to this call
01110         // Note: can change e so usually need to clone the argument
01111         // Was called substituteParams
01112         Exp         *localiseExp(Exp *e);
01113         void        localiseComp(Exp* e);           // Localise only xxx of m[xxx]
01114         // Do the call bypass logic e.g. r28{20} -> r28{17} + 4 (where 20 is this CallStatement)
01115         // Set ch if changed (bypassed)
01116         Exp*        bypassRef(RefExp* r, bool& ch);
01117         void        clearUseCollector() {useCol.clear();}
01118         void        addArgument(Exp *e, UserProc* proc);
01119         Exp*        findDefFor(Exp* e);         // Find the reaching definition for expression e
01120         Exp*        getArgumentExp(int i);
01121         void        setArgumentExp(int i, Exp *e);
01122         void        setNumArguments(int i);
01123         int         getNumArguments();
01124         void        removeArgument(int i);
01125         Type        *getArgumentType(int i);
01126         void        truncateArguments();
01127         void        clearLiveEntry();
01128         void        eliminateDuplicateArgs();
01129 
01130         // Range analysis
01131         void        rangeAnalysis(std::list<Statement*> &execution_paths);
01132 
01133 virtual void        print(std::ostream& os = std::cout, bool html = false);
01134 
01135         // general search
01136 virtual bool        search(Exp *search, Exp *&result);
01137 
01138         // Replace all instances of "search" with "replace".
01139 virtual bool        searchAndReplace(Exp* search, Exp* replace, bool cc = false);
01140     
01141         // Searches for all instances of a given subexpression within this
01142         // expression and adds them to a given list in reverse nesting order.
01143 virtual bool        searchAll(Exp* search, std::list<Exp*> &result);
01144 
01145         // Set and return whether the call is effectively followed by a return.
01146         // E.g. on Sparc, whether there is a restore in the delay slot.
01147         void        setReturnAfterCall(bool b);
01148         bool        isReturnAfterCall();
01149 
01150         // Set and return the list of Exps that occur *after* the call (the
01151         // list of exps in the RTL occur before the call). Useful for odd patterns.
01152         void        setPostCallExpList(std::list<Exp*>* le);
01153         std::list<Exp*>* getPostCallExpList();
01154 
01155         // Set and return the destination proc.
01156         void        setDestProc(Proc* dest);
01157         Proc*       getDestProc();
01158 
01159         // Generate constraints
01160 virtual void        genConstraints(LocationSet& cons);
01161 
01162         // Data flow based type analysis
01163         void        dfaTypeAnalysis(bool& ch);
01164 
01165         // code generation
01166 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
01167 
01168         // dataflow analysis
01169 virtual bool        usesExp(Exp *e);
01170 
01171         // dataflow related functions
01172 virtual bool        isDefinition();
01173 virtual void        getDefinitions(LocationSet &defs);
01174 
01175 virtual bool        definesLoc(Exp* loc);                   // True if this Statement defines loc
01176 virtual void        setLeftFor(Exp* forExp, Exp* newExp);
01177         // get how to replace this statement in a use
01178 //virtual Exp*      getRight() { return NULL; }
01179 
01180         // simplify all the uses/defs in this Statement
01181 virtual void        simplify();
01182 
01183 //      void        setIgnoreReturnLoc(bool b);
01184 
01185         void        decompile();
01186 
01187         // Insert actual arguments to match formal parameters
01188         //void      insertArguments(StatementSet& rs);
01189 
01190 virtual Type*       getTypeFor(Exp* e);                 // Get the type defined by this Statement for this location
01191 virtual void        setTypeFor(Exp* e, Type* ty);       // Set the type for this location, defined in this statement
01192         DefCollector*   getDefCollector() {return &defCol;}         // Return pointer to the def collector object
01193         UseCollector*   getUseCollector() {return &useCol;}         // Return pointer to the use collector object
01194         void        useBeforeDefine(Exp* x) {useCol.insert(x);}     // Add x to the UseCollector for this call
01195         void        removeLiveness(Exp* e) {useCol.remove(e);}      // Remove e from the UseCollector
01196         void        removeAllLive() {useCol.clear();}               // Remove all livenesses
01197 //      Exp*        fromCalleeContext(Exp* e);          // Convert e from callee to caller (this) context
01198         StatementList&  getDefines() {return defines;}  // Get list of locations defined by this call
01199         // Process this call for ellipsis parameters. If found, in a printf/scanf call, truncate the number of
01200         // parameters if needed, and return true if any signature parameters added
01201         bool        ellipsisProcessing(Prog* prog);
01202         bool        convertToDirect();                  // Internal function: attempt to convert an indirect to a
01203                                                         // direct call
01204         void        useColFromSsaForm(Statement* s) {useCol.fromSSAform(proc, s);}
01205 private:
01206         // Private helper functions for the above
01207         void        addSigParam(Type* ty, bool isScanf);
01208         Assign*     makeArgAssign(Type* ty, Exp* e);    
01209 
01210 protected:
01211 
01212         void        updateDefineWithType(int n);
01213         void        appendArgument(Assignment* as) {arguments.append(as);}
01214 friend  class       XMLProgParser;
01215 };      // class CallStatement
01216 
01217 
01218 
01219 
01220 /*===========================================================
01221  * ReturnStatement: represents an ordinary high level return.
01222  *==========================================================*/
01223 class ReturnStatement : public Statement {
01224 protected:
01225         // Native address of the (only) return instruction. Needed for branching to this only return statement
01226         ADDRESS     retAddr;
01227 
01228         /**
01229          * The progression of return information is as follows:
01230          * First, reaching definitions are collected in the DefCollector col. These are not sorted or filtered.
01231          * Second, some of those definitions make it to the modifieds list, which is sorted and filtered. These are
01232          * the locations that are modified by the enclosing procedure. As locations are proved to be preserved (with NO
01233          * modification, not even sp = sp+4), they are removed from this list. Defines in calls to the enclosing
01234          * procedure are based on this list.
01235          * Third, the modifications are initially copied to the returns list (also sorted and filtered, but the returns
01236          * have RHS where the modifieds don't). Locations not live at any caller are removed from the returns, but not
01237          * from the modifieds.
01238          */
01239         /// A DefCollector object to collect the reaching definitions
01240         DefCollector col;
01241 
01242         /// A list of assignments that represents the locations modified by the enclosing procedure. These assignments
01243         /// have no RHS?
01244         /// These transmit type information to callers
01245         /// Note that these include preserved locations early on (?)
01246         StatementList modifieds;
01247 
01248         /// A list of assignments of locations to expressions.
01249         /// Initially definitions reaching the exit less preserveds; later has locations unused by any callers removed.
01250         /// A list is used to facilitate ordering. (A set would be ideal, but the ordering depends at runtime on the
01251         /// signature)
01252         StatementList returns;
01253 
01254 public:
01255                     ReturnStatement();
01256 virtual             ~ReturnStatement();
01257 
01258 typedef StatementList::iterator iterator;
01259         iterator    begin()             {return returns.begin();}
01260         iterator    end()               {return returns.end();}
01261         iterator    erase(iterator it)  {return returns.erase(it);}
01262         StatementList& getModifieds()   {return modifieds;}
01263         StatementList& getReturns()     {return returns;}
01264         unsigned    getNumReturns()     {return returns.size(); }
01265         void        updateModifieds();      // Update modifieds from the collector
01266         void        updateReturns();        // Update returns from the modifieds
01267 
01268 virtual void        print(std::ostream& os = std::cout, bool html = false);
01269 
01270         // general search
01271 virtual bool        search(Exp*, Exp*&);
01272 
01273         // Replace all instances of "search" with "replace".
01274 virtual bool        searchAndReplace(Exp* search, Exp* replace, bool cc = false);
01275     
01276         // Searches for all instances of a given subexpression within this statement and adds them to a given list
01277 virtual bool        searchAll(Exp* search, std::list<Exp*> &result);
01278 
01279         // returns true if this statement uses the given expression
01280 virtual bool        usesExp(Exp *e);
01281 
01282 virtual void        getDefinitions(LocationSet &defs);
01283 
01284         void        removeModified(Exp* loc);           // Remove from modifieds AND from returns
01285         void        removeReturn(Exp* loc);             // Remove from returns only
01286         void        addReturn(Assignment* a);
01287 
01288         Type*       getTypeFor(Exp* e);
01289         void        setTypeFor(Exp* e, Type* ty);
01290 
01291         // simplify all the uses/defs in this Statement
01292 virtual void        simplify();
01293 
01294 virtual bool        isDefinition() { return true; }
01295 
01296         // Get a subscripted version of e from the collector
01297         Exp*        subscriptWithDef(Exp* e);
01298 
01299         // Make a deep copy, and make the copy a derived object if needed.
01300 virtual Statement* clone();
01301 
01302         // Accept a visitor to this Statement
01303 virtual bool        accept(StmtVisitor* visitor);
01304 virtual bool        accept(StmtExpVisitor* visitor);
01305 virtual bool        accept(StmtModifier* visitor);
01306 virtual bool        accept(StmtPartModifier* visitor);
01307 
01308 virtual bool        definesLoc(Exp* loc);                   // True if this Statement defines loc
01309 
01310         // code generation
01311 virtual void        generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel);
01312 
01313         //Exp       *getReturnExp(int n) { return returns[n]; }
01314         //void      setReturnExp(int n, Exp *e) { returns[n] = e; }
01315         //void      setSigArguments();                  // Set returns based on signature
01316         DefCollector* getCollector() {return &col;}     // Return pointer to the collector object
01317 
01318         // Get and set the native address for the first and only return statement
01319         ADDRESS     getRetAddr() {return retAddr;}
01320         void        setRetAddr(ADDRESS r) {retAddr = r;}
01321 
01322         // Find definition for e (in the collector)
01323         Exp*        findDefFor(Exp* e) {return col.findDefFor(e);}
01324 
01325 virtual void        dfaTypeAnalysis(bool& ch);
01326 
01327         // Remove the stack pointer and return a statement list
01328         StatementList* getCleanReturns();
01329 
01330         // Temporary hack (not neccesary anymore)
01331         // void     specialProcessing();
01332 
01333     friend class XMLProgParser;
01334 };  // class ReturnStatement
01335 
01336 
01337 #endif // __STATEMENT_H__

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