diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2010-07-23 14:25:55 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2010-07-23 14:25:55 +0000 |
commit | 3d03ead0b8273efde57f6194617b35111a84b05d (patch) | |
tree | be85c1a1d325c1a8b6496500d502795c61e15506 /gcc/fortran/trans-array.c | |
parent | c4fcd06a10ddacc81f535b165034dbaa93b6005c (diff) | |
download | gcc-3d03ead0b8273efde57f6194617b35111a84b05d.zip gcc-3d03ead0b8273efde57f6194617b35111a84b05d.tar.gz gcc-3d03ead0b8273efde57f6194617b35111a84b05d.tar.bz2 |
re PR fortran/24524 (Fortran dependency checking should reverse loops)
2009-07-23 Paul Thomas <pault@gcc.gnu.org>
PR fortran/24524
* trans-array.c (gfc_init_loopinfo): Initialize the reverse
field.
gfc_trans_scalarized_loop_end: If reverse set in dimension n,
reverse the scalarization loop.
gfc_conv_resolve_dependencies: Pass the reverse field of the
loopinfo to gfc_dep_resolver.
trans-expr.c (gfc_trans_assignment_1): Enable loop reversal for
assignment by resetting loop.reverse.
gfortran.h : Add the gfc_reverse enum.
trans.h : Add the reverse field to gfc_loopinfo.
dependency.c (gfc_check_dependency): Pass null to the new arg
of gfc_dep_resolver.
(gfc_check_section_vs_section): Check for reverse dependencies.
(gfc_dep_resolver): Add reverse argument and deal with the loop
reversal logic.
dependency.h : Modify prototype for gfc_dep_resolver to include
gfc_reverse *.
From-SVN: r162462
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index d4f1cdf..cca4ecc 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2180,9 +2180,12 @@ gfc_init_loopinfo (gfc_loopinfo * loop) gfc_init_block (&loop->pre); gfc_init_block (&loop->post); - /* Initially scalarize in order. */ + /* Initially scalarize in order and default to no loop reversal. */ for (n = 0; n < GFC_MAX_DIMENSIONS; n++) - loop->order[n] = n; + { + loop->order[n] = n; + loop->reverse[n] = GFC_CANNOT_REVERSE; + } loop->ss = gfc_ss_terminator; } @@ -2842,8 +2845,18 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n, } else { + bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET) + && (loop->temp_ss == NULL); + loopbody = gfc_finish_block (pbody); + if (reverse_loop) + { + tmp = loop->from[n]; + loop->from[n] = loop->to[n]; + loop->to[n] = tmp; + } + /* Initialize the loopvar. */ if (loop->loopvar[n] != loop->from[n]) gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]); @@ -2854,8 +2867,8 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n, gfc_init_block (&block); /* The exit condition. */ - cond = fold_build2 (GT_EXPR, boolean_type_node, - loop->loopvar[n], loop->to[n]); + cond = fold_build2 (reverse_loop ? LT_EXPR : GT_EXPR, + boolean_type_node, loop->loopvar[n], loop->to[n]); tmp = build1_v (GOTO_EXPR, exit_label); TREE_USED (exit_label) = 1; tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location)); @@ -2865,8 +2878,10 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n, gfc_add_expr_to_block (&block, loopbody); /* Increment the loopvar. */ - tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, - loop->loopvar[n], gfc_index_one_node); + tmp = fold_build2 (reverse_loop ? MINUS_EXPR : PLUS_EXPR, + gfc_array_index_type, loop->loopvar[n], + gfc_index_one_node); + gfc_add_modify (&block, loop->loopvar[n], tmp); /* Build the loop. */ @@ -3449,7 +3464,8 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest, lref = dest->expr->ref; rref = ss->expr->ref; - nDepend = gfc_dep_resolver (lref, rref); + nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]); + if (nDepend == 1) break; #if 0 |