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
This commit is contained in:
Chris Lattner 2009-09-03 05:19:59 +00:00
parent 47548d3365
commit e9f9a7e10e
2 changed files with 4 additions and 72 deletions

View File

@ -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<LibCallOptimization*> 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;

View File

@ -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
}