aboutsummaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c807
1 files changed, 480 insertions, 327 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 7df9f23..a78a574 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3101,52 +3101,72 @@ try_split (pat, trial, last)
if (seq)
{
- /* SEQ can either be a SEQUENCE or the pattern of a single insn.
- The latter case will normally arise only when being done so that
- it, in turn, will be split (SFmode on the 29k is an example). */
- if (GET_CODE (seq) == SEQUENCE)
+ /* SEQ can only be a list of insns. */
+ if (! INSN_P (seq))
+ abort ();
+
+ /* Sometimes there will be only one insn in that list, this case will
+ normally arise only when we want it in turn to be split (SFmode on
+ the 29k is an example). */
+ if (NEXT_INSN (seq) != NULL_RTX)
{
- int i, njumps = 0;
+ rtx insn_last, insn;
+ int njumps = 0;
/* Avoid infinite loop if any insn of the result matches
the original pattern. */
- for (i = 0; i < XVECLEN (seq, 0); i++)
- if (GET_CODE (XVECEXP (seq, 0, i)) == INSN
- && rtx_equal_p (PATTERN (XVECEXP (seq, 0, i)), pat))
- return trial;
+ insn_last = seq;
+ while (1)
+ {
+ if (rtx_equal_p (PATTERN (insn_last), pat))
+ return trial;
+ if (NEXT_INSN (insn_last) == NULL_RTX)
+ break;
+ insn_last = NEXT_INSN (insn_last);
+ }
/* Mark labels. */
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
- if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN)
- {
- rtx insn = XVECEXP (seq, 0, i);
- mark_jump_label (PATTERN (insn),
- XVECEXP (seq, 0, i), 0);
- njumps++;
- if (probability != -1
- && any_condjump_p (insn)
- && !find_reg_note (insn, REG_BR_PROB, 0))
- {
- /* We can preserve the REG_BR_PROB notes only if exactly
- one jump is created, otherwise the machine description
- is responsible for this step using
- split_branch_probability variable. */
- if (njumps != 1)
- abort ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (probability),
- REG_NOTES (insn));
- }
- }
+ insn = insn_last;
+ while (insn != NULL_RTX)
+ {
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ mark_jump_label (PATTERN (insn), insn, 0);
+ njumps++;
+ if (probability != -1
+ && any_condjump_p (insn)
+ && !find_reg_note (insn, REG_BR_PROB, 0))
+ {
+ /* We can preserve the REG_BR_PROB notes only if exactly
+ one jump is created, otherwise the machine description
+ is responsible for this step using
+ split_branch_probability variable. */
+ if (njumps != 1)
+ abort ();
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (probability),
+ REG_NOTES (insn));
+ }
+ }
+
+ insn = PREV_INSN (insn);
+ }
/* If we are splitting a CALL_INSN, look for the CALL_INSN
in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */
if (GET_CODE (trial) == CALL_INSN)
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
- if (GET_CODE (XVECEXP (seq, 0, i)) == CALL_INSN)
- CALL_INSN_FUNCTION_USAGE (XVECEXP (seq, 0, i))
- = CALL_INSN_FUNCTION_USAGE (trial);
+ {
+ insn = insn_last;
+ while (insn != NULL_RTX)
+ {
+ if (GET_CODE (insn) == CALL_INSN)
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = CALL_INSN_FUNCTION_USAGE (trial);
+
+ insn = PREV_INSN (insn);
+ }
+ }
/* Copy notes, particularly those related to the CFG. */
for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
@@ -3154,9 +3174,9 @@ try_split (pat, trial, last)
switch (REG_NOTE_KIND (note))
{
case REG_EH_REGION:
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
+ insn = insn_last;
+ while (insn != NULL_RTX)
{
- rtx insn = XVECEXP (seq, 0, i);
if (GET_CODE (insn) == CALL_INSN
|| (flag_non_call_exceptions
&& may_trap_p (PATTERN (insn))))
@@ -3164,32 +3184,35 @@ try_split (pat, trial, last)
= gen_rtx_EXPR_LIST (REG_EH_REGION,
XEXP (note, 0),
REG_NOTES (insn));
+ insn = PREV_INSN (insn);
}
break;
case REG_NORETURN:
case REG_SETJMP:
case REG_ALWAYS_RETURN:
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
+ insn = insn_last;
+ while (insn != NULL_RTX)
{
- rtx insn = XVECEXP (seq, 0, i);
if (GET_CODE (insn) == CALL_INSN)
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
XEXP (note, 0),
REG_NOTES (insn));
+ insn = PREV_INSN (insn);
}
break;
case REG_NON_LOCAL_GOTO:
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
+ insn = insn_last;
+ while (insn != NULL_RTX)
{
- rtx insn = XVECEXP (seq, 0, i);
if (GET_CODE (insn) == JUMP_INSN)
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
XEXP (note, 0),
REG_NOTES (insn));
+ insn = PREV_INSN (insn);
}
break;
@@ -3201,9 +3224,16 @@ try_split (pat, trial, last)
/* If there are LABELS inside the split insns increment the
usage count so we don't delete the label. */
if (GET_CODE (trial) == INSN)
- for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
- if (GET_CODE (XVECEXP (seq, 0, i)) == INSN)
- mark_label_nuses (PATTERN (XVECEXP (seq, 0, i)));
+ {
+ insn = last_insn;
+ while (insn != NULL_RTX)
+ {
+ if (GET_CODE (insn) == INSN)
+ mark_label_nuses (PATTERN (insn));
+
+ insn = PREV_INSN (insn);
+ }
+ }
tem = emit_insn_after_scope (seq, trial, INSN_SCOPE (trial));
@@ -3221,13 +3251,13 @@ try_split (pat, trial, last)
tem = try_split (PATTERN (tem), tem, 1);
}
/* Avoid infinite loop if the result matches the original pattern. */
- else if (rtx_equal_p (seq, pat))
+ else if (rtx_equal_p (PATTERN (seq), pat))
return trial;
else
{
- PATTERN (trial) = seq;
+ PATTERN (trial) = PATTERN (seq);
INSN_CODE (trial) = -1;
- try_split (seq, trial, last);
+ try_split (PATTERN (trial), trial, last);
}
/* Return either the first or the last insn, depending on which was
@@ -3274,7 +3304,7 @@ make_insn_raw (pattern)
return insn;
}
-/* Like `make_insn' but make a JUMP_INSN instead of an insn. */
+/* Like `make_insn_raw' but make a JUMP_INSN instead of an insn. */
static rtx
make_jump_insn_raw (pattern)
@@ -3296,7 +3326,7 @@ make_jump_insn_raw (pattern)
return insn;
}
-/* Like `make_insn' but make a CALL_INSN instead of an insn. */
+/* Like `make_insn_raw' but make a CALL_INSN instead of an insn. */
static rtx
make_call_insn_raw (pattern)
@@ -3782,97 +3812,173 @@ remove_unnecessary_notes ()
}
-/* Emit an insn of given code and pattern
- at a specified place within the doubly-linked list. */
+/* Emit insn(s) of given code and pattern
+ at a specified place within the doubly-linked list.
-/* Make an instruction with body PATTERN
- and output it before the instruction BEFORE. */
+ All of the emit_foo global entry points accept an object
+ X which is either an insn list or a PATTERN of a single
+ instruction.
-rtx
-emit_insn_before (pattern, before)
- rtx pattern, before;
-{
- rtx insn = before;
+ There are thus a few canonical ways to generate code and
+ emit it at a specific place in the instruction stream. For
+ example, consider the instruction named SPOT and the fact that
+ we would like to emit some instructions before SPOT. We might
+ do it like this:
- if (GET_CODE (pattern) == SEQUENCE)
- {
- int i;
+ start_sequence ();
+ ... emit the new instructions ...
+ insns_head = get_insns ();
+ end_sequence ();
- for (i = 0; i < XVECLEN (pattern, 0); i++)
- {
- insn = XVECEXP (pattern, 0, i);
- add_insn_before (insn, before);
- }
- }
- else
- {
- insn = make_insn_raw (pattern);
- add_insn_before (insn, before);
- }
+ emit_insn_before (insns_head, SPOT);
- return insn;
-}
+ It used to be common to generate SEQUENCE rtl instead, but that
+ is a relic of the past which no longer occurs. The reason is that
+ SEQUENCE rtl results in much fragmented RTL memory since the SEQUENCE
+ generated would almost certainly die right after it was created. */
-/* Make an instruction with body PATTERN and code JUMP_INSN
- and output it before the instruction BEFORE. */
+/* Make X be output before the instruction BEFORE. */
rtx
-emit_jump_insn_before (pattern, before)
- rtx pattern, before;
+emit_insn_before (x, before)
+ rtx x, before;
{
+ rtx last = before;
rtx insn;
- if (GET_CODE (pattern) == SEQUENCE)
- insn = emit_insn_before (pattern, before);
- else
+#ifdef ENABLE_RTL_CHECKING
+ if (before == NULL_RTX)
+ abort ();
+#endif
+
+ if (x == NULL_RTX)
+ return last;
+
+ switch (GET_CODE (x))
{
- insn = make_jump_insn_raw (pattern);
- add_insn_before (insn, before);
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn_before (insn, before);
+ last = insn;
+ insn = next;
+ }
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_insn_raw (x);
+ add_insn_before (last, before);
+ break;
}
- return insn;
+ return last;
}
-/* Make an instruction with body PATTERN and code CALL_INSN
+/* Make an instruction with body X and code JUMP_INSN
and output it before the instruction BEFORE. */
rtx
-emit_call_insn_before (pattern, before)
- rtx pattern, before;
+emit_jump_insn_before (x, before)
+ rtx x, before;
{
- rtx insn;
+ rtx insn, last;
- if (GET_CODE (pattern) == SEQUENCE)
- insn = emit_insn_before (pattern, before);
- else
+#ifdef ENABLE_RTL_CHECKING
+ if (before == NULL_RTX)
+ abort ();
+#endif
+
+ switch (GET_CODE (x))
{
- insn = make_call_insn_raw (pattern);
- add_insn_before (insn, before);
- PUT_CODE (insn, CALL_INSN);
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn_before (insn, before);
+ last = insn;
+ insn = next;
+ }
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_jump_insn_raw (x);
+ add_insn_before (last, before);
+ break;
}
- return insn;
+ return last;
}
-/* Make an instruction with body PATTERN and code CALL_INSN
+/* Make an instruction with body X and code CALL_INSN
and output it before the instruction BEFORE. */
rtx
-emit_call_insn_after (pattern, before)
- rtx pattern, before;
+emit_call_insn_before (x, before)
+ rtx x, before;
{
- rtx insn;
+ rtx last, insn;
- if (GET_CODE (pattern) == SEQUENCE)
- insn = emit_insn_after (pattern, before);
- else
+#ifdef ENABLE_RTL_CHECKING
+ if (before == NULL_RTX)
+ abort ();
+#endif
+
+ switch (GET_CODE (x))
{
- insn = make_call_insn_raw (pattern);
- add_insn_after (insn, before);
- PUT_CODE (insn, CALL_INSN);
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn_before (insn, before);
+ last = insn;
+ insn = next;
+ }
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_call_insn_raw (x);
+ add_insn_before (last, before);
+ break;
}
- return insn;
+ return last;
}
/* Make an insn of code BARRIER
@@ -3924,45 +4030,100 @@ emit_note_before (subtype, before)
return note;
}
-/* Make an insn of code INSN with body PATTERN
- and output it after the insn AFTER. */
+/* Helper for emit_insn_after, handles lists of instructions
+ efficiently. */
-rtx
-emit_insn_after (pattern, after)
- rtx pattern, after;
+static rtx emit_insn_after_1 PARAMS ((rtx, rtx));
+
+static rtx
+emit_insn_after_1 (first, after)
+ rtx first, after;
{
- rtx insn = after;
+ rtx last;
+ rtx after_after;
+ basic_block bb;
- if (GET_CODE (pattern) == SEQUENCE)
+ if (GET_CODE (after) != BARRIER
+ && (bb = BLOCK_FOR_INSN (after)))
{
- int i;
-
- for (i = 0; i < XVECLEN (pattern, 0); i++)
- {
- insn = XVECEXP (pattern, 0, i);
- add_insn_after (insn, after);
- after = insn;
- }
+ bb->flags |= BB_DIRTY;
+ for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
+ if (GET_CODE (last) != BARRIER)
+ set_block_for_insn (last, bb);
+ if (GET_CODE (last) != BARRIER)
+ set_block_for_insn (last, bb);
+ if (bb->end == after)
+ bb->end = last;
}
else
+ for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
+ continue;
+
+ after_after = NEXT_INSN (after);
+
+ NEXT_INSN (after) = first;
+ PREV_INSN (first) = after;
+ NEXT_INSN (last) = after_after;
+ if (after_after)
+ PREV_INSN (after_after) = last;
+
+ if (after == last_insn)
+ last_insn = last;
+ return last;
+}
+
+/* Make X be output after the insn AFTER. */
+
+rtx
+emit_insn_after (x, after)
+ rtx x, after;
+{
+ rtx last = after;
+
+#ifdef ENABLE_RTL_CHECKING
+ if (after == NULL_RTX)
+ abort ();
+#endif
+
+ if (x == NULL_RTX)
+ return last;
+
+ switch (GET_CODE (x))
{
- insn = make_insn_raw (pattern);
- add_insn_after (insn, after);
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ last = emit_insn_after_1 (x, after);
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_insn_raw (x);
+ add_insn_after (last, after);
+ break;
}
- return insn;
+ return last;
}
/* Similar to emit_insn_after, except that line notes are to be inserted so
as to act as if this insn were at FROM. */
void
-emit_insn_after_with_line_notes (pattern, after, from)
- rtx pattern, after, from;
+emit_insn_after_with_line_notes (x, after, from)
+ rtx x, after, from;
{
rtx from_line = find_line_note (from);
rtx after_line = find_line_note (after);
- rtx insn = emit_insn_after (pattern, after);
+ rtx insn = emit_insn_after (x, after);
if (from_line)
emit_line_note_after (NOTE_SOURCE_FILE (from_line),
@@ -3975,24 +4136,84 @@ emit_insn_after_with_line_notes (pattern, after, from)
insn);
}
-/* Make an insn of code JUMP_INSN with body PATTERN
+/* Make an insn of code JUMP_INSN with body X
and output it after the insn AFTER. */
rtx
-emit_jump_insn_after (pattern, after)
- rtx pattern, after;
+emit_jump_insn_after (x, after)
+ rtx x, after;
{
- rtx insn;
+ rtx last;
- if (GET_CODE (pattern) == SEQUENCE)
- insn = emit_insn_after (pattern, after);
- else
+#ifdef ENABLE_RTL_CHECKING
+ if (after == NULL_RTX)
+ abort ();
+#endif
+
+ switch (GET_CODE (x))
{
- insn = make_jump_insn_raw (pattern);
- add_insn_after (insn, after);
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ last = emit_insn_after_1 (x, after);
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_jump_insn_raw (x);
+ add_insn_after (last, after);
+ break;
}
- return insn;
+ return last;
+}
+
+/* Make an instruction with body X and code CALL_INSN
+ and output it after the instruction AFTER. */
+
+rtx
+emit_call_insn_after (x, after)
+ rtx x, after;
+{
+ rtx last;
+
+#ifdef ENABLE_RTL_CHECKING
+ if (after == NULL_RTX)
+ abort ();
+#endif
+
+ switch (GET_CODE (x))
+ {
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ last = emit_insn_after_1 (x, after);
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
+
+ default:
+ last = make_call_insn_raw (x);
+ add_insn_after (last, after);
+ break;
+ }
+
+ return last;
}
/* Make an insn of code BARRIER
@@ -4076,20 +4297,15 @@ emit_insn_after_scope (pattern, after, scope)
tree scope;
{
rtx last = emit_insn_after (pattern, after);
- for (after = NEXT_INSN (after); after != last; after = NEXT_INSN (after))
- INSN_SCOPE (after) = scope;
- return last;
-}
-/* Like emit_insns_after, but set INSN_SCOPE according to SCOPE. */
-rtx
-emit_insns_after_scope (pattern, after, scope)
- rtx pattern, after;
- tree scope;
-{
- rtx last = emit_insns_after (pattern, after);
- for (after = NEXT_INSN (after); after != last; after = NEXT_INSN (after))
- INSN_SCOPE (after) = scope;
+ after = NEXT_INSN (after);
+ while (1)
+ {
+ INSN_SCOPE (after) = scope;
+ if (after == last)
+ break;
+ after = NEXT_INSN (after);
+ }
return last;
}
@@ -4100,8 +4316,15 @@ emit_jump_insn_after_scope (pattern, after, scope)
tree scope;
{
rtx last = emit_jump_insn_after (pattern, after);
- for (after = NEXT_INSN (after); after != last; after = NEXT_INSN (after))
- INSN_SCOPE (after) = scope;
+
+ after = NEXT_INSN (after);
+ while (1)
+ {
+ INSN_SCOPE (after) = scope;
+ if (after == last)
+ break;
+ after = NEXT_INSN (after);
+ }
return last;
}
@@ -4112,8 +4335,15 @@ emit_call_insn_after_scope (pattern, after, scope)
tree scope;
{
rtx last = emit_call_insn_after (pattern, after);
- for (after = NEXT_INSN (after); after != last; after = NEXT_INSN (after))
- INSN_SCOPE (after) = scope;
+
+ after = NEXT_INSN (after);
+ while (1)
+ {
+ INSN_SCOPE (after) = scope;
+ if (after == last)
+ break;
+ after = NEXT_INSN (after);
+ }
return last;
}
@@ -4126,178 +4356,140 @@ emit_insn_before_scope (pattern, before, scope)
rtx first = PREV_INSN (before);
rtx last = emit_insn_before (pattern, before);
- for (first = NEXT_INSN (first); first != last; first = NEXT_INSN (first))
- INSN_SCOPE (first) = scope;
- return last;
-}
-
-/* Like emit_insns_before, but set INSN_SCOPE according to SCOPE. */
-rtx
-emit_insns_before_scope (pattern, before, scope)
- rtx pattern, before;
- tree scope;
-{
- rtx first = PREV_INSN (before);
- rtx last = emit_insns_before (pattern, before);
-
- for (first = NEXT_INSN (first); first != last; first = NEXT_INSN (first))
- INSN_SCOPE (first) = scope;
+ first = NEXT_INSN (first);
+ while (1)
+ {
+ INSN_SCOPE (first) = scope;
+ if (first == last)
+ break;
+ first = NEXT_INSN (first);
+ }
return last;
}
-/* Make an insn of code INSN with pattern PATTERN
- and add it to the end of the doubly-linked list.
- If PATTERN is a SEQUENCE, take the elements of it
- and emit an insn for each element.
+/* Take X and emit it at the end of the doubly-linked
+ INSN list.
Returns the last insn emitted. */
rtx
-emit_insn (pattern)
- rtx pattern;
+emit_insn (x)
+ rtx x;
{
- rtx insn = last_insn;
+ rtx last = last_insn;
+ rtx insn;
- if (GET_CODE (pattern) == SEQUENCE)
- {
- int i;
+ if (x == NULL_RTX)
+ return last;
- for (i = 0; i < XVECLEN (pattern, 0); i++)
+ switch (GET_CODE (x))
+ {
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
{
- insn = XVECEXP (pattern, 0, i);
+ rtx next = NEXT_INSN (insn);
add_insn (insn);
+ last = insn;
+ insn = next;
}
- }
- else
- {
- insn = make_insn_raw (pattern);
- add_insn (insn);
- }
-
- return insn;
-}
-
-/* Emit the insns in a chain starting with INSN.
- Return the last insn emitted. */
+ break;
-rtx
-emit_insns (insn)
- rtx insn;
-{
- rtx last = 0;
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
- while (insn)
- {
- rtx next = NEXT_INSN (insn);
- add_insn (insn);
- last = insn;
- insn = next;
+ default:
+ last = make_insn_raw (x);
+ add_insn (last);
+ break;
}
return last;
}
-/* Emit the insns in a chain starting with INSN and place them in front of
- the insn BEFORE. Return the last insn emitted. */
+/* Make an insn of code JUMP_INSN with pattern X
+ and add it to the end of the doubly-linked list. */
rtx
-emit_insns_before (insn, before)
- rtx insn;
- rtx before;
+emit_jump_insn (x)
+ rtx x;
{
- rtx last = 0;
+ rtx last, insn;
- while (insn)
+ switch (GET_CODE (x))
{
- rtx next = NEXT_INSN (insn);
- add_insn_before (insn, before);
- last = insn;
- insn = next;
- }
-
- return last;
-}
-
-/* Emit the insns in a chain starting with FIRST and place them in back of
- the insn AFTER. Return the last insn emitted. */
-
-rtx
-emit_insns_after (first, after)
- rtx first;
- rtx after;
-{
- rtx last;
- rtx after_after;
- basic_block bb;
-
- if (!after)
- abort ();
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn (insn);
+ last = insn;
+ insn = next;
+ }
+ break;
- if (!first)
- return after;
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
- if (GET_CODE (after) != BARRIER
- && (bb = BLOCK_FOR_INSN (after)))
- {
- bb->flags |= BB_DIRTY;
- for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
- if (GET_CODE (last) != BARRIER)
- set_block_for_insn (last, bb);
- if (GET_CODE (last) != BARRIER)
- set_block_for_insn (last, bb);
- if (bb->end == after)
- bb->end = last;
+ default:
+ last = make_jump_insn_raw (x);
+ add_insn (last);
+ break;
}
- else
- for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
- continue;
-
- after_after = NEXT_INSN (after);
-
- NEXT_INSN (after) = first;
- PREV_INSN (first) = after;
- NEXT_INSN (last) = after_after;
- if (after_after)
- PREV_INSN (after_after) = last;
- if (after == last_insn)
- last_insn = last;
return last;
}
-/* Make an insn of code JUMP_INSN with pattern PATTERN
+/* Make an insn of code CALL_INSN with pattern X
and add it to the end of the doubly-linked list. */
rtx
-emit_jump_insn (pattern)
- rtx pattern;
+emit_call_insn (x)
+ rtx x;
{
- if (GET_CODE (pattern) == SEQUENCE)
- return emit_insn (pattern);
- else
+ rtx insn;
+
+ switch (GET_CODE (x))
{
- rtx insn = make_jump_insn_raw (pattern);
- add_insn (insn);
- return insn;
- }
-}
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = emit_insn (x);
+ break;
-/* Make an insn of code CALL_INSN with pattern PATTERN
- and add it to the end of the doubly-linked list. */
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ abort ();
+ break;
+#endif
-rtx
-emit_call_insn (pattern)
- rtx pattern;
-{
- if (GET_CODE (pattern) == SEQUENCE)
- return emit_insn (pattern);
- else
- {
- rtx insn = make_call_insn_raw (pattern);
+ default:
+ insn = make_call_insn_raw (x);
add_insn (insn);
- PUT_CODE (insn, CALL_INSN);
- return insn;
+ break;
}
+
+ return insn;
}
/* Add the label LABEL to the end of the doubly-linked list. */
@@ -4634,12 +4826,12 @@ pop_topmost_sequence ()
/* After emitting to a sequence, restore previous saved state.
To get the contents of the sequence just made, you must call
- `gen_sequence' *before* calling here.
+ `get_insns' *before* calling here.
If the compiler might have deferred popping arguments while
generating this sequence, and this sequence will not be immediately
inserted into the instruction stream, use do_pending_stack_adjust
- before calling gen_sequence. That will ensure that the deferred
+ before calling get_insns. That will ensure that the deferred
pops are inserted into this sequence, and not into some random
location in the instruction stream. See INHIBIT_DEFER_POP for more
information about deferred popping of arguments. */
@@ -4678,45 +4870,6 @@ in_sequence_p ()
{
return seq_stack != 0;
}
-
-/* Generate a SEQUENCE rtx containing the insns already emitted
- to the current sequence.
-
- This is how the gen_... function from a DEFINE_EXPAND
- constructs the SEQUENCE that it returns. */
-
-rtx
-gen_sequence ()
-{
- rtx result;
- rtx tem;
- int i;
- int len;
-
- /* Count the insns in the chain. */
- len = 0;
- for (tem = first_insn; tem; tem = NEXT_INSN (tem))
- len++;
-
- /* If only one insn, return it rather than a SEQUENCE.
- (Now that we cache SEQUENCE expressions, it isn't worth special-casing
- the case of an empty list.)
- We only return the pattern of an insn if its code is INSN and it
- has no notes. This ensures that no information gets lost. */
- if (len == 1
- && GET_CODE (first_insn) == INSN
- && ! RTX_FRAME_RELATED_P (first_insn)
- /* Don't throw away any reg notes. */
- && REG_NOTES (first_insn) == 0)
- return PATTERN (first_insn);
-
- result = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (len));
-
- for (i = 0, tem = first_insn; tem; tem = NEXT_INSN (tem), i++)
- XVECEXP (result, 0, i) = tem;
-
- return result;
-}
/* Put the various virtual registers into REGNO_REG_RTX. */