syntax.cpp

Go to the documentation of this file.
00001 
00002 #include <fstream>
00003 #include <iomanip>          // For setfill etc
00004 #include "prog.h"
00005 #include "exp.h"
00006 #include "hllcode.h"
00007 #include "cfg.h"
00008 #include "statement.h"
00009 
00010 static int nodecount = 1000;
00011 
00012 
00013 #define PRINT_BEFORE_AFTER std::ofstream of("before.dot"); \
00014                 of << "digraph before {" << std::endl; \
00015                 root->printAST(root, of); \
00016                 of << "}" << std::endl; \
00017                 of.close(); \
00018                 std::ofstream of1("after.dot"); \
00019                 of1 << "digraph after {" << std::endl; \
00020                 n->printAST(n, of1); \
00021                 of1 << "}" << std::endl; \
00022                 of1.close(); \
00023                 exit(0);
00024 
00025 SyntaxNode::SyntaxNode() : pbb(NULL), score(-1), correspond(NULL), 
00026                            notGoto(false)
00027 {
00028     nodenum = nodecount++;
00029 }
00030 
00031 SyntaxNode::~SyntaxNode()
00032 {
00033 }
00034 
00035 int SyntaxNode::getScore()
00036 {
00037     if (score == -1)
00038         score = evaluate(this);
00039     return score;
00040 }
00041 
00042 bool SyntaxNode::isGoto()
00043 {
00044     return pbb && pbb->getType() == ONEWAY && !notGoto;
00045 }
00046 
00047 bool SyntaxNode::isBranch()
00048 {
00049     return pbb && pbb->getType() == TWOWAY;
00050 }
00051 
00052 BlockSyntaxNode::BlockSyntaxNode()
00053 {
00054 }
00055 
00056 BlockSyntaxNode::~BlockSyntaxNode()
00057 {
00058     for (unsigned i = 0; i < statements.size(); i++)
00059         delete statements[i];
00060 }
00061 
00062 int BlockSyntaxNode::getNumOutEdges() {
00063     if (pbb)
00064         return pbb->getNumOutEdges();
00065     if (statements.size() == 0)
00066         return 0;
00067     return statements[statements.size()-1]->getNumOutEdges();
00068 }
00069 
00070 SyntaxNode *BlockSyntaxNode::getOutEdge(SyntaxNode *root, int n) {
00071     if (pbb)
00072         return root->findNodeFor(pbb->getOutEdge(n));
00073     if (statements.size() == 0)
00074         return NULL;
00075     return statements[statements.size()-1]->getOutEdge(root, n);
00076 }
00077 
00078 SyntaxNode *BlockSyntaxNode::findNodeFor(PBB bb)
00079 {
00080     if (pbb == bb)
00081         return this;
00082     SyntaxNode *n = NULL;
00083     for (unsigned i = 0; i < statements.size(); i++) {
00084         n = statements[i]->findNodeFor(bb);
00085         if (n != NULL)
00086             break;
00087     }
00088     if (n && n == statements[0])
00089         return this;
00090     return n;
00091 }
00092 
00093 void BlockSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00094 {
00095     os << std::setw(4) << std::dec << nodenum << " ";
00096     os << "[label=\"";
00097     if (pbb) {
00098         switch(pbb->getType()) {
00099             case ONEWAY:    os << "Oneway"; 
00100                             if (notGoto) os << " (ignored)"; break;
00101             case TWOWAY:    os << "Twoway"; break;
00102             case NWAY:      os << "Nway"; break;
00103             case CALL:      os << "Call"; break;
00104             case RET:       os << "Ret"; break;
00105             case FALL:      os << "Fall"; break;
00106             case COMPJUMP:  os << "Computed jump"; break;
00107             case COMPCALL:  os << "Computed call"; break;
00108             case INVALID:   os << "Invalid"; break;
00109         }
00110         os << " " << std::hex << pbb->getLowAddr();
00111     } else
00112         os << "block";
00113     os << "\"];" << std::endl;
00114     if (pbb) {
00115         for (int i = 0; i < pbb->getNumOutEdges(); i++) {
00116             PBB out = pbb->getOutEdge(i);
00117             os << std::setw(4) << std::dec << nodenum << " ";
00118             SyntaxNode *to = root->findNodeFor(out);
00119             assert(to);
00120             os << " -> " << to->getNumber() << " [style=dotted";
00121             if (pbb->getNumOutEdges() > 1)
00122                 os << ",label=" << i;
00123             os << "];" << std::endl;
00124         }
00125     } else  {
00126         for (unsigned i = 0; i < statements.size(); i++)
00127             statements[i]->printAST(root, os);
00128         for (unsigned i = 0; i < statements.size(); i++) {
00129             os << std::setw(4) << std::dec << nodenum << " ";
00130             os << " -> " << statements[i]->getNumber() 
00131                          << " [label=\"" << i << "\"];" << std::endl;
00132         }
00133     }
00134 }
00135 
00136 #define DEBUG_EVAL 0
00137 
00138 int BlockSyntaxNode::evaluate(SyntaxNode *root)
00139 {
00140 #if DEBUG_EVAL
00141     if (this == root) 
00142         std::cerr << "begin eval =============" << std::endl;
00143 #endif
00144     if (pbb)
00145         return 1;
00146     int n = 1;
00147     if (statements.size() == 1) {
00148         SyntaxNode *out = statements[0]->getOutEdge(root, 0);
00149         if (out->getBB() != NULL && out->getBB()->getNumInEdges() > 1) {
00150 #if DEBUG_EVAL
00151             std::cerr << "add 15" << std::endl;
00152 #endif
00153             n += 15;
00154         } else {
00155 #if DEBUG_EVAL
00156             std::cerr << "add 30" << std::endl;
00157 #endif
00158             n += 30;
00159         }
00160     }
00161     for (unsigned i = 0; i < statements.size(); i++) {
00162         n += statements[i]->evaluate(root); 
00163         if (statements[i]->isGoto()) {
00164             if (i != statements.size()-1) {
00165 #if DEBUG_EVAL
00166                 std::cerr << "add 100" << std::endl;
00167 #endif
00168                 n += 100;
00169             } else {
00170 #if DEBUG_EVAL
00171                 std::cerr << "add 50" << std::endl;
00172 #endif
00173                 n += 50;
00174             }
00175         } else if (statements[i]->isBranch()) {
00176             SyntaxNode *loop = root->getEnclosingLoop(this);
00177             std::cerr << "branch " << statements[i]->getNumber() 
00178                       << " not in loop" << std::endl;
00179             if (loop) {
00180                 std::cerr << "branch " << statements[i]->getNumber() 
00181                           << " in loop " << loop->getNumber() << std::endl;
00182                 // this is a bit C specific
00183                 SyntaxNode *out = loop->getOutEdge(root, 0);
00184                 if (out && statements[i]->getOutEdge(root, 0) == out) {
00185                     std::cerr << "found break" << std::endl;
00186                     n += 10;
00187                 }
00188                 if (statements[i]->getOutEdge(root, 0) == loop) {
00189                     std::cerr << "found continue" << std::endl;
00190                     n += 10;
00191                 }
00192             } else {
00193 #if DEBUG_EVAL
00194                 std::cerr << "add 50" << std::endl;
00195 #endif
00196                 n += 50;
00197             }
00198         } else if (i < statements.size()-1 && 
00199                  statements[i]->getOutEdge(root, 0) != statements[i+1]) {
00200 #if DEBUG_EVAL
00201             std::cerr << "add 25" << std::endl;
00202             std::cerr << statements[i]->getNumber() << " -> "
00203                       << statements[i]->getOutEdge(root, 0)->getNumber() 
00204                       << " not " << statements[i+1]->getNumber() << std::endl;
00205 #endif
00206             n += 25;
00207         }
00208     }
00209 #if DEBUG_EVAL
00210     if (this == root) 
00211         std::cerr << "end eval = " << n << " =============" << std::endl;
00212 #endif
00213     return n;
00214 }
00215 
00216 void BlockSyntaxNode::addSuccessors(SyntaxNode *root,
00217                                     std::vector<SyntaxNode*> &successors)
00218 {
00219     for (unsigned i = 0; i < statements.size(); i++) {
00220         if (statements[i]->isBlock()) {
00221             //BlockSyntaxNode *b = (BlockSyntaxNode*)statements[i];
00222             // can move previous statements into this block
00223             if (i > 0) {
00224                 std::cerr << "successor: move previous statement into block" 
00225                           << std::endl;
00226                 SyntaxNode *n = root->clone();
00227                 n->setDepth(root->getDepth() + 1);
00228                 BlockSyntaxNode *b1 = (BlockSyntaxNode*)this->clone();
00229                 BlockSyntaxNode *nb = (BlockSyntaxNode*)b1->getStatement(i);
00230                 b1 = (BlockSyntaxNode*)b1->replace(statements[i-1], NULL);
00231                 nb->prependStatement(statements[i-1]->clone());
00232                 n = n->replace(this, b1);
00233                 successors.push_back(n);
00234                 //PRINT_BEFORE_AFTER
00235             }
00236         } else {
00237             if (statements.size() != 1) {
00238                 // can replace statement with a block containing that statement
00239                 std::cerr << "successor: replace statement with a block "
00240                           << "containing the statement" << std::endl;
00241                 BlockSyntaxNode *b = new BlockSyntaxNode();
00242                 b->addStatement(statements[i]->clone());
00243                 SyntaxNode *n = root->clone();
00244                 n->setDepth(root->getDepth() + 1);
00245                 n = n->replace(statements[i], b);
00246                 successors.push_back(n);
00247                 //PRINT_BEFORE_AFTER
00248             }
00249         }
00250         // "jump over" style of if-then
00251         if (i < statements.size() - 2 && statements[i]->isBranch()) {
00252             SyntaxNode *b = statements[i];
00253             if (b->getOutEdge(root, 0) == statements[i+2] &&
00254                 (statements[i+1]->getOutEdge(root, 0) == statements[i+2] ||
00255                  statements[i+1]->endsWithGoto())) {
00256                     std::cerr << "successor: jump over style if then" 
00257                               << std::endl;
00258                     BlockSyntaxNode *b1 = 
00259                         (BlockSyntaxNode*)this->clone();
00260                     b1 = (BlockSyntaxNode*)b1->replace(statements[i+1], NULL);
00261                     IfThenSyntaxNode *nif = new IfThenSyntaxNode();
00262                     Exp *cond = b->getBB()->getCond();
00263                     cond = new Unary(opLNot, cond->clone());
00264                     cond = cond->simplify();
00265                     nif->setCond(cond);
00266                     nif->setThen(statements[i+1]->clone());
00267                     nif->setBB(b->getBB());
00268                     b1->setStatement(i, nif);
00269                     SyntaxNode *n = root->clone();
00270                     n->setDepth(root->getDepth() + 1);
00271                     n = n->replace(this, b1);
00272                     successors.push_back(n);
00273                     //PRINT_BEFORE_AFTER
00274             }
00275         }
00276         // if then else
00277         if (i < statements.size() - 2 && statements[i]->isBranch()) {
00278             SyntaxNode *tThen = statements[i]->getOutEdge(root, 0);
00279             SyntaxNode *tElse = statements[i]->getOutEdge(root, 1);
00280 
00281             assert(tThen && tElse);
00282             if (((tThen == statements[i+2] && tElse == statements[i+1]) ||
00283                  (tThen == statements[i+1] && tElse == statements[i+2])) &&
00284                 tThen->getNumOutEdges() == 1 && tElse->getNumOutEdges() == 1) {
00285                 SyntaxNode *else_out = tElse->getOutEdge(root, 0);
00286                 SyntaxNode *then_out = tThen->getOutEdge(root, 0);
00287 
00288                 if (else_out == then_out) {
00289                     std::cerr << "successor: if then else" << std::endl;
00290                     SyntaxNode *n = root->clone();
00291                     n->setDepth(root->getDepth() + 1);
00292                     n = n->replace(tThen, NULL);
00293                     n = n->replace(tElse, NULL);
00294                     IfThenElseSyntaxNode *nif = new IfThenElseSyntaxNode();
00295                     nif->setCond(statements[i]->getBB()->getCond()->clone());
00296                     nif->setBB(statements[i]->getBB());
00297                     nif->setThen(tThen->clone());
00298                     nif->setElse(tElse->clone());
00299                     n = n->replace(statements[i], nif);
00300                     successors.push_back(n);
00301                     //PRINT_BEFORE_AFTER
00302                 }
00303             }
00304         }
00305 
00306         // pretested loop
00307         if (i < statements.size() - 2 && statements[i]->isBranch()) {
00308             SyntaxNode *tBody = statements[i]->getOutEdge(root, 0);
00309             SyntaxNode *tFollow =  statements[i]->getOutEdge(root, 1);
00310 
00311             assert(tBody && tFollow);
00312             if (tBody == statements[i+1] && tFollow == statements[i+2] &&
00313                 tBody->getNumOutEdges() == 1 &&
00314                 tBody->getOutEdge(root, 0) == statements[i]) {
00315                 std::cerr << "successor: pretested loop" << std::endl;
00316                 SyntaxNode *n = root->clone();
00317                 n->setDepth(root->getDepth() + 1);
00318                 n = n->replace(tBody, NULL);
00319                 PretestedLoopSyntaxNode *nloop = new PretestedLoopSyntaxNode();
00320                 nloop->setCond(statements[i]->getBB()->getCond()->clone());
00321                 nloop->setBB(statements[i]->getBB());
00322                 nloop->setBody(tBody->clone());
00323                 n = n->replace(statements[i], nloop);
00324                 successors.push_back(n);
00325                 //PRINT_BEFORE_AFTER
00326             }
00327         }
00328 
00329         // posttested loop
00330         if (i > 0 && i < statements.size()-1 && statements[i]->isBranch()) {
00331             SyntaxNode *tBody = statements[i]->getOutEdge(root, 0);
00332             SyntaxNode *tFollow =  statements[i]->getOutEdge(root, 1);
00333 
00334             assert(tBody && tFollow);
00335             if (tBody == statements[i-1] && tFollow == statements[i+1] &&
00336                 tBody->getNumOutEdges() == 1 &&
00337                 tBody->getOutEdge(root, 0) == statements[i]) {
00338                 std::cerr << "successor: posttested loop" << std::endl;
00339                 SyntaxNode *n = root->clone();
00340                 n->setDepth(root->getDepth() + 1);
00341                 n = n->replace(tBody, NULL);
00342                 PostTestedLoopSyntaxNode *nloop = 
00343                                                 new PostTestedLoopSyntaxNode();
00344                 nloop->setCond(statements[i]->getBB()->getCond()->clone());
00345                 nloop->setBB(statements[i]->getBB());
00346                 nloop->setBody(tBody->clone());
00347                 n = n->replace(statements[i], nloop);
00348                 successors.push_back(n);
00349                 //PRINT_BEFORE_AFTER
00350             }
00351         }
00352 
00353         // infinite loop
00354         if (statements[i]->getNumOutEdges() == 1 &&
00355             statements[i]->getOutEdge(root, 0) == statements[i]) {
00356             std::cerr << "successor: infinite loop" << std::endl;
00357             SyntaxNode *n = root->clone();
00358             n->setDepth(root->getDepth() + 1);
00359             InfiniteLoopSyntaxNode *nloop = new InfiniteLoopSyntaxNode();
00360             nloop->setBody(statements[i]->clone());
00361             n = n->replace(statements[i], nloop);
00362             successors.push_back(n);
00363             PRINT_BEFORE_AFTER
00364         }
00365 
00366         statements[i]->addSuccessors(root, successors);
00367     }
00368 }
00369 
00370 SyntaxNode *BlockSyntaxNode::clone()
00371 {
00372     BlockSyntaxNode *b = new BlockSyntaxNode();
00373     b->correspond = this;
00374     if (pbb)
00375         b->pbb = pbb;
00376     else
00377         for (unsigned i = 0; i < statements.size(); i++)
00378             b->addStatement(statements[i]->clone());
00379     return b;
00380 }
00381 
00382 SyntaxNode *BlockSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00383 {
00384     if (correspond == from)
00385         return to;
00386 
00387     if (pbb == NULL) {
00388         std::vector<SyntaxNode*> news;
00389         for (unsigned i = 0; i < statements.size(); i++) {
00390             SyntaxNode *n = statements[i];
00391             if (statements[i]->getCorrespond() == from)
00392                 n = to;
00393             else
00394                 n = statements[i]->replace(from, to);
00395             if (n)
00396                 news.push_back(n);
00397         }
00398         statements.resize(news.size());
00399         for (unsigned i = 0; i < news.size(); i++)
00400             statements[i] = news[i];
00401     }
00402     return this;
00403 }
00404 
00405 IfThenSyntaxNode::IfThenSyntaxNode() : pThen(NULL), cond(NULL)
00406 {
00407 }
00408 
00409 
00410 IfThenSyntaxNode::~IfThenSyntaxNode()
00411 {
00412     if (pThen)
00413         delete pThen;
00414 }
00415 
00416 SyntaxNode *IfThenSyntaxNode::getOutEdge(SyntaxNode *root, int n) {
00417     SyntaxNode *n1 = root->findNodeFor(pbb->getOutEdge(0));
00418     assert(n1 != pThen);
00419     return n1;
00420 }
00421 
00422 int IfThenSyntaxNode::evaluate(SyntaxNode *root)
00423 {
00424     int n = 1;
00425     n += pThen->evaluate(root);
00426     return n;
00427 }
00428 
00429 void IfThenSyntaxNode::addSuccessors(SyntaxNode *root,
00430                                      std::vector<SyntaxNode*> &successors)
00431 {
00432     pThen->addSuccessors(root, successors);
00433 }
00434 
00435 SyntaxNode *IfThenSyntaxNode::clone()
00436 {
00437     IfThenSyntaxNode *b = new IfThenSyntaxNode();
00438     b->correspond = this;
00439     b->pbb = pbb;
00440     b->cond = cond->clone();
00441     b->pThen = pThen->clone();
00442     return b;
00443 }
00444 
00445 SyntaxNode *IfThenSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00446 {
00447     assert(correspond != from);
00448     if (pThen->getCorrespond() == from) {
00449         assert(to);
00450         pThen = to;
00451     } else 
00452         pThen = pThen->replace(from, to);
00453     return this;
00454 }
00455 
00456 SyntaxNode *IfThenSyntaxNode::findNodeFor(PBB bb)
00457 {
00458     if (pbb == bb)
00459         return this;
00460     return pThen->findNodeFor(bb);
00461 }
00462 
00463 void IfThenSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00464 {
00465     os << std::setw(4) << std::dec << nodenum << " ";
00466     os << "[label=\"if " << cond << " \"];" << std::endl;
00467     pThen->printAST(root, os);
00468     os << std::setw(4) << std::dec << nodenum << " ";
00469     os << " -> " << pThen->getNumber() << " [label=then];" << std::endl;
00470     SyntaxNode *follows = root->findNodeFor(pbb->getOutEdge(0));
00471     os << std::setw(4) << std::dec << nodenum << " ";
00472     os << " -> " << follows->getNumber() << " [style=dotted];" << std::endl;
00473 }
00474 
00475 IfThenElseSyntaxNode::IfThenElseSyntaxNode() : pThen(NULL), pElse(NULL), 
00476     cond(NULL)
00477 {
00478 }
00479 
00480 IfThenElseSyntaxNode::~IfThenElseSyntaxNode()
00481 {
00482     if (pThen)
00483         delete pThen;
00484     if (pElse)
00485         delete pElse;
00486 }
00487 
00488 int IfThenElseSyntaxNode::evaluate(SyntaxNode *root)
00489 {
00490     int n = 1;
00491     n += pThen->evaluate(root);
00492     n += pElse->evaluate(root);
00493     return n;
00494 }
00495 
00496 void IfThenElseSyntaxNode::addSuccessors(SyntaxNode *root,
00497                                          std::vector<SyntaxNode*> &successors)
00498 {
00499     // at the moment we can always ignore gotos at the end of 
00500     // then and else, because we assume they have the same
00501     // follow
00502     if (pThen->getNumOutEdges() == 1 && pThen->endsWithGoto()) {
00503         std::cerr << "successor: ignoring goto at end of then of if then else" 
00504                   << std::endl;
00505         SyntaxNode *n = root->clone();
00506         n->setDepth(root->getDepth() + 1);
00507         SyntaxNode *nThen = pThen->clone();
00508         nThen->ignoreGoto();
00509         n = n->replace(pThen, nThen);
00510         successors.push_back(n);
00511     }
00512 
00513     if (pElse->getNumOutEdges() == 1 && pElse->endsWithGoto()) {
00514         std::cerr << "successor: ignoring goto at end of else of if then else" 
00515                   << std::endl;
00516         SyntaxNode *n = root->clone();
00517         n->setDepth(root->getDepth() + 1);
00518         SyntaxNode *nElse = pElse->clone();
00519         nElse->ignoreGoto();
00520         n = n->replace(pElse, nElse);
00521         successors.push_back(n);
00522     }
00523     
00524     pThen->addSuccessors(root, successors);
00525     pElse->addSuccessors(root, successors);
00526 }
00527 
00528 SyntaxNode *IfThenElseSyntaxNode::clone()
00529 {
00530     IfThenElseSyntaxNode *b = new IfThenElseSyntaxNode();
00531     b->correspond = this;
00532     b->pbb = pbb;
00533     b->cond = cond->clone();
00534     b->pThen = pThen->clone();
00535     b->pElse = pElse->clone();
00536     return b;
00537 }
00538 
00539 SyntaxNode *IfThenElseSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00540 {
00541     assert(correspond != from);
00542     if (pThen->getCorrespond() == from) {
00543         assert(to);
00544         pThen = to;
00545     } else 
00546         pThen = pThen->replace(from, to);
00547     if (pElse->getCorrespond() == from) {
00548         assert(to);
00549         pElse = to;
00550     } else 
00551         pElse = pElse->replace(from, to);
00552     return this;
00553 }
00554 
00555 SyntaxNode *IfThenElseSyntaxNode::findNodeFor(PBB bb)
00556 {
00557     if (pbb == bb)
00558         return this;
00559     SyntaxNode *n = pThen->findNodeFor(bb);
00560     if (n == NULL)
00561         n = pElse->findNodeFor(bb);
00562     return n;
00563 }
00564 
00565 void IfThenElseSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00566 {
00567     os << std::setw(4) << std::dec << nodenum << " ";
00568     os << "[label=\"if " << cond << " \"];" << std::endl;
00569     pThen->printAST(root, os);
00570     pElse->printAST(root, os);
00571     os << std::setw(4) << std::dec << nodenum << " ";
00572     os << " -> " << pThen->getNumber() << " [label=then];" << std::endl;
00573     os << std::setw(4) << std::dec << nodenum << " ";
00574     os << " -> " << pElse->getNumber() << " [label=else];" << std::endl;
00575 }
00576 
00577 
00578 PretestedLoopSyntaxNode::PretestedLoopSyntaxNode() : pBody(NULL), cond(NULL)
00579 {
00580 }
00581 
00582 PretestedLoopSyntaxNode::~PretestedLoopSyntaxNode()
00583 {
00584     if (pBody)
00585         delete pBody;
00586     if (cond)
00587         delete cond;
00588 }
00589 
00590 SyntaxNode *PretestedLoopSyntaxNode::getOutEdge(SyntaxNode *root, int n) {
00591     return root->findNodeFor(pbb->getOutEdge(1));
00592 }
00593 
00594 int PretestedLoopSyntaxNode::evaluate(SyntaxNode *root)
00595 {
00596     int n = 1;
00597     n += pBody->evaluate(root);
00598     return n;
00599 }
00600 
00601 void PretestedLoopSyntaxNode::addSuccessors(SyntaxNode *root,
00602                                         std::vector<SyntaxNode*> &successors)
00603 {
00604     // we can always ignore gotos at the end of the body.
00605     if (pBody->getNumOutEdges() == 1 && pBody->endsWithGoto()) {
00606         std::cerr << "successor: ignoring goto at end of body of pretested "
00607                   << "loop" << std::endl;
00608         SyntaxNode *out = pBody->getOutEdge(root, 0);
00609         assert(out->startsWith(this));
00610         SyntaxNode *n = root->clone();
00611         n->setDepth(root->getDepth() + 1);
00612         SyntaxNode *nBody = pBody->clone();
00613         nBody->ignoreGoto();
00614         n = n->replace(pBody, nBody);
00615         successors.push_back(n);
00616     }
00617 
00618     pBody->addSuccessors(root, successors);
00619 }
00620 
00621 SyntaxNode *PretestedLoopSyntaxNode::clone()
00622 {
00623     PretestedLoopSyntaxNode *b = new PretestedLoopSyntaxNode();
00624     b->correspond = this;
00625     b->pbb = pbb;
00626     b->cond = cond->clone();
00627     b->pBody = pBody->clone();
00628     return b;
00629 }
00630 
00631 SyntaxNode *PretestedLoopSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00632 {
00633     assert(correspond != from);
00634     if (pBody->getCorrespond() == from) {
00635         assert(to);
00636         pBody = to;
00637     } else 
00638         pBody = pBody->replace(from, to);
00639     return this;
00640 }
00641 
00642 SyntaxNode *PretestedLoopSyntaxNode::findNodeFor(PBB bb)
00643 {
00644     if (pbb == bb)
00645         return this;
00646     return pBody->findNodeFor(bb);
00647 }
00648 
00649 void PretestedLoopSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00650 {
00651     os << std::setw(4) << std::dec << nodenum << " ";
00652     os << "[label=\"loop pretested ";
00653     os  << cond << " \"];" << std::endl;
00654     pBody->printAST(root, os);
00655     os << std::setw(4) << std::dec << nodenum << " ";
00656     os << " -> " << pBody->getNumber() << ";" << std::endl;
00657     os << std::setw(4) << std::dec << nodenum << " ";
00658     os << " -> " << getOutEdge(root, 0)->getNumber() 
00659                  << " [style=dotted];" << std::endl;
00660 }
00661 
00662 PostTestedLoopSyntaxNode::PostTestedLoopSyntaxNode() : pBody(NULL), cond(NULL)
00663 {
00664 }
00665 
00666 PostTestedLoopSyntaxNode::~PostTestedLoopSyntaxNode()
00667 {
00668     if (pBody)
00669         delete pBody;
00670     if (cond)
00671         delete cond;
00672 }
00673 
00674 SyntaxNode *PostTestedLoopSyntaxNode::getOutEdge(SyntaxNode *root, int n) {
00675     return root->findNodeFor(pbb->getOutEdge(1));
00676 }
00677 
00678 int PostTestedLoopSyntaxNode::evaluate(SyntaxNode *root)
00679 {
00680     int n = 1;
00681     n += pBody->evaluate(root);
00682     return n;
00683 }
00684 
00685 void PostTestedLoopSyntaxNode::addSuccessors(SyntaxNode *root,
00686                                         std::vector<SyntaxNode*> &successors)
00687 {
00688     // we can always ignore gotos at the end of the body.
00689     if (pBody->getNumOutEdges() == 1 && pBody->endsWithGoto()) {
00690         std::cerr << "successor: ignoring goto at end of body of posttested "
00691                   << "loop" << std::endl;
00692         assert(pBody->getOutEdge(root, 0) == this);
00693         SyntaxNode *n = root->clone();
00694         n->setDepth(root->getDepth() + 1);
00695         SyntaxNode *nBody = pBody->clone();
00696         nBody->ignoreGoto();
00697         n = n->replace(pBody, nBody);
00698         successors.push_back(n);
00699     }
00700 
00701     pBody->addSuccessors(root, successors);
00702 }
00703 
00704 SyntaxNode *PostTestedLoopSyntaxNode::clone()
00705 {
00706     PostTestedLoopSyntaxNode *b = new PostTestedLoopSyntaxNode();
00707     b->correspond = this;
00708     b->pbb = pbb;
00709     b->cond = cond->clone();
00710     b->pBody = pBody->clone();
00711     return b;
00712 }
00713 
00714 SyntaxNode *PostTestedLoopSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00715 {
00716     assert(correspond != from);
00717     if (pBody->getCorrespond() == from) {
00718         assert(to);
00719         pBody = to;
00720     } else 
00721         pBody = pBody->replace(from, to);
00722     return this;
00723 }
00724 
00725 SyntaxNode *PostTestedLoopSyntaxNode::findNodeFor(PBB bb)
00726 {
00727     if (pbb == bb)
00728         return this;
00729     SyntaxNode *n = pBody->findNodeFor(bb);
00730     if (n == pBody)
00731         return this;
00732     return n;
00733 }
00734 
00735 void PostTestedLoopSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00736 {
00737     os << std::setw(4) << std::dec << nodenum << " ";
00738     os << "[label=\"loop posttested ";
00739     os  << cond << " \"];" << std::endl;
00740     pBody->printAST(root, os);
00741     os << std::setw(4) << std::dec << nodenum << " ";
00742     os << " -> " << pBody->getNumber() << ";" << std::endl;
00743     os << std::setw(4) << std::dec << nodenum << " ";
00744     os << " -> " << getOutEdge(root, 0)->getNumber() 
00745                  << " [style=dotted];" << std::endl;
00746 }
00747 
00748 InfiniteLoopSyntaxNode::InfiniteLoopSyntaxNode() : pBody(NULL)
00749 {
00750 }
00751 
00752 InfiniteLoopSyntaxNode::~InfiniteLoopSyntaxNode()
00753 {
00754     if (pBody)
00755         delete pBody;
00756 }
00757 
00758 int InfiniteLoopSyntaxNode::evaluate(SyntaxNode *root)
00759 {
00760     int n = 1;
00761     n += pBody->evaluate(root);
00762     return n;
00763 }
00764 
00765 void InfiniteLoopSyntaxNode::addSuccessors(SyntaxNode *root,
00766                                         std::vector<SyntaxNode*> &successors)
00767 {
00768     // we can always ignore gotos at the end of the body.
00769     if (pBody->getNumOutEdges() == 1 && pBody->endsWithGoto()) {
00770         std::cerr << "successor: ignoring goto at end of body of infinite "
00771                   << "loop" << std::endl;
00772         assert(pBody->getOutEdge(root, 0) == this);
00773         SyntaxNode *n = root->clone();
00774         n->setDepth(root->getDepth() + 1);
00775         SyntaxNode *nBody = pBody->clone();
00776         nBody->ignoreGoto();
00777         n = n->replace(pBody, nBody);
00778         successors.push_back(n);
00779     }
00780 
00781     pBody->addSuccessors(root, successors);
00782 }
00783 
00784 SyntaxNode *InfiniteLoopSyntaxNode::clone()
00785 {
00786     InfiniteLoopSyntaxNode *b = new InfiniteLoopSyntaxNode();
00787     b->correspond = this;
00788     b->pbb = pbb;
00789     b->pBody = pBody->clone();
00790     return b;
00791 }
00792 
00793 SyntaxNode *InfiniteLoopSyntaxNode::replace(SyntaxNode *from, SyntaxNode *to)
00794 {
00795     assert(correspond != from);
00796     if (pBody->getCorrespond() == from) {
00797         assert(to);
00798         pBody = to;
00799     } else 
00800         pBody = pBody->replace(from, to);
00801     return this;
00802 }
00803 
00804 SyntaxNode *InfiniteLoopSyntaxNode::findNodeFor(PBB bb)
00805 {
00806     if (pbb == bb)
00807         return this;
00808     SyntaxNode *n = pBody->findNodeFor(bb);
00809     if (n == pBody)
00810         return this;
00811     return n;
00812 }
00813 
00814 void InfiniteLoopSyntaxNode::printAST(SyntaxNode *root, std::ostream &os)
00815 {
00816     os << std::setw(4) << std::dec << nodenum << " ";
00817     os << "[label=\"loop infinite\"];" << std::endl;
00818     if (pBody)
00819         pBody->printAST(root, os);
00820     if (pBody) {
00821         os << std::setw(4) << std::dec << nodenum << " ";
00822         os << " -> " << pBody->getNumber() << ";" << std::endl;
00823     }
00824 }
00825 

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