cfg.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1997-2000, The University of Queensland
00003  * Copyright (C) 2000-2001, Sun Microsystems, Inc
00004  * Copyright (C) 2002, Trent Waddington
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:       cfg.cpp
00014  * OVERVIEW:   Implementation of the CFG class.
00015  *============================================================================*/
00016 
00017 /*
00018  * $Revision: 1.116 $   // 1.95.2.5
00019  * 18 Apr 02 - Mike: Mods for boomerang
00020  * 19 Jul 04 - Mike: Changed initialisation of BBs to not rely on out edges
00021  */
00022 
00023 
00024 /*==============================================================================
00025  * Dependencies.
00026  *============================================================================*/
00027 
00028 #include <assert.h>
00029 #if defined(_MSC_VER) && _MSC_VER <= 1200
00030 #pragma warning(disable:4786)
00031 #endif 
00032 
00033 #include <algorithm>        // For find()
00034 #include <fstream>
00035 #include <sstream>
00036 #include "types.h"
00037 #include "statement.h"
00038 #include "signature.h"
00039 #include "exp.h"
00040 #include "cfg.h"
00041 #include "register.h"
00042 #include "rtl.h"
00043 #include "proc.h"           // For Proc::setTailCaller()
00044 #include "prog.h"           // For findProc()
00045 #include "util.h"
00046 #include "hllcode.h"
00047 #include "boomerang.h"
00048 #include "log.h"
00049 
00050 void delete_lrtls(std::list<RTL*>* pLrtl);
00051 void erase_lrtls(std::list<RTL*>* pLrtl, std::list<RTL*>::iterator begin,
00052     std::list<RTL*>::iterator end);
00053 
00054 /**********************************
00055  * Cfg methods.
00056  **********************************/
00057 
00058 /*==============================================================================
00059  * FUNCTION:        Cfg::Cfg
00060  * OVERVIEW:        
00061  * PARAMETERS:      <none>
00062  * RETURNS:         <nothing>
00063  *============================================================================*/
00064 Cfg::Cfg()
00065   : entryBB(NULL), exitBB(NULL), m_bWellFormed(false), structured(false), lastLabel(0), bImplicitsDone(false)
00066 {}
00067 
00068 /*==============================================================================
00069  * FUNCTION:        Cfg::~Cfg
00070  * OVERVIEW:        Destructor. Note: destructs the component BBs as well
00071  * PARAMETERS:      <none>
00072  * RETURNS:         <nothing>
00073  *============================================================================*/
00074 Cfg::~Cfg() {
00075     // Delete the BBs
00076     BB_IT it;
00077     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
00078         if (*it) {
00079             delete *it;
00080         }
00081     }
00082 }
00083 
00084 /*==============================================================================
00085  * FUNCTION:        Cfg::setProc
00086  * OVERVIEW:        Set the pointer to the owning UserProc object
00087  * PARAMETERS:      proc - pointer to the owning UserProc object
00088  * RETURNS:         <nothing>
00089  *============================================================================*/
00090 void Cfg::setProc(UserProc* proc)
00091 {
00092     myProc = proc;
00093 }
00094 
00095 /*==============================================================================
00096  * FUNCTION:        Cfg::clear
00097  * OVERVIEW:        Clear the CFG of all basic blocks, ready for decode
00098  * PARAMETERS:      <none>
00099  * RETURNS:         <nothing>
00100  *============================================================================*/
00101 void Cfg::clear() {
00102     // Don't delete the BBs; this will delete any CaseStatements we want to save for the re-decode. Just let the garbage
00103     // collection take care of it.
00104     // for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
00105     //  delete *it;
00106     m_listBB.clear();
00107     m_mapBB.clear();
00108     implicitMap.clear();
00109     entryBB = NULL;
00110     exitBB = NULL;
00111     m_bWellFormed = false;
00112     callSites.clear();
00113     lastLabel = 0;    
00114 }
00115 
00116 /*==============================================================================
00117  * FUNCTION:        Cfg::operator=
00118  * OVERVIEW:        
00119  * PARAMETERS:      <none>
00120  * RETURNS:         <nothing>
00121  *============================================================================*/
00122 const Cfg& Cfg::operator=(const Cfg& other)
00123 {
00124     m_listBB = other.m_listBB;
00125     m_mapBB = other.m_mapBB;
00126     m_bWellFormed = other.m_bWellFormed;
00127     return *this;
00128 }
00129 
00130 /*==============================================================================
00131  * FUNCTION:        setEntryBB
00132  * OVERVIEW:        Set the entry and exut BB pointers
00133  * NOTE:            Each cfg should have only one exit node now
00134  * PARAMETERS:      bb: pointer to the entry BB
00135  * RETURNS:         nothing
00136  *============================================================================*/
00137 void Cfg::setEntryBB(PBB bb) {
00138     BB_IT it;
00139     entryBB = bb;
00140     for (it=m_listBB.begin(); it != m_listBB.end(); it++) {
00141         if ((*it)->getType() == RET) {
00142             exitBB = *it;
00143             return;
00144         }
00145     }
00146     // It is possible that there is no exit BB
00147 }
00148 
00149 void Cfg::setExitBB(PBB bb) {
00150     exitBB = bb;
00151 }
00152 
00153 /*==============================================================================
00154  * FUNCTION:        checkEntryBB
00155  * OVERVIEW:        Check the entry BB pointer; if zero, emit error message
00156  *                    and return true
00157  * PARAMETERS:      <none>
00158  * RETURNS:         true if was null
00159  *============================================================================*/
00160 bool Cfg::checkEntryBB()
00161 {
00162     if (entryBB == NULL) {
00163         std::cerr << "No entry BB for ";
00164         if (myProc)
00165             std::cerr << myProc->getName() << std::endl;
00166         else
00167             std::cerr << "unknown proc\n";
00168         return true;
00169     }
00170     return false;
00171 }
00172 
00173 /*==============================================================================
00174  * FUNCTION:        Cfg::newBB
00175  * OVERVIEW:        Add a new basic block to this cfg 
00176  * PARAMETERS:      pRtls: list of pointers to RTLs to initialise the BB with bbType: the type of the BB (e.g. TWOWAY)
00177  *                  iNumOutEdges: number of out edges this BB will eventually have
00178  * RETURNS:         Pointer to the newly created BB, or 0 if there is already an incomplete BB with the same address
00179  *============================================================================*/
00180 PBB Cfg::newBB(std::list<RTL*>* pRtls, BBTYPE bbType, int iNumOutEdges) throw(BBAlreadyExistsError)
00181 {
00182     MAPBB::iterator mi;
00183     PBB pBB;
00184 
00185     // First find the native address of the first RTL
00186     // Can't use BasicBlock::GetLowAddr(), since we don't yet have a BB!
00187     ADDRESS addr = pRtls->front()->getAddress();
00188 
00189     // If this is zero, try the next RTL (only). This may be necessary if e.g. there is a BB with a delayed branch only,
00190     // with its delay instruction moved in front of it (with 0 address).
00191     // Note: it is possible to see two RTLs with zero address with Sparc: jmpl %o0, %o1. There will be one for the delay
00192     // instr (if not a NOP), and one for the side effect of copying %o7 to %o1.
00193     // Note that orphaned BBs (for which we must compute addr here to to be 0) must not be added to the map, but they
00194     // have no RTLs with a non zero address.
00195     if ((addr == 0) && (pRtls->size() > 1)) {
00196         std::list<RTL*>::iterator next = pRtls->begin();
00197         addr = (*++next)->getAddress();
00198     }
00199 
00200     // If this addr is non zero, check the map to see if we have a (possibly incomplete) BB here already
00201     // If it is zero, this is a special BB for handling delayed branches or the like
00202     bool bDone = false;
00203     if (addr != 0) {
00204         mi = m_mapBB.find(addr);
00205         if (mi != m_mapBB.end() && (*mi).second) {
00206             pBB = (*mi).second;
00207             // It should be incomplete, or the pBB there should be zero (we have called Label but not yet created the BB
00208             // for it).  Else we have duplicated BBs. Note: this can happen with forward jumps into the middle of a
00209             // loop, so not error
00210             if (!pBB->m_bIncomplete) {
00211                 // This list of RTLs is not needed now
00212                 delete_lrtls(pRtls);
00213                 if (VERBOSE)
00214                     LOG << "throwing BBAlreadyExistsError\n";
00215                 throw BBAlreadyExistsError(pBB);
00216             }
00217             else {
00218                 // Fill in the details, and return it
00219                 pBB->setRTLs(pRtls);
00220                 pBB->m_nodeType = bbType;
00221                 pBB->m_iNumOutEdges = iNumOutEdges;
00222                 pBB->m_bIncomplete = false;
00223             }
00224             bDone = true;
00225         }
00226     }
00227     if (!bDone) {
00228         // Else add a new BB to the back of the current list.
00229         pBB = new BasicBlock(pRtls, bbType, iNumOutEdges);
00230         m_listBB.push_back(pBB);
00231 
00232         // Also add the address to the map from native (source) address to
00233         // pointer to BB, unless it's zero
00234         if (addr != 0)
00235         {
00236             m_mapBB[addr] = pBB;            // Insert the mapping
00237             mi = m_mapBB.find(addr);
00238         }
00239     }
00240 
00241     if (addr != 0 && (mi != m_mapBB.end()))
00242     {
00243         // Existing New         +---+ Top of new
00244         //          +---+       +---+
00245         //  +---+   |   |       +---+ Fall through
00246         //  |   |   |   | =>    |   |
00247         //  |   |   |   |       |   | Existing; rest of new discarded
00248         //  +---+   +---+       +---+
00249         //  
00250         // Check for overlap of the just added BB with the next BB (address wise).  If there is an overlap, truncate the
00251         // std::list<Exp*> for the new BB to not overlap, and make this a fall through BB.
00252         // We still want to do this even if the new BB overlaps with an incomplete BB, though in this case,
00253         // splitBB needs to fill in the details for the "bottom" BB of the split.
00254         // Also, in this case, we return a pointer to the newly completed BB, so it will get out edges added
00255         // (if required). In the other case (i.e. we overlap with an exising, completed BB), we want to return 0, since
00256         // the out edges are already created.
00257         if (++mi != m_mapBB.end()) {
00258             PBB pNextBB = (*mi).second;
00259             ADDRESS uNext = (*mi).first;
00260             bool bIncomplete = pNextBB->m_bIncomplete;
00261             if (uNext <= pRtls->back()->getAddress()) {
00262                 // Need to truncate the current BB. We use splitBB(), but pass it pNextBB so it doesn't create a new BB
00263                 // for the "bottom" BB of the split pair
00264                 splitBB(pBB, uNext, pNextBB);
00265                 // If the overlapped BB was incomplete, return the "bottom" part of the BB, so adding out edges will
00266                 // work properly.
00267                 if (bIncomplete) {
00268                     return pNextBB;
00269                 }
00270                 // However, if the overlapping BB was already complete, return 0, so out edges won't be added twice
00271                 throw BBAlreadyExistsError(pNextBB);
00272             }
00273         }
00274 
00275         // Existing New         +---+ Top of existing
00276         //  +---+               +---+
00277         //  |   |   +---+       +---+ Fall through
00278         //  |   |   |   | =>    |   |
00279         //  |   |   |   |       |   | New; rest of existing discarded
00280         //  +---+   +---+       +---+
00281         // Note: no need to check the other way around, because in this case, we will have called Cfg::Label(), and it
00282         // will have split the existing BB already.
00283     }
00284     assert(pBB);
00285     return pBB;
00286 }
00287 
00288 // Use this function when there are outedges to BBs that are not created yet. Usually used via addOutEdge()
00289 /*==============================================================================
00290  * FUNCTION:        Cfg::newIncompleteBB
00291  * OVERVIEW:        
00292  * PARAMETERS:      <none>
00293  * RETURNS:         <nothing>
00294  *============================================================================*/
00295 PBB Cfg::newIncompleteBB(ADDRESS addr)
00296 {
00297     // Create a new (basically empty) BB
00298     PBB pBB = new BasicBlock();
00299     // Add it to the list
00300     m_listBB.push_back(pBB);
00301     m_mapBB[addr] = pBB;                // Insert the mapping
00302     return pBB;
00303 }
00304 
00305 /*==============================================================================
00306  * FUNCTION:        Cfg::addOutEdge
00307  * OVERVIEW:        Add an out edge to this BB (and the in-edge to the dest BB)
00308  *                  May also set a label
00309  * NOTE:            Overloaded with address as 2nd argument (calls this proc in the end)
00310  * NOTE ALSO:       Does not increment m_iNumOutEdges; this is supposed to be constant for a BB.
00311  *                    (But see BasicBlock::addNewOutEdge())
00312  * PARAMETERS:      pBB: source BB (to have the out edge added to)
00313  *                  pDestBB: destination BB (to have the out edge point to)
00314  * RETURNS:         <nothing>
00315  *============================================================================*/
00316 void Cfg::addOutEdge(PBB pBB, PBB pDestBB, bool bSetLabel /* = false */)
00317 {
00318     // Add the given BB pointer to the list of out edges
00319     pBB->m_OutEdges.push_back(pDestBB);
00320     // Note that the number of out edges is set at constructor time, not incremented here.
00321     // Add the in edge to the destination BB
00322     pDestBB->m_InEdges.push_back(pBB);
00323     pDestBB->m_iNumInEdges++;           // Inc the count
00324     if (bSetLabel) setLabel(pDestBB);   // Indicate "label required"
00325 }
00326 
00327 /*==============================================================================
00328  * FUNCTION:        Cfg::addOutEdge
00329  * OVERVIEW:        Add an out edge to this BB (and the in-edge to the dest BB)
00330  *                  May also set a label
00331  * NOTE:            Calls the above
00332  * PARAMETERS:      pBB: source BB (to have the out edge added to) 
00333  *                  addr: source address of destination (the out edge is to point to the BB whose lowest address is
00334  *                    addr)
00335  *                  bSetLabel: if true, set a label at the destination address.  Set true on "true" branches of labels
00336  * RETURNS:         <nothing>
00337  *============================================================================*/
00338 void Cfg::addOutEdge(PBB pBB, ADDRESS addr, bool bSetLabel /* = false */)
00339 {
00340     // Check to see if the address is in the map, i.e. we already have a BB for this address
00341     MAPBB::iterator it = m_mapBB.find(addr);
00342     PBB pDestBB;
00343     if (it != m_mapBB.end() && (*it).second) {
00344         // Just add this PBB to the list of out edges
00345         pDestBB = (*it).second;
00346     }
00347     else {
00348         // Else, create a new incomplete BB, add that to the map, and add the new BB as the out edge
00349         pDestBB = newIncompleteBB(addr);
00350     }
00351     addOutEdge(pBB, pDestBB, bSetLabel);
00352 }
00353 
00354 /*==============================================================================
00355  * FUNCTION:        Cfg::existsBB 
00356  * OVERVIEW:        Return true if the given address is the start of a basic block, complete or not
00357  * PARAMETERS:      uNativeAddr: native address to look up
00358  * RETURNS:         True if uNativeAddr starts a BB
00359  *============================================================================*/
00360 // Note: must ignore entries with a null pBB, since these are caused by
00361 // calls to Label that failed, i.e. the instruction is not decoded yet.
00362 bool Cfg::existsBB (ADDRESS uNativeAddr)
00363 {
00364     MAPBB::iterator mi;
00365     mi = m_mapBB.find (uNativeAddr);
00366     return (mi != m_mapBB.end() && (*mi).second);
00367 }
00368 
00369 /*==============================================================================
00370  * FUNCTION:    Cfg::splitBB (private)
00371  * OVERVIEW:    Split the given basic block at the RTL associated with uNativeAddr. The first node's type becomes
00372  *              fall-through and ends at the RTL prior to that associated with uNativeAddr.  The second node's type
00373  *              becomes the type of the original basic block (pBB), and its out-edges are those of the original basic
00374  *              block. In edges of the new BB's descendants are changed.
00375  * PRECONDITION: assumes uNativeAddr is an address within the boundaries of the given basic block.
00376  * PARAMETERS:  pBB -  pointer to the BB to be split
00377  *              uNativeAddr - address of RTL to become the start of the new BB
00378  *              pNewBB -  if non zero, it remains as the "bottom" part of the BB, and splitBB only modifies the top part *              to not overlap.
00379  *              bDelRtls - if true, deletes the RTLs removed from the existing BB after the split point. Only used if
00380  *              there is an overlap with existing instructions
00381  * RETURNS:     Returns a pointer to the "bottom" (new) part of the split BB.
00382  *============================================================================*/
00383 PBB Cfg::splitBB (PBB pBB, ADDRESS uNativeAddr, PBB pNewBB /* = 0 */, bool bDelRtls /* = false */) { 
00384     std::list<RTL*>::iterator ri;
00385 
00386     // First find which RTL has the split address; note that this could fail (e.g. label in the middle of an
00387     // instruction, or some weird delay slot effects)
00388     for (ri = pBB->m_pRtls->begin(); ri != pBB->m_pRtls->end(); ri++) {
00389         if ((*ri)->getAddress() == uNativeAddr)
00390             break;
00391     }
00392     if (ri == pBB->m_pRtls->end()) {
00393         std::cerr << "could not split BB at " << std::hex << pBB->getLowAddr() << " at split address " << uNativeAddr
00394             << std::endl;
00395         return pBB;
00396     }
00397 
00398     // If necessary, set up a new basic block with information from the original bb
00399     if (pNewBB == NULL) {
00400         pNewBB = new BasicBlock(*pBB);
00401         // But we don't want the top BB's in edges; our only in-edge should be the out edge from the top BB
00402         pNewBB->m_iNumInEdges = 0;
00403         pNewBB->m_InEdges.erase(pNewBB->m_InEdges.begin(),
00404             pNewBB->m_InEdges.end());
00405         // The "bottom" BB now starts at the implicit label, so we create a new list that starts at ri. We need a new
00406         // list, since it is different from the original BB's list. We don't have to "deep copy" the RTLs themselves,
00407         // since they will never overlap
00408         pNewBB->setRTLs(new std::list<RTL*>(ri, pBB->m_pRtls->end()));
00409         // Put it in the graph
00410         m_listBB.push_back(pNewBB);
00411         // Put the implicit label into the map. Need to do this before the addOutEdge() below
00412         m_mapBB[uNativeAddr] = pNewBB;
00413         // There must be a label here; else would not be splitting.  Give it a new label
00414         pNewBB->m_iLabelNum = ++lastLabel;
00415     }
00416     else if (pNewBB->m_bIncomplete)
00417     {
00418         // We have an existing BB and a map entry, but no details except for in-edges and m_bHasLabel.
00419         // First save the in-edges and m_iLabelNum
00420         std::vector<PBB> ins(pNewBB->m_InEdges);
00421         int label = pNewBB->m_iLabelNum;
00422         // Copy over the details now, completing the bottom BB
00423         *pNewBB = *pBB;                 // Assign the BB, copying fields. This will set m_bIncomplete false
00424         // Replace the in edges (likely only one)
00425         pNewBB->m_InEdges = ins;
00426         pNewBB->m_iNumInEdges = ins.size();
00427         // Replace the label (must be one, since we are splitting this BB!)
00428         pNewBB->m_iLabelNum = label;
00429         // The "bottom" BB now starts at the implicit label
00430         // We need to create a new list of RTLs, as per above
00431         pNewBB->setRTLs(new std::list<RTL*>(ri, pBB->m_pRtls->end()));
00432     }
00433     // else pNewBB exists and is complete. We don't want to change the complete BB in any way, except to later add one
00434     // in-edge
00435 
00436     // Update original ("top") basic block's info and make it a fall-through
00437     pBB->m_nodeType = FALL;
00438     // Fix the in-edges of pBB's descendants. They are now pNewBB
00439     // Note: you can't believe m_iNumOutEdges at the time that this function may get called
00440     for (unsigned j=0; j < pBB->m_OutEdges.size(); j++) {
00441         PBB pDescendant = pBB->m_OutEdges[j];
00442         // Search through the in edges for pBB (old ancestor)
00443         unsigned k;
00444         for (k=0; k < pDescendant->m_InEdges.size(); k++) {
00445             if (pDescendant->m_InEdges[k] == pBB) {
00446                 // Replace with a pointer to the new ancestor
00447                 pDescendant->m_InEdges[k] = pNewBB;
00448                 break;
00449             }
00450         }
00451         // That pointer should have been found!
00452         assert (k < pDescendant->m_InEdges.size());
00453     }
00454     // The old BB needs to have part of its list of RTLs erased, since the instructions overlap
00455     if (bDelRtls) {
00456         // Delete the list of pointers, and also the RTLs they point to
00457         erase_lrtls(pBB->m_pRtls, ri, pBB->m_pRtls->end());
00458     }
00459     else {
00460         // Delete the list of pointers, but not the RTLs they point to
00461         pBB->m_pRtls->erase(ri, pBB->m_pRtls->end());
00462     }
00463     // Erase any existing out edges
00464     pBB->m_OutEdges.erase(pBB->m_OutEdges.begin(), pBB->m_OutEdges.end());
00465     pBB->m_iNumOutEdges = 1;
00466     addOutEdge (pBB, uNativeAddr);  
00467     return pNewBB;
00468 }
00469 
00470 /*==============================================================================
00471  * FUNCTION:        Cfg::getFirstBB
00472  * OVERVIEW:        Get the first BB of this cfg
00473  * PARAMETERS:      it: set to an value that must be passed to getNextBB
00474  * RETURNS:         Pointer to the first BB this cfg, or NULL if none
00475  *============================================================================*/
00476 PBB Cfg::getFirstBB(BB_IT& it)
00477 {
00478     if ((it = m_listBB.begin()) == m_listBB.end()) return 0;
00479     return *it;
00480 }
00481 
00482 /*==============================================================================
00483  * FUNCTION:        Cfg::getNextBB
00484  * OVERVIEW:        Get the next BB this cfg. Basically increments the given iterator and returns it
00485  * PARAMETERS:      iterator from a call to getFirstBB or getNextBB
00486  * RETURNS:         pointer to the BB, or NULL if no more
00487  *============================================================================*/
00488 PBB Cfg::getNextBB(BB_IT& it)
00489 {
00490     if (++it == m_listBB.end()) return 0;
00491     return *it;
00492 }
00493 
00494 /*==============================================================================
00495  * FUNCTION:    Cfg::label
00496  * OVERVIEW:    Checks whether the given native address is a label (explicit or non explicit) or not. Returns false for
00497  *              incomplete BBs.  So it returns true iff the address has already been decoded in some BB. If it was not
00498  *              already a label (i.e. the first instruction of some BB), the BB is split so that it becomes a label.
00499  *              Explicit labels are addresses that have already been tagged as being labels due to transfers of control
00500  *              to that address, and are therefore the start of some BB.     Non explicit labels are those that belong
00501  *              to basic blocks that have already been constructed (i.e. have previously been parsed) and now need to
00502  *              be made explicit labels. In the case of non explicit labels, the basic block is split into two and types
00503  *              and edges are adjusted accordingly. If pCurBB is the BB that gets split, it is changed to point to the
00504  *              address of the new (lower) part of the split BB.
00505  *              If there is an incomplete entry in the table for this address which overlaps with a completed address,
00506  *              the completed BB is split and the BB for this address is completed.
00507  * PARAMETERS:  uNativeAddress - native (source) address to check
00508  *              pCurBB - See above
00509  * RETURNS:     True if uNativeAddr is a label, i.e. (now) the start of a BB
00510  *              Note: pCurBB may be modified (as above)
00511  *============================================================================*/
00512 bool Cfg::label ( ADDRESS uNativeAddr, PBB& pCurBB )
00513 { 
00514     MAPBB::iterator mi, newi;
00515 
00516     // check if the native address is in the map already (explicit label)
00517     mi = m_mapBB.find (uNativeAddr);
00518     
00519     if (mi == m_mapBB.end())        // not in the map
00520     {
00521         // If not an explicit label, temporarily add the address to the map
00522         m_mapBB[uNativeAddr] = (PBB) 0;     // no PBB yet
00523 
00524         // get an iterator to the new native address and check if the previous element in the (sorted) map overlaps
00525         // this new native address; if so, it's a non-explicit label which needs to be made explicit by splitting the
00526         // previous BB.
00527         mi = m_mapBB.find (uNativeAddr);
00528 
00529         newi = mi;
00530         bool bSplit = false;
00531         PBB pPrevBB = NULL;
00532         if (newi != m_mapBB.begin()) {
00533             pPrevBB = (*--mi).second;
00534             if (!pPrevBB->m_bIncomplete &&
00535                   (pPrevBB->getLowAddr() < uNativeAddr) &&
00536                   (pPrevBB->getHiAddr () >= uNativeAddr)) {
00537                 bSplit = true;
00538             }
00539         }
00540         if (bSplit) {
00541             // Non-explicit label. Split the previous BB
00542             PBB pNewBB = splitBB (pPrevBB, uNativeAddr);    
00543             if (pCurBB == pPrevBB) {
00544                 // This means that the BB that we are expecting to use, usually to add out edges, has changed. We must
00545                 // change this pointer so that the right BB gets the out edges. However, if the new BB is not the BB of
00546                 // interest, we mustn't change pCurBB
00547                 pCurBB = pNewBB;
00548             }
00549             return true;            // wasn't a label, but already parsed
00550         }
00551         else {                      // not a non-explicit label
00552             // We don't have to erase this map entry. Having a null BasicBlock pointer is coped with in newBB() and
00553             // addOutEdge(); when eventually the BB is created, it will replace this entry.  We should be currently
00554             // processing this BB. The map will be corrected when newBB is called with this address.
00555             return false;               // was not already parsed
00556         }
00557     }
00558     else            // We already have uNativeAddr in the map
00559     {
00560         if ((*mi).second && !(*mi).second->m_bIncomplete) {
00561             // There is a complete BB here. Return true.
00562             return true;
00563         }
00564 
00565         // We are finalising an incomplete BB. Still need to check previous map entry to see if there is a complete BB
00566         // overlapping
00567         bool bSplit = false;
00568         PBB pPrevBB, pBB = (*mi).second;
00569         if (mi != m_mapBB.begin())
00570         {
00571             pPrevBB = (*--mi).second;
00572             if (!pPrevBB->m_bIncomplete &&
00573                 (pPrevBB->getLowAddr() < uNativeAddr) &&
00574                 (pPrevBB->getHiAddr () >= uNativeAddr))
00575                     bSplit = true;
00576         }
00577         if (bSplit)
00578         {
00579             // Pass the third parameter to splitBB, because we already have an (incomplete) BB for the "bottom" BB of
00580             // the split
00581             splitBB (pPrevBB, uNativeAddr, pBB);    // non-explicit label
00582             return true;            // wasn't a label, but already parsed
00583         }
00584         // A non overlapping, incomplete entry is in the map.
00585         return false;
00586     }
00587 }
00588 
00589 // Return true if there is an incomplete BB already at this address
00590 /*==============================================================================
00591  * FUNCTION:        Cfg::isIncomplete
00592  * OVERVIEW:        Return true if given address is the start of an incomplete basic block
00593  * PARAMETERS:      uAddr: Address to look up
00594  * RETURNS:         True if uAddr starts an incomplete BB
00595  *============================================================================*/
00596 bool Cfg::isIncomplete(ADDRESS uAddr)
00597 {
00598     MAPBB::iterator mi = m_mapBB.find(uAddr);
00599     if (mi == m_mapBB.end())
00600         // No entry at all
00601         return false;
00602     // Else, there is a BB there. If it's incomplete, return true
00603     PBB pBB = (*mi).second;
00604     return pBB->m_bIncomplete;
00605 }
00606 
00607 /*==============================================================================
00608  * FUNCTION:        Cfg::sortByAddress
00609  * OVERVIEW:        Sorts the BBs in a cfg by first address. Just makes it more convenient to read when BBs are
00610  *                  iterated.
00611  * PARAMETERS:      <none>
00612  * RETURNS:         <nothing>
00613  *============================================================================*/
00614 
00615 void Cfg::sortByAddress()
00616 {
00617     m_listBB.sort(BasicBlock::lessAddress);
00618 }
00619 
00620 /*==============================================================================
00621  * FUNCTION:        Cfg::sortByFirstDFT
00622  * OVERVIEW:        Sorts the BBs in a cfg by their first DFT numbers.
00623  * PARAMETERS:      <none>
00624  * RETURNS:         <nothing>
00625  *============================================================================*/
00626 void Cfg::sortByFirstDFT()
00627 {
00628 #ifndef _WIN32
00629     m_listBB.sort(BasicBlock::lessFirstDFT);
00630 #else
00631     updateVectorBB();
00632     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
00633         m_vectorBB[(*it)->m_DFTfirst-1] = *it;
00634     m_listBB.clear();
00635     for (size_t i = 0; i < m_vectorBB.size(); i++)
00636         m_listBB.push_back(m_vectorBB[i]);
00637 #endif
00638 }
00639 
00640 /*==============================================================================
00641  * FUNCTION:        Cfg::sortByLastDFT
00642  * OVERVIEW:        Sorts the BBs in a cfg by their last DFT numbers.
00643  * PARAMETERS:      <none>
00644  * RETURNS:         <nothing>
00645  *============================================================================*/
00646 void Cfg::sortByLastDFT()
00647 {
00648 #ifndef _WIN32
00649     m_listBB.sort(BasicBlock::lessLastDFT);
00650 #else
00651     updateVectorBB();
00652     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
00653         m_vectorBB[(*it)->m_DFTlast-1] = *it;
00654     m_listBB.clear();
00655     for (size_t i = 0; i < m_vectorBB.size(); i++)
00656         m_listBB.push_back(m_vectorBB[i]);
00657 #endif
00658 }
00659 
00660 /*==============================================================================
00661  * FUNCTION:        Cfg::updateVectorBB
00662  * OVERVIEW:        Updates m_vectorBB to m_listBB
00663  * PARAMETERS:      <none>
00664  * RETURNS:         <nothing>
00665  *============================================================================*/
00666 void Cfg::updateVectorBB()
00667 {
00668     m_vectorBB.clear();
00669     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
00670         m_vectorBB.push_back(*it);
00671 }
00672 
00673 
00674 /*==============================================================================
00675  * FUNCTION:        Cfg::wellFormCfg
00676  * OVERVIEW:        Checks that all BBs are complete, and all out edges are valid. However, ADDRESSes that are
00677  *                  interprocedural out edges are not checked or changed.
00678  * PARAMETERS:      <none>
00679  * RETURNS:         transformation was successful
00680  *============================================================================*/
00681 bool Cfg::wellFormCfg()
00682 {
00683     m_bWellFormed = true;
00684     for (BB_IT it = m_listBB.begin(); it != m_listBB.end(); it++) {
00685         // it iterates through all BBs in the list
00686         // Check that it's complete
00687         if ((*it)->m_bIncomplete) {
00688             m_bWellFormed = false;
00689             MAPBB::iterator itm;
00690             for (itm = m_mapBB.begin(); itm != m_mapBB.end(); itm++)
00691                 if ((*itm).second == *it) break;
00692             if (itm == m_mapBB.end())
00693                 std::cerr << "WellFormCfg: incomplete BB not even in map!\n";
00694             else {
00695                 std::cerr << "WellFormCfg: BB with native address ";
00696                 std::cerr << std::hex << (*itm).first << " is incomplete\n";
00697             }
00698         } else {
00699             // Complete. Test the out edges
00700             assert((int)(*it)->m_OutEdges.size() == (*it)->m_iNumOutEdges);
00701             for (int i=0; i < (*it)->m_iNumOutEdges; i++) {
00702                 // check if address is interprocedural
00703 //              if ((*it)->m_OutEdgeInterProc[i] == false)
00704                 {
00705                     // i iterates through the outedges in the BB *it
00706                     PBB pBB = (*it)->m_OutEdges[i];
00707 
00708                     // Check that the out edge has been written (i.e. nonzero)
00709                     if (pBB == NULL) {
00710                         m_bWellFormed = false;  // At least one problem
00711                         ADDRESS addr = (*it)->getLowAddr();
00712                         std::cerr << "WellFormCfg: BB with native address " << std::hex << addr <<
00713                             " is missing outedge " << i << std::endl;
00714                     }
00715                     else {
00716                         // Check that there is a corresponding in edge from the
00717                         // child to here
00718                         std::vector<PBB>::iterator ii;
00719                         for (ii=pBB->m_InEdges.begin();
00720                                 ii != pBB->m_InEdges.end(); ii++)
00721                             if (*ii == *it) break;
00722                         if (ii == pBB->m_InEdges.end()) {
00723                             std::cerr << "WellFormCfg: No in edge to BB at " << std::hex << (*it)->getLowAddr() <<
00724                                 " from successor BB at " << pBB->getLowAddr() << std::endl;
00725                             m_bWellFormed = false;  // At least one problem
00726                         }
00727                     }
00728                 }
00729             }
00730             // Also check that each in edge has a corresponding out edge to here (could have an extra in-edge, for
00731             // example)
00732             assert((int)(*it)->m_InEdges.size() == (*it)->m_iNumInEdges);
00733             std::vector<PBB>::iterator ii;
00734             for (ii = (*it)->m_InEdges.begin(); ii != (*it)->m_InEdges.end(); ii++) {
00735                 std::vector<PBB>::iterator oo;
00736                 for (oo=(*ii)->m_OutEdges.begin(); oo != (*ii)->m_OutEdges.end(); oo++)
00737                     if (*oo == *it) break;
00738                 if (oo == (*ii)->m_OutEdges.end()) {
00739                     std::cerr << "WellFormCfg: No out edge to BB at " << std::hex << (*it)->getLowAddr() <<
00740                         " from predecessor BB at " << (*ii)->getLowAddr() << std::endl;
00741                     m_bWellFormed = false;  // At least one problem
00742                 }
00743             }
00744         }
00745     }
00746     return m_bWellFormed;
00747 }
00748 
00749 /*==============================================================================
00750  * FUNCTION:        Cfg::mergeBBs
00751  * OVERVIEW:        
00752  * PARAMETERS:      <none>
00753  * RETURNS:         <nothing>
00754  *============================================================================*/
00755 bool Cfg::mergeBBs( PBB pb1, PBB pb2)
00756 {
00757     // Can only merge if pb1 has only one outedge to pb2, and pb2 has only one in-edge, from pb1. This can only be done
00758     // after the in-edges are done, which can only be done on a well formed CFG.
00759     if (!m_bWellFormed) return false;
00760     if (pb1->m_iNumOutEdges != 1) return false;
00761     if (pb2->m_iNumInEdges != 1) return false;
00762     if (pb1->m_OutEdges[0] != pb2) return false;
00763     if (pb2->m_InEdges[0] != pb1) return false;
00764 
00765     // Merge them! We remove pb1 rather than pb2, since this is also what is needed for many optimisations, e.g. jump to
00766     // jump.
00767     completeMerge(pb1, pb2, true);
00768     return true;
00769 }
00770 
00771 /*==============================================================================
00772  * FUNCTION:        Cfg::completeMerge
00773  * OVERVIEW:        Complete the merge of two BBs by adjusting in and out edges.  If bDelete is true, delete pb1
00774  * PARAMETERS:      pb1, pb2: pointers to the two BBs to merge
00775  *                  bDelete: if true, pb1 is deleted as well
00776  * RETURNS:         <nothing>
00777  *============================================================================*/
00778 void Cfg::completeMerge(PBB pb1, PBB pb2, bool bDelete = false)
00779 {
00780     // First we replace all of pb1's predecessors' out edges that used to point to pb1 (usually only one of these) with
00781     // pb2
00782     for (int i=0; i < pb1->m_iNumInEdges; i++)
00783     {
00784         PBB pPred = pb1->m_InEdges[i];
00785         for (int j=0; j < pPred->m_iNumOutEdges; j++)
00786         {
00787             if (pPred->m_OutEdges[j] == pb1)
00788                 pPred->m_OutEdges[j] = pb2;
00789         }
00790     }
00791 
00792     // Now we replace pb2's in edges by pb1's inedges
00793     pb2->m_InEdges = pb1->m_InEdges;
00794     pb2->m_iNumInEdges = pb1->m_iNumInEdges;
00795 
00796     if (bDelete) {
00797         // Finally, we delete pb1 from the BB list. Note: remove(pb1) should also work, but it would involve member
00798         // comparison (not implemented), and also would attempt to remove ALL elements of the list with this value (so
00799         // it has to search the whole list, instead of an average of half the list as we have here).
00800         for (BB_IT it = m_listBB.begin(); it != m_listBB.end(); it++)
00801         {
00802             if (*it == pb1)
00803             {
00804                 m_listBB.erase(it);
00805                 break;
00806             }
00807         }
00808     }
00809 }
00810 
00811 /*==============================================================================
00812  * FUNCTION:        Cfg::joinBB
00813  * OVERVIEW:        Amalgamate the RTLs for pb1 and pb2, and place the result into pb2
00814  * PARAMETERS:      pb1, pb2: pointers to the BBs to join
00815  * ASSUMES:         Fallthrough of *pb1 is *pb2
00816  * RETURNS:         True if successful
00817  *============================================================================*/
00818 bool Cfg::joinBB(PBB pb1, PBB pb2)
00819 {
00820     // Ensure that the fallthrough case for pb1 is pb2
00821     std::vector<PBB>& v = pb1->getOutEdges();
00822     if (v.size() != 2 || v[1] != pb2)
00823         return false;
00824     // Prepend the RTLs for pb1 to those of pb2. Since they will be pushed to the front of pb2, push them in reverse
00825     // order
00826     std::list<RTL*>::reverse_iterator it;
00827     for (it = pb1->m_pRtls->rbegin(); it != pb1->m_pRtls->rend(); it++) {
00828         pb2->m_pRtls->push_front(*it);
00829     }
00830     completeMerge(pb1, pb2);                // Mash them together
00831     // pb1 no longer needed. Remove it from the list of BBs.  This will also delete *pb1. It will be a shallow delete,
00832     // but that's good because we only did shallow copies to *pb2
00833     BB_IT bbit = std::find(m_listBB.begin(), m_listBB.end(), pb1);
00834     m_listBB.erase(bbit);
00835     return true;
00836 }
00837 
00838 void Cfg::removeBB( PBB bb)
00839 {
00840     BB_IT bbit = std::find(m_listBB.begin(), m_listBB.end(), bb);
00841     m_listBB.erase(bbit);
00842 }
00843 
00844 /*==============================================================================
00845  * FUNCTION:        Cfg::compressCfg
00846  * OVERVIEW:        Compress the CFG. For now, it only removes BBs that are
00847  *                    just branches
00848  * PARAMETERS:      <none>
00849  * RETURNS:         False if not well formed; true otherwise
00850  *============================================================================*/
00851 bool Cfg::compressCfg()
00852 {
00853     // must be well formed
00854     if (!m_bWellFormed) return false;
00855 
00856     // FIXME: The below was working while we still had reaching definitions.  It seems to me that it would be easy to
00857     // search the BB for definitions between the two branches (so we don't need reaching defs, just the SSA property of
00858     //  unique definition).
00859     //
00860     // Look in CVS for old code.
00861     
00862     // Find A -> J -> B  where J is a BB that is only a jump
00863     // Then A -> B
00864     for (BB_IT it = m_listBB.begin(); it != m_listBB.end(); it++)
00865     {
00866         for (std::vector<PBB>::iterator it1 = (*it)->m_OutEdges.begin();
00867           it1 != (*it)->m_OutEdges.end(); it1++) {
00868             PBB pSucc = (*it1);         // Pointer to J
00869             PBB bb = (*it);             // Pointer to A
00870             if (pSucc->m_InEdges.size()==1 && pSucc->m_OutEdges.size()==1 &&
00871               pSucc->m_pRtls->size()==1 &&
00872               pSucc->m_pRtls->front()->getNumStmt() == 1 &&
00873               pSucc->m_pRtls->front()->elementAt(0)->isGoto()) {
00874                 // Found an out-edge to an only-jump BB
00875                 /* std::cout << "outedge to jump detected at " << std::hex << bb->getLowAddr() << " to ";
00876                     std::cout << pSucc->getLowAddr() << " to " << pSucc->m_OutEdges.front()->getLowAddr() << std::dec <<
00877                     std::endl; */
00878                 // Point this outedge of A to the dest of the jump (B)
00879                 *it1=pSucc->m_OutEdges.front();
00880                 // Now pSucc still points to J; *it1 points to B.  Almost certainly, we will need a jump in the low
00881                 // level C that may be generated. Also force a label for B
00882                 bb->m_bJumpReqd = true;
00883                 setLabel(*it1);
00884                 // Find the in-edge from B to J; replace this with an in-edge to A
00885                 std::vector<PBB>::iterator it2;
00886                 for (it2 = (*it1)->m_InEdges.begin();
00887                   it2 != (*it1)->m_InEdges.end(); it2++) {
00888                     if (*it2==pSucc)
00889                         *it2 = bb;          // Point to A
00890                 }
00891                 // Remove the in-edge from J to A. First find the in-edge
00892                 for (it2 = pSucc->m_InEdges.begin();
00893                   it2 != pSucc->m_InEdges.end(); it2++) {
00894                     if (*it2 == bb)
00895                         break;
00896                 }
00897                 assert(it2 != pSucc->m_InEdges.end());
00898                 pSucc->deleteInEdge(it2);
00899                 // If nothing else uses this BB (J), remove it from the CFG
00900                 if (pSucc->m_iNumInEdges == 0) {
00901                     for (BB_IT it3 = m_listBB.begin(); it3 != m_listBB.end();
00902                       it3++) {
00903                         if (*it3==pSucc) {
00904                             m_listBB.erase(it3);
00905                             // And delete the BB
00906                             delete pSucc;
00907                             break;
00908                         }
00909                     }
00910                 }
00911             }
00912         }
00913     }
00914     return true;
00915 }
00916 
00917 /*==============================================================================
00918  * FUNCTION:        Cfg::unTraverse
00919  * OVERVIEW:        Reset all the traversed flags.
00920  * PARAMETERS:      <none>
00921  * RETURNS:         <nothing>
00922  *============================================================================*/
00923 void Cfg::unTraverse()
00924 {
00925     for (BB_IT it = m_listBB.begin(); it != m_listBB.end(); it++)
00926     {
00927         (*it)->m_iTraversed = false;
00928         (*it)->traversed = UNTRAVERSED;
00929     }
00930 }
00931     
00932 /*==============================================================================
00933  * FUNCTION:        Cfg::establishDFTOrder
00934  * OVERVIEW:        Given a well-formed cfg graph, a partial ordering is established between the nodes. The ordering is
00935  *                  based on the final visit to each node during a depth first traversal such that if node n1 was
00936  *                  visited for the last time before node n2 was visited for the last time, n1 will be less than n2.
00937  *                  The return value indicates if all nodes where ordered. This will not be the case for incomplete CFGs
00938  *                  (e.g. switch table not completely recognised) or where there are nodes unreachable from the entry
00939  *                  node.
00940  * PARAMETERS:      <none>
00941  * RETURNS:         all nodes where ordered
00942  *============================================================================*/
00943 bool Cfg::establishDFTOrder()
00944 {
00945     // Must be well formed.
00946     if (!m_bWellFormed) return false;
00947 
00948     // Reset all the traversed flags
00949     unTraverse();
00950 
00951     int first = 0;
00952     int last = 0;
00953     unsigned numTraversed;
00954 
00955     if (checkEntryBB()) return false;
00956 
00957     numTraversed = entryBB->DFTOrder(first,last);
00958 
00959     return numTraversed == m_listBB.size();
00960 }
00961 
00962 PBB Cfg::findRetNode()
00963 {
00964     PBB retNode = NULL;
00965     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); 
00966      it++) {
00967         if ((*it)->getType() == RET) {
00968             retNode = *it;
00969             break;
00970         } else if ((*it)->getType() == CALL) {
00971             Proc *p = (*it)->getCallDestProc();
00972             if (p && !strcmp(p->getName(), "exit"))
00973                 retNode = *it;
00974         }
00975     }
00976     return retNode;
00977 }
00978 
00979 /*==============================================================================
00980  * FUNCTION:        Cfg::establishRevDFTOrder
00981  * OVERVIEW:        Performs establishDFTOrder on the reverse (flip) of the graph, assumes: establishDFTOrder has
00982  *                  already been called
00983  * PARAMETERS:      <none>
00984  * RETURNS:         all nodes where ordered
00985  *============================================================================*/
00986 bool Cfg::establishRevDFTOrder()
00987 {
00988     // Must be well formed.
00989     if (!m_bWellFormed) return false;
00990 
00991     // WAS: sort by last dfs and grab the exit node
00992     // Why?  This does not seem like a the best way. What we need is the ret node, so let's find it.  If the CFG has
00993     // more than one ret node then it needs to be fixed.
00994     //sortByLastDFT();
00995 
00996     PBB retNode = findRetNode();
00997 
00998     if (retNode == NULL) return false;
00999 
01000     // Reset all the traversed flags
01001     unTraverse();
01002 
01003     int first = 0;
01004     int last = 0;
01005     unsigned numTraversed;
01006 
01007     numTraversed = retNode->RevDFTOrder(first,last);
01008 
01009     return numTraversed == m_listBB.size();
01010 }
01011 
01012 /*==============================================================================
01013  * FUNCTION:        Cfg::isWellFormed
01014  * OVERVIEW:        
01015  * PARAMETERS:      <none>
01016  * RETURNS:         <nothing>
01017  *============================================================================*/
01018 bool Cfg::isWellFormed()
01019 {
01020     return m_bWellFormed;
01021 }
01022 
01023 /*==============================================================================
01024  * FUNCTION:        Cfg::isOrphan
01025  * OVERVIEW:        
01026  * PARAMETERS:      <none>
01027  * RETURNS:         <nothing>
01028  *============================================================================*/
01029 bool Cfg::isOrphan(ADDRESS uAddr)
01030 {
01031     MAPBB::iterator mi = m_mapBB.find(uAddr);
01032     if (mi == m_mapBB.end())
01033         // No entry at all
01034         return false;
01035     // Return true if the first RTL at this address has an address set to 0
01036     PBB pBB = (*mi).second;
01037     // If it's incomplete, it can't be an orphan
01038     if (pBB->m_bIncomplete) return false;
01039     return pBB->m_pRtls->front()->getAddress() == 0;
01040 }
01041 
01042 /*==============================================================================
01043  * FUNCTION:        Cfg::pbbToIndex 
01044  * OVERVIEW:        Return an index for the given PBB
01045  * NOTE:            Linear search: O(N) complexity
01046  * PARAMETERS:      <none>
01047  * RETURNS:         Index, or -1 for unknown PBB
01048  *============================================================================*/
01049 int Cfg::pbbToIndex (PBB pBB) {
01050     BB_IT it = m_listBB.begin();
01051     int i = 0;
01052     while (it != m_listBB.end()) {
01053         if (*it++ == pBB) return i;
01054         i++;
01055     }
01056     return -1;
01057 }
01058 
01059 /*==============================================================================
01060  * FUNCTION:        Cfg::addCall
01061  * OVERVIEW:        Add a call to the set of calls within this procedure.
01062  * PARAMETERS:      call - a call instruction
01063  * RETURNS:         <nothing>
01064  *============================================================================*/
01065 void Cfg::addCall(CallStatement* call)
01066 {
01067     callSites.insert(call);
01068 }
01069 
01070 /*==============================================================================
01071  * FUNCTION:        Cfg::getCalls
01072  * OVERVIEW:        Get the set of calls within this procedure.
01073  * PARAMETERS:      <none>
01074  * RETURNS:         the set of calls within this procedure
01075  *============================================================================*/
01076 std::set<CallStatement*>& Cfg::getCalls()
01077 {
01078     return callSites;
01079 }
01080 
01081 /*==============================================================================
01082  * FUNCTION:        Cfg::searchAndReplace
01083  * OVERVIEW:        Replace all instances of search with replace.
01084  * PARAMETERS:      search - a location to search for
01085  *                  replace - the expression with which to replace it
01086  * RETURNS:         <nothing>
01087  *============================================================================*/
01088 void Cfg::searchAndReplace(Exp* search, Exp* replace) {
01089     for (BB_IT bb_it = m_listBB.begin(); bb_it != m_listBB.end(); bb_it++) {
01090         std::list<RTL*>& rtls = *((*bb_it)->getRTLs());
01091         for (std::list<RTL*>::iterator rtl_it = rtls.begin(); rtl_it != rtls.end(); rtl_it++) {
01092             RTL& rtl = **rtl_it;
01093             rtl.searchAndReplace(search,replace);
01094         }
01095     }
01096 }
01097 
01098 bool Cfg::searchAll(Exp *search, std::list<Exp*> &result)
01099 {
01100     bool ch = false;
01101     for (BB_IT bb_it = m_listBB.begin(); bb_it != m_listBB.end(); bb_it++) {
01102         std::list<RTL*>& rtls = *((*bb_it)->getRTLs());
01103         for (std::list<RTL*>::iterator rtl_it = rtls.begin(); rtl_it != rtls.end(); rtl_it++) {
01104             RTL& rtl = **rtl_it;
01105             ch |= rtl.searchAll(search, result);
01106         }
01107     }
01108     return ch;
01109 }
01110 
01111 /*==============================================================================
01112  * FUNCTION:    delete_lrtls
01113  * OVERVIEW:    "deep" delete for a list of pointers to RTLs
01114  * PARAMETERS:  pLrtl - the list
01115  * RETURNS:     <none>
01116  *============================================================================*/
01117 void delete_lrtls(std::list<RTL*>* pLrtl)
01118 {
01119     std::list<RTL*>::iterator it;
01120     for (it = pLrtl->begin(); it != pLrtl->end(); it++) {
01121         delete (*it);
01122     }
01123 }
01124 
01125 /*==============================================================================
01126  * FUNCTION:    erase_lrtls
01127  * OVERVIEW:    "deep" erase for a list of pointers to RTLs
01128  * PARAMETERS:  pLrtls - the list
01129  *              begin - iterator to first (inclusive) item to delete
01130  *              end - iterator to last (exclusive) item to delete
01131  * RETURNS:     <none>
01132  *============================================================================*/
01133 void erase_lrtls(std::list<RTL*>* pLrtl, std::list<RTL*>::iterator begin,
01134     std::list<RTL*>::iterator end)
01135 {
01136     std::list<RTL*>::iterator it;
01137     for (it = begin; it != end; it++) {
01138         delete (*it);
01139     }
01140     pLrtl->erase(begin, end);
01141 }
01142 
01143 /*==============================================================================
01144  * FUNCTION:        Cfg::setLabel
01145  * OVERVIEW:        Sets a flag indicating that this BB has a label, in the sense that a label is required in the
01146  *                  translated source code
01147  * PARAMETERS:      pBB: Pointer to the BB whose label will be set
01148  * RETURNS:         <nothing>
01149  *============================================================================*/
01150 void Cfg::setLabel(PBB pBB) {
01151     if (pBB->m_iLabelNum == 0)
01152         pBB->m_iLabelNum = ++lastLabel;
01153 }
01154 
01155 /*==============================================================================
01156  * FUNCTION:        Cfg::addNewOutEdge
01157  * OVERVIEW:        Append a new out-edge from the given BB to the other given BB
01158  *                  Needed for example when converting a one-way BB to a two-way BB
01159  * NOTE:            Use BasicBlock::setOutEdge() for the common case where an existing out edge is merely changed
01160  * NOTE ALSO:       Use Cfg::addOutEdge for ordinary BB creation; this is for unusual cfg manipulation
01161  * PARAMETERS:      pFromBB: pointer to the BB getting the new out edge
01162  *                  pNewOutEdge: pointer to BB that will be the new successor
01163  * SIDE EFFECTS:    Increments m_iNumOutEdges
01164  * RETURNS:         <nothing>
01165  *============================================================================*/
01166 void Cfg::addNewOutEdge(PBB pFromBB, PBB pNewOutEdge)
01167 {
01168     pFromBB->m_OutEdges.push_back(pNewOutEdge);
01169     pFromBB->m_iNumOutEdges++;
01170     // Since this is a new out-edge, set the "jump required" flag
01171     pFromBB->m_bJumpReqd = true;
01172     // Make sure that there is a label there
01173     setLabel(pNewOutEdge);
01174 }
01175 
01176 void Cfg::simplify() {
01177     if (VERBOSE)
01178         LOG << "simplifying...\n";
01179     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++) 
01180         (*it)->simplify();
01181 }
01182 
01183 // print this cfg, mainly for debugging
01184 void Cfg::print(std::ostream &out, bool html) {
01185     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++) 
01186         (*it)->print(out, html);
01187     out << std::endl;
01188 }
01189 
01190 void Cfg::dump() {
01191     print(std::cerr);
01192 }
01193 
01194 void Cfg::dumpImplicitMap() {
01195     std::map<Exp*, Statement*, lessExpStar>::iterator it;
01196     for (it = implicitMap.begin(); it != implicitMap.end(); ++it) {
01197         std::cerr << it->first << " -> " << it->second << "\n";
01198     }
01199 }
01200 
01201 void Cfg::printToLog() {
01202     std::ostringstream ost;
01203     print(ost);
01204     LOG << ost.str().c_str();
01205 }
01206 
01207 void Cfg::setTimeStamps() {
01208     // set DFS tag
01209     for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
01210         (*it)->traversed = DFS_TAG;
01211 
01212     // set the parenthesis for the nodes as well as setting the post-order ordering between the nodes
01213     int time = 1;
01214     Ordering.clear();
01215     entryBB->setLoopStamps(time, Ordering);
01216 
01217     // set the reverse parenthesis for the nodes
01218     time = 1;
01219     entryBB->setRevLoopStamps(time);
01220 
01221     PBB retNode = findRetNode();
01222     assert(retNode);
01223     revOrdering.clear();
01224     retNode->setRevOrder(revOrdering);
01225 }
01226 
01227 // Finds the common post dominator of the current immediate post dominator and its successor's immediate post dominator
01228 PBB Cfg::commonPDom(PBB curImmPDom, PBB succImmPDom) {
01229     if (!curImmPDom)
01230         return succImmPDom;
01231     if (!succImmPDom)
01232         return curImmPDom;
01233     if (curImmPDom->revOrd == succImmPDom->revOrd)
01234         return curImmPDom;  // ordering hasn't been done
01235 
01236     PBB oldCurImmPDom = curImmPDom;
01237     PBB oldSuccImmPDom = succImmPDom;
01238 
01239     int giveup = 0;
01240 #define GIVEUP 10000
01241     while (giveup < GIVEUP && curImmPDom && succImmPDom && (curImmPDom != succImmPDom)) {
01242         if (curImmPDom->revOrd > succImmPDom->revOrd)
01243             succImmPDom = succImmPDom->immPDom;
01244         else
01245             curImmPDom = curImmPDom->immPDom;
01246         giveup++;
01247     }
01248 
01249     if (giveup >= GIVEUP) {
01250         if (VERBOSE)
01251             LOG << "failed to find commonPDom for " << oldCurImmPDom->getLowAddr() << " and " <<
01252                 oldSuccImmPDom->getLowAddr() << "\n";
01253         return oldCurImmPDom;  // no change
01254     }
01255 
01256     return curImmPDom;
01257 }
01258 
01259 /* Finds the immediate post dominator of each node in the graph PROC->cfg.  Adapted version of the dominators algorithm
01260  * by Hecht and Ullman; finds immediate post dominators only.  Note: graph should be reducible
01261  */
01262 void Cfg::findImmedPDom() {
01263     PBB curNode, succNode;  // the current Node and its successor
01264 
01265     // traverse the nodes in order (i.e from the bottom up)
01266     int i;
01267     for (i = revOrdering.size() - 1; i >= 0; i--) {
01268         curNode = revOrdering[i];
01269         std::vector<PBB> &oEdges = curNode->getOutEdges();
01270         for (unsigned int j = 0; j < oEdges.size(); j++) {
01271             succNode = oEdges[j];
01272             if (succNode->revOrd > curNode->revOrd)
01273                 curNode->immPDom = commonPDom(curNode->immPDom, succNode);
01274         }
01275     }
01276 
01277     // make a second pass but consider the original CFG ordering this time
01278     unsigned u;
01279     for (u = 0; u < Ordering.size(); u++) {
01280         curNode = Ordering[u];
01281         std::vector<PBB> &oEdges = curNode->getOutEdges();
01282         if (oEdges.size() > 1)
01283             for (unsigned int j = 0; j < oEdges.size(); j++) {
01284                 succNode = oEdges[j];
01285             curNode->immPDom = commonPDom(curNode->immPDom, succNode);
01286         }
01287     }
01288 
01289     // one final pass to fix up nodes involved in a loop
01290     for (u = 0; u < Ordering.size(); u++) {
01291         curNode = Ordering[u];
01292         std::vector<PBB> &oEdges = curNode->getOutEdges();
01293         if (oEdges.size() > 1)
01294             for (unsigned int j = 0; j < oEdges.size(); j++) {
01295                 succNode = oEdges[j];
01296                 if (curNode->hasBackEdgeTo(succNode) && curNode->getOutEdges().size() > 1 &&
01297                         succNode->immPDom &&
01298                         succNode->immPDom->ord < curNode->immPDom->ord)
01299                     curNode->immPDom = commonPDom(succNode->immPDom, curNode->immPDom);
01300                 else
01301                     curNode->immPDom = commonPDom(curNode->immPDom, succNode);
01302             }
01303     }
01304 }
01305 
01306 // Structures all conditional headers (i.e. nodes with more than one outedge)
01307 void Cfg::structConds() {
01308     // Process the nodes in order
01309     for (unsigned int i = 0; i < Ordering.size(); i++) {
01310         PBB curNode = Ordering[i];
01311 
01312         // does the current node have more than one out edge?
01313         if (curNode->getOutEdges().size() > 1) {
01314             // if the current conditional header is a two way node and has a back edge, then it won't have a follow
01315             if (curNode->hasBackEdge() && curNode->getType() == TWOWAY) {
01316                 curNode->setStructType(Cond);
01317                 continue;
01318             }
01319         
01320             // set the follow of a node to be its immediate post dominator
01321             curNode->setCondFollow(curNode->immPDom);
01322 
01323             // set the structured type of this node
01324             curNode->setStructType(Cond);
01325 
01326             // if this is an nway header, then we have to tag each of the nodes within the body of the nway subgraph
01327             if (curNode->getCondType() == Case)
01328                 curNode->setCaseHead(curNode,curNode->getCondFollow());
01329         }
01330     }
01331 }
01332 
01333 // Pre: The loop induced by (head,latch) has already had all its member nodes tagged
01334 // Post: The type of loop has been deduced
01335 void Cfg::determineLoopType(PBB header, bool* &loopNodes) {
01336     assert(header->getLatchNode());
01337 
01338     // if the latch node is a two way node then this must be a post tested loop
01339     if (header->getLatchNode()->getType() == TWOWAY) {
01340         header->setLoopType(PostTested);
01341 
01342         // if the head of the loop is a two way node and the loop spans more than one block  then it must also be a
01343         // conditional header
01344         if (header->getType() == TWOWAY && header != header->getLatchNode())
01345             header->setStructType(LoopCond);
01346     }
01347 
01348     // otherwise it is either a pretested or endless loop
01349     else if (header->getType() == TWOWAY) {
01350         // if the header is a two way node then it must have a conditional follow (since it can't have any backedges
01351         // leading from it). If this follow is within the loop then this must be an endless loop
01352         if (header->getCondFollow() && loopNodes[header->getCondFollow()->ord]) {
01353             header->setLoopType(Endless);
01354 
01355             // retain the fact that this is also a conditional header
01356             header->setStructType(LoopCond);
01357         } else
01358             header->setLoopType(PreTested);
01359     }
01360 
01361     // both the header and latch node are one way nodes so this must be an endless loop
01362     else
01363         header->setLoopType(Endless);
01364 }
01365 
01366 // Pre: The loop headed by header has been induced and all it's member nodes have been tagged
01367 // Post: The follow of the loop has been determined.
01368 void Cfg::findLoopFollow(PBB header, bool* &loopNodes) {
01369     assert(header->getStructType() == Loop || header->getStructType() == LoopCond);
01370     loopType lType = header->getLoopType();
01371     PBB latch = header->getLatchNode();
01372 
01373     if (lType == PreTested) {
01374         // if the 'while' loop's true child is within the loop, then its false child is the loop follow
01375         if (loopNodes[header->getOutEdges()[0]->ord])
01376             header->setLoopFollow(header->getOutEdges()[1]);
01377         else
01378         header->setLoopFollow(header->getOutEdges()[0]);
01379     } else if (lType == PostTested) {
01380         // the follow of a post tested ('repeat') loop is the node on the end of the non-back edge from the latch node
01381         if (latch->getOutEdges()[0] == header)
01382             header->setLoopFollow(latch->getOutEdges()[1]);
01383         else
01384             header->setLoopFollow(latch->getOutEdges()[0]);
01385     } else { // endless loop
01386         PBB follow = NULL;
01387     
01388         // traverse the ordering array between the header and latch nodes.
01389         PBB latch = header->getLatchNode();
01390         for (int i = header->ord - 1; i > latch->ord; i--) {
01391             PBB &desc = Ordering[i];
01392             // the follow for an endless loop will have the following 
01393                 // properties:
01394                 //   i) it will have a parent that is a conditional header inside the loop whose follow is outside the
01395                 //      loop
01396                 //  ii) it will be outside the loop according to its loop stamp pair
01397                 // iii) have the highest ordering of all suitable follows (i.e. highest in the graph)
01398         
01399             if (desc->getStructType() == Cond && desc->getCondFollow() && 
01400                     desc->getLoopHead() == header) {
01401                 if (loopNodes[desc->getCondFollow()->ord]) {
01402                     // if the conditional's follow is in the same loop AND is lower in the loop, jump to this follow
01403                     if (desc->ord > desc->getCondFollow()->ord)
01404                         i = desc->getCondFollow()->ord;
01405                     // otherwise there is a backward jump somewhere to a node earlier in this loop. We don't need to any
01406                     //  nodes below this one as they will all have a conditional within the loop.  
01407                     else break;
01408                 } else {
01409                     // otherwise find the child (if any) of the conditional header that isn't inside the same loop 
01410                     PBB succ = desc->getOutEdges()[0];
01411                     if (loopNodes[succ->ord])
01412                         if (!loopNodes[desc->getOutEdges()[1]->ord])
01413                             succ = desc->getOutEdges()[1];
01414                         else
01415                             succ = NULL;
01416                     // if a potential follow was found, compare its ordering with the currently found follow
01417                     if (succ && (!follow || succ->ord > follow->ord))
01418                         follow = succ;
01419                 }
01420             }
01421         } 
01422         // if a follow was found, assign it to be the follow of the loop under 
01423             // investigation
01424         if (follow)
01425             header->setLoopFollow(follow);
01426     }
01427 }
01428 
01429 // Pre: header has been detected as a loop header and has the details of the 
01430 //      latching node
01431 // Post: the nodes within the loop have been tagged
01432 void Cfg::tagNodesInLoop(PBB header, bool* &loopNodes) {
01433     assert(header->getLatchNode());
01434 
01435     // traverse the ordering structure from the header to the latch node tagging the nodes determined to be within the
01436     // loop. These are nodes that satisfy the following:
01437     //  i) header.loopStamps encloses curNode.loopStamps and curNode.loopStamps encloses latch.loopStamps
01438     //  OR
01439     //  ii) latch.revLoopStamps encloses curNode.revLoopStamps and curNode.revLoopStamps encloses header.revLoopStamps
01440     //  OR
01441     //  iii) curNode is the latch node
01442 
01443     PBB latch = header->getLatchNode();
01444     for (int i = header->ord - 1; i >= latch->ord; i--)
01445         if (Ordering[i]->inLoop(header, latch)) {
01446             // update the membership map to reflect that this node is within the loop
01447             loopNodes[i] = true;
01448 
01449         Ordering[i]->setLoopHead(header);
01450     }
01451 }
01452 
01453 // Pre: The graph for curProc has been built.
01454 // Post: Each node is tagged with the header of the most nested loop of which it is a member (possibly none).
01455 // The header of each loop stores information on the latching node as well as the type of loop it heads.
01456 void Cfg::structLoops() {
01457     for (int i = Ordering.size() - 1; i >= 0; i--) {
01458         PBB curNode = Ordering[i];  // the current node under investigation
01459         PBB latch = NULL;           // the latching node of the loop
01460 
01461         // If the current node has at least one back edge into it, it is a loop header. If there are numerous back edges
01462         // into the header, determine which one comes form the proper latching node.
01463         // The proper latching node is defined to have the following properties:
01464         //   i) has a back edge to the current node
01465         //  ii) has the same case head as the current node
01466         // iii) has the same loop head as the current node
01467         //  iv) is not an nway node
01468         //   v) is not the latch node of an enclosing loop
01469         //  vi) has a lower ordering than all other suitable candiates
01470         // If no nodes meet the above criteria, then the current node is not a loop header
01471 
01472         std::vector<PBB> &iEdges = curNode->getInEdges();
01473         for (unsigned int j = 0; j < iEdges.size(); j++) {
01474             PBB pred = iEdges[j];
01475             if (pred->getCaseHead() == curNode->getCaseHead() &&  // ii)
01476                 pred->getLoopHead() == curNode->getLoopHead() &&  // iii)
01477                 (!latch || latch->ord > pred->ord) &&             // vi)
01478                 !(pred->getLoopHead() && 
01479                   pred->getLoopHead()->getLatchNode() == pred) && // v)
01480                 pred->hasBackEdgeTo(curNode))                     // i)
01481                 latch = pred;
01482         }
01483 
01484         // if a latching node was found for the current node then it is a loop header. 
01485         if (latch) {
01486             // define the map that maps each node to whether or not it is within the current loop
01487             bool* loopNodes = new bool[Ordering.size()];
01488             for (unsigned int j = 0; j < Ordering.size(); j++)
01489                 loopNodes[j] = false;
01490 
01491             curNode->setLatchNode(latch);
01492 
01493             // the latching node may already have been structured as a conditional header. If it is not also the loop
01494             // header (i.e. the loop is over more than one block) then reset it to be a sequential node otherwise it
01495             // will be correctly set as a loop header only later
01496             if (latch != curNode && latch->getStructType() == Cond)
01497                 latch->setStructType(Seq);
01498     
01499             // set the structured type of this node
01500             curNode->setStructType(Loop);
01501 
01502             // tag the members of this loop
01503             tagNodesInLoop(curNode, loopNodes);
01504 
01505             // calculate the type of this loop
01506             determineLoopType(curNode, loopNodes);
01507 
01508             // calculate the follow node of this loop
01509             findLoopFollow(curNode, loopNodes);
01510 
01511             // delete the space taken by the loopnodes map
01512             //delete[] loopNodes;
01513         }
01514     }
01515 }
01516 
01517 // This routine is called after all the other structuring has been done. It detects conditionals that are in fact the
01518 // head of a jump into/outof a loop or into a case body. Only forward jumps are considered as unstructured backward
01519 //jumps will always be generated nicely.
01520 void Cfg::checkConds() {
01521     for (unsigned int i = 0; i < Ordering.size(); i++) {
01522         PBB curNode = Ordering[i];
01523         std::vector<PBB> &oEdges = curNode->getOutEdges();
01524         
01525         // consider only conditional headers that have a follow and aren't case headers
01526         if ((curNode->getStructType() == Cond || 
01527              curNode->getStructType() == LoopCond) && curNode->getCondFollow() && curNode->getCondType() != Case) {
01528             // define convenient aliases for the relevant loop and case heads and the out edges
01529         PBB myLoopHead = (curNode->getStructType() == LoopCond ?  curNode : curNode->getLoopHead());
01530             PBB follLoopHead = curNode->getCondFollow()->getLoopHead();
01531 
01532             // analyse whether this is a jump into/outof a loop
01533             if (myLoopHead != follLoopHead) {
01534                 // we want to find the branch that the latch node is on for a jump out of a loop
01535                 if (myLoopHead) {
01536                     PBB myLoopLatch = myLoopHead->getLatchNode();
01537 
01538                     // does the then branch goto the loop latch?
01539                     if (oEdges[BTHEN]->isAncestorOf(myLoopLatch) || oEdges[BTHEN] == myLoopLatch) {
01540                         curNode->setUnstructType(JumpInOutLoop);
01541                         curNode->setCondType(IfElse);
01542                     }
01543             // does the else branch goto the loop latch?
01544             else if (oEdges[BELSE]->isAncestorOf(myLoopLatch) || oEdges[BELSE] == myLoopLatch) {
01545                         curNode->setUnstructType(JumpInOutLoop);
01546                         curNode->setCondType(IfThen);
01547                     }
01548                 }
01549 
01550                 if (curNode->getUnstructType() == Structured && follLoopHead) { 
01551                     // find the branch that the loop head is on for a jump into a loop body. If a branch has already
01552                     // been found, then it will match this one anyway
01553 
01554                     // does the else branch goto the loop head?
01555                     if (oEdges[BTHEN]->isAncestorOf(follLoopHead) || oEdges[BTHEN] == follLoopHead) {
01556                         curNode->setUnstructType(JumpInOutLoop);
01557                         curNode->setCondType(IfElse);
01558                     }
01559 
01560                     // does the else branch goto the loop head?
01561                     else if (oEdges[BELSE]->isAncestorOf(follLoopHead) || oEdges[BELSE] == follLoopHead) {
01562                         curNode->setUnstructType(JumpInOutLoop);
01563                         curNode->setCondType(IfThen);
01564                     }
01565                 }
01566             }
01567 
01568             // this is a jump into a case body if either of its children don't have the same same case header as itself
01569             if (curNode->getUnstructType() == Structured &&
01570                     (curNode->getCaseHead() != curNode->getOutEdges()[BTHEN]->getCaseHead() ||
01571                     curNode->getCaseHead() != curNode->getOutEdges()[BELSE]->getCaseHead())) {
01572                 PBB myCaseHead = curNode->getCaseHead();
01573                 PBB thenCaseHead = curNode->getOutEdges()[BTHEN]->getCaseHead();
01574                 PBB elseCaseHead = curNode->getOutEdges()[BELSE]->getCaseHead();
01575 
01576                 if (thenCaseHead == myCaseHead &&
01577                         (!myCaseHead || elseCaseHead != myCaseHead->getCondFollow())) {
01578                     curNode->setUnstructType(JumpIntoCase);
01579                     curNode->setCondType(IfElse);
01580                 } else if (elseCaseHead == myCaseHead && 
01581                         (!myCaseHead || thenCaseHead != myCaseHead->getCondFollow())) {
01582                     curNode->setUnstructType(JumpIntoCase);
01583                     curNode->setCondType(IfThen);
01584                 }
01585             }   
01586         }
01587 
01588         // for 2 way conditional headers that don't have a follow (i.e. are the source of a back edge) and haven't been
01589         // structured as latching nodes, set their follow to be the non-back edge child.
01590         if (curNode->getStructType() == Cond &&
01591               !curNode->getCondFollow() &&
01592               curNode->getCondType() != Case &&
01593               curNode->getUnstructType() == Structured) {
01594             // latching nodes will already have been reset to Seq structured type
01595             if (curNode->hasBackEdge()) {
01596                 if (curNode->hasBackEdgeTo(curNode->getOutEdges()[BTHEN])) {
01597                     curNode->setCondType(IfThen);
01598                     curNode->setCondFollow(curNode->getOutEdges()[BELSE]);
01599                 } else {
01600                     curNode->setCondType(IfElse);
01601                     curNode->setCondFollow(curNode->getOutEdges()[BTHEN]);
01602                 }
01603             }
01604         }
01605     }
01606 }
01607 
01608 void Cfg::structure() {
01609     if (structured) {
01610         unTraverse();
01611         return;
01612     }
01613     if (findRetNode() == NULL)
01614         return;
01615     setTimeStamps();
01616     findImmedPDom();
01617     if (!Boomerang::get()->noDecompile) {
01618         structConds();
01619         structLoops();
01620         checkConds();
01621     }
01622     structured = true;
01623 }
01624 
01625 void Cfg::addJunctionStatements()
01626 {
01627     std::list<PBB>::iterator it;
01628     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
01629         PBB pbb = *it;
01630         if (pbb->getNumInEdges() > 1 && (pbb->getFirstStmt() == NULL || !pbb->getFirstStmt()->isJunction())) {
01631             assert(pbb->getRTLs());
01632             JunctionStatement *j = new JunctionStatement();
01633             j->setBB(pbb);
01634             pbb->getRTLs()->front()->prependStmt(j);
01635         }
01636     }
01637 }
01638 
01639 void Cfg::removeJunctionStatements()
01640 {
01641     std::list<PBB>::iterator it;
01642     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
01643         PBB pbb = *it;
01644         if (pbb->getFirstStmt() && pbb->getFirstStmt()->isJunction()) {
01645             assert(pbb->getRTLs());
01646             pbb->getRTLs()->front()->deleteStmt(0);
01647         }
01648     }
01649 }
01650 void Cfg::removeUnneededLabels(HLLCode *hll) {
01651     hll->RemoveUnusedLabels(Ordering.size());
01652 }
01653 
01654 #define BBINDEX 0               // Non zero to print <index>: before <statement number>
01655 #define BACK_EDGES 0            // Non zero to generate green back edges
01656 void Cfg::generateDotFile(std::ofstream& of) {
01657     ADDRESS aret = NO_ADDRESS;
01658     // The nodes
01659     std::list<PBB>::iterator it;
01660     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
01661         of << "    " << "bb" << std::hex << (*it)->getLowAddr() << " [" << "label=\"";
01662         char* p = (*it)->getStmtNumber();
01663 #if BBINDEX
01664         of << std::dec << indices[*it];
01665         if (p[0] != 'b')
01666             // If starts with 'b', no statements (something like bb8101c3c).
01667             of << ":";
01668 #endif
01669         of << p << " ";
01670         switch((*it)->getType()) {
01671             case ONEWAY: of << "oneway"; break;
01672             case TWOWAY: 
01673                 if ((*it)->getCond()) {
01674                     of << "\\n";
01675                     (*it)->getCond()->print(of);
01676                     of << "\" shape=diamond];\n";
01677                     continue;
01678                 }
01679                 else
01680                     of << "twoway";
01681                 break;
01682             case NWAY: {
01683                 of << "nway";
01684                 Exp* de = (*it)->getDest();
01685                 if (de) {
01686                     of << "\\n";
01687                     of << de;
01688                 }
01689                 of << "\" shape=trapezium];\n";
01690                 continue;
01691             }
01692             case CALL: {
01693                 of << "call";
01694                 Proc* dest = (*it)->getDestProc();
01695                 if (dest) of << "\\n" << dest->getName();
01696                 break;
01697             }
01698             case RET: {
01699                 of << "ret\" shape=triangle];\n";
01700                 // Remember the (unbique) return BB's address
01701                 aret = (*it)->getLowAddr();
01702                 continue;
01703             }
01704             case FALL: of << "fall"; break;
01705             case COMPJUMP: of << "compjump"; break;
01706             case COMPCALL: of << "compcall"; break;
01707             case INVALID: of << "invalid"; break;
01708         }
01709         of << "\"];\n";
01710     }
01711 
01712     // Force the one return node to be at the bottom (max rank). Otherwise, with all its in-edges, it will end up in the
01713     // middle
01714     if (aret) 
01715         of << "{rank=max; bb" << std::hex << aret << "}\n";
01716 
01717     // Close the subgraph
01718     of << "}\n";
01719 
01720     // Now the edges
01721     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
01722         std::vector<PBB>& outEdges = (*it)->getOutEdges();
01723         for (unsigned int j = 0; j < outEdges.size(); j++) {
01724             of << "    " << "bb" << std::hex << (*it)->getLowAddr() << " -> ";
01725             of << "bb" << std::hex << outEdges[j]->getLowAddr();
01726             if ((*it)->getType() == TWOWAY) {
01727                 if (j == 0)
01728                     of << " [label=\"true\"]";
01729                 else
01730                     of << " [label=\"false\"]";
01731             }
01732             of << " [color = \"blue\"];\n";
01733         }
01734     }
01735 #if BACK_EDGES
01736     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
01737         std::vector<PBB>& inEdges = (*it)->getInEdges();
01738         for (unsigned int j = 0; j < inEdges.size(); j++) {
01739             of << "    " << "bb" << std::hex << (*it)->getLowAddr() << " -> ";
01740             of << "bb" << std::hex << inEdges[j]->getLowAddr();
01741             of << " [color = \"green\"];\n";
01742         }
01743     }
01744 #endif
01745 }
01746 
01747 
01748 
01749 ////////////////////////////////////
01750 //          Liveness             //
01751 ////////////////////////////////////
01752 
01753 void updateWorkListRev(PBB currBB, std::list<PBB>&workList, std::set<PBB>& workSet) {
01754     // Insert inedges of currBB into the worklist, unless already there
01755     std::vector<PBB>& ins = currBB->getInEdges();
01756     int n = ins.size();
01757     for (int i=0; i < n; i++) {
01758         PBB currIn = ins[i];
01759         if (workSet.find(currIn) == workSet.end()) {
01760             workList.push_front(currIn);
01761             workSet.insert(currIn);
01762         }
01763     }
01764 }
01765 
01766 static int progress = 0;
01767 void Cfg::findInterferences(ConnectionGraph& cg) {
01768     if (m_listBB.size() == 0) return;
01769 
01770     std::list<PBB> workList;            // List of BBs still to be processed
01771     // Set of the same; used for quick membership test
01772     std::set<PBB> workSet; 
01773     appendBBs(workList, workSet);
01774 
01775     bool change;
01776     int count = 0;
01777     while (workList.size() && count < 100000) {
01778         count++;  // prevent infinite loop
01779         if (++progress > 20) {
01780             std::cout << "i" << std::flush;
01781             progress = 0;
01782         }
01783         PBB currBB = workList.back();
01784         workList.erase(--workList.end());
01785         workSet.erase(currBB);
01786         // Calculate live locations and interferences
01787         change = currBB->calcLiveness(cg, myProc);
01788         if (change) {
01789             if (DEBUG_LIVENESS) {
01790                 LOG << "Revisiting BB ending with stmt ";
01791                 Statement* last = NULL;
01792                 if (currBB->m_pRtls->size()) {
01793                     RTL* lastRtl = currBB->m_pRtls->back();
01794                     std::list<Statement*>& lst = lastRtl->getList();
01795                     if (lst.size()) last = lst.back();
01796                 }
01797                 if (last)
01798                     LOG << last->getNumber();
01799                 else
01800                     LOG << "<none>";
01801                 LOG << " due to change\n";
01802             }
01803             updateWorkListRev(currBB, workList, workSet);
01804         }
01805     }
01806 }
01807 
01808 void Cfg::appendBBs(std::list<PBB>& worklist, std::set<PBB>& workset) {
01809     // Append my list of BBs to the worklist
01810     worklist.insert(worklist.end(), m_listBB.begin(), m_listBB.end());
01811     // Do the same for the workset
01812     std::list<PBB>::iterator it;
01813     for (it = m_listBB.begin(); it != m_listBB.end(); it++)
01814         workset.insert(*it);
01815 }
01816 
01817 void dumpBB(PBB bb) {
01818     std::cerr << "For BB at " << std::hex << bb << ":\nIn edges: ";
01819     int i, n;
01820     std::vector<PBB> ins = bb->getInEdges();
01821     std::vector<PBB> outs = bb->getOutEdges();
01822     n = ins.size();
01823     for (i=0; i < n; i++)
01824       std::cerr << ins[i] << " ";
01825     std::cerr << "\nOut Edges: ";
01826     n = outs.size();
01827     for (i=0; i < n; i++)
01828       std::cerr << outs[i] << " ";
01829     std::cerr << "\n";
01830 }
01831 
01832 /*  pBB-> +----+    +----+ <-pBB
01833  * Change | A  | to | A  | where A and B could be empty. S is the string
01834  *        |    |    |    | instruction (with will branch to itself and to the
01835  *        +----+    +----+ start of the next instruction, i.e. the start of B,
01836  *        | S  |      |    if B is non empty).
01837  *        +----+      V
01838  *        | B  |    +----+ <-skipBB
01839  *        |    |    +-b1-+            b1 is just a branch for the skip part
01840  *        +----+      |
01841  *                    V
01842  *                  +----+ <-rptBB
01843  *                  | S' |            S' = S less the skip and repeat parts
01844  *                  +-b2-+            b2 is a branch for the repeat part
01845  *                    |
01846  *                    V
01847  *                  +----+ <-newBb
01848  *                  | B  |
01849  *                  |    |
01850  *                  +----+
01851  * S is an RTL with 6 statements representing one string instruction (so this function is highly specialised for the job
01852  * of replacing the %SKIP and %RPT parts of string instructions)
01853  */
01854 
01855 PBB Cfg::splitForBranch(PBB pBB, RTL* rtl, BranchStatement* br1, BranchStatement* br2, BB_IT& it) {
01856 
01857 #if 0
01858     std::cerr << "splitForBranch before:\n";
01859     std::cerr << pBB->prints() << "\n";
01860 #endif
01861 
01862     unsigned i, j;
01863     std::list<RTL*>::iterator ri;
01864     // First find which RTL has the split address
01865     for (ri = pBB->m_pRtls->begin(); ri != pBB->m_pRtls->end(); ri++) {
01866         if ((*ri) == rtl)
01867             break;
01868     }
01869     assert(ri != pBB->m_pRtls->end());
01870 
01871     bool haveA = (ri != pBB->m_pRtls->begin());
01872 
01873     ADDRESS addr = rtl->getAddress();
01874  
01875     // Make a BB for the br1 instruction
01876     std::list<RTL*>* pRtls = new std::list<RTL*>;
01877     std::list<Statement*>* ls = new std::list<Statement*>;
01878     ls->push_back(br1);
01879     // Don't give this "instruction" the same address as the rest of the string instruction (causes problems when
01880     // creating the rptBB). Or if there is no A, temporarily use 0
01881     ADDRESS a = (haveA) ? addr : 0;
01882     RTL* skipRtl = new RTL(a, ls);
01883     pRtls->push_back(skipRtl);
01884     PBB skipBB = newBB(pRtls, TWOWAY, 2);
01885     rtl->updateAddress(addr+1);
01886     if (!haveA) {
01887         skipRtl->updateAddress(addr);
01888         // Address addr now refers to the splitBB
01889         m_mapBB[addr] = skipBB;
01890         // Fix all predecessors of pBB to point to splitBB instead
01891         for (unsigned i=0; i < pBB->m_InEdges.size(); i++) {
01892             PBB pred = pBB->m_InEdges[i];
01893             for (unsigned j=0; j < pred->m_OutEdges.size(); j++) {
01894                 PBB succ = pred->m_OutEdges[j];
01895                 if (succ == pBB) {
01896                     pred->m_OutEdges[j] = skipBB;
01897                     skipBB->addInEdge(pred);
01898                     break;
01899                 }
01900             }
01901         }
01902     }
01903 
01904     // Remove the SKIP from the start of the string instruction RTL
01905     std::list<Statement*>& li = rtl->getList();
01906     assert(li.size() >= 4);
01907     li.erase(li.begin());
01908     // Replace the last statement with br2
01909     std::list<Statement*>::iterator ll = --li.end();
01910     li.erase(ll);
01911     li.push_back(br2);
01912     
01913     // Move the remainder of the string RTL into a new BB
01914     pRtls = new std::list<RTL*>;
01915     pRtls->push_back(*ri);
01916     PBB rptBB = newBB(pRtls, TWOWAY, 2);
01917     ri = pBB->m_pRtls->erase(ri);
01918 
01919     // Move the remaining RTLs (if any) to a new list of RTLs
01920     PBB newBb;
01921     unsigned oldOutEdges = 0;
01922     bool haveB = true;
01923     if (ri != pBB->m_pRtls->end()) {
01924         pRtls = new std::list<RTL*>;
01925         while (ri != pBB->m_pRtls->end()) {
01926             pRtls->push_back(*ri);
01927             ri = pBB->m_pRtls->erase(ri);
01928         }
01929         oldOutEdges = pBB->getNumOutEdges();
01930         newBb = newBB(pRtls, pBB->getType(), oldOutEdges);
01931         // Transfer the out edges from A to B (pBB to newBb)
01932         for (i=0; i < oldOutEdges; i++)
01933             // Don't use addOutEdge, since it will also add in-edges back to pBB
01934             newBb->m_OutEdges.push_back(pBB->getOutEdge(i));
01935             //addOutEdge(newBb, pBB->getOutEdge(i));
01936     } else {
01937         // The "B" part of the above diagram is empty.
01938         // Don't create a new BB; just point newBB to the successor of pBB
01939         haveB = false;
01940         newBb = pBB->getOutEdge(0);
01941     }
01942 
01943     // Change pBB to a FALL bb
01944     pBB->updateType(FALL, 1);
01945     // Set the first out-edge to be skipBB
01946     pBB->m_OutEdges.erase(pBB->m_OutEdges.begin(), pBB->m_OutEdges.end());
01947     addOutEdge(pBB, skipBB);
01948     // Set the out edges for skipBB. First is the taken (true) leg.
01949     addOutEdge(skipBB, newBb);
01950     addOutEdge(skipBB, rptBB);
01951     // Set the out edges for the rptBB
01952     addOutEdge(rptBB, skipBB);
01953     addOutEdge(rptBB, newBb);
01954 
01955     // For each out edge of newBb, change any in-edges from pBB to instead come from newBb
01956     if (haveB) {
01957         for (i=0; i < oldOutEdges; i++) {
01958             PBB succ = newBb->m_OutEdges[i];
01959             for (j=0; j < succ->m_InEdges.size(); j++) {
01960                 PBB pred = succ->m_InEdges[j];
01961                 if (pred == pBB) {
01962                     succ->m_InEdges[j] = newBb;
01963                     break;
01964                 }
01965             }
01966         }
01967     } else {
01968         // There is no "B" bb (newBb is just the successor of pBB) Fix that one out-edge to point to rptBB
01969         for (j=0; j < newBb->m_InEdges.size(); j++) {
01970             PBB pred = newBb->m_InEdges[j];
01971             if (pred == pBB) {
01972                 newBb->m_InEdges[j] = rptBB;
01973                 break;
01974             }
01975         }
01976     }
01977     if (!haveA) {
01978         // There is no A any more. All A's in-edges have been copied to the skipBB. It is possible that the original BB
01979         // had a self edge (branch to start of self). If so, this edge, now in to skipBB, must now come from newBb (if
01980         // there is a B) or rptBB if none.  Both of these will already exist, so delete it.
01981         for (j=0; j < skipBB->m_InEdges.size(); j++) {
01982             PBB pred = skipBB->m_InEdges[j];
01983             if (pred == pBB) {
01984                 skipBB->deleteInEdge(pBB);
01985                 break;
01986             }
01987         }
01988         
01989 #if DEBUG_SPLIT_FOR_BRANCH
01990         std::cerr << "About to delete pBB: " << std::hex << pBB << "\n";
01991         dumpBB(pBB);
01992         dumpBB(skipBB);
01993         dumpBB(rptBB);
01994         dumpBB(newBb);
01995 #endif
01996 
01997         // Must delete pBB. Note that this effectively "increments" iterator it
01998         it = m_listBB.erase(it);
01999         pBB = NULL;
02000     } else
02001         it++;
02002 
02003 #if 0
02004     std::cerr << "splitForBranch after:\n";
02005     if (pBB) std::cerr << pBB->prints(); else std::cerr << "<null>\n";
02006     std::cerr << skipBB->prints();
02007     std::cerr << rptBB->prints();
02008     std::cerr << newBb->prints() << "\n";
02009 #endif
02010     return newBb;
02011 }
02012 
02013 // Check for indirect jumps and calls in all my BBs; decode any new code
02014 bool Cfg::decodeIndirectJmp(UserProc* proc) {
02015     std::list<PBB>::iterator it;
02016     bool res = false;
02017     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
02018         res |= (*it)->decodeIndirectJmp(proc);
02019     }
02020     return res;
02021 }
02022 
02023 void Cfg::undoComputedBB(Statement* stmt) {
02024     std::list<PBB>::iterator it;
02025     for (it = m_listBB.begin(); it != m_listBB.end(); it++) {
02026         if ((*it)->undoComputedBB(stmt))
02027             break;
02028     }
02029 }
02030 
02031 Statement* Cfg::findImplicitAssign(Exp* x) {
02032     Statement* def;
02033     std::map<Exp*, Statement*, lessExpStar>::iterator it = implicitMap.find(x);
02034     if (it == implicitMap.end()) {
02035         // A use with no explicit definition. Create a new implicit assignment
02036         x = x->clone();             // In case the original gets changed
02037         def = new ImplicitAssign(x);
02038         entryBB->prependStmt(def, myProc);
02039         // Remember it for later so we don't insert more than one implicit assignment for any one location
02040         // We don't clone the copy in the map. So if the location is a m[...], the same type information is available in
02041         // the definition as at all uses
02042         implicitMap[x] = def;
02043     } else {
02044         // Use an existing implicit assignment
02045         def = it->second;
02046     }
02047     return def;
02048 }
02049 
02050 Statement* Cfg::findTheImplicitAssign(Exp* x) {
02051     // As per the above, but don't create an implicit if it doesn't already exist
02052     std::map<Exp*, Statement*, lessExpStar>::iterator it = implicitMap.find(x);
02053     if (it == implicitMap.end())
02054         return NULL;
02055     return it->second;
02056 }
02057 
02058 Statement* Cfg::findImplicitParamAssign(Parameter* param) {
02059     // As per the above, but for parameters (signatures don't get updated with opParams)
02060     std::map<Exp*, Statement*, lessExpStar>::iterator it = implicitMap.find(param->getExp());
02061     if (it == implicitMap.end()) {
02062         Exp* eParam = Location::param(param->getName());
02063         it = implicitMap.find(eParam);
02064     }
02065     if (it == implicitMap.end())
02066         return NULL;
02067     return it->second;
02068 }
02069 
02070 void Cfg::removeImplicitAssign(Exp* x) {
02071     std::map<Exp*, Statement*, lessExpStar>::iterator it = implicitMap.find(x);
02072     assert(it != implicitMap.end());
02073     Statement* ia = it->second;
02074     implicitMap.erase(it);              // Delete the mapping
02075     myProc->removeStatement(ia);        // Remove the actual implicit assignment statement as well
02076     
02077 }
02078 

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