diff options
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 3afcccbcf5e..8a00d6b0498 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -2130,9 +2130,10 @@ add_insn (insn) last_insn = insn; } -/* Add INSN into the doubly-linked list after insn AFTER. This should be the - only function called to insert an insn once delay slots have been filled - since only it knows how to update a SEQUENCE. */ +/* Add INSN into the doubly-linked list after insn AFTER. This and + the next should be the only functions called to insert an insn once + delay slots have been filled since only they knows how to update a + SEQUENCE. */ void add_insn_after (insn, after) @@ -2158,6 +2159,9 @@ add_insn_after (insn, after) for (; stack; stack = stack->next) if (after == stack->last) stack->last = insn; + + if (stack == 0) + abort (); } NEXT_INSN (after) = insn; @@ -2168,6 +2172,48 @@ add_insn_after (insn, after) } } +/* Add INSN into the doubly-linked list before insn BEFORE. This and + the previous should be the only functions called to insert an insn once + delay slots have been filled since only they knows how to update a + SEQUENCE. */ + +void +add_insn_before (insn, before) + rtx insn, before; +{ + rtx prev = PREV_INSN (before); + + PREV_INSN (insn) = prev; + NEXT_INSN (insn) = before; + + if (prev) + { + NEXT_INSN (prev) = insn; + if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE) + { + rtx sequence = PATTERN (prev); + NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn; + } + } + else if (first_insn == before) + first_insn = insn; + else + { + struct sequence_stack *stack = sequence_stack; + /* Scan all pending sequences too. */ + for (; stack; stack = stack->next) + if (before == stack->first) + stack->first = insn; + + if (stack == 0) + abort (); + } + + PREV_INSN (before) = insn; + if (GET_CODE (before) == INSN && GET_CODE (PATTERN (before)) == SEQUENCE) + PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn; +} + /* Delete all insns made since FROM. FROM becomes the new last instruction. */ @@ -2279,7 +2325,7 @@ emit_insn_before (pattern, before) for (i = 0; i < XVECLEN (pattern, 0); i++) { insn = XVECEXP (pattern, 0, i); - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); } if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) sequence_result[XVECLEN (pattern, 0)] = pattern; @@ -2287,7 +2333,7 @@ emit_insn_before (pattern, before) else { insn = make_insn_raw (pattern); - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); } return insn; @@ -2307,7 +2353,7 @@ emit_jump_insn_before (pattern, before) else { insn = make_jump_insn_raw (pattern); - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); } return insn; @@ -2327,7 +2373,7 @@ emit_call_insn_before (pattern, before) else { insn = make_call_insn_raw (pattern); - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); PUT_CODE (insn, CALL_INSN); } @@ -2345,7 +2391,7 @@ emit_barrier_before (before) INSN_UID (insn) = cur_insn_uid++; - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); return insn; } @@ -2361,7 +2407,7 @@ emit_note_before (subtype, before) NOTE_SOURCE_FILE (note) = 0; NOTE_LINE_NUMBER (note) = subtype; - add_insn_after (note, PREV_INSN (before)); + add_insn_before (note, before); return note; } @@ -2577,7 +2623,7 @@ emit_insns_before (insn, before) while (insn) { rtx next = NEXT_INSN (insn); - add_insn_after (insn, PREV_INSN (before)); + add_insn_before (insn, before); last = insn; insn = next; } |