]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
emit-rtl.c (link_insn_into_chain): Handle chaining of SEQUENCEs.
authorSteven Bosscher <steven@gcc.gnu.org>
Wed, 17 Apr 2013 19:33:24 +0000 (19:33 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Wed, 17 Apr 2013 19:33:24 +0000 (19:33 +0000)
* emit-rtl.c (link_insn_into_chain): Handle chaining of SEQUENCEs.
* reorg.c (emit_delay_sequence): Simplify with emit-rtl API.

From-SVN: r198036

gcc/ChangeLog
gcc/emit-rtl.c
gcc/reorg.c

index ee4bb5f6d3fc31431e6209dd3f78a0ce13ff5fe1..19d51f1f5e771c7c5a850cd7023a0751feb7cfd6 100644 (file)
@@ -1,11 +1,16 @@
-2013-04-17  Greta Yorsh  <Greta.Yorsh at arm.com>
+2013-04-17  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * emit-rtl.c (link_insn_into_chain): Handle chaining of SEQUENCEs.
+       * reorg.c (emit_delay_sequence): Simplify with emit-rtl API.
+
+2013-04-17  Greta Yorsh  <Greta.Yorsh@arm.com>
 
        * config/arm/arm.md (movsicc_insn): Convert define_insn into
        define_insn_and_split.
        (and_scc,ior_scc,negscc): Likewise.
        (cmpsi2_addneg, subsi3_compare): Convert to named patterns.
 
-2013-04-17  Greta Yorsh  <Greta.Yorsh at arm.com>
+2013-04-17  Greta Yorsh  <Greta.Yorsh@arm.com>
 
        * config/arm/arm.c (use_return_insn): Return 0 for targets that
        can benefit from using a sequence of LDRD instructions in epilogue
index c8efb5ca4c5cb58426ce8a75175cbbe441f85baf..a7cdf843fd9e3cef54ba1fa67af37b736beb8461 100644 (file)
@@ -3806,6 +3806,13 @@ link_insn_into_chain (rtx insn, rtx prev, rtx next)
       if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
        PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
     }
