diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index ed4dc9031ab..1a4fc0465bb 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -203,12 +203,10 @@ BranchProbabilityInfo::updatePostDominatedByColdCall(const BasicBlock *BB) { /// unreachable-terminated block as extremely unlikely. bool BranchProbabilityInfo::calcUnreachableHeuristics(const BasicBlock *BB) { const TerminatorInst *TI = BB->getTerminator(); + (void) TI; assert(TI->getNumSuccessors() > 1 && "expected more than one successor!"); - - // Return false here so that edge weights for InvokeInst could be decided - // in calcInvokeHeuristics(). - if (isa(TI)) - return false; + assert(!isa(TI) && + "Invokes should have already been handled by calcInvokeHeuristics"); SmallVector UnreachableEdges; SmallVector ReachableEdges; @@ -351,12 +349,10 @@ bool BranchProbabilityInfo::calcMetadataWeights(const BasicBlock *BB) { /// Return false, otherwise. bool BranchProbabilityInfo::calcColdCallHeuristics(const BasicBlock *BB) { const TerminatorInst *TI = BB->getTerminator(); + (void) TI; assert(TI->getNumSuccessors() > 1 && "expected more than one successor!"); - - // Return false here so that edge weights for InvokeInst could be decided - // in calcInvokeHeuristics(). - if (isa(TI)) - return false; + assert(!isa(TI) && + "Invokes should have already been handled by calcInvokeHeuristics"); // Determine which successors are post-dominated by a cold block. SmallVector ColdEdges; @@ -975,6 +971,8 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI, continue; if (calcMetadataWeights(BB)) continue; + if (calcInvokeHeuristics(BB)) + continue; if (calcUnreachableHeuristics(BB)) continue; if (calcColdCallHeuristics(BB)) @@ -987,7 +985,6 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI, continue; if (calcFloatingPointHeuristics(BB)) continue; - calcInvokeHeuristics(BB); } PostDominatedByUnreachable.clear(); diff --git a/test/Analysis/BlockFrequencyInfo/loop_with_invoke.ll b/test/Analysis/BlockFrequencyInfo/loop_with_invoke.ll new file mode 100644 index 00000000000..4e554f8d9c8 --- /dev/null +++ b/test/Analysis/BlockFrequencyInfo/loop_with_invoke.ll @@ -0,0 +1,35 @@ +; RUN: opt < %s -analyze -block-freq | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s + +; CHECK-LABEL: Printing analysis {{.*}} for function 'loop_with_invoke': +; CHECK-NEXT: block-frequency-info: loop_with_invoke +define void @loop_with_invoke(i32 %n) personality i8 0 { +; CHECK-NEXT: entry: float = 1.0, int = [[ENTRY:[0-9]+]] +entry: + br label %loop + +; CHECK-NEXT: loop: float = 9905.6 +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %invoke.cont ] + invoke void @foo() to label %invoke.cont unwind label %lpad + +; CHECK-NEXT: invoke.cont: float = 9905.6 +invoke.cont: + %i.next = add i32 %i, 1 + %cont = icmp ult i32 %i.next, %n + br i1 %cont, label %loop, label %exit, !prof !0 + +; CHECK-NEXT: lpad: float = 0.0094467 +lpad: + %ll = landingpad { i8*, i32 } + cleanup + br label %exit + +; CHECK-NEXT: exit: float = 1.0, int = [[ENTRY]] +exit: + ret void +} + +declare void @foo() + +!0 = !{!"branch_weights", i32 9999, i32 1} diff --git a/test/Analysis/BranchProbabilityInfo/loop.ll b/test/Analysis/BranchProbabilityInfo/loop.ll index e8bf19061d6..63377e3ba95 100644 --- a/test/Analysis/BranchProbabilityInfo/loop.ll +++ b/test/Analysis/BranchProbabilityInfo/loop.ll @@ -489,3 +489,35 @@ for.inc: br label %for.cond ; CHECK: edge for.inc -> for.cond probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] } + +; The loop heuristic should not overwrite the invoke heuristic. The unwind destination +; of an invoke should be considered VERY rare even in a loop. +define void @test12(i32 %a) personality i8 0 { +entry: + br label %loop +; CHECK: edge entry -> loop probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] + +loop: + %i.0 = phi i32 [ 0, %entry ], [ %inc, %invoke.cont ] + invoke i32 @InvokeCall() + to label %invoke.cont unwind label %lpad +; CHECK: edge loop -> invoke.cont probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] +; CHECK: edge loop -> lpad probability is 0x00000800 / 0x80000000 = 0.00% + +invoke.cont: + %inc = add nsw i32 %i.0, 1 + %cmp = icmp slt i32 %inc, %a + br i1 %cmp, label %loop, label %exit +; CHECK: edge invoke.cont -> loop probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge] +; CHECK: edge invoke.cont -> exit probability is 0x04000000 / 0x80000000 = 3.12% + +lpad: + %ll = landingpad { i8*, i32 } + cleanup + br label %exit + +exit: + ret void +} + +declare i32 @InvokeCall()