https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570

--- Comment #14 from kargls at comcast dot net ---
(In reply to Andi Kleen from comment #13)
> Reducing the use of the function makes sense (I suspect it's not needed in
> many cases), but another option would be to allow moving it out of loops if
> it covers the whole loop body. The later would fix this test case too. This
> would need some special case code in the loop im optimizer though.

It would be better to understand if it is needed at all
than adding code to do the analysis of whether it can be
moved out of a loop.

Consider, 

  program bah
    integer i
    real :: y = 1.
    do i = 1, 10
       call foo(y)
    end do
  end program bah

  subroutine foo(x)
    use ieee_arithmetic
    integer i
    real x
    real, external :: bar
    x = ieee_next_after(x, 10.) + bar(x)
  end subroutine foo

This has the intermediate code (with comments added)

__attribute__((fn spec (". w ")))
void foo (real(kind=4) & restrict x)
{
  c_char fpstate.0[33];

  try
    {
      /* Required on entry into foo() */
      _gfortran_ieee_procedure_entry ((void *) &fpstate.0);

      {
        c_char fpstate.1[33];

        /* Intended for entry into ieee_next_after, but applies to entire
           expression.  There is no loop, and it is clear the this should
           not be needed here. */
        _gfortran_ieee_procedure_entry ((void *) &fpstate.1);

        *x = __builtin_nextafterf (*x, 1.0e+1) + bar ((real(kind=4) *) x);

        /* Intended for exit from ieee_next_after, but applies to entire
           expression.  There is no loop, and it is clear the this should
           not be need here as the 'finally' section takes care of updating
          . */
        _gfortran_ieee_procedure_exit ((void *) &fpstate.1);
      }
    }
  finally
    {
      /* Required on exit from foo() */
      _gfortran_ieee_procedure_exit ((void *) &fpstate.0);
    }
}


__attribute__((fn spec (". ")))
void bah ()
{
  integer(kind=4) i;
  static real(kind=4) y = 1.0e+0;

  /* Here's your loop. */
  i = 1;
  while (1)
    {
      {
        logical(kind=4) D.4673;

        D.4673 = i > 10;
        if (D.4673) goto L.2;
        foo (&y);
        L.1:;
        i = i + 1;
      }
    }
  L.2:;
}

Reply via email to