[PATCH] Loop unswitching: support gswitch statements.

Martin Liška mliska@suse.cz
Tue Nov 16 13:53:35 GMT 2021


On 11/11/21 08:15, Richard Biener wrote:
> If you look at simplify_using_entry_checks then this is really really simple,
> so I'd try to abstract this, recording sth like a unswitch_predicate where
> we store the condition we unswitch on plus maybe cache the constant
> range of a VAR cmp CST variable condition on the true/false edge.  We
> can then try to simplify each gcond/gswitch based on such an unswitch_predicate
> (when we ever scan the loop once to discover all opportunities we'd have a
> set of unswitch_predicates to try simplifying against).  As said the integer
> range thing would be an improvement over the current state so even that
> can be done as followup but I guess for gswitch support that's going to be
> the thing to use.

I started working on the unswitch_predicate where I recond also true/false-edge irange
of an expression we unswitch on.

I noticed one significant problem, let's consider:

   for (int i = 0; i < size; i++)
   {
     double tmp;

     if (order == 1)
       tmp = -8 * a[i];
     else
       {
	if (order == 2)
	  tmp = -4 * b[i];
	else
	  tmp = a[i];
       }

     r[i] = 3.4f * tmp + d[i];
   }

We can end up with first unswitching candidate being 'if (order == 2)' (I have a real benchmark where it happens).
So I collect ranges and they are [2,2] for true edge and [-INF, 0], [3, INF] (because we came to the condition through order != 1 cond).
Then the loop is cloned and we have

if (order == 2)
    loop_version_1
else
    loop_version_2

but in loop_version_2 we wrongly fold 'if (order == 1)' to false because it's reflected in the range.

So the question is, can one iterate get_loop_body stmts in some dominator order?

Thanks,
Martin




More information about the Gcc-patches mailing list