]> git.ipfire.org Git - thirdparty/gcc.git/commit
fortran: Inline MINLOC/MAXLOC with DIM and scalar MASK [PR90608]
authorMikael Morin <mikael@gcc.gnu.org>
Tue, 19 Nov 2024 16:31:25 +0000 (17:31 +0100)
committerMikael Morin <mikael@gcc.gnu.org>
Tue, 19 Nov 2024 16:31:25 +0000 (17:31 +0100)
commitf74f52642fc0bd6b4c6828bd6e86aa5bb206cbca
treef7ed86f146d518087a7263e6ce23ee2bdf32c7b4
parentb111b55f5bd7903643326ae4447b6d112609cafa
fortran: Inline MINLOC/MAXLOC with DIM and scalar MASK [PR90608]

Enable the generation of inline code for MINLOC/MAXLOC when argument
ARRAY is of integral type and has rank > 1, DIM is a constant, and MASK is
scalar (only absent MASK or rank 1 ARRAY were inlined before).

Scalar masks are implemented with a wrapping condition around the code
one would generate if MASK wasn't present, so they are easy to support
once inline code without MASK is working.

With this change, there are both expressions evaluated inside the nested
loop (ARRAY, and in the future MASK if non-scalar) and expressions evaluated
outside of it (MASK if scalar).  For both one has to advance the
scalarization chain passed as argument SE to gfc_conv_intrinsic_minmaxloc as
they are evaluated, but for expressions evaluated from within the nested
loop one has to advance additionally the nested scalarization chain of the
reduction loop.  This is normally handled transparently through the
inheritance that is defined when initializing gfc_se structs, but there has
to be some variable to inherit from, and there is a single one, SE.  This
variable is kept as base for out of nested loop expressions only (i.e. for
scalar MASK), and this change introduces a new variable to hold the current
advance of the nested loop scalarization chain and serve as inheritance base
to evaluate nested loop expressions (just ARRAY for now, additionally
non-scalar MASK later).

PR fortran/90608

gcc/fortran/ChangeLog:

* trans-intrinsic.cc (gfc_inline_intrinsic_function_p): Return TRUE
if MASK is scalar.
(walk_inline_intrinsic_minmaxloc): Append to the scalarization chain
a scalar element for MASK if it's present.
(gfc_conv_intrinsic_minmaxloc): Use a local gfc_se struct to serve
as base for all the expressions evaluated in the nested loop.  To
evaluate MASK when there is a nested loop, enable usage of the
scalarizer and set the original passed in SE argument as current
scalarization chain element to use.  And use the nested loop from
the scalarizer instead of the local loop in that case.

gcc/testsuite/ChangeLog:

* gfortran.dg/maxloc_bounds_8.f90: Accept the error message
generated by the scalarizer in case the MAXLOC intrinsic call is
implemented through inline code.
* gfortran.dg/minmaxloc_20.f90: New test.
gcc/fortran/trans-intrinsic.cc
gcc/testsuite/gfortran.dg/maxloc_bounds_8.f90
gcc/testsuite/gfortran.dg/minmaxloc_20.f90 [new file with mode: 0644]