aboutsummaryrefslogtreecommitdiff
path: root/gcc/reorg.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-09-15 22:48:00 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-09-15 22:48:00 +0000
commit9fa07b131e21a921ecc535f736882a5fb0698a9c (patch)
tree53bdda0670a317b7ee0c5d54eced29a316056e18 /gcc/reorg.c
parent06730c5d14d81a26842428dc85ff9e9849dba96f (diff)
downloadgcc-9fa07b131e21a921ecc535f736882a5fb0698a9c.zip
gcc-9fa07b131e21a921ecc535f736882a5fb0698a9c.tar.gz
gcc-9fa07b131e21a921ecc535f736882a5fb0698a9c.tar.bz2
re PR rtl-optimization/45593 (segfault with -Os)
PR rtl-optimization/45593 * reorg.c (relax_delay_slots): Use emit_copy_of_insn_after to re-emit insns that were in delay slots as stand-alone insns. From-SVN: r164318
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r--gcc/reorg.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c
index ec13bcc..7776fa2 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -3459,9 +3459,13 @@ relax_delay_slots (rtx first)
We do this by deleting the INSN containing the SEQUENCE, then
re-emitting the insns separately, and then deleting the RETURN.
This allows the count of the jump target to be properly
- decremented. */
+ decremented.
- /* Clear the from target bit, since these insns are no longer
+ Note that we need to change the INSN_UID of the re-emitted insns
+ since it is used to hash the insns for mark_target_live_regs and
+ the re-emitted insns will no longer be wrapped up in a SEQUENCE.
+
+ Clear the from target bit, since these insns are no longer
in delay slots. */
for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
@@ -3469,13 +3473,10 @@ relax_delay_slots (rtx first)
trial = PREV_INSN (insn);
delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE);
- after = trial;
- for (i = 0; i < XVECLEN (pat, 0); i++)
- {
- rtx this_insn = XVECEXP (pat, 0, i);
- add_insn_after (this_insn, after, NULL);
- after = this_insn;
- }
+ add_insn_after (delay_insn, trial, NULL);
+ after = delay_insn;
+ for (i = 1; i < XVECLEN (pat, 0); i++)
+ after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
delete_scheduled_jump (delay_insn);
continue;
}
@@ -3580,9 +3581,13 @@ relax_delay_slots (rtx first)
We do this by deleting the INSN containing the SEQUENCE, then
re-emitting the insns separately, and then deleting the jump.
This allows the count of the jump target to be properly
- decremented. */
+ decremented.
- /* Clear the from target bit, since these insns are no longer
+ Note that we need to change the INSN_UID of the re-emitted insns
+ since it is used to hash the insns for mark_target_live_regs and
+ the re-emitted insns will no longer be wrapped up in a SEQUENCE.
+
+ Clear the from target bit, since these insns are no longer
in delay slots. */
for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
@@ -3590,13 +3595,10 @@ relax_delay_slots (rtx first)
trial = PREV_INSN (insn);
delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE);
- after = trial;
- for (i = 0; i < XVECLEN (pat, 0); i++)
- {
- rtx this_insn = XVECEXP (pat, 0, i);
- add_insn_after (this_insn, after, NULL);
- after = this_insn;
- }
+ add_insn_after (delay_insn, trial, NULL);
+ after = delay_insn;
+ for (i = 1; i < XVECLEN (pat, 0); i++)
+ after = emit_copy_of_insn_after (XVECEXP (pat, 0, i), after);
delete_scheduled_jump (delay_insn);
continue;
}