OSDN Git Service

PR middle-end/14470
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Mar 2004 11:59:08 +0000 (11:59 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Mar 2004 11:59:08 +0000 (11:59 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@79822 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index c4098af..8d3238b 100644 (file)
@@ -1,3 +1,13 @@
+2004-03-22  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       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-22  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        * configure.ac: Allow --disable-coverage-flags (for the future benefit
index 8064726..d77b6e5 100644 (file)
@@ -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);
+}
 \f
 /* 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)