------- Comment #1 from burnus at gcc dot gnu dot org  2009-11-02 21:23 -------
Actually, it is not as simple as it seems. Currently, one gets for


  subroutine one(a)
    integer, dimension(:) :: a
    call two(a)
  end subroutine one
  subroutine two(a)
    integer, dimension(:) :: a
  end subroutine two


the following dump:


one (struct array1_integer(kind=4) & restrict a)
{
  integer(kind=8) ubound.0;
  integer(kind=8) stride.1;
  integer(kind=8) offset.2;
  integer(kind=8) size.3;
  integer(kind=4)[0:D.1401] * restrict a.0;
  integer(kind=8) D.1401;
  bit_size_type D.1402;
  <unnamed-unsigned:64> D.1403;

  {
    integer(kind=8) D.1400;

    D.1400 = a->dim[0].stride;
    stride.1 = D.1400 != 0 ? D.1400 : 1;
    a.0 = (integer(kind=4)[0:D.1401] * restrict) a->data;
    ubound.0 = (a->dim[0].ubound - a->dim[0].lbound) + 1;
    size.3 = stride.1 * NON_LVALUE_EXPR <ubound.0>;
    offset.2 = -stride.1;
    D.1401 = size.3 + -1;
    D.1402 = (bit_size_type) size.3 * 32;
    D.1403 = (<unnamed-unsigned:64>) size.3 * 4;
  }
  {
    integer(kind=8) D.1399;
    integer(kind=8) D.1398;
    struct array1_integer(kind=4) parm.4;
    integer(kind=8) D.1394;

    D.1394 = ubound.0;
    parm.4.dtype = 265;
    D.1398 = offset.2;
    D.1399 = stride.1;
    parm.4.dim[0].lbound = 1;
    parm.4.dim[0].ubound = D.1394;
    parm.4.dim[0].stride = NON_LVALUE_EXPR <D.1399>;
    parm.4.data = (void *) &(*a.0)[0];
    parm.4.offset = NON_LVALUE_EXPR <D.1398>;
    two (&parm.4);
  }
}


In principle. passing "two(&a)" would be sufficient. However:

The "a -> a.0" conversion happens at the very beginning of the procedure
(trans-decl.c I presume). Passing "a.0" (== parmse.expr in
gfc_conv_procedure_call) is wrong as "a.0" is not a descriptor but just a
pointer to the (noncontiguous) array.

Passing "a" as in "two (&a)" is presumably also wrong as this presumably
collides with "restricted".

 * * *

One way out would be -- assuming ABI breakage -- to do the same conversion for
the caller but then do not do conversion in the callee. Thus:

one (struct array1_integer(kind=4) & restrict a)
{
   a.data[0] = 5
rather than
   /* generate a whole stuff of plain variables used like a descriptor */
   a.0[0] = 5
   two (&a)

That way one uses the restricted variable directly, and one saves the
generation of a extra variables and arithmetic.

The question is whether one needs to take care of things like:
    stride.1 = D.1400 != a->dim[0].stride ? D.1400 : 1;

Actually, it might be no ABI breakage - assuming all descriptor variables are
properly initialized in current 4.(3-5). One needs to check this.


-- 

burnus at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|burnus at gcc dot gnu dot   |unassigned at gcc dot gnu
                   |org                         |dot org
             Status|ASSIGNED                    |NEW


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41911

Reply via email to