void BlockSyntaxNode::addSuccessors(SyntaxNode *root, std::vector<SyntaxNode *> &successors) { for (unsigned i = 0; i < statements.size(); i++) { if (statements[i]->isBlock()) { //BlockSyntaxNode *b = (BlockSyntaxNode*)statements[i]; // can move previous statements into this block if (i > 0) { std::cerr << "successor: move previous statement into block" << std::endl; SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); BlockSyntaxNode *b1 = (BlockSyntaxNode *)this->clone(); BlockSyntaxNode *nb = (BlockSyntaxNode *)b1->getStatement(i); b1 = (BlockSyntaxNode *)b1->replace(statements[i - 1], NULL); nb->prependStatement(statements[i - 1]->clone()); n = n->replace(this, b1); successors.push_back(n); //PRINT_BEFORE_AFTER } } else { if (statements.size() != 1) { // can replace statement with a block containing that statement std::cerr << "successor: replace statement with a block containing the statement" << std::endl; BlockSyntaxNode *b = new BlockSyntaxNode(); b->addStatement(statements[i]->clone()); SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); n = n->replace(statements[i], b); successors.push_back(n); //PRINT_BEFORE_AFTER } } // "jump over" style of if-then if (i < statements.size() - 2 && statements[i]->isBranch()) { SyntaxNode *b = statements[i]; if (b->getOutEdge(root, 0) == statements[i + 2] && (statements[i + 1]->getOutEdge(root, 0) == statements[i + 2] || statements[i + 1]->endsWithGoto())) { std::cerr << "successor: jump over style if then" << std::endl; BlockSyntaxNode *b1 = (BlockSyntaxNode *)this->clone(); b1 = (BlockSyntaxNode *)b1->replace(statements[i + 1], NULL); IfThenSyntaxNode *nif = new IfThenSyntaxNode(); Exp *cond = b->getBB()->getCond(); cond = new Unary(opLNot, cond->clone()); cond = cond->simplify(); nif->setCond(cond); nif->setThen(statements[i + 1]->clone()); nif->setBB(b->getBB()); b1->setStatement(i, nif); SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); n = n->replace(this, b1); successors.push_back(n); //PRINT_BEFORE_AFTER } } // if then else if (i < statements.size() - 2 && statements[i]->isBranch()) { SyntaxNode *tThen = statements[i]->getOutEdge(root, 0); SyntaxNode *tElse = statements[i]->getOutEdge(root, 1); assert(tThen && tElse); if (((tThen == statements[i + 2] && tElse == statements[i + 1]) || (tThen == statements[i + 1] && tElse == statements[i + 2])) && tThen->getNumOutEdges() == 1 && tElse->getNumOutEdges() == 1) { SyntaxNode *else_out = tElse->getOutEdge(root, 0); SyntaxNode *then_out = tThen->getOutEdge(root, 0); if (else_out == then_out) { std::cerr << "successor: if then else" << std::endl; SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); n = n->replace(tThen, NULL); n = n->replace(tElse, NULL); IfThenElseSyntaxNode *nif = new IfThenElseSyntaxNode(); nif->setCond(statements[i]->getBB()->getCond()->clone()); nif->setBB(statements[i]->getBB()); nif->setThen(tThen->clone()); nif->setElse(tElse->clone()); n = n->replace(statements[i], nif); successors.push_back(n); //PRINT_BEFORE_AFTER } } } // pretested loop if (i < statements.size() - 2 && statements[i]->isBranch()) { SyntaxNode *tBody = statements[i]->getOutEdge(root, 0); SyntaxNode *tFollow = statements[i]->getOutEdge(root, 1); assert(tBody && tFollow); if (tBody == statements[i + 1] && tFollow == statements[i + 2] && tBody->getNumOutEdges() == 1 && tBody->getOutEdge(root, 0) == statements[i]) { std::cerr << "successor: pretested loop" << std::endl; SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); n = n->replace(tBody, NULL); PretestedLoopSyntaxNode *nloop = new PretestedLoopSyntaxNode(); nloop->setCond(statements[i]->getBB()->getCond()->clone()); nloop->setBB(statements[i]->getBB()); nloop->setBody(tBody->clone()); n = n->replace(statements[i], nloop); successors.push_back(n); //PRINT_BEFORE_AFTER } } // posttested loop if (i > 0 && i < statements.size() - 1 && statements[i]->isBranch()) { SyntaxNode *tBody = statements[i]->getOutEdge(root, 0); SyntaxNode *tFollow = statements[i]->getOutEdge(root, 1); assert(tBody && tFollow); if (tBody == statements[i - 1] && tFollow == statements[i + 1] && tBody->getNumOutEdges() == 1 && tBody->getOutEdge(root, 0) == statements[i]) { std::cerr << "successor: posttested loop" << std::endl; SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); n = n->replace(tBody, NULL); PostTestedLoopSyntaxNode *nloop = new PostTestedLoopSyntaxNode(); nloop->setCond(statements[i]->getBB()->getCond()->clone()); nloop->setBB(statements[i]->getBB()); nloop->setBody(tBody->clone()); n = n->replace(statements[i], nloop); successors.push_back(n); //PRINT_BEFORE_AFTER } } // infinite loop if (statements[i]->getNumOutEdges() == 1 && statements[i]->getOutEdge(root, 0) == statements[i]) { std::cerr << "successor: infinite loop" << std::endl; SyntaxNode *n = root->clone(); n->setDepth(root->getDepth() + 1); InfiniteLoopSyntaxNode *nloop = new InfiniteLoopSyntaxNode(); nloop->setBody(statements[i]->clone()); n = n->replace(statements[i], nloop); successors.push_back(n); PRINT_BEFORE_AFTER } statements[i]->addSuccessors(root, successors); }