[llvm-commits] [llvm] r148941 - in /llvm/trunk: lib/Analysis/InlineCost.cpp test/Transforms/Inline/alloca-bonus.ll
Nick Lewycky
nicholas at mxc.ca
Wed Jan 25 00:27:40 PST 2012
Author: nicholas
Date: Wed Jan 25 02:27:40 2012
New Revision: 148941
URL: http://llvm.org/viewvc/llvm-project?rev=148941&view=rev
Log:
Support pointer comparisons against constants, when looking at the inline-cost
savings from a pointer argument becoming an alloca. Sometimes callees will even
compare a pointer to null and then branch to an otherwise unreachable block!
Detect these cases and compute the number of saved instructions, instead of
bailing out and reporting no savings.
Modified:
llvm/trunk/lib/Analysis/InlineCost.cpp
llvm/trunk/test/Transforms/Inline/alloca-bonus.ll
Modified: llvm/trunk/lib/Analysis/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=148941&r1=148940&r2=148941&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InlineCost.cpp (original)
+++ llvm/trunk/lib/Analysis/InlineCost.cpp Wed Jan 25 02:27:40 2012
@@ -222,6 +222,11 @@
if (!V->getType()->isPointerTy()) return 0; // Not a pointer
unsigned Reduction = 0;
+ // Looking at ICmpInsts will never abort the analysis and return zero, and
+ // analyzing them is expensive, so save them for last so that we don't do
+ // extra work that we end up throwing out.
+ SmallVector<ICmpInst *, 4> ICmpInsts;
+
SmallVector<Value *, 4> Worklist;
Worklist.push_back(V);
do {
@@ -271,10 +276,14 @@
case Intrinsic::memmove:
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
- // SROA can usually chew through these intrinsics.
+ // SROA can usually chew through these intrinsics.
Reduction += InlineConstants::InstrCost;
break;
}
+ } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(I)) {
+ if (!isa<Constant>(ICI->getOperand(1)))
+ return 0;
+ ICmpInsts.push_back(ICI);
} else {
// If there is some other strange instruction, we're not going to be
// able to do much if we inline this.
@@ -283,6 +292,51 @@
}
} while (!Worklist.empty());
+ while (!ICmpInsts.empty()) {
+ ICmpInst *ICI = ICmpInsts.pop_back_val();
+
+ // An icmp pred (alloca, C) becomes true if the predicate is true when
+ // equal and false otherwise.
+ bool Result = ICI->isTrueWhenEqual();
+
+ SmallVector<Instruction *, 4> Worklist;
+ Worklist.push_back(ICI);
+ do {
+ Instruction *U = Worklist.pop_back_val();
+ Reduction += InlineConstants::InstrCost;
+ for (Value::use_iterator UI = U->use_begin(), UE = U->use_end();
+ UI != UE; ++UI) {
+ Instruction *I = dyn_cast<Instruction>(*UI);
+ if (!I || I->mayHaveSideEffects()) continue;
+ if (I->getNumOperands() == 1)
+ Worklist.push_back(I);
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
+ // If BO produces the same value as U, then the other operand is
+ // irrelevant and we can put it into the Worklist to continue
+ // deleting dead instructions. If BO produces the same value as the
+ // other operand, we can delete BO but that's it.
+ if (Result == true) {
+ if (BO->getOpcode() == Instruction::Or)
+ Worklist.push_back(I);
+ if (BO->getOpcode() == Instruction::And)
+ Reduction += InlineConstants::InstrCost;
+ } else {
+ if (BO->getOpcode() == Instruction::Or ||
+ BO->getOpcode() == Instruction::Xor)
+ Reduction += InlineConstants::InstrCost;
+ if (BO->getOpcode() == Instruction::And)
+ Worklist.push_back(I);
+ }
+ }
+ if (BranchInst *BI = dyn_cast<BranchInst>(I)) {
+ BasicBlock *BB = BI->getSuccessor(Result ? 0 : 1);
+ if (BB->getSinglePredecessor())
+ Reduction += InlineConstants::InstrCost * BB->size();
+ }
+ }
+ } while (!Worklist.empty());
+ }
+
return Reduction;
}
Modified: llvm/trunk/test/Transforms/Inline/alloca-bonus.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/alloca-bonus.ll?rev=148941&r1=148940&r2=148941&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/alloca-bonus.ll (original)
+++ llvm/trunk/test/Transforms/Inline/alloca-bonus.ll Wed Jan 25 02:27:40 2012
@@ -42,3 +42,42 @@
call void @llvm.lifetime.start(i64 0, i8* %E)
ret void
}
+
+define void @outer3() {
+; CHECK: @outer3
+; CHECK-NOT: call void @inner3
+ %ptr = alloca i32
+ call void @inner3(i32* %ptr, i1 undef)
+ ret void
+}
+
+define void @inner3(i32 *%ptr, i1 %x) {
+ %A = icmp eq i32* %ptr, null
+ %B = and i1 %x, %A
+ br i1 %A, label %bb.true, label %bb.false
+bb.true:
+ ; This block musn't be counted in the inline cost.
+ %t1 = load i32* %ptr
+ %t2 = add i32 %t1, 1
+ %t3 = add i32 %t2, 1
+ %t4 = add i32 %t3, 1
+ %t5 = add i32 %t4, 1
+ %t6 = add i32 %t5, 1
+ %t7 = add i32 %t6, 1
+ %t8 = add i32 %t7, 1
+ %t9 = add i32 %t8, 1
+ %t10 = add i32 %t9, 1
+ %t11 = add i32 %t10, 1
+ %t12 = add i32 %t11, 1
+ %t13 = add i32 %t12, 1
+ %t14 = add i32 %t13, 1
+ %t15 = add i32 %t14, 1
+ %t16 = add i32 %t15, 1
+ %t17 = add i32 %t16, 1
+ %t18 = add i32 %t17, 1
+ %t19 = add i32 %t18, 1
+ %t20 = add i32 %t19, 1
+ ret void
+bb.false:
+ ret void
+}
More information about the llvm-commits
mailing list