You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For example, `llvm/test/Transforms/LoopUnroll/peel-branch-weights.ll`
tests the following LLVM IR:
```
define void @test() {
entry:
br label %loop
loop:
%x = call i32 @get.x()
switch i32 %x, label %loop.latch [
i32 0, label %loop.latch
i32 1, label %loop.exit
i32 2, label %loop.exit
], !prof !0
loop.latch:
br label %loop
loop.exit:
ret void
}
!0 = !{!"branch_weights", i32 100, i32 200, i32 20, i32 10}
```
Given those branch weights, once any loop iteration is actually
reached, the probability of the loop exiting at the iteration's end is
(20+10)/(100+200+20+10) = 1/11. That is, the loop is likely to exit
every 11 iterations. `opt -passes='print<block-freq>'` shows that 11
is indeed the frequency of the loop body:
```
block-frequency-info: test
- entry: float = 1.0, int = 1637672590245888
- loop: float = 11.0, int = 18014398509481984
- loop.latch: float = 10.0, int = 16376725919236096
- loop.exit: float = 1.0, int = 1637672590245888
```
Key Observation: The frequency of reaching any particular iteration is
logically less than for the previous iteration exactly because the
previous iteration has a non-zero probability of exiting the loop.
This observation holds even though every loop iteration, once actually
reached, has exactly the same probability of exiting and exactly the
same branch weights.
After peeling 2 iterations as in the test, we expect those
observations not to change, but they do under the implementation
without this patch. The block frequency becomes 1.0 for the first
iteration, 0.90909 for the second, and 7.3636 for the main loop body.
Again, a decreasing frequency is expected, but it decreases too much:
the total frequency of the original loop body becomes 9.2727. The new
branch weights reveal the problem:
```
!0 = !{!"branch_weights", i32 100, i32 200, i32 20, i32 10}
!1 = !{!"branch_weights", i32 90, i32 180, i32 20, i32 10}
!2 = !{!"branch_weights", i32 80, i32 160, i32 20, i32 10}
```
The exit probability is now 1/11 for the first peeled iteration, 1/10
for the second, and 1/9 for the remaining loop iterations. Based on
comments in `LoopPeel.cpp`, it seems this behavior was trying to
ensure a decreasing frequency. However, as explained above for the
original loop, that happens correctly without decreasing the branch
weights across iterations.
This patch changes the peeling implementation not to decrease the
branch weights across loop iterations so that the probabilities for
every iteration are the same as they were in the original loop. The
total frequency of the loop body, summed across all its occurrences,
thus remains 11 after peeling.
0 commit comments