diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-03-22 12:59:08 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2004-03-22 11:59:08 +0000 |
commit | 1bbd65cd87bfaca465f4fee1c5e2ac28f8200bda (patch) | |
tree | c6ea3b97c37379d4cfbc40dc996134d5e6fa2293 /gcc/expr.c | |
parent | aadfde5010ff1ed470b006784cdf32da2f48608e (diff) | |
download | gcc-1bbd65cd87bfaca465f4fee1c5e2ac28f8200bda.zip gcc-1bbd65cd87bfaca465f4fee1c5e2ac28f8200bda.tar.gz gcc-1bbd65cd87bfaca465f4fee1c5e2ac28f8200bda.tar.bz2 |
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: r79822
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 43 |
1 files changed, 37 insertions, 6 deletions
@@ -466,13 +466,30 @@ queued_subexp_p (rtx x) } } -/* Perform all the pending incrementations. */ +/* Retrieve a mark on the queue. */ + +static rtx +mark_queue (void) +{ + return pending_chain; +} -void -emit_queue (void) +/* 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 (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); @@ -499,9 +516,18 @@ emit_queue (void) break; } + QUEUED_BODY (p) = 0; pending_chain = QUEUED_NEXT (p); } } + +/* Perform all the pending incrementations. */ + +void +emit_queue (void) +{ + 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. @@ -4003,6 +4029,7 @@ store_expr (tree exp, rtx target, int want_value) { rtx temp; rtx alt_rtl = NULL_RTX; + rtx mark = mark_queue (); int dont_return_target = 0; int dont_store_target = 0; @@ -4214,7 +4241,11 @@ store_expr (tree exp, rtx target, int 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: @@ -4242,7 +4273,7 @@ store_expr (tree exp, rtx target, int 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) |