mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Switch lowering: Take branch weight into account when ordering for fall-through
Previously, the code would try to put a fall-through case last, even if that meant moving a case with much higher branch weight further down the chain. Ordering by branch weight is most important, putting a fall-through block last is secondary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235942 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ae51ba7ea1
commit
b176a4f2e4
@ -7678,11 +7678,12 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
|
||||
return a.Weight > b.Weight;
|
||||
});
|
||||
|
||||
// Rearrange the case blocks so that the last one falls through if possible.
|
||||
// Start at the bottom as that's the case with the lowest weight.
|
||||
// FIXME: Take branch probability into account.
|
||||
// Rearrange the case blocks so that the last one falls through if possible
|
||||
// without without changing the order of weights.
|
||||
for (CaseClusterIt I = W.LastCluster; I > W.FirstCluster; ) {
|
||||
--I;
|
||||
if (I->Weight > W.LastCluster->Weight)
|
||||
break;
|
||||
if (I->Kind == CC_Range && I->MBB == NextMBB) {
|
||||
std::swap(*I, *W.LastCluster);
|
||||
break;
|
||||
|
@ -49,14 +49,14 @@ tailrecurse.switch: ; preds = %tailrecurse
|
||||
; V8-NEXT: beq
|
||||
; V8-NEXT: %tailrecurse.switch
|
||||
; V8: cmp
|
||||
; V8-NEXT: beq
|
||||
; V8-NEXT: bne
|
||||
; V8-NEXT: b
|
||||
; The trailing space in the last line checks that the branch is unconditional
|
||||
switch i32 %and, label %sw.epilog [
|
||||
i32 1, label %sw.bb
|
||||
i32 3, label %sw.bb6
|
||||
i32 2, label %sw.bb8
|
||||
]
|
||||
], !prof !1
|
||||
|
||||
sw.bb: ; preds = %tailrecurse.switch, %tailrecurse
|
||||
%shl = shl i32 %acc.tr, 1
|
||||
@ -134,3 +134,5 @@ bb4: ; preds = %bb2
|
||||
return: ; preds = %bb2, %bb, %entry
|
||||
ret i8 1
|
||||
}
|
||||
|
||||
!1 = !{!"branch_weights", i32 1, i32 1, i32 3, i32 2 }
|
||||
|
@ -17,9 +17,9 @@ entry:
|
||||
; CHECK: BB#0: derived from LLVM BB %entry
|
||||
; CHECK: Successors according to CFG: BB#2(64) BB#4(14)
|
||||
; CHECK: BB#4: derived from LLVM BB %entry
|
||||
; CHECK: Successors according to CFG: BB#1(4) BB#5(10)
|
||||
; CHECK: Successors according to CFG: BB#1(10) BB#5(4)
|
||||
; CHECK: BB#5: derived from LLVM BB %entry
|
||||
; CHECK: Successors according to CFG: BB#1(10) BB#3(7)
|
||||
; CHECK: Successors according to CFG: BB#1(4) BB#3(7)
|
||||
|
||||
sw.bb:
|
||||
br label %return
|
||||
|
@ -30,7 +30,7 @@ if.then:
|
||||
if.end:
|
||||
switch i64 undef, label %if.end25 [
|
||||
i64 0, label %if.then4
|
||||
i64 1, label %land.lhs.true14
|
||||
i64 1, label %if.end25
|
||||
]
|
||||
|
||||
if.then4:
|
||||
|
@ -413,3 +413,32 @@ return: ret void
|
||||
i32 4294967295, i32 2, i32 4294967295,
|
||||
; Cases 2,5,8,9:
|
||||
i32 3, i32 3, i32 3, i32 3}
|
||||
|
||||
define void @order_by_weight_and_fallthrough(i32 %x) {
|
||||
entry:
|
||||
switch i32 %x, label %return [
|
||||
i32 100, label %bb1
|
||||
i32 200, label %bb0
|
||||
i32 300, label %bb0
|
||||
], !prof !2
|
||||
bb0: tail call void @g(i32 0) br label %return
|
||||
bb1: tail call void @g(i32 1) br label %return
|
||||
return: ret void
|
||||
|
||||
; Case 200 has the highest weight and should come first. 100 and 300 have the
|
||||
; same weight, but 300 goes to the 'next' block, so should be last.
|
||||
; CHECK-LABEL: order_by_weight_and_fallthrough
|
||||
; CHECK: cmpl $200
|
||||
; CHECK: cmpl $100
|
||||
; CHECK: cmpl $300
|
||||
}
|
||||
|
||||
!2 = !{!"branch_weights",
|
||||
; Default:
|
||||
i32 1,
|
||||
; Case 100:
|
||||
i32 10,
|
||||
; Case 200:
|
||||
i32 1000,
|
||||
; Case 300:
|
||||
i32 10}
|
||||
|
Loading…
Reference in New Issue
Block a user