From e9f9a7e10ef6c159e6afb9f230ce216828d3282a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 3 Sep 2009 05:19:59 +0000 Subject: [PATCH] In C++, code is not allowed to call main. In C it is, this simplifylibcalls optimization is thus valid for C++ but not C. It's not important enough to worry about for C++ apps, so just remove it. rdar://7191924 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80887 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SimplifyLibCalls.cpp | 61 ++----------------- .../Transforms/SimplifyLibCalls/ExitInMain.ll | 15 ----- 2 files changed, 4 insertions(+), 72 deletions(-) delete mode 100644 test/Transforms/SimplifyLibCalls/ExitInMain.ll diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 32a547398de..419d66f7af4 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -9,11 +9,9 @@ // // This file implements a simple pass that applies a variety of small // optimizations for calls to specific well-known function calls (e.g. runtime -// library functions). For example, a call to the function "exit(3)" that -// occurs within the main() function can be transformed into a simple "return 3" -// instruction. Any optimization that takes this form (replace call to library -// function with simpler code that provides the same result) belongs in this -// file. +// library functions). Any optimization that takes the very simple form +// "replace call to library function with simpler code that provides the same +// result" belongs in this file. // //===----------------------------------------------------------------------===// @@ -498,59 +496,13 @@ static bool IsOnlyUsedInZeroEqualityComparison(Value *V) { return true; } -//===----------------------------------------------------------------------===// -// Miscellaneous LibCall Optimizations -//===----------------------------------------------------------------------===// - -namespace { -//===---------------------------------------===// -// 'exit' Optimizations - -/// ExitOpt - int main() { exit(4); } --> int main() { return 4; } -struct ExitOpt : public LibCallOptimization { - virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { - // Verify we have a reasonable prototype for exit. - if (Callee->arg_size() == 0 || !CI->use_empty()) - return 0; - - // Verify the caller is main, and that the result type of main matches the - // argument type of exit. - if (Caller->getName() != "main" || !Caller->hasExternalLinkage() || - Caller->getReturnType() != CI->getOperand(1)->getType()) - return 0; - - TerminatorInst *OldTI = CI->getParent()->getTerminator(); - - // Drop all successor phi node entries. - for (unsigned i = 0, e = OldTI->getNumSuccessors(); i != e; ++i) - OldTI->getSuccessor(i)->removePredecessor(CI->getParent()); - - // Remove all instructions after the exit. - BasicBlock::iterator Dead = CI, E = OldTI; ++Dead; - while (Dead != E) { - BasicBlock::iterator Next = next(Dead); - if (Dead->getType() != Type::getVoidTy(*Context)) - Dead->replaceAllUsesWith(UndefValue::get(Dead->getType())); - Dead->eraseFromParent(); - Dead = Next; - } - - // Insert a return instruction. - OldTI->eraseFromParent(); - B.SetInsertPoint(B.GetInsertBlock()); - B.CreateRet(CI->getOperand(1)); - - return CI; - } -}; - //===----------------------------------------------------------------------===// // String and Memory LibCall Optimizations //===----------------------------------------------------------------------===// //===---------------------------------------===// // 'strcat' Optimizations - +namespace { struct StrCatOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify the "strcat" function prototype. @@ -1554,8 +1506,6 @@ namespace { /// class SimplifyLibCalls : public FunctionPass { StringMap Optimizations; - // Miscellaneous LibCall Optimizations - ExitOpt Exit; // String and Memory LibCall Optimizations StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrNCpyOpt StrNCpy; StrLenOpt StrLen; @@ -1602,9 +1552,6 @@ FunctionPass *llvm::createSimplifyLibCallsPass() { /// Optimizations - Populate the Optimizations map with all the optimizations /// we know. void SimplifyLibCalls::InitOptimizations() { - // Miscellaneous LibCall Optimizations - Optimizations["exit"] = &Exit; - // String and Memory LibCall Optimizations Optimizations["strcat"] = &StrCat; Optimizations["strncat"] = &StrNCat; diff --git a/test/Transforms/SimplifyLibCalls/ExitInMain.ll b/test/Transforms/SimplifyLibCalls/ExitInMain.ll deleted file mode 100644 index 8abf3b1cc46..00000000000 --- a/test/Transforms/SimplifyLibCalls/ExitInMain.ll +++ /dev/null @@ -1,15 +0,0 @@ -; Test that the ExitInMainOptimization pass works correctly -; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | \ -; RUN: grep {ret i32 3} | count 1 -; END. - -declare void @exit(i32) - -declare void @exitonly(i32) - -define i32 @main() { - call void @exitonly( i32 3 ) - call void @exit( i32 3 ) - ret i32 0 -} -