aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/frontend-passes.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2017-05-08 18:22:44 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2017-05-08 18:22:44 +0000
commit0f6ed1211d4e6759a0c35bc8d05fb07e5eab7bea (patch)
tree0590178a17fc64dd8917d650ffd6af7caef96161 /gcc/fortran/frontend-passes.c
parent507e429b2fe28c21889d166817a35496777d19ba (diff)
downloadgcc-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.c77
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. */