diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2017-05-08 18:22:44 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2017-05-08 18:22:44 +0000 |
commit | 0f6ed1211d4e6759a0c35bc8d05fb07e5eab7bea (patch) | |
tree | 0590178a17fc64dd8917d650ffd6af7caef96161 /gcc/fortran/frontend-passes.c | |
parent | 507e429b2fe28c21889d166817a35496777d19ba (diff) | |
download | gcc-0f6ed1211d4e6759a0c35bc8d05fb07e5eab7bea.zip gcc-0f6ed1211d4e6759a0c35bc8d05fb07e5eab7bea.tar.gz gcc-0f6ed1211d4e6759a0c35bc8d05fb07e5eab7bea.tar.bz2 |
re PR fortran/79930 (Potentially Missed Optimisation for MATMUL / DOT_PRODUCT)
2017-05-08 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/79930
* frontend-passes.c (matmul_to_var_expr): New function,
add prototype.
(matmul_to_var_code): Likewise.
(optimize_namespace): Use them from gfc_code_walker.
2017-05-08 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/79930
* gfortran.dg/inline_transpose_1.f90: Add
-finline-matmul-limit=0 to options.
* gfortran.dg/matmul_5.f90: Likewise.
* gfortran.dg/vect/vect-8.f90: Likewise.
* gfortran.dg/inline_matmul_14.f90: New test.
* gfortran.dg/inline_matmul_15.f90: New test.
From-SVN: r247755
Diffstat (limited to 'gcc/fortran/frontend-passes.c')
-rw-r--r-- | gcc/fortran/frontend-passes.c | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 069ec28..32b4e80 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -43,6 +43,8 @@ static void optimize_reduction (gfc_namespace *); static int callback_reduction (gfc_expr **, int *, void *); static void realloc_strings (gfc_namespace *); static gfc_expr *create_var (gfc_expr *, const char *vname=NULL); +static int matmul_to_var_expr (gfc_expr **, int *, void *); +static int matmul_to_var_code (gfc_code **, int *, void *); static int inline_matmul_assign (gfc_code **, int *, void *); static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *, locus *, gfc_namespace *, @@ -1076,9 +1078,20 @@ optimize_namespace (gfc_namespace *ns) gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL); gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL); if (flag_inline_matmul_limit != 0) - gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback, - NULL); - + { + bool found; + do + { + found = false; + gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr, + (void *) &found); + } + while (found); + + gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback, + NULL); + } + /* BLOCKs are handled in the expression walker below. */ for (ns = ns->contained; ns; ns = ns->sibling) { @@ -2086,6 +2099,64 @@ doloop_warn (gfc_namespace *ns) /* This selction deals with inlining calls to MATMUL. */ +/* Replace calls to matmul outside of straight assignments with a temporary + variable so that later inlining will work. */ + +static int +matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data) +{ + gfc_expr *e, *n; + bool *found = (bool *) data; + + e = *ep; + + if (e->expr_type != EXPR_FUNCTION + || e->value.function.isym == NULL + || e->value.function.isym->id != GFC_ISYM_MATMUL) + return 0; + + if (forall_level > 0 || iterator_level > 0 || in_omp_workshare + || in_where) + return 0; + + /* Check if this is already in the form c = matmul(a,b). */ + + if ((*current_code)->expr2 == e) + return 0; + + n = create_var (e, "matmul"); + + /* If create_var is unable to create a variable (for example if + -fno-realloc-lhs is in force with a variable that does not have bounds + known at compile-time), just return. */ + + if (n == NULL) + return 0; + + *ep = n; + *found = true; + return 0; +} + +/* Set current_code and associated variables so that matmul_to_var_expr can + work. */ + +static int +matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + if (current_code != c) + { + current_code = c; + inserted_block = NULL; + changed_statement = NULL; + } + + return 0; +} + + /* Auxiliary function to build and simplify an array inquiry function. dim is zero-based. */ |