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 << "`"; }