+
+  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
+    {
+      rtx sequence = PATTERN (insn);
+      PREV_INSN (XVECEXP (sequence, 0, 0)) = prev;
+      NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
+    }
 }
 
 /* Add INSN to the end of the doubly-linked list.
index 30efd79be8208541cb7bb0884b2692237d453285..5a457e2c8e54bd8ec6466afb2a1f5b6eca0b6556 100644 (file)
@@ -458,69 +458,32 @@ find_end_label (rtx kind)
 /* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace
    the pattern of INSN with the SEQUENCE.
 
-   Chain the insns so that NEXT_INSN of each insn in the sequence points to
-   the next and NEXT_INSN of the last insn in the sequence points to
-   the first insn after the sequence.  Similarly for PREV_INSN.  This makes
-   it easier to scan all insns.
-
    Returns the SEQUENCE that replaces INSN.  */
 
 static rtx
 emit_delay_sequence (rtx insn, rtx list, int length)
 {
-  int i = 1;
-  rtx li;
-  int had_barrier = 0;
-
   /* Allocate the rtvec to hold the insns and the SEQUENCE.  */
   rtvec seqv = rtvec_alloc (length + 1);
   rtx seq = gen_rtx_SEQUENCE (VOIDmode, seqv);
   rtx seq_insn = make_insn_raw (seq);
-  rtx first = get_insns ();
-  rtx last = get_last_insn ();
-
-  /* Make a copy of the insn having delay slots.  */
-  rtx delay_insn = copy_rtx (insn);
-
-  /* If INSN is followed by a BARRIER, delete the BARRIER since it will only
-     confuse further processing.  Update LAST in case it was the last insn.
-     We will put the BARRIER back in later.  */
-  if (NEXT_INSN (insn) && BARRIER_P (NEXT_INSN (insn)))
-    {
-      delete_related_insns (NEXT_INSN (insn));
-      last = get_last_insn ();
-      had_barrier = 1;
-    }
-
-  /* Splice our SEQUENCE into the insn stream where INSN used to be.  */
-  NEXT_INSN (seq_insn) = NEXT_INSN (insn);
-  PREV_INSN (seq_insn) = PREV_INSN (insn);
-
-  if (insn != last)
-    PREV_INSN (NEXT_INSN (seq_insn)) = seq_insn;
-
-  if (insn != first)
-    NEXT_INSN (PREV_INSN (seq_insn)) = seq_insn;
 
-  /* Note the calls to set_new_first_and_last_insn must occur after
-     SEQ_INSN has been completely spliced into the insn stream.
+  /* If DELAY_INSN has a location, use it for SEQ_INSN.  If DELAY_INSN does
+     not have a location, but one of the delayed insns does, we pick up a
+     location from there later.  */
+  INSN_LOCATION (seq_insn) = INSN_LOCATION (insn);
 
-     Otherwise CUR_INSN_UID will get set to an incorrect value because
-     set_new_first_and_last_insn will not find SEQ_INSN in the chain.  */
-  if (insn == last)
-    set_new_first_and_last_insn (first, seq_insn);
-
-  if (insn == first)
-    set_new_first_and_last_insn (seq_insn, last);
+  /* Unlink INSN from the insn chain, so that we can put it into
+     the SEQUENCE.   Remember where we want to emit SEQUENCE in AFTER.  */
+  rtx after = PREV_INSN (insn);
+  remove_insn (insn);
+  NEXT_INSN (insn) = PREV_INSN (insn) = NULL;
 
   /* Build our SEQUENCE and rebuild the insn chain.  */
-  XVECEXP (seq, 0, 0) = delay_insn;
-  INSN_DELETED_P (delay_insn) = 0;
-  PREV_INSN (delay_insn) = PREV_INSN (seq_insn);
-
-  INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);
-
-  for (li = list; li; li = XEXP (li, 1), i++)
+  int i = 1;
+  start_sequence ();
+  XVECEXP (seq, 0, 0) = emit_insn (insn);
+  for (rtx li = list; li; li = XEXP (li, 1), i++)
     {
       rtx tem = XEXP (li, 0);
       rtx note, next;
@@ -528,9 +491,10 @@ emit_delay_sequence (rtx insn, rtx list, int length)
       /* Show that this copy of the insn isn't deleted.  */
       INSN_DELETED_P (tem) = 0;
 
-      XVECEXP (seq, 0, i) = tem;
-      PREV_INSN (tem) = XVECEXP (seq, 0, i - 1);
-      NEXT_INSN (XVECEXP (seq, 0, i - 1)) = tem;
+      /* Unlink insn from its original place, and re-emit it into
+        the sequence.  */
+      NEXT_INSN (tem) = PREV_INSN (tem) = NULL;
+      XVECEXP (seq, 0, i) = emit_insn (tem);
 
       /* SPARC assembler, for instance, emit warning when debug info is output
          into the delay slot.  */
@@ -538,6 +502,8 @@ emit_delay_sequence (rtx insn, rtx list, int length)
        INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
       INSN_LOCATION (tem) = 0;
 
+      /* Remove any REG_DEAD notes because we can't rely on them now
+        that the insn has been moved.  */
       for (note = REG_NOTES (tem); note; note = next)
        {
          next = XEXP (note, 1);
@@ -561,29 +527,12 @@ emit_delay_sequence (rtx insn, rtx list, int length)
            }
        }
     }
-
-  NEXT_INSN (XVECEXP (seq, 0, length)) = NEXT_INSN (seq_insn);
-
-  /* If the previous insn is a SEQUENCE, update the NEXT_INSN pointer on the
-     last insn in that SEQUENCE to point to us.  Similarly for the first
-     insn in the following insn if it is a SEQUENCE.  */
-
-  if (PREV_INSN (seq_insn) && NONJUMP_INSN_P (PREV_INSN (seq_insn))
-      && GET_CODE (PATTERN (PREV_INSN (seq_insn))) == SEQUENCE)
-    NEXT_INSN (XVECEXP (PATTERN (PREV_INSN (seq_insn)), 0,
-                       XVECLEN (PATTERN (PREV_INSN (seq_insn)), 0) - 1))
-      = seq_insn;
-
-  if (NEXT_INSN (seq_insn) && NONJUMP_INSN_P (NEXT_INSN (seq_insn))
-      && GET_CODE (PATTERN (NEXT_INSN (seq_insn))) == SEQUENCE)
-    PREV_INSN (XVECEXP (PATTERN (NEXT_INSN (seq_insn)), 0, 0)) = seq_insn;
-
-  /* If there used to be a BARRIER, put it back.  */
-  if (had_barrier)
-    emit_barrier_after (seq_insn);
-
+  end_sequence ();
   gcc_assert (i == length + 1);
 
+  /* Splice our SEQUENCE into the insn stream where INSN used to be.  */
+  add_insn_after (seq_insn, after, NULL);
+
   return seq_insn;
 }