summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-17 19:33:24 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-17 19:33:24 +0000
commit34f5b9ac205770850324c0536dca3eb377ad69b2 (patch)
tree0fcf1bced9e337bdcc941f146c80f42ae9406b42 /gcc
parent51c040f862753909cd465a73d61a5becd66f4be8 (diff)
downloadgcc-34f5b9ac205770850324c0536dca3eb377ad69b2.tar.gz
* emit-rtl.c (link_insn_into_chain): Handle chaining of SEQUENCEs.
* reorg.c (emit_delay_sequence): Simplify with emit-rtl API. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198036 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/emit-rtl.c7
-rw-r--r--gcc/reorg.c97
3 files changed, 37 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ee4bb5f6d3f..19d51f1f5e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index c8efb5ca4c5..a7cdf843fd9 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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.
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 30efd79be82..5a457e2c8e5 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -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;
}