diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2013-11-24 19:15:36 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2013-11-24 19:15:36 +0000 |
commit | 57d6c446c787d1dacd89c5cd504747d6857ad494 (patch) | |
tree | f5db0208687505d3114934ff0a9f353f86b4947f /gcc/jump.c | |
parent | 58b07297511c491cdd3feab39fcb0d84713f736e (diff) | |
download | gcc-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.c | 80 |
1 files changed, 57 insertions, 23 deletions
@@ -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); } } } |