aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-03-22 12:59:08 +0100
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-03-22 11:59:08 +0000
commit1bbd65cd87bfaca465f4fee1c5e2ac28f8200bda (patch)
treec6ea3b97c37379d4cfbc40dc996134d5e6fa2293 /gcc/expr.c
parentaadfde5010ff1ed470b006784cdf32da2f48608e (diff)
downloadgcc-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.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 80647265..d77b6e5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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)