From 8107f5eda0b719e02cf8093392f9ff11f3dcbd4e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 22 Mar 2004 19:39:55 +0100 Subject: [PATCH] re PR tree-optimization/14470 ([tree-ssa] trouble with post-increment) PR middle-end/14470 * expr.c (mark_queue): New function. (emit_insns_enqueued_after_mark): New function replacing emit_queue. Clear the body of emitted queued insns. (emit_queue): Call emit_insns_enqueued_after_mark. (store_expr): Mark the increment queue on entry. Emit only the incrementations queued when expanding the source. From-SVN: r79836 --- gcc/ChangeLog | 10 ++++++++++ gcc/expr.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0781d106c04..601652fde96e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-03-22 Eric Botcazou + + PR middle-end/14470 + * expr.c (mark_queue): New function. + (emit_insns_enqueued_after_mark): New function replacing + emit_queue. Clear the body of emitted queued insns. + (emit_queue): Call emit_insns_enqueued_after_mark. + (store_expr): Mark the increment queue on entry. Emit + only the incrementations queued when expanding the source. + 2004-03-17 Ralf Corsepius PR target/14260 diff --git a/gcc/expr.c b/gcc/expr.c index f3a6f1ea88ba..526e52c82366 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -129,6 +129,8 @@ struct store_by_pieces }; static rtx enqueue_insn PARAMS ((rtx, rtx)); +static rtx mark_queue PARAMS ((void)); +static void emit_insns_enqueued_after_mark PARAMS ((rtx)); static unsigned HOST_WIDE_INT move_by_pieces_ninsns PARAMS ((unsigned HOST_WIDE_INT, unsigned int)); @@ -500,13 +502,31 @@ queued_subexp_p (x) } } -/* Perform all the pending incrementations. */ +/* Retrieve a mark on the queue. */ + +static rtx +mark_queue () +{ + return pending_chain; +} -void -emit_queue () +/* Perform all the pending incrementations that have been enqueued + after MARK was retrieved. If MARK is null, perform all the + pending incrementations. */ + +static void +emit_insns_enqueued_after_mark (mark) + rtx mark; { rtx p; - while ((p = pending_chain)) + + /* The marked incrementation may have been emitted in the meantime + through a call to emit_queue. In this case, the mark is not valid + anymore so do nothing. */ + if (mark && ! QUEUED_BODY (mark)) + return; + + while ((p = pending_chain) != mark) { rtx body = QUEUED_BODY (p); @@ -533,9 +553,18 @@ emit_queue () break; } + QUEUED_BODY (p) = 0; pending_chain = QUEUED_NEXT (p); } } + +/* Perform all the pending incrementations. */ + +void +emit_queue () +{ + emit_insns_enqueued_after_mark (NULL_RTX); +} /* Copy data from FROM to TO, where the machine modes are not the same. Both modes may be integer, or both may be floating. @@ -4314,6 +4343,7 @@ store_expr (exp, target, want_value) int want_value; { rtx temp; + rtx mark = mark_queue (); int dont_return_target = 0; int dont_store_target = 0; @@ -4523,7 +4553,11 @@ store_expr (exp, target, want_value) temp, TREE_UNSIGNED (TREE_TYPE (exp))); /* If value was not generated in the target, store it there. - Convert the value to TARGET's type first if necessary. + Convert the value to TARGET's type first if necessary and emit the + pending incrementations that have been queued when expanding EXP. + Note that we cannot emit the whole queue blindly because this will + effectively disable the POST_INC optimization later. + If TEMP and TARGET compare equal according to rtx_equal_p, but one or both of them are volatile memory refs, we have to distinguish two cases: @@ -4552,7 +4586,7 @@ store_expr (exp, target, want_value) bit-initialized. */ && expr_size (exp) != const0_rtx) { - emit_queue (); + emit_insns_enqueued_after_mark (mark); target = protect_from_queue (target, 1); temp = protect_from_queue (temp, 0); if (GET_MODE (temp) != GET_MODE (target) -- 2.47.2