X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=libgfortran%2Fm4%2Feoshift1.m4;h=196a65ef5a33040edde752198894ca4f93bf8eec;hb=83ffe9cde7fe0b4deb0d1b54175fd9b19c38179c;hp=01ca57ec68ded957d5f36f3259de1418b7d108be;hpb=c44109aaf3be31a6816a8a4f3c4454261d8d2622;p=thirdparty%2Fgcc.git diff --git a/libgfortran/m4/eoshift1.m4 b/libgfortran/m4/eoshift1.m4 index 01ca57ec68de..196a65ef5a33 100644 --- a/libgfortran/m4/eoshift1.m4 +++ b/libgfortran/m4/eoshift1.m4 @@ -1,36 +1,29 @@ `/* Implementation of the EOSHIFT intrinsic - Copyright 2002, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2002-2023 Free Software Foundation, Inc. Contributed by Paul Brook -This file is part of the GNU Fortran 95 runtime library (libgfortran). +This file is part of the GNU Fortran runtime library (libgfortran). Libgfortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) +version 3 of the License, or (at your option) any later version. Libgfortran is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public -License along with libgfortran; see the file COPYING. If not, -write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ #include "libgfortran.h" -#include -#include #include ' include(iparm.m4)dnl @@ -43,7 +36,7 @@ eoshift1 (gfc_array_char * const restrict ret, const 'atype` * const restrict h, const char * const restrict pbound, const 'atype_name` * const restrict pwhich, - index_type size, const char * filler, index_type filler_len) + const char * filler, index_type filler_len) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; @@ -67,6 +60,8 @@ eoshift1 (gfc_array_char * const restrict ret, index_type dim; index_type len; index_type n; + index_type size; + index_type arraysize; int which; 'atype_name` sh; 'atype_name` delta; @@ -77,6 +72,8 @@ eoshift1 (gfc_array_char * const restrict ret, soffset = 0; roffset = 0; + size = GFC_DESCRIPTOR_SIZE(array); + if (pwhich) which = *pwhich - 1; else @@ -85,51 +82,66 @@ eoshift1 (gfc_array_char * const restrict ret, extent[0] = 1; count[0] = 0; - if (ret->data == NULL) + arraysize = size0 ((array_t *) array); + if (ret->base_addr == NULL) { - int i; - - ret->data = internal_malloc_size (size * size0 ((array_t *)array)); ret->offset = 0; - ret->dtype = array->dtype; - for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) + GFC_DTYPE_COPY(ret,array); + for (index_type i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { - ret->dim[i].lbound = 0; - ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound; + index_type ub, str; + + ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1; if (i == 0) - ret->dim[i].stride = 1; + str = 1; else - ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride; + str = GFC_DESCRIPTOR_EXTENT(ret,i-1) + * GFC_DESCRIPTOR_STRIDE(ret,i-1); + + GFC_DIMENSION_SET(ret->dim[i], 0, ub, str); + } + /* xmallocarray allocates a single byte for zero size. */ + ret->base_addr = xmallocarray (arraysize, size); + } - else + else if (unlikely (compile_options.bounds_check)) { - if (size0 ((array_t *) ret) == 0) - return; + bounds_equal_extents ((array_t *) ret, (array_t *) array, + "return value", "EOSHIFT"); } + if (unlikely (compile_options.bounds_check)) + { + bounds_reduced_extents ((array_t *) h, (array_t *) array, which, + "SHIFT argument", "EOSHIFT"); + } + + if (arraysize == 0) + return; + n = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { - roffset = ret->dim[dim].stride * size; + roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); if (roffset == 0) roffset = size; - soffset = array->dim[dim].stride * size; + soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); if (soffset == 0) soffset = size; - len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; + len = GFC_DESCRIPTOR_EXTENT(array,dim); } else { count[n] = 0; - extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound; - rstride[n] = ret->dim[dim].stride * size; - sstride[n] = array->dim[dim].stride * size; + extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim); + rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); + sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); - hstride[n] = h->dim[n].stride; + hstride[n] = GFC_DESCRIPTOR_STRIDE(h,n); n++; } } @@ -144,9 +156,9 @@ eoshift1 (gfc_array_char * const restrict ret, rstride0 = rstride[0]; sstride0 = sstride[0]; hstride0 = hstride[0]; - rptr = ret->data; - sptr = array->data; - hptr = h->data; + rptr = ret->base_addr; + sptr = array->base_addr; + hptr = h->base_addr; while (rptr) { @@ -170,12 +182,23 @@ eoshift1 (gfc_array_char * const restrict ret, src = sptr; dest = &rptr[delta * roffset]; } - for (n = 0; n < len - delta; n++) - { - memcpy (dest, src, size); - dest += roffset; - src += soffset; - } + + /* If the elements are contiguous, perform a single block move. */ + if (soffset == size && roffset == size) + { + size_t chunk = size * (len - delta); + memcpy (dest, src, chunk); + dest += chunk; + } + else + { + for (n = 0; n < len - delta; n++) + { + memcpy (dest, src, size); + dest += roffset; + src += soffset; + } + } if (sh < 0) dest = rptr; n = delta; @@ -247,8 +270,7 @@ eoshift1_'atype_kind` (gfc_array_char * const restrict ret, const char * const restrict pbound, const 'atype_name` * const restrict pwhich) { - eoshift1 (ret, array, h, pbound, pwhich, GFC_DESCRIPTOR_SIZE (array), - "\0", 1); + eoshift1 (ret, array, h, pbound, pwhich, "\0", 1); } @@ -268,10 +290,10 @@ eoshift1_'atype_kind`_char (gfc_array_char * const restrict ret, const 'atype` * const restrict h, const char * const restrict pbound, const 'atype_name` * const restrict pwhich, - GFC_INTEGER_4 array_length, + GFC_INTEGER_4 array_length __attribute__((unused)), GFC_INTEGER_4 bound_length __attribute__((unused))) { - eoshift1 (ret, array, h, pbound, pwhich, array_length, " ", 1); + eoshift1 (ret, array, h, pbound, pwhich, " ", 1); } @@ -291,11 +313,11 @@ eoshift1_'atype_kind`_char4 (gfc_array_char * const restrict ret, const 'atype` * const restrict h, const char * const restrict pbound, const 'atype_name` * const restrict pwhich, - GFC_INTEGER_4 array_length, + GFC_INTEGER_4 array_length __attribute__((unused)), GFC_INTEGER_4 bound_length __attribute__((unused))) { static const gfc_char4_t space = (unsigned char) ''` ''`; - eoshift1 (ret, array, h, pbound, pwhich, array_length * sizeof (gfc_char4_t), + eoshift1 (ret, array, h, pbound, pwhich, (const char *) &space, sizeof (gfc_char4_t)); }