From: Mikael Morin Date: Fri, 4 Nov 2011 00:11:39 +0000 (+0000) Subject: trans-intrinsic.c (gfc_conv_intrinsic_minmaxval): Set loop's temporary rank to the... X-Git-Tag: releases/gcc-4.7.0~2528 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa6ad95c057d748c351fc50cac9f710299e8be07;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 9b518595fbdd..86551b71b8a7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2011-11-04 Mikael Morin + + * 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 * trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Set loop's diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 506cdf22b800..3cdc1e0970aa 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) {