00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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>
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"
00044 #include "prog.h"
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
00056
00057
00058
00059
00060
00061
00062
00063
00064 Cfg::Cfg()
00065 : entryBB(NULL), exitBB(NULL), m_bWellFormed(false), structured(false), lastLabel(0), bImplicitsDone(false)
00066 {}
00067
00068
00069
00070
00071
00072
00073
00074 Cfg::~Cfg() {
00075
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
00086
00087
00088
00089
00090 void Cfg::setProc(UserProc* proc)
00091 {
00092 myProc = proc;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 void Cfg::clear() {
00102
00103
00104
00105
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
00118
00119
00120
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
00132
00133
00134
00135
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
00147 }
00148
00149 void Cfg::setExitBB(PBB bb) {
00150 exitBB = bb;
00151 }
00152
00153
00154
00155
00156
00157
00158
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
00175
00176
00177
00178
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
00186
00187 ADDRESS addr = pRtls->front()->getAddress();
00188
00189
00190
00191
00192
00193
00194
00195 if ((addr == 0) && (pRtls->size() > 1)) {
00196 std::list<RTL*>::iterator next = pRtls->begin();
00197 addr = (*++next)->getAddress();
00198 }
00199
00200
00201
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
00208
00209
00210 if (!pBB->m_bIncomplete) {
00211
00212 delete_lrtls(pRtls);
00213 if (VERBOSE)
00214 LOG << "throwing BBAlreadyExistsError\n";
00215 throw BBAlreadyExistsError(pBB);
00216 }
00217 else {
00218
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
00229 pBB = new BasicBlock(pRtls, bbType, iNumOutEdges);
00230 m_listBB.push_back(pBB);
00231
00232
00233
00234 if (addr != 0)
00235 {
00236 m_mapBB[addr] = pBB;
00237 mi = m_mapBB.find(addr);
00238 }
00239 }
00240
00241 if (addr != 0 && (mi != m_mapBB.end()))
00242 {
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
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
00263
00264 splitBB(pBB, uNext, pNextBB);
00265
00266
00267 if (bIncomplete) {
00268 return pNextBB;
00269 }
00270
00271 throw BBAlreadyExistsError(pNextBB);
00272 }
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 }
00284 assert(pBB);
00285 return pBB;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 PBB Cfg::newIncompleteBB(ADDRESS addr)
00296 {
00297
00298 PBB pBB = new BasicBlock();
00299
00300 m_listBB.push_back(pBB);
00301 m_mapBB[addr] = pBB;
00302 return pBB;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 void Cfg::addOutEdge(PBB pBB, PBB pDestBB, bool bSetLabel )
00317 {
00318
00319 pBB->m_OutEdges.push_back(pDestBB);
00320
00321
00322 pDestBB->m_InEdges.push_back(pBB);
00323 pDestBB->m_iNumInEdges++;
00324 if (bSetLabel) setLabel(pDestBB);
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 void Cfg::addOutEdge(PBB pBB, ADDRESS addr, bool bSetLabel )
00339 {
00340
00341 MAPBB::iterator it = m_mapBB.find(addr);
00342 PBB pDestBB;
00343 if (it != m_mapBB.end() && (*it).second) {
00344
00345 pDestBB = (*it).second;
00346 }
00347 else {
00348
00349 pDestBB = newIncompleteBB(addr);
00350 }
00351 addOutEdge(pBB, pDestBB, bSetLabel);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
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
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 PBB Cfg::splitBB (PBB pBB, ADDRESS uNativeAddr, PBB pNewBB , bool bDelRtls ) {
00384 std::list<RTL*>::iterator ri;
00385
00386
00387
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
00399 if (pNewBB == NULL) {
00400 pNewBB = new BasicBlock(*pBB);
00401
00402 pNewBB->m_iNumInEdges = 0;
00403 pNewBB->m_InEdges.erase(pNewBB->m_InEdges.begin(),
00404 pNewBB->m_InEdges.end());
00405
00406
00407
00408 pNewBB->setRTLs(new std::list<RTL*>(ri, pBB->m_pRtls->end()));
00409
00410 m_listBB.push_back(pNewBB);
00411
00412 m_mapBB[uNativeAddr] = pNewBB;
00413
00414 pNewBB->m_iLabelNum = ++lastLabel;
00415 }
00416 else if (pNewBB->m_bIncomplete)
00417 {
00418
00419
00420 std::vector<PBB> ins(pNewBB->m_InEdges);
00421 int label = pNewBB->m_iLabelNum;
00422
00423 *pNewBB = *pBB;
00424
00425 pNewBB->m_InEdges = ins;
00426 pNewBB->m_iNumInEdges = ins.size();
00427
00428 pNewBB->m_iLabelNum = label;
00429
00430
00431 pNewBB->setRTLs(new std::list<RTL*>(ri, pBB->m_pRtls->end()));
00432 }
00433
00434
00435
00436
00437 pBB->m_nodeType = FALL;
00438
00439
00440 for (unsigned j=0; j < pBB->m_OutEdges.size(); j++) {
00441 PBB pDescendant = pBB->m_OutEdges[j];
00442
00443 unsigned k;
00444 for (k=0; k < pDescendant->m_InEdges.size(); k++) {
00445 if (pDescendant->m_InEdges[k] == pBB) {
00446
00447 pDescendant->m_InEdges[k] = pNewBB;
00448 break;
00449 }
00450 }
00451
00452 assert (k < pDescendant->m_InEdges.size());
00453 }
00454
00455 if (bDelRtls) {
00456
00457 erase_lrtls(pBB->m_pRtls, ri, pBB->m_pRtls->end());
00458 }
00459 else {
00460
00461 pBB->m_pRtls->erase(ri, pBB->m_pRtls->end());
00462 }
00463
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
00472
00473
00474
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
00484
00485
00486
00487
00488 PBB Cfg::getNextBB(BB_IT& it)
00489 {
00490 if (++it == m_listBB.end()) return 0;
00491 return *it;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 bool Cfg::label ( ADDRESS uNativeAddr, PBB& pCurBB )
00513 {
00514 MAPBB::iterator mi, newi;
00515
00516
00517 mi = m_mapBB.find (uNativeAddr);
00518
00519 if (mi == m_mapBB.end())
00520 {
00521
00522 m_mapBB[uNativeAddr] = (PBB) 0;
00523
00524
00525
00526
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
00542 PBB pNewBB = splitBB (pPrevBB, uNativeAddr);
00543 if (pCurBB == pPrevBB) {
00544
00545
00546
00547 pCurBB = pNewBB;
00548 }
00549 return true;
00550 }
00551 else {
00552
00553
00554
00555 return false;
00556 }
00557 }
00558 else
00559 {
00560 if ((*mi).second && !(*mi).second->m_bIncomplete) {
00561
00562 return true;
00563 }
00564
00565
00566
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
00580
00581 splitBB (pPrevBB, uNativeAddr, pBB);
00582 return true;
00583 }
00584
00585 return false;
00586 }
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596 bool Cfg::isIncomplete(ADDRESS uAddr)
00597 {
00598 MAPBB::iterator mi = m_mapBB.find(uAddr);
00599 if (mi == m_mapBB.end())
00600
00601 return false;
00602
00603 PBB pBB = (*mi).second;
00604 return pBB->m_bIncomplete;
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 void Cfg::sortByAddress()
00616 {
00617 m_listBB.sort(BasicBlock::lessAddress);
00618 }
00619
00620
00621
00622
00623
00624
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
00642
00643
00644
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
00662
00663
00664
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
00676
00677
00678
00679
00680
00681 bool Cfg::wellFormCfg()
00682 {
00683 m_bWellFormed = true;
00684 for (BB_IT it = m_listBB.begin(); it != m_listBB.end(); it++) {
00685
00686
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
00700 assert((int)(*it)->m_OutEdges.size() == (*it)->m_iNumOutEdges);
00701 for (int i=0; i < (*it)->m_iNumOutEdges; i++) {
00702
00703
00704 {
00705
00706 PBB pBB = (*it)->m_OutEdges[i];
00707
00708
00709 if (pBB == NULL) {
00710 m_bWellFormed = false;
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
00717
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;
00726 }
00727 }
00728 }
00729 }
00730
00731
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;
00742 }
00743 }
00744 }
00745 }
00746 return m_bWellFormed;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755 bool Cfg::mergeBBs( PBB pb1, PBB pb2)
00756 {
00757
00758
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
00766
00767 completeMerge(pb1, pb2, true);
00768 return true;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778 void Cfg::completeMerge(PBB pb1, PBB pb2, bool bDelete = false)
00779 {
00780
00781
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
00793 pb2->m_InEdges = pb1->m_InEdges;
00794 pb2->m_iNumInEdges = pb1->m_iNumInEdges;
00795
00796 if (bDelete) {
00797
00798
00799
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
00813
00814
00815
00816
00817
00818 bool Cfg::joinBB(PBB pb1, PBB pb2)
00819 {
00820
00821 std::vector<PBB>& v = pb1->getOutEdges();
00822 if (v.size() != 2 || v[1] != pb2)
00823 return false;
00824
00825
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);
00831
00832
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
00846
00847
00848
00849
00850
00851 bool Cfg::compressCfg()
00852 {
00853
00854 if (!m_bWellFormed) return false;
00855
00856
00857
00858
00859
00860
00861
00862
00863
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);
00869 PBB bb = (*it);
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
00875
00876
00877
00878
00879 *it1=pSucc->m_OutEdges.front();
00880
00881
00882 bb->m_bJumpReqd = true;
00883 setLabel(*it1);
00884
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;
00890 }
00891
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
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
00906 delete pSucc;
00907 break;
00908 }
00909 }
00910 }
00911 }
00912 }
00913 }
00914 return true;
00915 }
00916
00917
00918
00919
00920
00921
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
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 bool Cfg::establishDFTOrder()
00944 {
00945
00946 if (!m_bWellFormed) return false;
00947
00948
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
00981
00982
00983
00984
00985
00986 bool Cfg::establishRevDFTOrder()
00987 {
00988
00989 if (!m_bWellFormed) return false;
00990
00991
00992
00993
00994
00995
00996 PBB retNode = findRetNode();
00997
00998 if (retNode == NULL) return false;
00999
01000
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
01014
01015
01016
01017
01018 bool Cfg::isWellFormed()
01019 {
01020 return m_bWellFormed;
01021 }
01022
01023
01024
01025
01026
01027
01028
01029 bool Cfg::isOrphan(ADDRESS uAddr)
01030 {
01031 MAPBB::iterator mi = m_mapBB.find(uAddr);
01032 if (mi == m_mapBB.end())
01033
01034 return false;
01035
01036 PBB pBB = (*mi).second;
01037
01038 if (pBB->m_bIncomplete) return false;
01039 return pBB->m_pRtls->front()->getAddress() == 0;
01040 }
01041
01042
01043
01044
01045
01046
01047
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
01061
01062
01063
01064
01065 void Cfg::addCall(CallStatement* call)
01066 {
01067 callSites.insert(call);
01068 }
01069
01070
01071
01072
01073
01074
01075
01076 std::set<CallStatement*>& Cfg::getCalls()
01077 {
01078 return callSites;
01079 }
01080
01081
01082
01083
01084
01085
01086
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
01113
01114
01115
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
01127
01128
01129
01130
01131
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
01145
01146
01147
01148
01149
01150 void Cfg::setLabel(PBB pBB) {
01151 if (pBB->m_iLabelNum == 0)
01152 pBB->m_iLabelNum = ++lastLabel;
01153 }
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 void Cfg::addNewOutEdge(PBB pFromBB, PBB pNewOutEdge)
01167 {
01168 pFromBB->m_OutEdges.push_back(pNewOutEdge);
01169 pFromBB->m_iNumOutEdges++;
01170
01171 pFromBB->m_bJumpReqd = true;
01172
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
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
01209 for (std::list<PBB>::iterator it = m_listBB.begin(); it != m_listBB.end(); it++)
01210 (*it)->traversed = DFS_TAG;
01211
01212
01213 int time = 1;
01214 Ordering.clear();
01215 entryBB->setLoopStamps(time, Ordering);
01216
01217
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
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;
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;
01254 }
01255
01256 return curImmPDom;
01257 }
01258
01259
01260
01261
01262 void Cfg::findImmedPDom() {
01263 PBB curNode, succNode;
01264
01265
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
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
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
01307 void Cfg::structConds() {
01308
01309 for (unsigned int i = 0; i < Ordering.size(); i++) {
01310 PBB curNode = Ordering[i];
01311
01312
01313 if (curNode->getOutEdges().size() > 1) {
01314
01315 if (curNode->hasBackEdge() && curNode->getType() == TWOWAY) {
01316 curNode->setStructType(Cond);
01317 continue;
01318 }
01319
01320
01321 curNode->setCondFollow(curNode->immPDom);
01322
01323
01324 curNode->setStructType(Cond);
01325
01326
01327 if (curNode->getCondType() == Case)
01328 curNode->setCaseHead(curNode,curNode->getCondFollow());
01329 }
01330 }
01331 }
01332
01333
01334
01335 void Cfg::determineLoopType(PBB header, bool* &loopNodes) {
01336 assert(header->getLatchNode());
01337
01338
01339 if (header->getLatchNode()->getType() == TWOWAY) {
01340 header->setLoopType(PostTested);
01341
01342
01343
01344 if (header->getType() == TWOWAY && header != header->getLatchNode())
01345 header->setStructType(LoopCond);
01346 }
01347
01348
01349 else if (header->getType() == TWOWAY) {
01350
01351
01352 if (header->getCondFollow() && loopNodes[header->getCondFollow()->ord]) {
01353 header->setLoopType(Endless);
01354
01355
01356 header->setStructType(LoopCond);
01357 } else
01358 header->setLoopType(PreTested);
01359 }
01360
01361
01362 else
01363 header->setLoopType(Endless);
01364 }
01365
01366
01367
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
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
01381 if (latch->getOutEdges()[0] == header)
01382 header->setLoopFollow(latch->getOutEdges()[1]);
01383 else
01384 header->setLoopFollow(latch->getOutEdges()[0]);
01385 } else {
01386 PBB follow = NULL;
01387
01388
01389 PBB latch = header->getLatchNode();
01390 for (int i = header->ord - 1; i > latch->ord; i--) {
01391 PBB &desc = Ordering[i];
01392
01393
01394
01395
01396
01397
01398
01399 if (desc->getStructType() == Cond && desc->getCondFollow() &&
01400 desc->getLoopHead() == header) {
01401 if (loopNodes[desc->getCondFollow()->ord]) {
01402
01403 if (desc->ord > desc->getCondFollow()->ord)
01404 i = desc->getCondFollow()->ord;
01405
01406
01407 else break;
01408 } else {
01409
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
01417 if (succ && (!follow || succ->ord > follow->ord))
01418 follow = succ;
01419 }
01420 }
01421 }
01422
01423
01424 if (follow)
01425 header->setLoopFollow(follow);
01426 }
01427 }
01428
01429
01430
01431
01432 void Cfg::tagNodesInLoop(PBB header, bool* &loopNodes) {
01433 assert(header->getLatchNode());
01434
01435
01436
01437
01438
01439
01440
01441
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
01447 loopNodes[i] = true;
01448
01449 Ordering[i]->setLoopHead(header);
01450 }
01451 }
01452
01453
01454
01455
01456 void Cfg::structLoops() {
01457 for (int i = Ordering.size() - 1; i >= 0; i--) {
01458 PBB curNode = Ordering[i];
01459 PBB latch = NULL;
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
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() &&
01476 pred->getLoopHead() == curNode->getLoopHead() &&
01477 (!latch || latch->ord > pred->ord) &&
01478 !(pred->getLoopHead() &&
01479 pred->getLoopHead()->getLatchNode() == pred) &&
01480 pred->hasBackEdgeTo(curNode))
01481 latch = pred;
01482 }
01483
01484
01485 if (latch) {
01486
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
01494
01495
01496 if (latch != curNode && latch->getStructType() == Cond)
01497 latch->setStructType(Seq);
01498
01499
01500 curNode->setStructType(Loop);
01501
01502
01503 tagNodesInLoop(curNode, loopNodes);
01504
01505
01506 determineLoopType(curNode, loopNodes);
01507
01508
01509 findLoopFollow(curNode, loopNodes);
01510
01511
01512
01513 }
01514 }
01515 }
01516
01517
01518
01519
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
01526 if ((curNode->getStructType() == Cond ||
01527 curNode->getStructType() == LoopCond) && curNode->getCondFollow() && curNode->getCondType() != Case) {
01528
01529 PBB myLoopHead = (curNode->getStructType() == LoopCond ? curNode : curNode->getLoopHead());
01530 PBB follLoopHead = curNode->getCondFollow()->getLoopHead();
01531
01532
01533 if (myLoopHead != follLoopHead) {
01534
01535 if (myLoopHead) {
01536 PBB myLoopLatch = myLoopHead->getLatchNode();
01537
01538
01539 if (oEdges[BTHEN]->isAncestorOf(myLoopLatch) || oEdges[BTHEN] == myLoopLatch) {
01540 curNode->setUnstructType(JumpInOutLoop);
01541 curNode->setCondType(IfElse);
01542 }
01543
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
01552
01553
01554
01555 if (oEdges[BTHEN]->isAncestorOf(follLoopHead) || oEdges[BTHEN] == follLoopHead) {
01556 curNode->setUnstructType(JumpInOutLoop);
01557 curNode->setCondType(IfElse);
01558 }
01559
01560
01561 else if (oEdges[BELSE]->isAncestorOf(follLoopHead) || oEdges[BELSE] == follLoopHead) {
01562 curNode->setUnstructType(JumpInOutLoop);
01563 curNode->setCondType(IfThen);
01564 }
01565 }
01566 }
01567
01568
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
01589
01590 if (curNode->getStructType() == Cond &&
01591 !curNode->getCondFollow() &&
01592 curNode->getCondType() != Case &&
01593 curNode->getUnstructType() == Structured) {
01594
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
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
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
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
01713
01714 if (aret)
01715 of << "{rank=max; bb" << std::hex << aret << "}\n";
01716
01717
01718 of << "}\n";
01719
01720
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
01751
01752
01753 void updateWorkListRev(PBB currBB, std::list<PBB>&workList, std::set<PBB>& workSet) {
01754
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;
01771
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++;
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
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
01810 worklist.insert(worklist.end(), m_listBB.begin(), m_listBB.end());
01811
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
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
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
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
01876 std::list<RTL*>* pRtls = new std::list<RTL*>;
01877 std::list<Statement*>* ls = new std::list<Statement*>;
01878 ls->push_back(br1);
01879
01880
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
01889 m_mapBB[addr] = skipBB;
01890
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
01905 std::list<Statement*>& li = rtl->getList();
01906 assert(li.size() >= 4);
01907 li.erase(li.begin());
01908
01909 std::list<Statement*>::iterator ll = --li.end();
01910 li.erase(ll);
01911 li.push_back(br2);
01912
01913
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
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
01932 for (i=0; i < oldOutEdges; i++)
01933
01934 newBb->m_OutEdges.push_back(pBB->getOutEdge(i));
01935
01936 } else {
01937
01938
01939 haveB = false;
01940 newBb = pBB->getOutEdge(0);
01941 }
01942
01943
01944 pBB->updateType(FALL, 1);
01945
01946 pBB->m_OutEdges.erase(pBB->m_OutEdges.begin(), pBB->m_OutEdges.end());
01947 addOutEdge(pBB, skipBB);
01948
01949 addOutEdge(skipBB, newBb);
01950 addOutEdge(skipBB, rptBB);
01951
01952 addOutEdge(rptBB, skipBB);
01953 addOutEdge(rptBB, newBb);
01954
01955
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
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
01979
01980
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
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
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
02036 x = x->clone();
02037 def = new ImplicitAssign(x);
02038 entryBB->prependStmt(def, myProc);
02039
02040
02041
02042 implicitMap[x] = def;
02043 } else {
02044
02045 def = it->second;
02046 }
02047 return def;
02048 }
02049
02050 Statement* Cfg::findTheImplicitAssign(Exp* x) {
02051
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
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);
02075 myProc->removeStatement(ia);
02076
02077 }
02078