diff options
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r-- | gcc/cfgrtl.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 3a4afcaf8b..cafa38d35b 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1,5 +1,5 @@ /* Control flow graph manipulation code for GNU compiler. - Copyright (C) 1987-2016 Free Software Foundation, Inc. + Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "cfghooks.h" #include "df.h" #include "insn-config.h" +#include "memmodel.h" #include "emit-rtl.h" #include "cfgrtl.h" #include "cfganal.h" @@ -115,15 +116,15 @@ can_delete_label_p (const rtx_code_label *label) return (!LABEL_PRESERVE_P (label) /* User declared labels must be preserved. */ && LABEL_NAME (label) == 0 - && !in_insn_list_p (forced_labels, label)); + && !vec_safe_contains<rtx_insn *> (forced_labels, + const_cast<rtx_code_label *> (label))); } /* Delete INSN by patching it out. */ void -delete_insn (rtx uncast_insn) +delete_insn (rtx_insn *insn) { - rtx_insn *insn = as_a <rtx_insn *> (uncast_insn); rtx note; bool really_delete = true; @@ -215,9 +216,10 @@ delete_insn (rtx uncast_insn) } } -/* Like delete_insn but also purge dead edges from BB. */ +/* Like delete_insn but also purge dead edges from BB. + Return true if any edges are eliminated. */ -void +bool delete_insn_and_edges (rtx_insn *insn) { bool purge = false; @@ -228,7 +230,8 @@ delete_insn_and_edges (rtx_insn *insn) purge = true; delete_insn (insn); if (purge) - purge_dead_edges (BLOCK_FOR_INSN (insn)); + return purge_dead_edges (BLOCK_FOR_INSN (insn)); + return false; } /* Unlink a chain of insns between START and FINISH, leaving notes @@ -236,17 +239,15 @@ delete_insn_and_edges (rtx_insn *insn) insns that cannot be removed to NULL. */ void -delete_insn_chain (rtx start, rtx finish, bool clear_bb) +delete_insn_chain (rtx start, rtx_insn *finish, bool clear_bb) { - rtx_insn *prev, *current; - /* Unchain the insns one by one. It would be quicker to delete all of these with a single unchaining, rather than one at a time, but we need to keep the NOTE's. */ - current = safe_as_a <rtx_insn *> (finish); + rtx_insn *current = finish; while (1) { - prev = PREV_INSN (current); + rtx_insn *prev = PREV_INSN (current); if (NOTE_P (current) && !can_delete_note_p (as_a <rtx_note *> (current))) ; else @@ -1097,7 +1098,7 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) { rtx_code_label *target_label = block_label (target); rtx_insn *barrier; - rtx label; + rtx_insn *label; rtx_jump_table_data *table; emit_jump_insn_after_noloc (targetm.gen_jump (target_label), insn); @@ -1197,7 +1198,7 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb) && SET_DEST (tmp) == pc_rtx && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF - && LABEL_REF_LABEL (XEXP (SET_SRC (tmp), 2)) == old_label) + && label_ref_label (XEXP (SET_SRC (tmp), 2)) == old_label) { XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode, new_label); @@ -1769,7 +1770,7 @@ rtl_tidy_fallthru_edge (edge e) && (any_uncondjump_p (q) || single_succ_p (b))) { - rtx label; + rtx_insn *label; rtx_jump_table_data *table; if (tablejump_p (q, &label, &table)) @@ -1782,8 +1783,7 @@ rtl_tidy_fallthru_edge (edge e) PUT_CODE (label, NOTE); NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL; NOTE_DELETED_LABEL_NAME (label) = name; - rtx_insn *lab = safe_as_a <rtx_insn *> (label); - reorder_insns (lab, lab, PREV_INSN (q)); + reorder_insns (label, label, PREV_INSN (q)); delete_insn (table); } @@ -1794,6 +1794,10 @@ rtl_tidy_fallthru_edge (edge e) q = PREV_INSN (q); } + /* Unconditional jumps with side-effects (i.e. which we can't just delete + together with the barrier) should never have a fallthru edge. */ + else if (JUMP_P (q) && any_uncondjump_p (q)) + return; /* Selectively unlink the sequence. */ if (q != PREV_INSN (BB_HEAD (c))) @@ -1931,7 +1935,8 @@ rtl_split_edge (edge edge_in) if (last && JUMP_P (last) && edge_in->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) - && extract_asm_operands (PATTERN (last)) != NULL_RTX + && (extract_asm_operands (PATTERN (last)) + || JUMP_LABEL (last) == before) && patch_jump_insn (last, before, bb)) df_set_bb_dirty (edge_in->src); } @@ -3646,7 +3651,8 @@ relink_block_chain (bool stay_in_cfglayout_mode) /* Maybe reset the original copy tables, they are not valid anymore when we renumber the basic blocks in compact_blocks. If we are are going out of cfglayout mode, don't re-allocate the tables. */ - free_original_copy_tables (); + if (original_copy_tables_initialized_p ()) + free_original_copy_tables (); if (stay_in_cfglayout_mode) initialize_original_copy_tables (); @@ -3816,7 +3822,7 @@ fixup_reorder_chain (void) update_br_prob_note (bb); if (LABEL_NUSES (ret_label) == 0 && single_pred_p (e_taken->dest)) - delete_insn (ret_label); + delete_insn (as_a<rtx_insn *> (ret_label)); continue; } } @@ -4270,11 +4276,10 @@ cfg_layout_initialize (unsigned int flags) void break_superblocks (void) { - sbitmap superblocks; bool need = false; basic_block bb; - superblocks = sbitmap_alloc (last_basic_block_for_fn (cfun)); + auto_sbitmap superblocks (last_basic_block_for_fn (cfun)); bitmap_clear (superblocks); FOR_EACH_BB_FN (bb, cfun) @@ -4290,8 +4295,6 @@ break_superblocks (void) rebuild_jump_labels (get_insns ()); find_many_sub_basic_blocks (superblocks); } - - free (superblocks); } /* Finalize the changes: reorder insn list according to the sequence specified |