@@ -216,7 +216,7 @@ make_edges (basic_block min, basic_block max, int update_p)
/* Heavy use of computed goto in machine-generated code can lead to
nearly fully-connected CFGs. In that case we spend a significant
amount of time searching the edge lists for duplicates. */
- if (forced_labels || cfun->cfg->max_jumptable_ents > 100)
+ if (!VEC_empty (rtx, forced_labels) || cfun->cfg->max_jumptable_ents > 100)
edge_cache = sbitmap_alloc (last_basic_block);
/* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
@@ -296,8 +296,9 @@ make_edges (basic_block min, basic_block max, int update_p)
everything on the forced_labels list. */
else if (computed_jump_p (insn))
{
- for (x = forced_labels; x; x = XEXP (x, 1))
- make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
+ unsigned int ix;
+ FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+ make_label_edge (edge_cache, bb, x, EDGE_ABNORMAL);
}
/* Returns create an exit out. */
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
static int can_delete_note_p (const_rtx);
-static int can_delete_label_p (const_rtx);
+static bool can_delete_label_p (const_rtx);
static basic_block rtl_split_edge (edge);
static bool rtl_move_block_after (basic_block, basic_block);
static int rtl_verify_flow_info (void);
@@ -101,13 +101,20 @@ can_delete_note_p (const_rtx note)
/* True if a given label can be deleted. */
-static int
+static bool
can_delete_label_p (const_rtx label)
{
- return (!LABEL_PRESERVE_P (label)
- /* User declared labels must be preserved. */
- && LABEL_NAME (label) == 0
- && !in_expr_list_p (forced_labels, label));
+ rtx x;
+ unsigned int ix;
+
+ if (LABEL_PRESERVE_P (label) || LABEL_NAME (label) != 0)
+ return false;
+
+ FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+ if (x == label)
+ return false;
+
+ return true;
}
/* Delete INSN by patching it out. Return the next insn. */
@@ -1233,8 +1233,7 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
label on the nonlocal_goto_label list. Since we're modeling these
CFG edges more exactly, we can use the forced_labels list instead. */
LABEL_PRESERVE_P (dispatch_label) = 1;
- forced_labels
- = gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
+ note_forced_label (dispatch_label);
#endif
/* Load up exc_ptr and filter values from the function context. */
@@ -137,7 +137,7 @@ struct GTY(()) expr_status {
rtx x_apply_args_value;
/* List of labels that must never be deleted. */
- rtx x_forced_labels;
+ VEC(rtx,gc) *x_forced_labels;
};
typedef struct call_site_record_d *call_site_record;
@@ -463,6 +463,14 @@ extern GTY(()) struct rtl_data x_rtl;
want to do differently. */
#define crtl (&x_rtl)
+/* Add X to the forced_labels list. */
+
+static inline void
+note_forced_label (rtx x)
+{
+ VEC_safe_push (rtx, gc, forced_labels, x);
+}
+
struct GTY(()) stack_usage
{
/* # of bytes of static stack space allocated by the function. */
@@ -76,7 +76,8 @@ static int returnjump_p_1 (rtx *, void *);
static void
rebuild_jump_labels_1 (rtx f, bool count_forced)
{
- rtx insn;
+ rtx x;
+ unsigned int ix;
timevar_push (TV_REBUILD_JUMP);
init_label_info (f);
@@ -87,9 +88,9 @@ rebuild_jump_labels_1 (rtx f, bool count_forced)
count doesn't drop to zero. */
if (count_forced)
- for (insn = forced_labels; insn; insn = XEXP (insn, 1))
- if (LABEL_P (XEXP (insn, 0)))
- LABEL_NUSES (XEXP (insn, 0))++;
+ FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+ if (LABEL_P (x))
+ LABEL_NUSES (x)++;
timevar_pop (TV_REBUILD_JUMP);
}
@@ -3903,11 +3903,14 @@ static void
set_initial_label_offsets (void)
{
rtx x;
+ unsigned int ix;
memset (offsets_known_at, 0, num_labels);
- for (x = forced_labels; x; x = XEXP (x, 1))
- if (XEXP (x, 0))
- set_label_offsets (XEXP (x, 0), NULL_RTX, 1);
+ FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+ {
+ gcc_assert (x != NULL_RTX);
+ set_label_offsets (x, NULL_RTX, 1);
+ }
for_each_eh_label (set_initial_eh_label_offset);
}
@@ -259,7 +259,7 @@ is_cfg_nonregular (void)
return 1;
/* If we have any forced labels, then the cfg is not well structured. */
- if (forced_labels)
+ if (!VEC_empty (rtx, forced_labels))
return 1;
/* If we have exception handlers, then we consider the cfg not well
@@ -158,7 +158,7 @@ force_label_rtx (tree label)
gcc_assert (function);
- forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels);
+ note_forced_label (ref);
return ref;
}
@@ -218,7 +218,7 @@ expand_label (tree label)
}
if (FORCED_LABEL (label))
- forced_labels = gen_rtx_EXPR_LIST (VOIDmode, label_r, forced_labels);
+ note_forced_label (label_r);
if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
maybe_set_first_label_num (label_r);