Exemple #1
0
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);
	}