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

             Bug #: 54238
           Summary: If possible, TRANSFER should use assignment instead of
                    MEMCPY
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: bur...@gcc.gnu.org


In some cases TRANSFER can be replaced by a normal assignment (with cast),
possibly also a ARRAY_RANGE_REF with cast?

Example, the following code – which matches the currently used scalarizer for
FINAL:


use iso_c_binding, only: c_intptr_t, c_loc, c_ptr, c_int, c_f_pointer
integer(c_int), target :: array(4)
integer(c_int), pointer :: ptr

integer(c_intptr_t) :: addr
type(c_ptr) :: cptr

array = [11,22,33,44]
do i = 0, 3
  cptr = c_loc (array)
  addr = transfer (cptr, addr) + i * storage_size (array)/8
  call c_f_pointer (transfer (addr, cptr), ptr)
  print *, i,': ', ptr
end do
end


Dump of: addr = transfer (cptr, addr) + i * storage_size (array)/8

              {
                struct array1_integer(kind=4) parm.2;
                integer(kind=8) transfer.1;
                integer(kind=8) D.1876;
                integer(kind=8) D.1875;
                integer(kind=8) D.1874;

                D.1874 = 8;
                D.1875 = 8;
                __builtin_memcpy ((void *) &transfer.1, (void *) &cptr,
                                  MAX_EXPR <MIN_EXPR <D.1875, D.1874>, 0>);
                parm.2.dtype = 265;
                parm.2.dim[0].lbound = 1;
                parm.2.dim[0].ubound = 4;
                parm.2.dim[0].stride = 1;
                parm.2.data = (void *) &array[0];
                parm.2.offset = -1;
                addr = (integer(kind=8)) ((i * 32) / 8) + transfer.1;
              }

While a simple
  addr = (intptr_t) cptr;
should be sufficient.

Reply via email to