summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cfgrtl.c2
-rw-r--r--gcc/emit-rtl.c21
-rw-r--r--gcc/haifa-sched.c2
-rw-r--r--gcc/lra-spills.c2
-rw-r--r--gcc/sel-sched-ir.c27
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);
}