mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
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:
parent
47548d3365
commit
e9f9a7e10e
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user