trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Set loop's temporary rank to the loop rank.

* 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
	and start another.

From-SVN: r180908
This commit is contained in:
Mikael Morin 2011-11-04 00:09:27 +00:00
parent 89d65e2d2f
commit 610f068d4c
2 changed files with 27 additions and 4 deletions

View File

@ -1,3 +1,10 @@
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
and start another.
2011-11-04 Mikael Morin <mikael@gcc.gnu.org> 2011-11-04 Mikael Morin <mikael@gcc.gnu.org>
* trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Don't calculate * trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Don't calculate

View File

@ -3061,6 +3061,23 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* Initialize the loop. */ /* Initialize the loop. */
gfc_conv_ss_startstride (&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}loc
are currently inlined in the scalar case only (for which loop is of rank
one). 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 minmaxloc 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 minmaxloc implementation. See PR 31067. */
loop.temp_dim = loop.dimen;
gfc_conv_loop_setup (&loop, &expr->where); gfc_conv_loop_setup (&loop, &expr->where);
gcc_assert (loop.dimen == 1); gcc_assert (loop.dimen == 1);
@ -3098,9 +3115,9 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
gfc_index_one_node, loop.from[0]); gfc_index_one_node, loop.from[0]);
gfc_add_modify (&loop.pre, offset, tmp); gfc_add_modify (&loop.pre, offset, tmp);
gfc_mark_ss_chain_used (arrayss, 1); gfc_mark_ss_chain_used (arrayss, lab1 ? 3 : 1);
if (maskss) if (maskss)
gfc_mark_ss_chain_used (maskss, 1); gfc_mark_ss_chain_used (maskss, lab1 ? 3 : 1);
/* Generate the loop body. */ /* Generate the loop body. */
gfc_start_scalarized_body (&loop, &body); gfc_start_scalarized_body (&loop, &body);
@ -3186,7 +3203,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
if (lab1) if (lab1)
{ {
gfc_trans_scalarized_loop_end (&loop, 0, &body); gfc_trans_scalarized_loop_boundary (&loop, &body);
if (HONOR_NANS (DECL_MODE (limit))) if (HONOR_NANS (DECL_MODE (limit)))
{ {
@ -3201,7 +3218,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2)); gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1)); gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
gfc_start_block (&body);
/* If we have a mask, only check this element if the mask is set. */ /* If we have a mask, only check this element if the mask is set. */
if (maskss) if (maskss)