[Bug fortran/48636] Enable more inlining with -O2 and higher
jb at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Apr 20 18:15:00 GMT 2011
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48636
--- Comment #11 from Janne Blomqvist <jb at gcc dot gnu.org> 2011-04-20 18:14:20 UTC ---
(In reply to comment #9)
> > But do we actually do this? I did some tests a while ago, and IIRC for assumed
> > shape dummy arguments the procedure always calculates new bounds such that they
> > start from 1. That is, the procedure assumes that the actual argument
> > descriptor may have lower bounds != 1.
> > So my argument is basically that with the new descriptor it might make sense to
> > switch the responsibility around such that it's the caller who makes sure that
> > all lower bounds are 0 (as we must have the capability to do this anyway in
> > order to call inter-operable procedures, no?) instead of the callee.
>
> No, the conversion is already done in the caller:
>
> subroutine bar(B)
> interface; subroutine foo(a); integer :: a(:); end subroutine foo
> end interface
> integer :: B(:)
> call foo(B)
> end subroutine bar
>
> Shows:
> parm.4.dim[0].lbound = 1;
> [...]
> foo (&parm.4);
> For assumed-shape actual arguments, creating a new descriptor is actually not
> needed - only for deferred shape ones - or if one does not have a full array
> ref.
> Cf. gfc_conv_array_parameter, which is called by gfc_conv_procedure_call.
>
> However, some additional calculation is also done in the the callee to
> determine the stride and offset; e.g.
> ubound.0 = (b->dim[0].ubound - b->dim[0].lbound) + 1;
> again, if the dummy argument is not deferred-shaped (allocatable or pointer),
> one actually knows that "b->dim[0].lbound" == 1. I think we have some
> redundancy here -> missed optimization.
Yes, there seems to be some redundancy indeed in that case. I dug up my
testcase:
module asstest
implicit none
contains
subroutine assub(a, r)
real, intent(in) :: a(:,:)
real, intent(out) :: r
r = a(42,43)
end subroutine assub
subroutine assub2(a, r)
real, intent(in), allocatable :: a(:,:)
real, intent(out) :: r
r = a(42,43)
end subroutine assub2
end module asstest
The -fdump-tree-original tree for this module is:
assub2 (struct array2_real(kind=4) & a, real(kind=4) & r)
{
*r = (*(real(kind=4)[0:] *) a->data)[(a->dim[0].stride * 42 +
a->dim[1].stride * 43) + a->offset];
}
assub (struct array2_real(kind=4) & a, real(kind=4) & r)
{
integer(kind=8) ubound.0;
integer(kind=8) stride.1;
integer(kind=8) ubound.2;
integer(kind=8) stride.3;
integer(kind=8) offset.4;
integer(kind=8) size.5;
real(kind=4)[0:D.1567] * a.0;
integer(kind=8) D.1567;
bit_size_type D.1568;
<unnamed-unsigned:64> D.1569;
{
integer(kind=8) D.1566;
D.1566 = a->dim[0].stride;
stride.1 = D.1566 != 0 ? D.1566 : 1;
a.0 = (real(kind=4)[0:D.1567] *) a->data;
ubound.0 = (a->dim[0].ubound - a->dim[0].lbound) + 1;
stride.3 = a->dim[1].stride;
ubound.2 = (a->dim[1].ubound - a->dim[1].lbound) + 1;
size.5 = stride.3 * NON_LVALUE_EXPR <ubound.2>;
offset.4 = -stride.1 - NON_LVALUE_EXPR <stride.3>;
D.1567 = size.5 + -1;
D.1568 = (bit_size_type) size.5 * 32;
D.1569 = (<unnamed-unsigned:64>) size.5 * 4;
}
*r = (*a.0)[(stride.1 * 42 + stride.3 * 43) + offset.4];
}
So if we make sure that the caller fixes up the descriptor so that bounds are
correct for assumed-shape parameters (as the TR requires for inter-operable
procedures), then assub could be as simple as assub2.
More information about the Gcc-bugs
mailing list