basicblock.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1997-2000, The University of Queensland
00003  * Copyright (C) 2001, Sun Microsystems, Inc
00004  * Copyright (C) 2002-2006, Trent Waddington and Mike Van Emmerik
00005  *
00006  * See the file "LICENSE.TERMS" for information on usage and
00007  * redistribution of this file, and for a DISCLAIMER OF ALL
00008  * WARRANTIES.
00009  *
00010  */
00011 
00012 /*==============================================================================
00013  * FILE:       basicblock.h
00014  * OVERVIEW:   Interface for the basic block class, which form nodes of the control flow graph
00015  *============================================================================*/
00016 
00017 /*
00018  * $Revision: 1.13 $    // 1.1.2.2
00019  *
00020  * 28 Jun 05 - Mike: Split off from cfg.h
00021  */
00022 
00023 #ifndef __BASIC_BLOCK_H__
00024 #define __BASIC_BLOCK_H__
00025 
00026 #if defined(_MSC_VER)
00027 #pragma warning(disable:4290)
00028 #endif
00029 
00030 #include "managed.h"            // For LocationSet etc
00031 
00032 class Location;
00033 class HLLCode;
00034 class BasicBlock;
00035 class RTL;
00036 class Proc;
00037 class UserProc;
00038 struct SWITCH_INFO;             // Declared in include/statement.h
00039 
00040 typedef BasicBlock* PBB;
00041 
00042 /*  *   *   *   *   *   *   *   *   *   *   *   *   *   *   *\
00043 *                                                            *
00044 *   e n u m s   u s e d   i n   C f g . h   a n d   h e r e  *
00045 *                                                            *
00046 \*  *   *   *   *   *   *   *   *   *   *   *   *   *   *   */
00047 
00048 // Depth-first traversal constants.
00049 enum travType {
00050     UNTRAVERSED,   // Initial value
00051     DFS_TAG,       // Remove redundant nodes pass
00052     DFS_LNUM,      // DFS loop stamping pass
00053     DFS_RNUM,      // DFS reverse loop stamping pass
00054     DFS_CASE,      // DFS case head tagging traversal
00055     DFS_PDOM,      // DFS post dominator ordering
00056     DFS_CODEGEN    // Code generating pass
00057 };
00058 
00059 // an enumerated type for the class of stucture determined for a node
00060 enum structType { 
00061     Loop,      // Header of a loop only
00062     Cond,      // Header of a conditional only (if-then-else or switch)
00063     LoopCond,  // Header of a loop and a conditional
00064     Seq        // sequential statement (default)
00065 };
00066 
00067 // an type for the class of unstructured conditional jumps
00068 enum unstructType {
00069     Structured,
00070     JumpInOutLoop,
00071     JumpIntoCase
00072 };
00073 
00074 
00075 // an enumerated type for the type of conditional headers
00076 enum condType {
00077     IfThen,     // conditional with only a then clause
00078     IfThenElse, // conditional with a then and an else clause
00079     IfElse,     // conditional with only an else clause
00080     Case        // nway conditional header (case statement)
00081 };
00082 
00083 // an enumerated type for the type of loop headers
00084 enum loopType {
00085     PreTested,     // Header of a while loop
00086     PostTested,    // Header of a repeat loop
00087     Endless        // Header of an endless loop
00088 };
00089 
00090 /*  *   *   *   *   *   *   *   *   *\
00091 *                                    *
00092 *   B a s i c B l o c k   e n u m s  *
00093 *                                    *
00094 \*  *   *   *   *   *   *   *   *   */
00095 
00096 // Kinds of basic block nodes
00097 // reordering these will break the save files - trent
00098 enum BBTYPE {
00099     ONEWAY,                  // unconditional branch
00100     TWOWAY,                  // conditional branch
00101     NWAY,                    // case branch
00102     CALL,                    // procedure call
00103     RET,                     // return
00104     FALL,                    // fall-through node
00105     COMPJUMP,                // computed jump
00106     COMPCALL,                // computed call
00107     INVALID                  // invalid instruction
00108 };
00109 
00110 enum SBBTYPE {
00111     NONE,                    // not structured
00112     PRETESTLOOP,             // header of a loop
00113     POSTTESTLOOP,
00114     ENDLESSLOOP,
00115     JUMPINOUTLOOP,           // an unstructured jump in or out of a loop
00116     JUMPINTOCASE,            // an unstructured jump into a case statement
00117     IFGOTO,                  // unstructured conditional
00118     IFTHEN,                  // conditional with then clause
00119     IFTHENELSE,              // conditional with then and else clauses
00120     IFELSE,                  // conditional with else clause only
00121     CASE                     // case statement (switch)
00122 };
00123 
00124 typedef std::list<PBB>::iterator BB_IT;
00125 
00126 /*==============================================================================
00127  * BasicBlock class. <more comments>
00128  *============================================================================*/
00129 class BasicBlock {
00130         /*
00131          * Objects of class Cfg can access the internals of a BasicBlock object.
00132          */
00133         friend class Cfg;
00134 
00135 public:
00136         /*
00137          * Constructor.
00138          */
00139                     BasicBlock();
00140 
00141         /*
00142          * Destructor.
00143          */
00144                     ~BasicBlock();
00145 
00146         /*
00147          * Copy constructor.
00148          */
00149                     BasicBlock(const BasicBlock& bb);
00150 
00151         /*
00152          * Return the type of the basic block.
00153          */
00154         BBTYPE      getType();
00155 
00156         /*
00157          * Check if this BB has a label. If so, return the numeric value of the label (nonzero integer). If not, returns
00158          * zero.  See also Cfg::setLabel()
00159          */
00160         int         getLabel();
00161 
00162         std::string &getLabelStr() { return m_labelStr; }
00163         void        setLabelStr(std::string &s) { m_labelStr = s; }
00164         bool        isLabelNeeded() { return m_labelneeded; }
00165         void        setLabelNeeded(bool b) { m_labelneeded = b; }
00166         bool        isCaseOption();
00167 
00168         /*
00169          * Return whether this BB has been traversed or not
00170          */
00171         bool        isTraversed();
00172 
00173         /*
00174          * Set the traversed flag
00175          */
00176         void        setTraversed(bool bTraversed);
00177 
00178         /*
00179          * Print the BB. For -R and for debugging
00180          * Don't use = std::cout, because gdb doesn't know about std::
00181          */
00182         void        print(std::ostream& os, bool html = false);
00183         void        printToLog();
00184         char*       prints();                       // For debugging
00185         void        dump();
00186 
00187         /*
00188          * Set the type of the basic block.
00189          */
00190         void        updateType(BBTYPE bbType, int iNumOutEdges);
00191 
00192         /*
00193          * Set the "jump reqd" bit. This means that this is an orphan BB (it is generated, not part of the original
00194          * program), and that the "fall through" out edge (m_OutEdges[1]) has to be implemented as a jump. The back end
00195          * needs to take heed of this bit
00196          */
00197         void        setJumpReqd();
00198 
00199         /*
00200          * Check if jump is required (see above).
00201          */
00202         bool        isJumpReqd();
00203 
00204         /*
00205          * Get the address associated with the BB
00206          * Note that this is not always the same as getting the address of the first RTL (e.g. if the first RTL is a
00207          * delay instruction of a DCTI instruction; then the address of this RTL will be 0)
00208          */
00209         ADDRESS     getLowAddr();
00210         ADDRESS     getHiAddr();
00211 
00212         /*
00213          * Get ptr to the list of RTLs.
00214          */
00215         std::list<RTL*>* getRTLs();
00216 
00217         RTL* getRTLWithStatement(Statement *stmt);
00218 
00219         /*
00220          * Get the set of in edges.
00221          */
00222         std::vector<PBB>& getInEdges();
00223 
00224         int         getNumInEdges() { return m_iNumInEdges; }
00225 
00226         /*
00227          * Get the set of out edges.
00228          */
00229         std::vector<PBB>& getOutEdges();
00230 
00231         /*
00232          * Set an in edge to a new value; same number of in edges as before
00233          */
00234         void        setInEdge(int i, PBB newIn);
00235 
00236         /*
00237          * Set an out edge to a new value; same number of out edges as before
00238          */
00239         void        setOutEdge(int i, PBB newInEdge);
00240 
00241         /*
00242          * Get the n-th out edge or 0 if it does not exist
00243          */
00244         PBB         getOutEdge(unsigned int i);
00245 
00246         int         getNumOutEdges() { return m_iNumOutEdges; }
00247 
00248         /*
00249          * Get the index of my in-edges is BB pred
00250          */
00251         int         whichPred(PBB pred);
00252 
00253         /*
00254          * Add an in-edge
00255          */
00256         void        addInEdge(PBB newInEdge);
00257         void        deleteEdge(PBB edge);
00258 
00259         /*
00260          * Delete an in-edge
00261          */
00262         void        deleteInEdge(std::vector<PBB>::iterator& it);
00263         void        deleteInEdge(PBB edge);
00264 
00265         /*
00266          * If this is a call BB, find the fixed destination (if any).  Returns -1 otherwise
00267          */
00268         ADDRESS     getCallDest();
00269         Proc        *getCallDestProc();
00270 
00271         /*
00272          * Traverse this node and recurse on its children in a depth first manner.
00273          * Records the times at which this node was first visited and last visited.
00274          * Returns the number of nodes traversed.
00275          */
00276         unsigned    DFTOrder(int& first, int& last);
00277 
00278         /*
00279          * Traverse this node and recurse on its parents in a reverse depth first manner.
00280          * Records the times at which this node was first visited and last visited.
00281          * Returns the number of nodes traversed.
00282          */
00283         unsigned    RevDFTOrder(int& first, int& last);
00284 
00285         /*
00286          * Static comparison function that returns true if the first BB has an address less than the second BB.
00287          */
00288 static bool         lessAddress(PBB bb1, PBB bb2);
00289 
00290         /*
00291          * Static comparison function that returns true if the first BB has an DFT first number less than the second BB.
00292          */
00293 static bool         lessFirstDFT(PBB bb1, PBB bb2);
00294 
00295         /*
00296          * Static comparison function that returns true if the first BB has an DFT last less than the second BB.
00297          */
00298 static bool         lessLastDFT(PBB bb1, PBB bb2);
00299 
00300         /*
00301          * Resets the DFA sets of this BB.
00302          */
00303         void        resetDFASets();
00304 
00305         class LastStatementNotABranchError : public std::exception {
00306         public:
00307             Statement *stmt;
00308             LastStatementNotABranchError(Statement *stmt) : stmt(stmt) { }
00309         };
00310         /* get the condition */
00311         Exp         *getCond() throw(LastStatementNotABranchError);
00312 
00313         /* set the condition */
00314         void        setCond(Exp *e) throw(LastStatementNotABranchError);
00315 
00316         class LastStatementNotAGotoError : public std::exception {
00317         public:
00318             Statement *stmt;
00319             LastStatementNotAGotoError(Statement *stmt) : stmt(stmt) { }
00320         };
00321         /* Get the destination expression, if any */
00322         Exp*        getDest() throw(LastStatementNotAGotoError);
00323 
00324         /* Check if there is a jump if equals relation */
00325         bool        isJmpZ(PBB dest);
00326 
00327         /* get the loop body */
00328         BasicBlock  *getLoopBody();
00329 
00330         /* Simplify all the expressions in this BB
00331          */
00332         void        simplify();
00333 
00334 
00335         /*
00336          *  given an address, returns the outedge which corresponds to that address or 0 if there was no such outedge
00337          */
00338 
00339         PBB         getCorrectOutEdge(ADDRESS a);
00340         
00341         /*
00342          * Depth first traversal of all bbs, numbering as we go and as we come back, forward and reverse passes.
00343          * Use Cfg::establishDFTOrder() and CFG::establishRevDFTOrder to create these values.
00344          */
00345         int         m_DFTfirst;        // depth-first traversal first visit
00346         int         m_DFTlast;         // depth-first traversal last visit
00347         int         m_DFTrevfirst;     // reverse depth-first traversal first visit
00348         int         m_DFTrevlast;      // reverse depth-first traversal last visit
00349 
00350 private:
00351         /*
00352          * Constructor. Called by Cfg::NewBB.
00353          */
00354                     BasicBlock(std::list<RTL*>* pRtls, BBTYPE bbType, int iNumOutEdges);
00355 
00356         /*
00357          * Sets the RTLs for this BB. This is the only place that
00358          * the RTLs for a block must be set as we need to add the back
00359          * link for a call instruction to its enclosing BB.
00360          */
00361         void        setRTLs(std::list<RTL*>* rtls);
00362 
00363 public:
00364 
00365         // code generation
00366         void        generateBodyCode(HLLCode &hll, bool dup = false);
00367 
00368 /* high level structuring */
00369         SBBTYPE     m_structType;   // structured type of this node
00370         SBBTYPE     m_loopCondType; // type of conditional to treat this loop header as (if any)
00371         PBB         m_loopHead;     // head of the most nested enclosing loop
00372         PBB         m_caseHead;     // head of the most nested enclosing case
00373         PBB         m_condFollow;   // follow of a conditional header
00374         PBB         m_loopFollow;   // follow of a loop header
00375         PBB         m_latchNode;    // latch node of a loop header  
00376 
00377 protected:
00378 /* general basic block information */
00379         BBTYPE      m_nodeType;     // type of basic block
00380         std::list<RTL*>* m_pRtls;   // Ptr to list of RTLs
00381         int         m_iLabelNum;    // Nonzero if start of BB needs label
00382         std::string m_labelStr;     // string label of this bb.
00383         bool        m_labelneeded;
00384         bool        m_bIncomplete;  // True if not yet complete
00385         bool        m_bJumpReqd;    // True if jump required for "fall through"
00386 
00387 /* in-edges and out-edges */
00388         std::vector<PBB> m_InEdges; // Vector of in-edges
00389         std::vector<PBB> m_OutEdges;// Vector of out-edges
00390         int         m_iNumInEdges;  // We need these two because GCC doesn't
00391         int         m_iNumOutEdges; // support resize() of vectors!
00392 
00393 /* for traversal */
00394         bool        m_iTraversed;   // traversal marker
00395 
00396 /* Liveness */
00397         LocationSet liveIn;         // Set of locations live at BB start
00398 
00399 public:
00400 
00401         bool        isPostCall();
00402 static void         doAvail(StatementSet& s, PBB inEdge);
00403         Proc*       getDestProc();
00404 
00405         /**
00406          * Get first/next statement this BB
00407          * Somewhat intricate because of the post call semantics; these funcs save a lot of duplicated, easily-bugged
00408          * code
00409          */
00410         typedef std::list<RTL*>::iterator rtlit;
00411         typedef std::list<RTL*>::reverse_iterator rtlrit;
00412         typedef std::list<Exp*>::iterator elit;
00413         Statement*  getFirstStmt(rtlit& rit, StatementList::iterator& sit);
00414         Statement*  getNextStmt(rtlit& rit, StatementList::iterator& sit);
00415         Statement*  getLastStmt(rtlrit& rit, StatementList::reverse_iterator& sit);
00416         Statement*  getFirstStmt(); // for those of us that don't want the iterators
00417         Statement*  getLastStmt(); // for those of us that don't want the iterators
00418         Statement*  getPrevStmt(rtlrit& rit, StatementList::reverse_iterator& sit);
00419         RTL*        getLastRtl() {return m_pRtls->back();}
00420 
00421         void        getStatements(StatementList &stmts);
00422 
00423         /**
00424          * Get the statement number for the first BB as a character array.
00425          * If not possible (e.g. because the BB has no statements), return
00426          * a unique string (e.g. bb8048c10)
00427          */
00428         char*       getStmtNumber();
00429 
00430 protected:
00431         /* Control flow analysis stuff, lifted from Doug Simon's honours thesis.
00432          */
00433         int         ord;     // node's position within the ordering structure
00434         int         revOrd;  // position within ordering structure for the reverse graph
00435         int         inEdgesVisited; // counts the number of in edges visited during a DFS
00436         int         numForwardInEdges; // inedges to this node that aren't back edges
00437         int         loopStamps[2], revLoopStamps[2]; // used for structuring analysis
00438         travType    traversed; // traversal flag for the numerous DFS's
00439         bool        hllLabel; // emit a label for this node when generating HL code?
00440         char*       labelStr; // the high level label for this node (if needed)
00441         int         indentLevel; // the indentation level of this node in the final code
00442 
00443         // analysis information
00444         PBB         immPDom; // immediate post dominator
00445         PBB         loopHead; // head of the most nested enclosing loop
00446         PBB         caseHead; // head of the most nested enclosing case
00447         PBB         condFollow; // follow of a conditional header
00448         PBB         loopFollow; // follow of a loop header
00449         PBB         latchNode; // latching node of a loop header
00450 
00451         // Structured type of the node
00452         structType  sType; // the structuring class (Loop, Cond , etc)
00453         unstructType usType; // the restructured type of a conditional header
00454         loopType    lType; // the loop type of a loop header
00455         condType    cType; // the conditional type of a conditional header
00456 
00457         void        setLoopStamps(int &time, std::vector<PBB> &order);
00458         void        setRevLoopStamps(int &time);
00459         void        setRevOrder(std::vector<PBB> &order);
00460 
00461         void        setLoopHead(PBB head) { loopHead = head; }
00462         PBB         getLoopHead() { return loopHead; }
00463         void        setLatchNode(PBB latch) { latchNode = latch; }
00464         bool        isLatchNode() { return loopHead && loopHead->latchNode == this; }
00465         PBB         getLatchNode() { return latchNode; }
00466         PBB         getCaseHead() { return caseHead; }
00467         void        setCaseHead(PBB head, PBB follow);
00468 
00469         structType  getStructType() { return sType; }
00470         void        setStructType(structType s);
00471 
00472         unstructType getUnstructType();
00473         void        setUnstructType(unstructType us);
00474 
00475         loopType    getLoopType();
00476         void        setLoopType(loopType l);
00477 
00478         condType    getCondType();
00479         void        setCondType(condType l);
00480 
00481         void        setLoopFollow(PBB other) { loopFollow = other; }
00482         PBB         getLoopFollow() { return loopFollow; }
00483 
00484         void        setCondFollow(PBB other) { condFollow = other; }
00485         PBB         getCondFollow() { return condFollow; }
00486 
00487         // establish if this bb has a back edge to the given destination
00488         bool        hasBackEdgeTo(BasicBlock *dest);
00489 
00490         // establish if this bb has any back edges leading FROM it
00491         bool        hasBackEdge() {
00492                         for (unsigned int i = 0; i < m_OutEdges.size(); i++)
00493                             if (hasBackEdgeTo(m_OutEdges[i])) 
00494                                 return true;
00495                         return false;
00496                     }
00497 
00498 public:
00499         bool        isBackEdge(int inEdge);
00500 
00501 protected:
00502         // establish if this bb is an ancestor of another BB
00503         bool        isAncestorOf(BasicBlock *other);
00504 
00505         bool        inLoop(PBB header, PBB latch);
00506 
00507         bool        isIn(std::list<PBB> &set, PBB bb) {
00508                         for (std::list<PBB>::iterator it = set.begin(); it != set.end(); it++)
00509                             if (*it == bb) return true;
00510                         return false;
00511                     }
00512 
00513         char*       indent(int indLevel, int extra = 0);
00514         bool        allParentsGenerated();
00515         void        emitGotoAndLabel(HLLCode *hll, int indLevel, PBB dest);
00516         void        WriteBB(HLLCode *hll, int indLevel);
00517 
00518 public:
00519         void        generateCode(HLLCode *hll, int indLevel, PBB latch, std::list<PBB> &followSet,
00520                         std::list<PBB> &gotoSet, UserProc* proc);
00521         // For prepending phi functions
00522         void        prependStmt(Statement* s, UserProc* proc);
00523 
00524         // Liveness
00525         bool        calcLiveness(ConnectionGraph& ig, UserProc* proc);
00526         void        getLiveOut(LocationSet& live, LocationSet& phiLocs);
00527 
00528         // Find indirect jumps and calls
00529         bool        decodeIndirectJmp(UserProc* proc);
00530         void        processSwitch(UserProc* proc);
00531         int         findNumCases();
00532 
00533         /*
00534          * Change the BB enclosing stmt to be CALL, not COMPCALL
00535          */
00536         bool        undoComputedBB(Statement* stmt);
00537 
00538         // true if processing for overlapped registers on statements in this BB
00539         // has been completed.
00540         bool        overlappedRegProcessingDone;
00541 
00542 protected:
00543         friend class XMLProgParser;
00544         void        addOutEdge(PBB bb) { m_OutEdges.push_back(bb); }
00545         void        addRTL(RTL *rtl) {
00546                         if (m_pRtls == NULL) 
00547                             m_pRtls = new std::list<RTL*>;
00548                         m_pRtls->push_back(rtl);
00549                     }
00550         void        addLiveIn(Exp *e) { liveIn.insert(e); }
00551 
00552 };      // class BasicBlock
00553 
00554 #endif      // #define __BASIC_BLOCK_H__

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