This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[FORTRAN PATCH] Eliminate temporary when passing constant array constructors as arguments


The following patch to the gfortran front-end improves the way that array
constructors are passed as function arguments.  The current implementation
copies the entire array constructor into a temporary array to allow the
temporary array's descriptor to be passed to the function.  In the patch
below we improve this for constant array constructors (of non-character
types) by creating a descriptor for the array constructor (much like we do
for regular array variables) and pass that.  As with regular array
variables this avoids any copying loops.

When combined with my previous patch to correctly detect dependencies on
array constructors we can now expand the following code without any array
temporaries.

  integer :: x(6)

  x = cshift((/ 1, 2, 3, 4, 5, 6/), 2)
end

With these two pending patches we get:

    int4 x[6];
    static int4 C.1362 = 2;
    struct array1_int4 parm.2;
    static int4 A.1[6] = {1, 2, 3, 4, 5, 6};
    struct array1_int4 parm.0;

    parm.0.dtype = 265;
    parm.0.dim[0].lbound = 1;
    parm.0.dim[0].ubound = 6;
    parm.0.dim[0].stride = 1;
    parm.0.data = (void *) &x[0];
    parm.0.offset = 0;
    parm.2.dtype = 265;
    parm.2.dim[0].lbound = 1;
    parm.2.dim[0].ubound = 6;
    parm.2.dim[0].stride = 1;
    parm.2.data = (void *) &A.1[0];
    parm.2.offset = 0;
    _gfortran_cshift0_4 (&parm.0, &parm.2, &C.1362, 0B);


Compare this to current mainline where we generate:

    int4 x[6];
    int4 A.5[6];
    struct array1_int4 atmp.4;
    static int4 C.1364 = 2;
    int4 A.2[6];
    struct array1_int4 atmp.1;
    static int4 A.0[6] = {1, 2, 3, 4, 5, 6};

    atmp.1.dtype = 265;
    atmp.1.dim[0].stride = 1;
    atmp.1.dim[0].lbound = 0;
    atmp.1.dim[0].ubound = 5;
    atmp.1.data = (void *) &A.2;
    atmp.1.offset = 0;
    {
      int8 S.3;

      S.3 = 0;
      while (1)
        {
          if (S.3 > 5) goto L.1;
          (*(int4[0:] *) atmp.1.data)[S.3] = A.0[S.3];
          S.3 = S.3 + 1;
        }
      L.1:;
    }
    atmp.4.dtype = 265;
    atmp.4.dim[0].stride = 1;
    atmp.4.dim[0].lbound = 0;
    atmp.4.dim[0].ubound = 5;
    atmp.4.data = (void *) &A.5;
    atmp.4.offset = 0;
    _gfortran_cshift0_4 (&atmp.4, &atmp.1, &C.1364, 0B);
    {
      int8 S.6;

      S.6 = 0;
      while (1)
        {
          if (S.6 > 5) goto L.2;
          x[NON_LVALUE_EXPR <S.6>] = (*(int4[0:] *) atmp.4.data)[S.6];
          S.6 = S.6 + 1;
        }
      L.2:;
    }


The following patch has been tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", all default languages including gfortran, and
regression tested with a top-level "make -k check" with no new failures.

Ok for mainline?


2007-02-01  Roger Sayle  <roger@eyesopen.com>

        * trans-array.c (gfc_conv_expr_descriptor): We don't need to use
        a temporary array to pass a constant non-chracter array constructor.
        Generalize the descriptor generation code to handle scalarizer
        "info" without an array reference.

Roger
--

Attachment: patchf3.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]