diff options
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 2 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 21 | ||||
-rw-r--r-- | gcc/haifa-sched.c | 2 | ||||
-rw-r--r-- | gcc/lra-spills.c | 2 | ||||
-rw-r--r-- | gcc/sel-sched-ir.c | 27 |
6 files changed, 39 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ead79e8f8f..f61412c5b69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-04-13 Steven Bosscher <steven@gcc.gnu.org> + + * emit-rtl.c (remove_insn): Do not call df_insn_delete here. + * cfgrtl.c (delete_insn): Call it here instead. + * lra-spills.c (lra_final_code_change): Use delete_insn. + * haifa-sched.c (sched_remove_insn): Likewise. + * sel-sched-ir.c (return_nop_to_pool): Clear INSN_DELETED_P for nops + returning to the nop pool. + (sel_remove_insn): Simplify the only_disconnect case via remove_insn, + use delete_insn for definitive removal. Clear BLOCK_FOR_INSN. + 2013-04-12 Steven Bosscher <steven@gcc.gnu.org> * doc/tm.texi.in (LOOP_ALIGN): Remove loop note references. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 6e8a31d95da..f59051daab5 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -164,6 +164,8 @@ delete_insn (rtx insn) { /* If this insn has already been deleted, something is very wrong. */ gcc_assert (!INSN_DELETED_P (insn)); + if (INSN_P (insn)) + df_insn_delete (insn); remove_insn (insn); INSN_DELETED_P (insn) = 1; } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 73a59b58046..82e476683ca 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3908,8 +3908,21 @@ set_insn_deleted (rtx insn) } -/* Remove an insn from its doubly-linked list. This function knows how - to handle sequences. */ +/* Unlink INSN from the insn chain. + + This function knows how to handle sequences. + + This function does not invalidate data flow information associated with + INSN (i.e. does not call df_insn_delete). That makes this function + usable for only disconnecting an insn from the chain, and re-emit it + elsewhere later. + + To later insert INSN elsewhere in the insn chain via add_insn and + similar functions, PREV_INSN and NEXT_INSN must be nullified by + the caller. Nullifying them here breaks many insn chain walks. + + To really delete an insn and related DF information, use delete_insn. */ + void remove_insn (rtx insn) { @@ -3968,10 +3981,6 @@ remove_insn (rtx insn) gcc_assert (stack); } - /* Invalidate data flow information associated with INSN. */ - if (INSN_P (insn)) - df_insn_delete (insn); - /* Fix up basic block boundaries, if necessary. */ if (!BARRIER_P (insn) && (bb = BLOCK_FOR_INSN (insn))) diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index c4591bfe35b..16094b231b2 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -8198,7 +8198,7 @@ sched_remove_insn (rtx insn) change_queue_index (insn, QUEUE_NOWHERE); current_sched_info->add_remove_insn (insn, 1); - remove_insn (insn); + delete_insn (insn); } /* Clear priorities of all instructions, that are forward dependent on INSN. diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index 163ca11509d..60e51eec0c5 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -639,7 +639,7 @@ lra_final_code_change (void) need them anymore and don't want to waste compiler time processing them in a few subsequent passes. */ lra_invalidate_insn_data (insn); - remove_insn (insn); + delete_insn (insn); continue; } diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 91e91ec37fd..47e769534db 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -1065,6 +1065,9 @@ return_nop_to_pool (insn_t nop, bool full_tidying) gcc_assert (INSN_IN_STREAM_P (nop)); sel_remove_insn (nop, false, full_tidying); + /* We'll recycle this nop. */ + INSN_DELETED_P (nop) = 0; + if (nop_pool.n == nop_pool.s) nop_pool.v = XRESIZEVEC (rtx, nop_pool.v, (nop_pool.s = 2 * nop_pool.s + 1)); @@ -3929,31 +3932,19 @@ sel_remove_insn (insn_t insn, bool only_disconnect, bool full_tidying) } if (only_disconnect) - { - insn_t prev = PREV_INSN (insn); - insn_t next = NEXT_INSN (insn); - basic_block bb = BLOCK_FOR_INSN (insn); - - NEXT_INSN (prev) = next; - PREV_INSN (next) = prev; - - if (BB_HEAD (bb) == insn) - { - gcc_assert (BLOCK_FOR_INSN (prev) == bb); - BB_HEAD (bb) = prev; - } - if (BB_END (bb) == insn) - BB_END (bb) = prev; - } + remove_insn (insn); else { - remove_insn (insn); + delete_insn (insn); clear_expr (INSN_EXPR (insn)); } - /* It is necessary to null this fields before calling add_insn (). */ + /* It is necessary to NULL these fields in case we are going to re-insert + INSN into the insns stream, as will usually happen in the ONLY_DISCONNECT + case, but also for NOPs that we will return to the nop pool. */ PREV_INSN (insn) = NULL_RTX; NEXT_INSN (insn) = NULL_RTX; + set_block_for_insn (insn, NULL); return tidy_control_flow (bb, full_tidying); } |