예제 #1
0
int main()
{
  char c;
  c = 'z';
  c = returnA(&c);
  if (c != 'A') abort();
  c = returnB();
  if (c != 'B') abort();
  test();
  return 0;
}
TEST_F(AuxiliaryVariablesOptimizerTests,
OptimizeAssignStmtsOneUse) {
	// Add a body to the testing function:
	//
	//   a      (VarDefStmt)
	//   b      (VarDefStmt)
	//   a = 1  (AssignStmt)
	//   b = a  (AssignStmt)
	//   return b
	//
	ShPtr<Variable> varA(Variable::create("a", IntType::create(16)));
	ShPtr<Variable> varB(Variable::create("b", IntType::create(16)));
	ShPtr<ConstInt> constInt1(ConstInt::create(llvm::APInt(16, 1)));
	ShPtr<ReturnStmt> returnB(ReturnStmt::create(varB));
	ShPtr<AssignStmt> assignBA(AssignStmt::create(varB, varA, returnB));
	ShPtr<AssignStmt> assignA1(AssignStmt::create(varA, constInt1, assignBA));
	ShPtr<VarDefStmt> varDefB(VarDefStmt::create(varB, ShPtr<Expression>(), assignA1));
	ShPtr<VarDefStmt> varDefA(VarDefStmt::create(varA, ShPtr<Expression>(), varDefB));
	testFunc->setBody(varDefA);

	INSTANTIATE_ALIAS_ANALYSIS_AND_VALUE_ANALYSIS(module);

	// Optimize the module.
	Optimizer::optimize<AuxiliaryVariablesOptimizer>(module, va,
		OptimCallInfoObtainer::create());

	// Check that the output is correct.
	ASSERT_TRUE(testFunc->getBody()) <<
		"expected a non-empty body";
	// a
	ShPtr<VarDefStmt> outVarDefA(cast<VarDefStmt>(testFunc->getBody()));
	ASSERT_EQ(varDefA, outVarDefA) <<
		"expected `" << varDefA << "`, got `" << testFunc->getBody() << "`";
	// a = 1
	ASSERT_TRUE(outVarDefA->hasSuccessor());
	ShPtr<AssignStmt> outAssignA1(cast<AssignStmt>(outVarDefA->getSuccessor()));
	ASSERT_EQ(assignA1, outAssignA1) <<
		"expected `" << assignA1 << "`, got `" << outVarDefA->getSuccessor() << "`";
	// return a
	ASSERT_TRUE(outAssignA1->hasSuccessor());
	ShPtr<ReturnStmt> outReturnA(cast<ReturnStmt>(outAssignA1->getSuccessor()));
	ASSERT_TRUE(outReturnA) <<
		"expected ReturnStmt, got `" << outAssignA1->getSuccessor() << "`";
	ASSERT_TRUE(outReturnA->getRetVal()) <<
		"expected a return value, got no return value";
	ASSERT_EQ(varA, outReturnA->getRetVal()) <<
		"expected `" << varA->getName() << "`, got `" << outReturnA->getRetVal() << "`";
}
TEST_F(AuxiliaryVariablesOptimizerTests,
OptimizeNoAssignStmtOneUseEvenIfLhsVarIsExternal) {
	// Add a body to the testing function:
	//
	//   a = 1  (VarDefStmt, where 'a' is an 'external' variable comming from a
	//           volatile load/store, see #1146)
	//   b = a  (VarDefStmt)
	//   return b
	//
	ShPtr<Variable> varA(Variable::create("a", IntType::create(16)));
	varA->markAsExternal();
	ShPtr<Variable> varB(Variable::create("b", IntType::create(16)));
	ShPtr<ConstInt> constInt1(ConstInt::create(llvm::APInt(16, 1)));
	ShPtr<ReturnStmt> returnB(ReturnStmt::create(varB));
	ShPtr<VarDefStmt> varDefB(
		VarDefStmt::create(varB, varA, returnB));
	ShPtr<VarDefStmt> varDefA(
		VarDefStmt::create(varA, constInt1, varDefB));
	testFunc->setBody(varDefA);

	INSTANTIATE_ALIAS_ANALYSIS_AND_VALUE_ANALYSIS(module);

	// Optimize the module.
	Optimizer::optimize<AuxiliaryVariablesOptimizer>(module, va,
		OptimCallInfoObtainer::create());

	// Check that the output is correct.
	ASSERT_TRUE(testFunc->getBody()) <<
		"expected a non-empty body";
	// a = 1
	ShPtr<VarDefStmt> outVarDefA(cast<VarDefStmt>(testFunc->getBody()));
	ASSERT_EQ(varDefA, outVarDefA) <<
		"expected `" << varDefA << "`, got `" << testFunc->getBody() << "`";
	// return a
	ASSERT_TRUE(outVarDefA->hasSuccessor());
	ShPtr<ReturnStmt> outReturnA(cast<ReturnStmt>(outVarDefA->getSuccessor()));
	ASSERT_TRUE(outReturnA) <<
		"expected ReturnStmt, got `" << outVarDefA->getSuccessor() << "`";
	ASSERT_TRUE(outReturnA->getRetVal()) <<
		"expected a return value, got no return value";
	ASSERT_EQ(varA, outReturnA->getRetVal()) <<
		"expected `" << varA->getName() << "`, got `" << outReturnA->getRetVal() << "`";
}
TEST_F(AuxiliaryVariablesOptimizerTests,
DoNotOptimizeWhenRhsIsGlobalVariable) {
	// Add a body to the testing function:
	//
	//   global a
	//
	//   a = 1  (AssignStmt)
	//   b = a  (VarDefStmt)
	//   return b
	//
	ShPtr<Variable> varA(Variable::create("a", IntType::create(16)));
	module->addGlobalVar(varA);
	ShPtr<Variable> varB(Variable::create("b", IntType::create(16)));
	ShPtr<ConstInt> constInt1(ConstInt::create(llvm::APInt(16, 1)));
	ShPtr<ReturnStmt> returnB(ReturnStmt::create(varB));
	ShPtr<VarDefStmt> varDefB(
		VarDefStmt::create(varB, varA, returnB));
	ShPtr<AssignStmt> assignA1(
		AssignStmt::create(varA, constInt1, varDefB));
	testFunc->setBody(assignA1);

	INSTANTIATE_ALIAS_ANALYSIS_AND_VALUE_ANALYSIS(module);

	// Optimize the module.
	Optimizer::optimize<AuxiliaryVariablesOptimizer>(module, va,
		OptimCallInfoObtainer::create());

	// Check that the output is correct.
	// a = 1
	ShPtr<Statement> stmt1(testFunc->getBody());
	ASSERT_EQ(assignA1, stmt1) <<
		"expected `" << assignA1 << "`, got `" << stmt1 << "`";
	// b = a
	ShPtr<Statement> stmt2(stmt1->getSuccessor());
	ASSERT_EQ(varDefB, stmt2) <<
		"expected `" << varDefB << "`, got `" << stmt2 << "`";
	// return b
	ShPtr<Statement> stmt3(stmt2->getSuccessor());
	ASSERT_EQ(returnB, stmt3) <<
		"expected `" << returnB << "`, got `" << stmt3 << "`";
}
TEST_F(AuxiliaryVariablesOptimizerTests,
DoNotOptimizeWhenAuxiliaryVariableIsExternal) {
	// Add a body to the testing function:
	//
	//   a = 1  (VarDefStmt)
	//   b = a  (VarDefStmt, where 'b' is an 'external' variable comming from a
	//           volatile load/store, see #1146)
	//   return b
	//
	ShPtr<Variable> varA(Variable::create("a", IntType::create(16)));
	ShPtr<Variable> varB(Variable::create("b", IntType::create(16)));
	varB->markAsExternal();
	ShPtr<ConstInt> constInt1(ConstInt::create(llvm::APInt(16, 1)));
	ShPtr<ReturnStmt> returnB(ReturnStmt::create(varB));
	ShPtr<VarDefStmt> varDefB(
		VarDefStmt::create(varB, varA, returnB));
	ShPtr<VarDefStmt> varDefA(
		VarDefStmt::create(varA, constInt1, varDefB));
	testFunc->setBody(varDefA);

	INSTANTIATE_ALIAS_ANALYSIS_AND_VALUE_ANALYSIS(module);

	// Optimize the module.
	Optimizer::optimize<AuxiliaryVariablesOptimizer>(module, va,
		OptimCallInfoObtainer::create());

	// Check that the output is correct.
	// a = 1
	ShPtr<Statement> stmt1(testFunc->getBody());
	ASSERT_EQ(varDefA, stmt1) <<
		"expected `" << varDefA << "`, got `" << stmt1 << "`";
	// b = a
	ShPtr<Statement> stmt2(stmt1->getSuccessor());
	ASSERT_EQ(varDefB, stmt2) <<
		"expected `" << varDefB << "`, got `" << stmt2 << "`";
	// return b
	ShPtr<Statement> stmt3(stmt2->getSuccessor());
	ASSERT_EQ(returnB, stmt3) <<
		"expected `" << returnB << "`, got `" << stmt3 << "`";
}