[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
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31593
--- 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
interface
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
unrolling):
.L2:
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:
.L3:
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
.L4:
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
.L5:
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.
Hmm...
More information about the Gcc-bugs
mailing list