[Bug fortran/31593] Invariant DO loop variables and subroutines

tkoenig at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Jul 19 17:00:33 GMT 2020


--- Comment #49 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
(In reply to Tobias Schlüter from comment #48)
> Forgive me, I wasn't aware of this oversight which may have turned away
> people who could fix this for the past 6 years.

That didn't happen :-)

Unfortunately, we still have the problem:

$ gfortran -O3 call_intent.f90 && time ./a.out > /dev/null

real    0m1,208s
user    0m1,203s
sys     0m0,004s
$ gfortran -O3 call_parens.f90 && time ./a.out > /dev/null

real    0m1,130s
user    0m1,126s
sys     0m0,004s
$ gfortran -O3 call_unspec.f90 && time ./a.out > /dev/null

real    0m1,994s
user    0m1,989s
sys     0m0,004s

Revisiting this with a test case that is a bit more simple:

program main
     subroutine intent_unspec (i)
       integer :: i
     end subroutine intent_unspec
     subroutine intent_in (i)
       integer, intent(in) :: i
     end subroutine intent_in
     subroutine do_value (i)
       integer, value :: i
     end subroutine do_value
  end interface
  integer :: i

  do i=1,10
     call intent_unspec(i)
  end do

  do i=1,10
     call intent_in(i)
  end do
  do i=1,10
     call intent_unspec ((i))
  end do

  do i=1,10
     call do_value (i)
  end do

end program main

The looping part of the first loop gets translated to (with -O2, so no loop

        leaq    8(%rsp), %rdi
        call    intent_unspec_
        movl    8(%rsp), %eax
        addl    $1, %eax
        movl    %eax, 8(%rsp)
        cmpl    $10, %eax
        jle     .L2

You can see the reload of the index variable from the stack
after the call.

The second loop:

        leaq    8(%rsp), %rdi
        call    intent_in_
        movl    %ebx, 8(%rsp)
        addl    $1, %ebx
        cmpl    $12, %ebx
        jne     .L3

No reload from the stack, but not quite ideal yet.  That
movl %ebx, 8(%rsp) would have been unneeded had one of the
callee-saved registers been used.

The third one is

        movl    %ebx, 12(%rsp)
        leaq    12(%rsp), %rdi
        addl    $1, %ebx
        call    intent_unspec_
        movl    %ebx, 8(%rsp)
        cmpl    $11, %ebx
        jne     .L4

short (six instructions) but to loads / stores from
and two stack.

Finally, the last one

        movl    %ebx, %edi
        addl    $1, %ebx
        call    do_value_
        cmpl    $11, %ebx
        jne     .L5

That, of course, can use a register to pass the value,
this is the best.


More information about the Gcc-bugs mailing list