diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-08-02 22:08:01 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-08-02 22:08:01 +0000 |
commit | d8030c79fd4531a691381e7e870fe99b8a4cb8a4 (patch) | |
tree | 7b239073981a96487c4da6b27e7657e7c762e8af /lib/Transforms/InstCombine/InstructionCombining.cpp | |
parent | 0e0a8806d49038b60a0c20427d9f410b01cbb012 (diff) | |
download | external_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.zip external_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.tar.gz external_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.tar.bz2 |
Teach InstCombine that lifetime intrincs aren't a real user on the result of a
malloc call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136732 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r-- | lib/Transforms/InstCombine/InstructionCombining.cpp | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index b4a2e2a..5b763c0 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1043,7 +1043,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { -static bool IsOnlyNullComparedAndFreed(const Value &V) { +static bool IsOnlyNullComparedAndFreed(const Value &V, int Depth = 0) { + if (Depth == 8) + return false; + for (Value::const_use_iterator UI = V.use_begin(), UE = V.use_end(); UI != UE; ++UI) { const User *U = *UI; @@ -1052,6 +1055,20 @@ static bool IsOnlyNullComparedAndFreed(const Value &V) { if (const ICmpInst *ICI = dyn_cast<ICmpInst>(U)) if (ICI->isEquality() && isa<ConstantPointerNull>(ICI->getOperand(1))) continue; + if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) { + if (IsOnlyNullComparedAndFreed(*BCI, Depth+1)) + continue; + } + if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U)) { + if (GEPI->hasAllZeroIndices() && + IsOnlyNullComparedAndFreed(*GEPI, Depth+1)) + continue; + } + if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) + continue; + } return false; } return true; @@ -1064,22 +1081,29 @@ Instruction *InstCombiner::visitMalloc(Instruction &MI) { if (IsOnlyNullComparedAndFreed(MI)) { for (Value::use_iterator UI = MI.use_begin(), UE = MI.use_end(); UI != UE;) { - // We can assume that every remaining use is a free call or an icmp eq/ne - // to null, so the cast is safe. + // All the users permitted by IsOnlyNullComparedAndFreed are Instructions. Instruction *I = cast<Instruction>(*UI); // Early increment here, as we're about to get rid of the user. ++UI; - if (isFreeCall(I)) { - EraseInstFromFunction(*cast<CallInst>(I)); - continue; + if (CallInst *CI = isFreeCall(I)) { + if (CI != I) + EraseInstFromFunction(*CI); + EraseInstFromFunction(*I); + } else if (ICmpInst *C = dyn_cast<ICmpInst>(I)) { + ReplaceInstUsesWith(*C, + ConstantInt::get(Type::getInt1Ty(C->getContext()), + C->isFalseWhenEqual())); + EraseInstFromFunction(*C); + } else if (I->getType()->isVoidTy()) { + // An all-zero GEP or a bitcast. + ReplaceInstUsesWith(*I, UndefValue::get(I->getType())); + EraseInstFromFunction(*I); + } else { + // A lifetime intrinsic. + EraseInstFromFunction(*I); } - // Again, the cast is safe. - ICmpInst *C = cast<ICmpInst>(I); - ReplaceInstUsesWith(*C, ConstantInt::get(Type::getInt1Ty(C->getContext()), - C->isFalseWhenEqual())); - EraseInstFromFunction(*C); } return EraseInstFromFunction(MI); } |