[PATCH] peephole optimization in switch table lookup: reuse the guarding table comparison if possible

Hans Wennborg hans at chromium.org
Fri Nov 21 10:50:42 PST 2014


On Thu, Nov 20, 2014 at 6:49 AM, Erik Eckstein <eeckstein at apple.com> wrote:
>> From what I understand, this is doing something different
>
> The approach is different, but the result is the same: v1, v2, ... are constants and op is the compare (r == 0 in our example). Together with jump threading the compare will be eliminated.
> I actually tried it and it works. The only limitation is that FoldOpIntoPhi requires that the phi has no other uses than the compare (but this could be changed).

But if the phi has multiple uses, we're no longer replacing it with
the compare, we'd need to create one new phi node for each different
operation we're folding, thus creating a bunch of new values which is
probably a pessimization.

> Now I thought it would be a good idea to just do FoldOpIntoPhi instead of my patch. But it's not that easy because of phase ordering: it must be done before switch table generation but only if it does not prevent switch table generation.
> Anyway I found that doing it separately is easier and it has the advantage that I only do it if the cmp can be optimized away afterwards (FoldOpIntoPhi would also trigger if the cmp is against a case value).
>
> I attached another version of my patch. The main difference is that I made it more general by doing "constant propagation" on the compare.

This jump threading doesn't have anything to do with switch tables,
and forwarding the switch table range check is not interesting in
itself (it might even be a pessimization); what's interesting is that
the if condition is only true for one of the predecessors, so we can
get rid off the expensive conditional branch with jump threading
should kick in.

Could jump threading or one of its analyses be taught to handle this?
So that we could also handle a case like:

  switch (x) {
    case 0: r = 10; break;
    case 1: foo(); r = 11; break; // side effects; can't build lookup table
    ...
    default: r = 0; break;
  }
  if (r == 0) { // condition is only true for one predecessor; jump thread!
    do_something;
  }

 - Hans



More information about the llvm-commits mailing list