Index: lib/Analysis/BranchProbabilityInfo.cpp =================================================================== --- lib/Analysis/BranchProbabilityInfo.cpp +++ lib/Analysis/BranchProbabilityInfo.cpp @@ -204,11 +204,8 @@ bool BranchProbabilityInfo::calcUnreachableHeuristics(const BasicBlock *BB) { const TerminatorInst *TI = BB->getTerminator(); 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; @@ -352,11 +349,8 @@ bool BranchProbabilityInfo::calcColdCallHeuristics(const BasicBlock *BB) { const TerminatorInst *TI = BB->getTerminator(); 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 +969,8 @@ continue; if (calcMetadataWeights(BB)) continue; + if (calcInvokeHeuristics(BB)) + continue; if (calcUnreachableHeuristics(BB)) continue; if (calcColdCallHeuristics(BB)) @@ -987,7 +983,6 @@ continue; if (calcFloatingPointHeuristics(BB)) continue; - calcInvokeHeuristics(BB); } PostDominatedByUnreachable.clear(); Index: test/Analysis/BlockFrequencyInfo/loop_with_invoke.ll =================================================================== --- /dev/null +++ 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} Index: test/Analysis/BranchProbabilityInfo/loop.ll =================================================================== --- test/Analysis/BranchProbabilityInfo/loop.ll +++ test/Analysis/BranchProbabilityInfo/loop.ll @@ -489,3 +489,35 @@ 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()