From d266391244dae81f7f1693d9927df4c6c1bc146b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 28 Jul 2011 22:56:50 +0200 Subject: re PR fortran/31067 (MINLOC should sometimes be inlined (gas_dyn is sooooo sloooow)) PR fortran/31067 * frontend-passes.c (optimize_minmaxloc): New function. (optimize_expr): Call it. * gfortran.dg/maxloc_2.f90: New test. * gfortran.dg/maxloc_3.f90: New test. * gfortran.dg/minloc_1.f90: New test. * gfortran.dg/minloc_2.f90: New test. * gfortran.dg/minloc_3.f90: New test. * gfortran.dg/minmaxloc_7.f90: New test. From-SVN: r176897 --- gcc/fortran/ChangeLog | 6 +++++ gcc/fortran/frontend-passes.c | 57 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) (limited to 'gcc/fortran') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 275285e..89825e3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2011-07-28 Jakub Jelinek + + PR fortran/31067 + * frontend-passes.c (optimize_minmaxloc): New function. + (optimize_expr): Call it. + 2011-07-27 Tobias Burnus PR fortran/45586 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 4d8c77a..5c3e280 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -1,5 +1,5 @@ /* Pass manager for Fortran front end. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010, 2011 Free Software Foundation, Inc. Contributed by Thomas König. This file is part of GCC. @@ -36,6 +36,7 @@ static bool optimize_op (gfc_expr *); static bool optimize_comparison (gfc_expr *, gfc_intrinsic_op); static bool optimize_trim (gfc_expr *); static bool optimize_lexical_comparison (gfc_expr *); +static void optimize_minmaxloc (gfc_expr **); /* How deep we are inside an argument list. */ @@ -129,6 +130,17 @@ optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, if ((*e)->expr_type == EXPR_OP && optimize_op (*e)) gfc_simplify_expr (*e, 0); + if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym) + switch ((*e)->value.function.isym->id) + { + case GFC_ISYM_MINLOC: + case GFC_ISYM_MAXLOC: + optimize_minmaxloc (e); + break; + default: + break; + } + if (function_expr) count_arglist --; @@ -862,6 +874,49 @@ optimize_trim (gfc_expr *e) return true; } +/* Optimize minloc(b), where b is rank 1 array, into + (/ minloc(b, dim=1) /), and similarly for maxloc, + as the latter forms are expanded inline. */ + +static void +optimize_minmaxloc (gfc_expr **e) +{ + gfc_expr *fn = *e; + gfc_actual_arglist *a; + char *name, *p; + + if (fn->rank != 1 + || fn->value.function.actual == NULL + || fn->value.function.actual->expr == NULL + || fn->value.function.actual->expr->rank != 1) + return; + + *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where); + (*e)->shape = fn->shape; + fn->rank = 0; + fn->shape = NULL; + gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where); + + name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1); + strcpy (name, fn->value.function.name); + p = strstr (name, "loc0"); + p[3] = '1'; + fn->value.function.name = gfc_get_string (name); + if (fn->value.function.actual->next) + { + a = fn->value.function.actual->next; + gcc_assert (a->expr == NULL); + } + else + { + a = gfc_get_actual_arglist (); + fn->value.function.actual->next = a; + } + a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind, + &fn->where); + mpz_set_ui (a->expr->value.integer, 1); +} + #define WALK_SUBEXPR(NODE) \ do \ { \ -- cgit v1.1