On Mon, May 20, 2019 at 4:51 PM Feng Xue OS <f...@os.amperecomputing.com> wrote:
>
> > I don't see how it is safe in a late pass when it is not safe in an
>
> > earlier one.  Optimization is imperfect - we could fail to remove
> > an "obvious" never taken exit and still have a loop that appears to be
> > finite according to our definition.
>
> Yes. it is. This is somewhat similar to strict-alias option/loop dep pragma.
> Compiler tries to do something based on hint you tell it, but does not ensure 
> correctness.
>
> > The only way
> > to define it would be if there was, at any point, an exit from the
> > loop (and there it _may_ be exclude EH edges) then
> > the loop is assumed to be finite.
>
> No catch your point. If we treat an infinite loop as finite, it's bad because 
> the loop might be removed.
>
> Suppose we have a function:
>
>     void foo(int bound)
>      { for (int i = 0; i <= bound; i++); }
>
>  In an early CD-DCE pass, "bound" is represented as a variable, and loop has 
> a exit, so it is assumed to finite, and is removed.
>
> But in a late pass, this function is inlined into another one, and "bound" 
> has value of INT_MAX, this loop is infinite, and here we can know it should 
> not be removed.

But if "bound" is always INT_MAX but that's not visible to the
compiler we will still remove the
loop so I see no difference with removing it always.

> This is why I suggest doing the optimization as late as possible.

But this will defeat the purpose of allowing followup optimizations.

IMHO the only "sensible" thing is to do

Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c  (revision 271415)
+++ gcc/tree-ssa-dce.c  (working copy)
@@ -417,7 +417,7 @@ find_obviously_necessary_stmts (bool agg
          }

       FOR_EACH_LOOP (loop, 0)
-       if (!finite_loop_p (loop))
+       if (!loop_has_exit_edges (loop))
          {
            if (dump_file)
              fprintf (dump_file, "cannot prove finiteness of loop
%i\n", loop->num);

that also has the obvious advantage that we don't need to replace the loop
with a trap() but have a place to forward control flow to.  The loop in the
following testcase is then successfully removed:

int main(int argc, char **argv)
{
  unsigned i = argc;
  while (i+=2);
  return 0;
}

Likewise is the loop

void **q;
int main(int argc, char **argv)
{
  void **p = q;
  while (p = (void **)*p);
  return 0;
}

(that's the pointer-chasing).  Not with -fnon-call-exceptions
-fexceptions though.

Richard.

> Feng
>

Reply via email to