aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2011-11-04 00:11:39 +0000
committerMikael Morin <mikael@gcc.gnu.org>2011-11-04 00:11:39 +0000
commitaa6ad95c057d748c351fc50cac9f710299e8be07 (patch)
tree52f466be34e8765b0d22fdcddd8a5850ae55f2a8
parent610f068d4c18d6c732945fb85b0ac519da9451c6 (diff)
downloadgcc-aa6ad95c057d748c351fc50cac9f710299e8be07.zip
gcc-aa6ad95c057d748c351fc50cac9f710299e8be07.tar.gz
gcc-aa6ad95c057d748c351fc50cac9f710299e8be07.tar.bz2
trans-intrinsic.c (gfc_conv_intrinsic_minmaxval): Set loop's temporary rank to the loop rank.
* trans-intrinsic.c (gfc_conv_intrinsic_minmaxval): Set loop's temporary rank to the loop rank. Mark ss chains for multiple loop if necessary. Use gfc_trans_scalarized_loop_boundary to end one loop and start another. From-SVN: r180909
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/trans-intrinsic.c24
2 files changed, 26 insertions, 5 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 9b51859..86551b7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,12 @@
2011-11-04 Mikael Morin <mikael@gcc.gnu.org>
+ * trans-intrinsic.c (gfc_conv_intrinsic_minmaxval): Set loop's
+ temporary rank to the loop rank. Mark ss chains for multiple loop
+ if necessary. Use gfc_trans_scalarized_loop_boundary to end one loop
+ and start another.
+
+2011-11-04 Mikael Morin <mikael@gcc.gnu.org>
+
* trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Set loop's
temporary rank to the loop rank. Mark ss chains for multiple loop
if necessary. Use gfc_trans_scalarized_loop_boundary to end one loop
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 506cdf2..3cdc1e0 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -3522,6 +3522,22 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
+
+ /* The code generated can have more than one loop in sequence (see the
+ comment at the function header). This doesn't work well with the
+ scalarizer, which changes arrays' offset when the scalarization loops
+ are generated (see gfc_trans_preloop_setup). Fortunately, {min,max}val
+ are currently inlined in the scalar case only. As there is no dependency
+ to care about in that case, there is no temporary, so that we can use the
+ scalarizer temporary code to handle multiple loops. Thus, we set temp_dim
+ here, we call gfc_mark_ss_chain_used with flag=3 later, and we use
+ gfc_trans_scalarized_loop_boundary even later to restore offset.
+ TODO: this prevents inlining of rank > 0 minmaxval calls, so this
+ should eventually go away. We could either create two loops properly,
+ or find another way to save/restore the array offsets between the two
+ loops (without conflicting with temporary management), or use a single
+ loop minmaxval implementation. See PR 31067. */
+ loop.temp_dim = loop.dimen;
gfc_conv_loop_setup (&loop, &expr->where);
if (nonempty == NULL && maskss == NULL
@@ -3553,9 +3569,9 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
}
}
- gfc_mark_ss_chain_used (arrayss, 1);
+ gfc_mark_ss_chain_used (arrayss, lab ? 3 : 1);
if (maskss)
- gfc_mark_ss_chain_used (maskss, 1);
+ gfc_mark_ss_chain_used (maskss, lab ? 3 : 1);
/* Generate the loop body. */
gfc_start_scalarized_body (&loop, &body);
@@ -3665,15 +3681,13 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
if (lab)
{
- gfc_trans_scalarized_loop_end (&loop, 0, &body);
+ gfc_trans_scalarized_loop_boundary (&loop, &body);
tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
nan_cst, huge_cst);
gfc_add_modify (&loop.code[0], limit, tmp);
gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
- gfc_start_block (&body);
-
/* If we have a mask, only add this element if the mask is set. */
if (maskss)
{