aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/frontend-passes.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2018-08-24 17:26:57 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2018-08-24 17:26:57 +0000
commit3413d168824e022555c8246095dfdea297b4c4cc (patch)
tree88e470a177f6b9dbc6b486d379ed245e99400a85 /gcc/fortran/frontend-passes.c
parent01aa3748261d9fa531b87f0c5701f5b7eb03a475 (diff)
downloadgcc-3413d168824e022555c8246095dfdea297b4c4cc.zip
gcc-3413d168824e022555c8246095dfdea297b4c4cc.tar.gz
gcc-3413d168824e022555c8246095dfdea297b4c4cc.tar.bz2
re PR fortran/86837 (Optimization breaks an unformatted read with implicit loop)
2018-08-24 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/86837 * frontend-passes.c (var_in_expr_callback): New function. (var_in_expr): New function. (traverse_io_block): Use var_in_expr instead of gfc_check_dependency for checking if the variable depends on the previous interators. 2018-08-24 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/86837 * gfortran.dg/implied_do_io_6.f90: New test. From-SVN: r263838
Diffstat (limited to 'gcc/fortran/frontend-passes.c')
-rw-r--r--gcc/fortran/frontend-passes.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index f9dcddc..0a5e893 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -1104,6 +1104,31 @@ convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
return 0;
}
+/* Callback function to var_in_expr - return true if expr1 and
+ expr2 are identical variables. */
+static int
+var_in_expr_callback (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ gfc_expr *expr1 = (gfc_expr *) data;
+ gfc_expr *expr2 = *e;
+
+ if (expr2->expr_type != EXPR_VARIABLE)
+ return 0;
+
+ return expr1->symtree->n.sym == expr2->symtree->n.sym;
+}
+
+/* Return true if expr1 is found in expr2. */
+
+static bool
+var_in_expr (gfc_expr *expr1, gfc_expr *expr2)
+{
+ gcc_assert (expr1->expr_type == EXPR_VARIABLE);
+
+ return gfc_expr_walker (&expr2, var_in_expr_callback, (void *) expr1);
+}
+
struct do_stack
{
struct do_stack *prev;
@@ -1256,9 +1281,9 @@ traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
for (int j = i - 1; j < i; j++)
{
if (iters[j]
- && (gfc_check_dependency (var, iters[j]->start, true)
- || gfc_check_dependency (var, iters[j]->end, true)
- || gfc_check_dependency (var, iters[j]->step, true)))
+ && (var_in_expr (var, iters[j]->start)
+ || var_in_expr (var, iters[j]->end)
+ || var_in_expr (var, iters[j]->step)))
return false;
}
}