mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 06:32:09 +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
|
// This file implements a simple pass that applies a variety of small
|
||||||
// optimizations for calls to specific well-known function calls (e.g. runtime
|
// optimizations for calls to specific well-known function calls (e.g. runtime
|
||||||
// library functions). For example, a call to the function "exit(3)" that
|
// library functions). Any optimization that takes the very simple form
|
||||||
// occurs within the main() function can be transformed into a simple "return 3"
|
// "replace call to library function with simpler code that provides the same
|
||||||
// instruction. Any optimization that takes this form (replace call to library
|
// result" belongs in this file.
|
||||||
// function with simpler code that provides the same result) belongs in this
|
|
||||||
// file.
|
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@ -498,59 +496,13 @@ static bool IsOnlyUsedInZeroEqualityComparison(Value *V) {
|
|||||||
return true;
|
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
|
// String and Memory LibCall Optimizations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
//===---------------------------------------===//
|
//===---------------------------------------===//
|
||||||
// 'strcat' Optimizations
|
// 'strcat' Optimizations
|
||||||
|
namespace {
|
||||||
struct StrCatOpt : public LibCallOptimization {
|
struct StrCatOpt : public LibCallOptimization {
|
||||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||||
// Verify the "strcat" function prototype.
|
// Verify the "strcat" function prototype.
|
||||||
@ -1554,8 +1506,6 @@ namespace {
|
|||||||
///
|
///
|
||||||
class SimplifyLibCalls : public FunctionPass {
|
class SimplifyLibCalls : public FunctionPass {
|
||||||
StringMap<LibCallOptimization*> Optimizations;
|
StringMap<LibCallOptimization*> Optimizations;
|
||||||
// Miscellaneous LibCall Optimizations
|
|
||||||
ExitOpt Exit;
|
|
||||||
// String and Memory LibCall Optimizations
|
// String and Memory LibCall Optimizations
|
||||||
StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrCmpOpt StrCmp;
|
StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrCmpOpt StrCmp;
|
||||||
StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrNCpyOpt StrNCpy; StrLenOpt StrLen;
|
StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrNCpyOpt StrNCpy; StrLenOpt StrLen;
|
||||||
@ -1602,9 +1552,6 @@ FunctionPass *llvm::createSimplifyLibCallsPass() {
|
|||||||
/// Optimizations - Populate the Optimizations map with all the optimizations
|
/// Optimizations - Populate the Optimizations map with all the optimizations
|
||||||
/// we know.
|
/// we know.
|
||||||
void SimplifyLibCalls::InitOptimizations() {
|
void SimplifyLibCalls::InitOptimizations() {
|
||||||
// Miscellaneous LibCall Optimizations
|
|
||||||
Optimizations["exit"] = &Exit;
|
|
||||||
|
|
||||||
// String and Memory LibCall Optimizations
|
// String and Memory LibCall Optimizations
|
||||||
Optimizations["strcat"] = &StrCat;
|
Optimizations["strcat"] = &StrCat;
|
||||||
Optimizations["strncat"] = &StrNCat;
|
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…
x
Reference in New Issue
Block a user