diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-08-24 17:26:57 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-08-24 17:26:57 +0000 |
commit | 3413d168824e022555c8246095dfdea297b4c4cc (patch) | |
tree | 88e470a177f6b9dbc6b486d379ed245e99400a85 /gcc/fortran/frontend-passes.c | |
parent | 01aa3748261d9fa531b87f0c5701f5b7eb03a475 (diff) | |
download | gcc-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.c | 31 |
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; } } |