From 710c37c494229334f59b9be328366807db2a7d01 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 10 Nov 2009 13:49:50 +0000 Subject: [PATCH] Teach DSE to eliminate useless trampolines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86683 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/DeadStoreElimination.cpp | 25 ++++++++++++++----- .../2009-11-10-Trampoline.ll | 16 ++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index 4dd0e91f908..ae25d38718d 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(I)) return MI->getOperand(1); - assert(cast(I)->getIntrinsicID() == Intrinsic::lifetime_end); - return cast(I)->getOperand(2); + IntrinsicInst *II = cast(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(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(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 00000000000..9a943b47602 --- /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 ; [#uses=1] + %tramp = call i8* @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @f to i8*), i8* null ) ; [#uses=1] +; CHECK-NOT: trampoline + ret void +; CHECK: ret void +} -- 2.34.1