CfgTest.cpp

Go to the documentation of this file.
00001 /*==============================================================================
00002  * FILE:       CfgTest.cc
00003  * OVERVIEW:   Provides the implementation for the CfgTest class, which
00004  *              tests the Exp and derived classes
00005  *============================================================================*/
00006 /*
00007  * $Revision: 1.19 $    // 1.14.2.1
00008  *
00009  * 17 Jul 03 - Mike: Created
00010  */
00011 
00012 #define FRONTIER_PENTIUM        "test/pentium/frontier"
00013 #define SEMI_PENTIUM            "test/pentium/semi"
00014 #define IFTHEN_PENTIUM          "test/pentium/ifthen"
00015 
00016 #include "CfgTest.h"
00017 #include <sstream>
00018 #include <string>
00019 #include "BinaryFile.h"
00020 #include "frontend.h"
00021 #include "proc.h"
00022 #include "prog.h"
00023 #include "dataflow.h"
00024 #include "pentiumfrontend.h"
00025 
00026 /*==============================================================================
00027  * FUNCTION:        CfgTest::registerTests
00028  * OVERVIEW:        Register the test functions in the given suite
00029  * PARAMETERS:      Pointer to the test suite
00030  * RETURNS:         <nothing>
00031  *============================================================================*/
00032 #define MYTEST(name) suite->addTest(new CppUnit::TestCaller<CfgTest> ("CfgTest", &CfgTest::name, *this))
00033 
00034 void CfgTest::registerTests(CppUnit::TestSuite* suite) {
00035     // Oops - they were all for dataflow. Need some real Cfg tests!
00036 }
00037 
00038 int CfgTest::countTestCases () const
00039 { return 2; }   // ? What's this for?
00040 
00041 /*==============================================================================
00042  * FUNCTION:        CfgTest::setUp
00043  * OVERVIEW:        Set up some expressions for use with all the tests
00044  * NOTE:            Called before any tests
00045  * PARAMETERS:      <none>
00046  * RETURNS:         <nothing>
00047  *============================================================================*/
00048 void CfgTest::setUp () {
00049     //prog.setName("default name");
00050 }
00051 
00052 /*==============================================================================
00053  * FUNCTION:        CfgTest::tearDown
00054  * OVERVIEW:        Delete expressions created in setUp
00055  * NOTE:            Called after all tests
00056  * PARAMETERS:      <none>
00057  * RETURNS:         <nothing>
00058  *============================================================================*/
00059 void CfgTest::tearDown () {
00060 }
00061 
00062 /*==============================================================================
00063  * FUNCTION:        CfgTest::testDominators
00064  * OVERVIEW:        Test the dominator frontier code
00065  *============================================================================*/
00066 #define FRONTIER_FOUR   0x08048347
00067 #define FRONTIER_FIVE   0x08048351
00068 #define FRONTIER_TWELVE 0x080483b2
00069 #define FRONTIER_THIRTEEN 0x080483b9
00070 
00071 void CfgTest::testDominators () {
00072     BinaryFileFactory bff;
00073     BinaryFile *pBF = bff.Load(FRONTIER_PENTIUM);
00074     CPPUNIT_ASSERT(pBF != 0);
00075     Prog* prog = new Prog;
00076     FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00077     Type::clearNamedTypes();
00078     prog->setFrontEnd(pFE);
00079     pFE->decode(prog);
00080 
00081     bool gotMain;
00082     ADDRESS addr = pFE->getMainEntryPoint(gotMain);
00083     CPPUNIT_ASSERT (addr != NO_ADDRESS);
00084 
00085     UserProc* pProc = (UserProc*) prog->getProc(0);
00086     Cfg* cfg = pProc->getCFG();
00087     DataFlow* df = pProc->getDataFlow();
00088     df->dominators(cfg);
00089 
00090     // Find BB "5" (as per Appel, Figure 19.5).
00091     BB_IT it;
00092     PBB bb = cfg->getFirstBB(it);
00093     while (bb && bb->getLowAddr() != FRONTIER_FIVE) {
00094         bb = cfg->getNextBB(it);
00095     }
00096     CPPUNIT_ASSERT(bb);
00097 
00098     std::ostringstream expected, actual;
00099   //expected << std::hex << FRONTIER_FIVE << " " << FRONTIER_THIRTEEN << " " << FRONTIER_TWELVE << " " <<
00100   //    FRONTIER_FOUR << " ";
00101     expected << std::hex << FRONTIER_THIRTEEN << " " << FRONTIER_FOUR << " " << FRONTIER_TWELVE << " " <<
00102         FRONTIER_FIVE << " ";
00103     int n5 = df->pbbToNode(bb);
00104     std::set<int>::iterator ii;
00105     std::set<int>& DFset = df->getDF(n5);
00106     for (ii=DFset.begin(); ii != DFset.end(); ii++)
00107         actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " ";
00108     CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str());
00109 
00110     pBF->UnLoad();
00111     delete pFE;
00112 }
00113 
00114 
00115 /*==============================================================================
00116  * FUNCTION:        CfgTest::testSemiDominators
00117  * OVERVIEW:        Test a case where semi dominators are different to dominators
00118  *============================================================================*/
00119 #define SEMI_L  0x80483b0
00120 #define SEMI_M  0x80483e2
00121 #define SEMI_B  0x8048345
00122 #define SEMI_D  0x8048354
00123 #define SEMI_M  0x80483e2
00124 
00125 void CfgTest::testSemiDominators () {
00126     BinaryFileFactory bff;
00127     BinaryFile* pBF = bff.Load(SEMI_PENTIUM);
00128     CPPUNIT_ASSERT(pBF != 0);
00129     Prog* prog = new Prog;
00130     FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
00131     Type::clearNamedTypes();
00132     prog->setFrontEnd(pFE);
00133     pFE->decode(prog);
00134 
00135     bool gotMain;
00136     ADDRESS addr = pFE->getMainEntryPoint(gotMain);
00137     CPPUNIT_ASSERT (addr != NO_ADDRESS);
00138 
00139     UserProc* pProc = (UserProc*) prog->getProc(0);
00140     Cfg* cfg = pProc->getCFG();
00141 
00142     DataFlow* df = pProc->getDataFlow();
00143     df->dominators(cfg);
00144 
00145     // Find BB "L (6)" (as per Appel, Figure 19.8).
00146     BB_IT it;
00147     PBB bb = cfg->getFirstBB(it);
00148     while (bb && bb->getLowAddr() != SEMI_L) {
00149         bb = cfg->getNextBB(it);
00150     }
00151     CPPUNIT_ASSERT(bb);
00152     int nL = df->pbbToNode(bb);
00153 
00154     // The dominator for L should be B, where the semi dominator is D
00155     // (book says F)
00156     unsigned actual_dom  = (unsigned)df->nodeToBB(df->getIdom(nL))->getLowAddr();
00157     unsigned actual_semi = (unsigned)df->nodeToBB(df->getSemi(nL))->getLowAddr();
00158     CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_B, actual_dom);
00159     CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_D, actual_semi);
00160     // Check the final dominator frontier as well; should be M and B
00161     std::ostringstream expected, actual;
00162   //expected << std::hex << SEMI_M << " " << SEMI_B << " ";
00163     expected << std::hex << SEMI_B << " " << SEMI_M << " ";
00164     std::set<int>::iterator ii;
00165     std::set<int>& DFset = df->getDF(nL);
00166     for (ii=DFset.begin(); ii != DFset.end(); ii++)
00167         actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " ";
00168     CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str());
00169     delete pFE;
00170 }
00171 
00172 /*==============================================================================
00173  * FUNCTION:        CfgTest::testPlacePhi
00174  * OVERVIEW:        Test the placing of phi functions
00175  *============================================================================*/
00176 void CfgTest::testPlacePhi () {
00177     BinaryFileFactory bff;
00178     BinaryFile* pBF = bff.Load(FRONTIER_PENTIUM);
00179     CPPUNIT_ASSERT(pBF != 0);
00180     Prog* prog = new Prog;
00181     FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
00182     Type::clearNamedTypes();
00183     prog->setFrontEnd(pFE);
00184     pFE->decode(prog);
00185 
00186     UserProc* pProc = (UserProc*) prog->getProc(0);
00187     Cfg* cfg = pProc->getCFG();
00188 
00189     // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
00190     prog->finishDecode();
00191 
00192     DataFlow* df = pProc->getDataFlow();
00193     df->dominators(cfg);
00194     df->placePhiFunctions(pProc);
00195 
00196     // m[r29 - 8] (x for this program)
00197     Exp* e = new Unary(opMemOf,
00198         new Binary(opMinus,
00199             Location::regOf(29),
00200             new Const(4)));
00201 
00202     // A_phi[x] should be the set {7 8 10 15 20 21} (all the join points)
00203     std::ostringstream ost;
00204     std::set<int>::iterator ii;
00205     std::set<int>& A_phi = df->getA_phi(e);
00206     for (ii = A_phi.begin(); ii != A_phi.end(); ++ii)
00207         ost << *ii << " ";
00208     std::string expected("7 8 10 15 20 21 ");
00209     CPPUNIT_ASSERT_EQUAL(expected, ost.str());
00210     delete pFE;
00211 }
00212 
00213 /*==============================================================================
00214  * FUNCTION:        CfgTest::testPlacePhi2
00215  * OVERVIEW:        Test a case where a phi function is not needed
00216  *============================================================================*/
00217 void CfgTest::testPlacePhi2 () {
00218     BinaryFileFactory bff;
00219     BinaryFile* pBF = bff.Load(IFTHEN_PENTIUM);
00220     CPPUNIT_ASSERT(pBF != 0);
00221     Prog* prog = new Prog;
00222     FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
00223     Type::clearNamedTypes();
00224     prog->setFrontEnd(pFE);
00225     pFE->decode(prog);
00226 
00227     UserProc* pProc = (UserProc*) prog->getProc(0);
00228     Cfg* cfg = pProc->getCFG();
00229     DataFlow* df = pProc->getDataFlow();
00230 
00231     // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
00232     prog->finishDecode();
00233 
00234     df->dominators(cfg);
00235     df->placePhiFunctions(pProc);
00236 
00237     // In this program, x is allocated at [ebp-4], a at [ebp-8], and
00238     // b at [ebp-12]
00239     // We check that A_phi[ m[ebp-8] ] is 4, and that
00240     // A_phi A_phi[ m[ebp-8] ] is null
00241     // (block 4 comes out with n=4)
00242 
00243     std::string expected = "4 ";
00244     std::ostringstream actual;
00245     // m[r29 - 8]
00246     Exp* e = new Unary(opMemOf,
00247         new Binary(opMinus,
00248             Location::regOf(29),
00249             new Const(8)));
00250     std::set<int>& s = df->getA_phi(e);
00251     std::set<int>::iterator pp;
00252     for (pp = s.begin(); pp != s.end(); pp++)
00253         actual << *pp << " ";
00254     CPPUNIT_ASSERT_EQUAL(expected, actual.str());
00255     delete e;
00256 
00257     expected = "";
00258     std::ostringstream actual2;
00259     // m[r29 - 12]
00260     e = new Unary(opMemOf,
00261         new Binary(opMinus,
00262             Location::regOf(29),
00263             new Const(12)));
00264  
00265     std::set<int>& s2 = df->getA_phi(e);
00266     for (pp = s2.begin(); pp != s2.end(); pp++)
00267         actual2 << *pp << " ";
00268     CPPUNIT_ASSERT_EQUAL(expected, actual2.str());
00269     delete e;
00270     delete pFE;
00271 }
00272 
00273 /*==============================================================================
00274  * FUNCTION:        CfgTest::testRenameVars
00275  * OVERVIEW:        Test the renaming of variables
00276  *============================================================================*/
00277 void CfgTest::testRenameVars () {
00278     BinaryFileFactory bff;
00279     BinaryFile* pBF = bff.Load(FRONTIER_PENTIUM);
00280     CPPUNIT_ASSERT(pBF != 0);
00281     Prog* prog = new Prog;
00282     FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
00283     Type::clearNamedTypes();
00284     prog->setFrontEnd(pFE);
00285     pFE->decode(prog);
00286 
00287     UserProc* pProc = (UserProc*) prog->getProc(0);
00288     Cfg* cfg = pProc->getCFG();
00289     DataFlow* df = pProc->getDataFlow();
00290 
00291     // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
00292     prog->finishDecode();
00293 
00294     df->dominators(cfg);
00295     df->placePhiFunctions(pProc);
00296     pProc->numberStatements();              // After placing phi functions!
00297     df->renameBlockVars(pProc, 0, 1);       // Block 0, mem depth 1
00298 
00299     // MIKE: something missing here?
00300 
00301     delete pFE;
00302 }

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