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

Erik Eckstein eeckstein at apple.com
Tue Nov 25 06:19:49 PST 2014


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

Actually the current jump threading can handle this, but only if the "r == 0" is a compare + branch. E.g. if do_something is a call, it will work.
It currently does not handle select instructions. So if do_something is a simple variable assignment, then it will not work. I think this could be added easily.

But we have a phase ordering problem: jump threading is obviously done after switch table generation (so it does not work currently for switches which are converted to tables).
If we would do jump threading before, then it might prevent switch table generation.

I suggest the following:
1) Use my patch to do this kind of "jump threading" for switch tables (solves the phase ordering problem).
2) Teach the jump threading pass to handle select instructions.

1) and 2) are unrelated.

Erik


> On 21 Nov 2014, at 19:50, Hans Wennborg <hans at chromium.org> wrote:
> 
> 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