00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
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"            
00031 
00032 class Location;
00033 class HLLCode;
00034 class BasicBlock;
00035 class RTL;
00036 class Proc;
00037 class UserProc;
00038 struct SWITCH_INFO;             
00039 
00040 typedef BasicBlock* PBB;
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 enum travType {
00050     UNTRAVERSED,   
00051     DFS_TAG,       
00052     DFS_LNUM,      
00053     DFS_RNUM,      
00054     DFS_CASE,      
00055     DFS_PDOM,      
00056     DFS_CODEGEN    
00057 };
00058 
00059 
00060 enum structType { 
00061     Loop,      
00062     Cond,      
00063     LoopCond,  
00064     Seq        
00065 };
00066 
00067 
00068 enum unstructType {
00069     Structured,
00070     JumpInOutLoop,
00071     JumpIntoCase
00072 };
00073 
00074 
00075 
00076 enum condType {
00077     IfThen,     
00078     IfThenElse, 
00079     IfElse,     
00080     Case        
00081 };
00082 
00083 
00084 enum loopType {
00085     PreTested,     
00086     PostTested,    
00087     Endless        
00088 };
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 enum BBTYPE {
00099     ONEWAY,                  
00100     TWOWAY,                  
00101     NWAY,                    
00102     CALL,                    
00103     RET,                     
00104     FALL,                    
00105     COMPJUMP,                
00106     COMPCALL,                
00107     INVALID                  
00108 };
00109 
00110 enum SBBTYPE {
00111     NONE,                    
00112     PRETESTLOOP,             
00113     POSTTESTLOOP,
00114     ENDLESSLOOP,
00115     JUMPINOUTLOOP,           
00116     JUMPINTOCASE,            
00117     IFGOTO,                  
00118     IFTHEN,                  
00119     IFTHENELSE,              
00120     IFELSE,                  
00121     CASE                     
00122 };
00123 
00124 typedef std::list<PBB>::iterator BB_IT;
00125 
00126 
00127 
00128 
00129 class BasicBlock {
00130         
00131 
00132 
00133         friend class Cfg;
00134 
00135 public:
00136         
00137 
00138 
00139                     BasicBlock();
00140 
00141         
00142 
00143 
00144                     ~BasicBlock();
00145 
00146         
00147 
00148 
00149                     BasicBlock(const BasicBlock& bb);
00150 
00151         
00152 
00153 
00154         BBTYPE      getType();
00155 
00156         
00157 
00158 
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 
00170 
00171         bool        isTraversed();
00172 
00173         
00174 
00175 
00176         void        setTraversed(bool bTraversed);
00177 
00178         
00179 
00180 
00181 
00182         void        print(std::ostream& os, bool html = false);
00183         void        printToLog();
00184         char*       prints();                       
00185         void        dump();
00186 
00187         
00188 
00189 
00190         void        updateType(BBTYPE bbType, int iNumOutEdges);
00191 
00192         
00193 
00194 
00195 
00196 
00197         void        setJumpReqd();
00198 
00199         
00200 
00201 
00202         bool        isJumpReqd();
00203 
00204         
00205 
00206 
00207 
00208 
00209         ADDRESS     getLowAddr();
00210         ADDRESS     getHiAddr();
00211 
00212         
00213 
00214 
00215         std::list<RTL*>* getRTLs();
00216 
00217         RTL* getRTLWithStatement(Statement *stmt);
00218 
00219         
00220 
00221 
00222         std::vector<PBB>& getInEdges();
00223 
00224         int         getNumInEdges() { return m_iNumInEdges; }
00225 
00226         
00227 
00228 
00229         std::vector<PBB>& getOutEdges();
00230 
00231         
00232 
00233 
00234         void        setInEdge(int i, PBB newIn);
00235 
00236         
00237 
00238 
00239         void        setOutEdge(int i, PBB newInEdge);
00240 
00241         
00242 
00243 
00244         PBB         getOutEdge(unsigned int i);
00245 
00246         int         getNumOutEdges() { return m_iNumOutEdges; }
00247 
00248         
00249 
00250 
00251         int         whichPred(PBB pred);
00252 
00253         
00254 
00255 
00256         void        addInEdge(PBB newInEdge);
00257         void        deleteEdge(PBB edge);
00258 
00259         
00260 
00261 
00262         void        deleteInEdge(std::vector<PBB>::iterator& it);
00263         void        deleteInEdge(PBB edge);
00264 
00265         
00266 
00267 
00268         ADDRESS     getCallDest();
00269         Proc        *getCallDestProc();
00270 
00271         
00272 
00273 
00274 
00275 
00276         unsigned    DFTOrder(int& first, int& last);
00277 
00278         
00279 
00280 
00281 
00282 
00283         unsigned    RevDFTOrder(int& first, int& last);
00284 
00285         
00286 
00287 
00288 static bool         lessAddress(PBB bb1, PBB bb2);
00289 
00290         
00291 
00292 
00293 static bool         lessFirstDFT(PBB bb1, PBB bb2);
00294 
00295         
00296 
00297 
00298 static bool         lessLastDFT(PBB bb1, PBB bb2);
00299 
00300         
00301 
00302 
00303         void        resetDFASets();
00304 
00305         class LastStatementNotABranchError : public std::exception {
00306         public:
00307             Statement *stmt;
00308             LastStatementNotABranchError(Statement *stmt) : stmt(stmt) { }
00309         };
00310         
00311         Exp         *getCond() throw(LastStatementNotABranchError);
00312 
00313         
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         
00322         Exp*        getDest() throw(LastStatementNotAGotoError);
00323 
00324         
00325         bool        isJmpZ(PBB dest);
00326 
00327         
00328         BasicBlock  *getLoopBody();
00329 
00330         
00331 
00332         void        simplify();
00333 
00334 
00335         
00336 
00337 
00338 
00339         PBB         getCorrectOutEdge(ADDRESS a);
00340         
00341         
00342 
00343 
00344 
00345         int         m_DFTfirst;        
00346         int         m_DFTlast;         
00347         int         m_DFTrevfirst;     
00348         int         m_DFTrevlast;      
00349 
00350 private:
00351         
00352 
00353 
00354                     BasicBlock(std::list<RTL*>* pRtls, BBTYPE bbType, int iNumOutEdges);
00355 
00356         
00357 
00358 
00359 
00360 
00361         void        setRTLs(std::list<RTL*>* rtls);
00362 
00363 public:
00364 
00365         
00366         void        generateBodyCode(HLLCode &hll, bool dup = false);
00367 
00368 
00369         SBBTYPE     m_structType;   
00370         SBBTYPE     m_loopCondType; 
00371         PBB         m_loopHead;     
00372         PBB         m_caseHead;     
00373         PBB         m_condFollow;   
00374         PBB         m_loopFollow;   
00375         PBB         m_latchNode;    
00376 
00377 protected:
00378 
00379         BBTYPE      m_nodeType;     
00380         std::list<RTL*>* m_pRtls;   
00381         int         m_iLabelNum;    
00382         std::string m_labelStr;     
00383         bool        m_labelneeded;
00384         bool        m_bIncomplete;  
00385         bool        m_bJumpReqd;    
00386 
00387 
00388         std::vector<PBB> m_InEdges; 
00389         std::vector<PBB> m_OutEdges;
00390         int         m_iNumInEdges;  
00391         int         m_iNumOutEdges; 
00392 
00393 
00394         bool        m_iTraversed;   
00395 
00396 
00397         LocationSet liveIn;         
00398 
00399 public:
00400 
00401         bool        isPostCall();
00402 static void         doAvail(StatementSet& s, PBB inEdge);
00403         Proc*       getDestProc();
00404 
00405 
00406 
00407 
00408 
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(); 
00417         Statement*  getLastStmt(); 
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 
00425 
00426 
00427 
00428         char*       getStmtNumber();
00429 
00430 protected:
00431         
00432 
00433         int         ord;     
00434         int         revOrd;  
00435         int         inEdgesVisited; 
00436         int         numForwardInEdges; 
00437         int         loopStamps[2], revLoopStamps[2]; 
00438         travType    traversed; 
00439         bool        hllLabel; 
00440         char*       labelStr; 
00441         int         indentLevel; 
00442 
00443         
00444         PBB         immPDom; 
00445         PBB         loopHead; 
00446         PBB         caseHead; 
00447         PBB         condFollow; 
00448         PBB         loopFollow; 
00449         PBB         latchNode; 
00450 
00451         
00452         structType  sType; 
00453         unstructType usType; 
00454         loopType    lType; 
00455         condType    cType; 
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         
00488         bool        hasBackEdgeTo(BasicBlock *dest);
00489 
00490         
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         
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         
00522         void        prependStmt(Statement* s, UserProc* proc);
00523 
00524         
00525         bool        calcLiveness(ConnectionGraph& ig, UserProc* proc);
00526         void        getLiveOut(LocationSet& live, LocationSet& phiLocs);
00527 
00528         
00529         bool        decodeIndirectJmp(UserProc* proc);
00530         void        processSwitch(UserProc* proc);
00531         int         findNumCases();
00532 
00533         
00534 
00535 
00536         bool        undoComputedBB(Statement* stmt);
00537 
00538         
00539         
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 };      
00553 
00554 #endif      // #define __BASIC_BLOCK_H__