00001
00002 #include <fstream>
00003 #include <iomanip>
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
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
00222
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
00235 }
00236 } else {
00237 if (statements.size() != 1) {
00238
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
00248 }
00249 }
00250
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
00274 }
00275 }
00276
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
00302 }
00303 }
00304 }
00305
00306
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
00326 }
00327 }
00328
00329
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
00350 }
00351 }
00352
00353
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
00500
00501
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
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
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
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