summaryrefslogtreecommitdiff
path: root/gcc/cfgrtl.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
commit34efdaf078b01a7387007c4e6bde6db86384c4b7 (patch)
treed503eaf41d085669d1481bb46ec038bc866fece6 /gcc/cfgrtl.c
parentf733cf303bcdc952c92b81dd62199a40a1f555ec (diff)
downloadgcc-tarball-master.tar.gz
gcc-7.1.0gcc-7.1.0
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r--gcc/cfgrtl.c51
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