[fortran] Implement Maxval in compile-time-constants

Message ID 204e00c4-c4fe-0f7d-5085-37ddcb693152@netcologne.de
State New
Headers show
Series
  • [fortran] Implement Maxval in compile-time-constants
Related show

Commit Message

Thomas Koenig Dec. 10, 2017, 8:31 p.m.
Hello world,

the attached patch allows for maxval in parameter statements
with DIM and MASK arguments.

It does so by removing a function which does only a partial
job and using the machinery which is already in use for the
other transformational intrinsics.

Regression-tested. OK for trunk?

Regards

	Thomas

2017-12-10  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/45689
	* simplify.c (min_max_choose): Add prototype.
	(gfc_count): Format correctly.
	(simplify_transformation): Pass array argument to init_result_expr.
	(gfc_simplify_minval_maxval): Remove.
	(gfc_min): New function.
	(gfc_simplify_minval): Call simplify_transformation.
	(gfc_max): New function.
	(gfc_simplify_maxval): Call simplify_transformation.

2017-12-10  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/45689
	* gfortran.dg/minval_parameter_1.f90: New test.
	* gfortran.dg/maxval_parameter_1.f90: New test.

Comments

Jerry Dec. 10, 2017, 11:18 p.m. | #1
On 12/10/2017 12:31 PM, Thomas Koenig wrote:
> Hello world,

> 

> the attached patch allows for maxval in parameter statements

> with DIM and MASK arguments.

> 

> It does so by removing a function which does only a partial

> job and using the machinery which is already in use for the

> other transformational intrinsics.

> 

> Regression-tested. OK for trunk?

> 


OK, thanks,

Jerry

Patch

Index: simplify.c
===================================================================
--- simplify.c	(Revision 255522)
+++ simplify.c	(Arbeitskopie)
@@ -29,7 +29,10 @@  along with GCC; see the file COPYING3.  If not see
 #include "constructor.h"
 #include "version.h"	/* For version_string.  */
 
+/* Prototypes.  */
 
+static void min_max_choose (gfc_expr *, gfc_expr *, int);
+
 gfc_expr gfc_bad_expr;
 
 static gfc_expr *simplify_size (gfc_expr *, gfc_expr *, int);
@@ -436,7 +439,8 @@  typedef gfc_expr* (*transformational_op)(gfc_expr*
    Interface and implementation mimics arith functions as
    gfc_add, gfc_multiply, etc.  */
 
-static gfc_expr* gfc_count (gfc_expr *op1, gfc_expr *op2)
+static gfc_expr *
+gfc_count (gfc_expr *op1, gfc_expr *op2)
 {
   gfc_expr *result;
 
@@ -666,7 +670,7 @@  simplify_transformation (gfc_expr *array, gfc_expr
 
   result = transformational_result (array, dim, array->ts.type,
 				    array->ts.kind, &array->where);
-  init_result_expr (result, init_val, NULL);
+  init_result_expr (result, init_val, array);
 
   return !dim || array->rank == 1 ?
     simplify_transformation_to_scalar (result, array, mask, op) :
@@ -4539,67 +4543,41 @@  gfc_simplify_max (gfc_expr *e)
   return simplify_min_max (e, 1);
 }
 
+/* Helper function for gfc_simplify_minval.  */
 
-/* This is a simplified version of simplify_min_max to provide
-   simplification of minval and maxval for a vector.  */
-
 static gfc_expr *
-simplify_minval_maxval (gfc_expr *expr, int sign)
+gfc_min (gfc_expr *op1, gfc_expr *op2)
 {
-  gfc_constructor *c, *extremum;
-  gfc_intrinsic_sym * specific;
-
-  extremum = NULL;
-  specific = expr->value.function.isym;
-
-  for (c = gfc_constructor_first (expr->value.constructor);
-       c; c = gfc_constructor_next (c))
-    {
-      if (c->expr->expr_type != EXPR_CONSTANT)
-	return NULL;
-
-      if (extremum == NULL)
-	{
-	  extremum = c;
-	  continue;
-	}
-
-      min_max_choose (c->expr, extremum->expr, sign);
-     }
-
-  if (extremum == NULL)
-    return NULL;
-
-  /* Convert to the correct type and kind.  */
-  if (expr->ts.type != BT_UNKNOWN)
-    return gfc_convert_constant (extremum->expr,
-	expr->ts.type, expr->ts.kind);
-
-  if (specific->ts.type != BT_UNKNOWN)
-    return gfc_convert_constant (extremum->expr,
-	specific->ts.type, specific->ts.kind);
-
-  return gfc_copy_expr (extremum->expr);
+  min_max_choose (op1, op2, -1);
+  gfc_free_expr (op1);
+  return op2;
 }
 
+/* Simplify minval for constant arrays.  */
 
 gfc_expr *
 gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
 {
-  if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask)
-    return NULL;
+  return simplify_transformation (array, dim, mask, INT_MAX, gfc_min);
+}
 
-  return simplify_minval_maxval (array, -1);
+/* Helper function for gfc_simplify_maxval.  */
+
+static gfc_expr *
+gfc_max (gfc_expr *op1, gfc_expr *op2)
+{
+  min_max_choose (op1, op2, 1);
+  gfc_free_expr (op1);
+  return op2;
 }
 
 
+/* Simplify maxval for constant arrays.  */
+
 gfc_expr *
 gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
 {
-  if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask)
-    return NULL;
-
-  return simplify_minval_maxval (array, 1);
+  return simplify_transformation (array, dim, mask, INT_MIN, gfc_max);
 }