diff options
author | Duncan Sands <baldrick@free.fr> | 2009-11-10 13:49:50 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2009-11-10 13:49:50 +0000 |
commit | 710c37c494229334f59b9be328366807db2a7d01 (patch) | |
tree | 8d7374d97bcfa2d82ff170e2e356e0699fa1fa05 | |
parent | e9097f7438cceb80871cda5f2cecb51e6639b3cc (diff) |
Teach DSE to eliminate useless trampolines.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86683 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 25 | ||||
-rw-r--r-- | test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll | 16 |
2 files changed, 35 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index 4dd0e91f90..ae25d38718 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -87,13 +87,13 @@ static bool doesClobberMemory(Instruction *I) { switch (II->getIntrinsicID()) { default: return false; case Intrinsic::memset: case Intrinsic::memmove: case Intrinsic::memcpy: - case Intrinsic::lifetime_end: return true; + case Intrinsic::init_trampoline: case Intrinsic::lifetime_end: return true; } } return false; } -/// isElidable - If the memory this instruction and the memory it writes to is +/// isElidable - If the value of this instruction and the memory it writes to is /// unused, may we delete this instrtction? static bool isElidable(Instruction *I) { assert(doesClobberMemory(I)); @@ -111,8 +111,15 @@ static Value *getPointerOperand(Instruction *I) { return SI->getPointerOperand(); if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) return MI->getOperand(1); - assert(cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::lifetime_end); - return cast<IntrinsicInst>(I)->getOperand(2); + IntrinsicInst *II = cast<IntrinsicInst>(I); + switch (II->getIntrinsicID()) { + default: + assert(false && "Unexpected intrinsic!"); + case Intrinsic::init_trampoline: + return II->getOperand(1); + case Intrinsic::lifetime_end: + return II->getOperand(2); + } } /// getStoreSize - Return the length in bytes of the write by the clobbering @@ -129,8 +136,14 @@ static unsigned getStoreSize(Instruction *I, const TargetData *TD) { Len = MI->getLength(); } else { IntrinsicInst *II = cast<IntrinsicInst>(I); - assert(II->getIntrinsicID() == Intrinsic::lifetime_end); - Len = II->getOperand(0); + switch (II->getIntrinsicID()) { + default: + assert(false && "Unexpected intrinsic!"); + case Intrinsic::init_trampoline: + return -1u; + case Intrinsic::lifetime_end: + Len = II->getOperand(0); + } } if (ConstantInt *LenCI = dyn_cast<ConstantInt>(Len)) if (!LenCI->isAllOnesValue()) diff --git a/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll b/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll new file mode 100644 index 0000000000..9a943b4760 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll @@ -0,0 +1,16 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare i8* @llvm.init.trampoline(i8*, i8*, i8*) + +declare void @f() + +define void @unused_trampoline() { +; CHECK: @unused_trampoline + %storage = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1] +; CHECK-NOT: alloca + %cast = getelementptr [10 x i8]* %storage, i32 0, i32 0 ; <i8*> [#uses=1] + %tramp = call i8* @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @f to i8*), i8* null ) ; <i8*> [#uses=1] +; CHECK-NOT: trampoline + ret void +; CHECK: ret void +} |