Пример #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);
	}
Пример #2
0
int BlockSyntaxNode::evaluate(SyntaxNode *root)
{
#if DEBUG_EVAL
	if (this == root)
		std::cerr << "begin eval =============" << std::endl;
#endif
	if (pbb)
		return 1;
	int n = 1;
	if (statements.size() == 1) {
		SyntaxNode *out = statements[0]->getOutEdge(root, 0);
		if (out->getBB() != NULL && out->getBB()->getNumInEdges() > 1) {
#if DEBUG_EVAL
			std::cerr << "add 15" << std::endl;
#endif
			n += 15;
		} else {
#if DEBUG_EVAL
			std::cerr << "add 30" << std::endl;
#endif
			n += 30;
		}
	}
	for (unsigned i = 0; i < statements.size(); i++) {
		n += statements[i]->evaluate(root);
		if (statements[i]->isGoto()) {
			if (i != statements.size() - 1) {
#if DEBUG_EVAL
				std::cerr << "add 100" << std::endl;
#endif
				n += 100;
			} else {
#if DEBUG_EVAL
				std::cerr << "add 50" << std::endl;
#endif
				n += 50;
			}
		} else if (statements[i]->isBranch()) {
			SyntaxNode *loop = root->getEnclosingLoop(this);
			std::cerr << "branch " << statements[i]->getNumber()
			          << " not in loop" << std::endl;
			if (loop) {
				std::cerr << "branch " << statements[i]->getNumber()
				          << " in loop " << loop->getNumber() << std::endl;
				// this is a bit C specific
				SyntaxNode *out = loop->getOutEdge(root, 0);
				if (out && statements[i]->getOutEdge(root, 0) == out) {
					std::cerr << "found break" << std::endl;
					n += 10;
				}
				if (statements[i]->getOutEdge(root, 0) == loop) {
					std::cerr << "found continue" << std::endl;
					n += 10;
				}
			} else {
#if DEBUG_EVAL
				std::cerr << "add 50" << std::endl;
#endif
				n += 50;
			}
		} else if (i < statements.size() - 1
		        && statements[i]->getOutEdge(root, 0) != statements[i + 1]) {
#if DEBUG_EVAL
			std::cerr << "add 25" << std::endl;
			std::cerr << statements[i]->getNumber() << " -> "
			          << statements[i]->getOutEdge(root, 0)->getNumber()
			          << " not " << statements[i + 1]->getNumber() << std::endl;
#endif
			n += 25;
		}
	}
#if DEBUG_EVAL
	if (this == root)
		std::cerr << "end eval = " << n << " =============" << std::endl;
#endif
	return n;
}