# [PATCH] Improving LowerSwitch behavior for contiguous ranges

David Blaikie dblaikie at gmail.com
Tue Jun 10 08:19:46 PDT 2014

```On Tue, Jun 10, 2014 at 5:26 AM, Marcello Maggioni <hayarms at gmail.com> wrote:
> Hello,
>
> when LowerSwitch transforms a switch instruction into a tree of ifs it is
> actually performing a binary search into the various case ranges, to see if
> the current value falls into one cases range of values.
>
> So, if we have a program with something like this:
>
> switch (a) {
> case 0:
>   do0();
>   break;
> case 1:
>   do1();
>   break;
> case 2:
>   do2();
>   break;
> default:
>   break;
> }
>
> the code produced is something like this:
>
>   if (a < 1) {
>     if (a == 0) {
>       do0();
>     }
>   } else {
>     if (a < 2) {
>       if (a == 1) {
>         do1();
>       }
>     } else {
>       if (a == 2) {
>         do2();
>       }
>     }
>   }
>
> This code is inefficient because the check (a == 1) to execute do1() is not
> needed.
>
> The reason is that because we already checked that (a >= 1) initially by
> checking that also  (a < 2) we basically already inferred that (a == 1)
> without the need of an extra basic block spawned to check if actually (a ==
> 1).
>
> The proposed patch addresses this problem by keeping track of already
> checked bounds in the LowerSwitch algorithm, so that when the time arrives
> to produce a Leaf Block that checks the equality with the case value / range
> the algorithm can decide if that block is really needed depending on the
>
> For example, the above with "a = 1" would work like this:
>
> the bounds start as LB: NONE , UB: NONE
> as (a < 1) is emitted the bounds for the else path become LB: 1 UB: NONE.
> This happens because by failing the test (a < 1) we know that the value "a"
> cannot be smaller than 1 if we enter the else branch.
> After the emitting the check (a < 2) the bounds in the if branch become LB:
> 1 UB: 1. This is because by checking that "a" is smaller than 2 then the
> upper bound becomes 2 - 1 = 1.
>
> When is time to emit the leaf block for "case 1:" we notice that 1 is
> squeezed exactly in between the LB and UB, which means that if we arrived to
> that block there is no need to emit a block that checks if (a == 1).
>
>
> Please let me know if I did something wrong here and if the reasoning is
> correct :)
>
> The proposed patch also sets as XFAIL the test:
> "test/Transforms/LowerSwitch/feature.ll".
> This test checks that the emitted lowered CFG is exactly the one expected by
> the previous algorithm without this optimization. Of course this test starts
> failing when this optimization is added. I added another test that is the
> same, but is updated with the new expected CFG.
>
> Don't know what is the best thing to do with the original "feature.ll" test
> in the case this patch gets accepted. Should we remove it or keep it as a
> reference?

Most likely we should just change the original to test the new
behavior, and not introduce a new test. If the original test doesn't
test all cases of the new behavior and can't be reasonably made to do
so, we could introduce a new test for those new cases (while keeping
the old one covering the existing cases, but updated to verify the new
optimization you've implemented is functioning)

- David

>
> Cheers,
> Marcello
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>

```