/// 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<InvokeInst>(TI))
- return false;
+ assert(!isa<InvokeInst>(TI) &&
+ "Invokes should have already been handled by calcInvokeHeuristics");
SmallVector<unsigned, 4> UnreachableEdges;
SmallVector<unsigned, 4> ReachableEdges;
/// 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<InvokeInst>(TI))
- return false;
+ assert(!isa<InvokeInst>(TI) &&
+ "Invokes should have already been handled by calcInvokeHeuristics");
// Determine which successors are post-dominated by a cold block.
SmallVector<unsigned, 4> ColdEdges;
continue;
if (calcMetadataWeights(BB))
continue;
+ if (calcInvokeHeuristics(BB))
+ continue;
if (calcUnreachableHeuristics(BB))
continue;
if (calcColdCallHeuristics(BB))
continue;
if (calcFloatingPointHeuristics(BB))
continue;
- calcInvokeHeuristics(BB);
}
PostDominatedByUnreachable.clear();
--- /dev/null
+; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -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}
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()