]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/14470 ([tree-ssa] trouble with post-increment)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Mon, 22 Mar 2004 18:39:55 +0000 (19:39 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 22 Mar 2004 18:39:55 +0000 (18:39 +0000)
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
gcc/expr.c

index d0781d106c04e2eef13426e7e919ab3f08c7a112..601652fde96e3b38eeba913dce92ae0e1d10ab34 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-17  Ralf Corsepius <corsepiu@faw.uni-ulm.de>
 
        PR target/14260
index f3a6f1ea88babb1309a15e594e3ded3583cefa74..526e52c823668744e89a16779329a81d9f2d72a2 100644 (file)
@@ -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);
+}
 \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.
@@ -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)