For the following Fortran program, the recursion could be replaced by a loop. That's what happening for the related C program, but for the Fortran program the recursion remains. (Tried with -O3.) (I guess the I/O statement (_gfortran_st_write* and _gfortran_transfer_*_write) confuse the ME, but I do not see why that should prevent the loop transformation. Hints how to modify the FE to help the ME are welcome, too.) ! Fortran version call x (1) contains recursive subroutine x (i) use iso_fortran_env integer, value :: i if (mod (i, 1000000) == 0) write (error_unit,'(a,i0)')'i=', i call x (i+1) end subroutine x end /* C version */ #include <stdio.h> static void x (int i) { if (!(i % 1000000)) fprintf(stderr, "i=%d\n", i); x(i + 1); } int main () { x (1); }
The parameter has its address taken in _gfortran_transfer_integer_write (&dt_parm.0, &i, 4); thus we can't tail-recurse here (well, at least not as trivial as if that wasn't the case).
(In reply to comment #1) > The parameter has its address taken in > _gfortran_transfer_integer_write (&dt_parm.0, &i, 4); True, but the value is not modified - which the ME should know as the "fn spec" is ".wR"
(In reply to comment #2) > (In reply to comment #1) > > The parameter has its address taken in > > _gfortran_transfer_integer_write (&dt_parm.0, &i, 4); > > True, but the value is not modified - which the ME should know as the "fn spec" > is ".wR" The parameter is not in SSA form so tail-recursion would have to insert a store and reload the value at appropriate places. It doesn't support that.
I think this is solved. For gcc 9.2.0, when I build the testcase as `gcc test.c -o a -g -O2`, and then look at the assembly with `objdump -d a | vim -`, I see `main` function has just a single `callq`, which is to `printf`. So the whole code was apparently optimized and inlined into main().