diff mbox series

[2/8] fortran: Disable frontend passes for inlinable MINLOC/MAXLOC [PR90608]

Message ID 20240731200735.229898-3-morin-mikael@orange.fr
State New
Headers show
Series fortran: Inline MINLOC/MAXLOC without DIM argument [PR90608] | expand

Commit Message

Mikael Morin July 31, 2024, 8:07 p.m. UTC
From: Mikael Morin <mikael@gcc.gnu.org>

Regression-tested on x86_64-pc-linux-gnu.
OK for master?

-- >8 --

Disable rewriting of MINLOC/MAXLOC expressions for which inline code
generation is supported.  Update the gfc_inline_intrinsic_function_p
predicate (already existing) for that, with the current state of
MINLOC/MAXLOC inlining support, that is only the cases of a scalar
result and non-CHARACTER argument for now.

This change has no effect currently, as the MINLOC/MAXLOC front-end passes
only change expressions of rank 1, but the inlining control predicate
gfc_inline_intrinsic_function_p returns false for those.  However, later
changes will extend MINLOC/MAXLOC inline expansion support to array
expressions and update the inlining control predicate, and this will become
effective.

	PR fortran/90608

gcc/fortran/ChangeLog:

	* frontend-passes.cc (optimize_minmaxloc): Skip if we can generate
	inline code for the unmodified expression.
	* trans-intrinsic.cc (gfc_inline_intrinsic_function_p): Add
	MINLOC and MAXLOC cases.
---
 gcc/fortran/frontend-passes.cc |  3 ++-
 gcc/fortran/trans-intrinsic.cc | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc
index 3c06018fdbb..8e4c6310ba8 100644
--- a/gcc/fortran/frontend-passes.cc
+++ b/gcc/fortran/frontend-passes.cc
@@ -2277,7 +2277,8 @@  optimize_minmaxloc (gfc_expr **e)
       || fn->value.function.actual == NULL
       || fn->value.function.actual->expr == NULL
       || fn->value.function.actual->expr->ts.type == BT_CHARACTER
-      || fn->value.function.actual->expr->rank != 1)
+      || fn->value.function.actual->expr->rank != 1
+      || gfc_inline_intrinsic_function_p (fn))
     return;
 
   *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 9f3c3ce47bc..cc0d00f4e39 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -11650,6 +11650,29 @@  gfc_inline_intrinsic_function_p (gfc_expr *expr)
     case GFC_ISYM_TRANSPOSE:
       return true;
 
+    case GFC_ISYM_MINLOC:
+    case GFC_ISYM_MAXLOC:
+      {
+	/* Disable inline expansion if code size matters.  */
+	if (optimize_size)
+	  return false;
+
+	gfc_actual_arglist *array_arg = expr->value.function.actual;
+	gfc_actual_arglist *dim_arg = array_arg->next;
+
+	gfc_expr *array = array_arg->expr;
+	gfc_expr *dim = dim_arg->expr;
+
+	if (!(array->ts.type == BT_INTEGER
+	      || array->ts.type == BT_REAL))
+	  return false;
+
+	if (array->rank == 1 && dim != nullptr)
+	  return true;
+
+	return false;
+      }
+
     default:
       return false;
     }