aboutsummaryrefslogtreecommitdiff
path: root/gcc/jump.c
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2013-11-24 19:15:36 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2013-11-24 19:15:36 +0000
commit57d6c446c787d1dacd89c5cd504747d6857ad494 (patch)
treef5db0208687505d3114934ff0a9f353f86b4947f /gcc/jump.c
parent58b07297511c491cdd3feab39fcb0d84713f736e (diff)
downloadgcc-57d6c446c787d1dacd89c5cd504747d6857ad494.zip
gcc-57d6c446c787d1dacd89c5cd504747d6857ad494.tar.gz
gcc-57d6c446c787d1dacd89c5cd504747d6857ad494.tar.bz2
jump.c (reset_insn_reg_label_operand_notes): New function, split out from ...
* jump.c (reset_insn_reg_label_operand_notes): New function, split out from ... (init_label_info): ... here. Reset LABEL_NUSES in cfglayout mode. * cfgcleanup.c (delete_dead_jump_tables_between): New function, split out from ... (delete_dead_jumptables): ... here. Handle cfglayout mode. (cleanup_cfg): Delete dead jump tables in cfglayout mode if an expensive CFG cleanup is called for. * cfgrtl.c (fixup_reorder_chain): Remove BARRIERs from fallthru paths. (cfg_layout_finalize): Delete dead jump tables before re-building the insns chain. * ira.c (ira): Rebuild jump labels *after* deleting unreachable basic blocks, not before. * loop-init.c (rtl_loop_done): Call for an expensive CFG cleanup. * modulo-sched.c (sms_schedule): Do not look for BARRIERs in the insns chain of a scheduling extended basic block, they cannot appear there in cfglayout mode. From-SVN: r205337
Diffstat (limited to 'gcc/jump.c')
-rw-r--r--gcc/jump.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/gcc/jump.c b/gcc/jump.c
index a27aaa9..87f9619 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -177,6 +177,34 @@ make_pass_cleanup_barriers (gcc::context *ctxt)
}
+/* Remove all REG_LABEL_OPERAND notes from INSN.
+
+ REG_LABEL_TARGET notes (including the JUMP_LABEL field) are sticky and
+ not reset here; that way we won't lose association with a label when
+ e.g. the source for a target register disappears out of reach for targets
+ that may use jump-target registers. Jump transformations are supposed to
+ transform any REG_LABEL_TARGET notes. The target label reference in a
+ branch may disappear from the branch (and from the instruction before it)
+ for other reasons, like register allocation. */
+
+static void
+reset_insn_reg_label_operand_notes (rtx insn)
+{
+ if (INSN_P (insn))
+ {
+ rtx note, next;
+
+ for (note = REG_NOTES (insn); note; note = next)
+ {
+ next = XEXP (note, 1);
+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
+ && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
+ remove_note (insn, note);
+ }
+ }
+}
+
+
/* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
notes whose labels don't occur in the insn any more. */
@@ -186,32 +214,38 @@ init_label_info (rtx f)
{
rtx insn;
- for (insn = f; insn; insn = NEXT_INSN (insn))
+ if (current_ir_type () == IR_RTL_CFGLAYOUT)
{
- if (LABEL_P (insn))
- LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
-
- /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
- sticky and not reset here; that way we won't lose association
- with a label when e.g. the source for a target register
- disappears out of reach for targets that may use jump-target
- registers. Jump transformations are supposed to transform
- any REG_LABEL_TARGET notes. The target label reference in a
- branch may disappear from the branch (and from the
- instruction before it) for other reasons, like register
- allocation. */
-
- if (INSN_P (insn))
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
{
- rtx note, next;
+ /* Labels only appear between BB_HEAD and the basic block note,
+ and in the basic block header and footer. */
+ for (insn = BB_HEAD (bb);
+ insn && LABEL_P (insn);
+ insn = NEXT_INSN (insn))
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
+ for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn))
+ if (LABEL_P (insn))
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
+ for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn))
+ if (LABEL_P (insn))
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
- for (note = REG_NOTES (insn); note; note = next)
- {
- next = XEXP (note, 1);
- if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
- && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
- remove_note (insn, note);
- }
+ FOR_BB_INSNS (bb, insn)
+ if (INSN_P (insn))
+ reset_insn_reg_label_operand_notes (insn);
+ }
+ }
+ else
+ {
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ {
+ if (LABEL_P (insn))
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
+ if (INSN_P (insn))
+ reset_insn_reg_label_operand_notes (insn);
}
}
}