]> git.ipfire.org Git - thirdparty/gcc.git/commit
fortran: Inline non-character MINLOC/MAXLOC with no DIM [PR90608]
authorMikael Morin <mikael@gcc.gnu.org>
Sat, 21 Sep 2024 16:32:59 +0000 (18:32 +0200)
committerMikael Morin <mikael@gcc.gnu.org>
Sat, 21 Sep 2024 16:32:59 +0000 (18:32 +0200)
commit7d43b4e06786c1023210f90e5231bde947aef3af
tree88938c917f25d22695e99fe6fac5f816638b289a
parent5999d558e74b3531536c74976e8f05bb3ed31335
fortran: Inline non-character MINLOC/MAXLOC with no DIM [PR90608]

Enable generation of inline MINLOC/MAXLOC code in the case where DIM
is not present, and either ARRAY is of floating point type or MASK is an
array.  Those cases are the remaining bits to fully support inlining of
non-CHARACTER MINLOC/MAXLOC without DIM.  They are treated together because
they generate similar code, the NANs for REAL types being handled a bit like
a second level of masking.  These are the cases for which we generate two
sets of loops.

This change affects the code generating the second loop, that was previously
accessible only in the cases ARRAY has rank 1 only.  The single variable
initialization and update are changed to apply to multiple variables, one
per dimension.

The code generated is as follows (if ARRAY has rank 2):

for (idx11 in lower1..upper1)
  {
    for (idx12 in lower2..upper2)
      {
...
if (...)
  {
    ...
    goto second_loop;
  }
      }
  }
second_loop:
for (idx21 in lower1..upper1)
  {
    for (idx22 in lower2..upper2)
      {
...
      }
  }

This code leads to processing the first elements redundantly, both in the
first set of loops and in the second one.  The loop over idx22 could
start from idx12 the first time it is run, but as it has to start from
lower2 for the rest of the runs, this change uses the same bounds for both
set of loops for simplicity.  In the rank 1 case, this makes the generated
code worse compared to the inline code that was generated before.  A later
change will introduce conditionals to avoid the duplicate processing and
restore the generated code in that case.

PR fortran/90608

gcc/fortran/ChangeLog:

* trans-intrinsic.cc (gfc_conv_intrinsic_minmaxloc): Initialize
and update all the variables.  Put the label and goto in the
outermost scalarizer loop.  Don't start the second loop where the
first stopped.
(gfc_inline_intrinsic_function_p): Also return TRUE for array MASK
or for any REAL type.

gcc/testsuite/ChangeLog:

* gfortran.dg/maxloc_bounds_5.f90: Additionally accept error
messages reported by the scalarizer.
* gfortran.dg/maxloc_bounds_6.f90: Ditto.
gcc/fortran/trans-intrinsic.cc
gcc/testsuite/gfortran.dg/maxloc_bounds_5.f90
gcc/testsuite/gfortran.dg/maxloc_bounds_6.f90