summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/IPO/PartialInlining.cpp19
-rw-r--r--llvm/test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll40
2 files changed, 49 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp
index 00ad0d84697..917582a706b 100644
--- a/llvm/lib/Transforms/IPO/PartialInlining.cpp
+++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp
@@ -834,42 +834,41 @@ bool PartialInlinerImpl::shouldPartialInline(
int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB) {
int InlineCost = 0;
const DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
- for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
- if (isa<DbgInfoIntrinsic>(I))
- continue;
-
- switch (I->getOpcode()) {
+ for (Instruction &I : BB->instructionsWithoutDebug()) {
+ // Skip free instructions.
+ switch (I.getOpcode()) {
case Instruction::BitCast:
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::Alloca:
+ case Instruction::PHI:
continue;
case Instruction::GetElementPtr:
- if (cast<GetElementPtrInst>(I)->hasAllZeroIndices())
+ if (cast<GetElementPtrInst>(&I)->hasAllZeroIndices())
continue;
break;
default:
break;
}
- IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(I);
+ IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&I);
if (IntrInst) {
if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start ||
IntrInst->getIntrinsicID() == Intrinsic::lifetime_end)
continue;
}
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (CallInst *CI = dyn_cast<CallInst>(&I)) {
InlineCost += getCallsiteCost(CallSite(CI), DL);
continue;
}
- if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
+ if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
InlineCost += getCallsiteCost(CallSite(II), DL);
continue;
}
- if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
+ if (SwitchInst *SI = dyn_cast<SwitchInst>(&I)) {
InlineCost += (SI->getNumCases() + 1) * InlineConstants::InstrCost;
continue;
}
diff --git a/llvm/test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll b/llvm/test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll
new file mode 100644
index 00000000000..a8c2d62710d
--- /dev/null
+++ b/llvm/test/Transforms/CodeExtractor/PartialInlineEntryPHICost.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -partial-inliner -S | FileCheck %s
+; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s
+
+; Check that we do not overcompute the outlined region cost, where the PHIs in
+; the outlined region entry (BB4) are moved outside the region by CodeExtractor.
+
+define i32 @bar(i32 %arg) {
+bb:
+ %tmp = icmp slt i32 %arg, 0
+ br i1 %tmp, label %bb1, label %bb2
+
+bb1:
+ br i1 undef, label %bb4, label %bb2
+
+bb2: ; preds = %bb, %bb1
+ br i1 undef, label %bb4, label %bb5
+
+bb4: ; preds = %bb1, %bb2
+ %xx1 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ]
+ %xx2 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ]
+ %xx3 = phi i32 [ 1, %bb1 ], [ 9, %bb2 ]
+ tail call void (...) @foo() #2
+ br label %bb5
+
+bb5: ; preds = %bb4, %bb2
+ %tmp6 = phi i32 [ 1, %bb2 ], [ 9, %bb4 ]
+ ret i32 %tmp6
+}
+
+declare void @foo(...)
+
+define i32 @dummy_caller(i32 %arg) {
+bb:
+; CHECK-LABEL: @dummy_caller
+; CHECK: br i1
+; CHECK: br i1
+; CHECK: call void @bar.1.
+ %tmp = tail call i32 @bar(i32 %arg)
+ ret i32 %tmp
+}
OpenPOWER on IntegriCloud