commit 012a3d7ebbfed963db2a8f6f1275c451cbe25d5a Author: David Malcolm Date: Thu Aug 7 11:14:54 2014 -0400 Experimentally use a vec rather than an EXPR_LIST for forced_labels gcc/ * function.h (struct expr_status): Convert field "x_forced_labels" from rtx_expr_list * to vec *. (rtl_data::mark_label_as_forced): New method. (rtl_data::label_forced_p): New method. * cfgbuild.c (make_edges): Rewrite forced_labels iteration from a walk down an EXPR_LIST to instead use FOR_EACH_VEC_ELT. * cfgrtl.c (can_delete_label_p): Replace determination of "label" being forced from using in_expr_list_p to using the new rtl_data::label_forced_p method. * dwarf2cfi.c (create_trace_edges): Rewrite forced_labels iteration from a walk down an EXPR_LIST to instead use FOR_EACH_VEC_ELT. * except.c (sjlj_emit_dispatch_table): When marking dispatch_label as a forced label, replace the prepend to an EXPR_LIST logic with a call to the new method rtl_data::mark_label_as_forced. * function.c (rtl_data::mark_label_as_forced): New method, allocating/growing a vec if necessary. (rtl_data::label_forced_p): New method. Replace linear walk down a linked list with linear search through a vec. * jump.c (rebuild_jump_labels_1): Update for conversion of forced_labels from an EXPR_LIST to a vec. * reload1.c (set_initial_label_offsets): Likewise. * stmt.c (force_label_rtx): When marking "ref" as a forced label, replace the prepend to an EXPR_LIST logic with a call to the new method rtl_data::mark_label_as_forced, adding a checked cast to rtx_code_label *. (expand_label): Likewise for "label_r". diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c index ab268ae..1d9e8be 100644 --- a/gcc/cfgbuild.c +++ b/gcc/cfgbuild.c @@ -284,8 +284,13 @@ make_edges (basic_block min, basic_block max, int update_p) everything on the forced_labels list. */ else if (computed_jump_p (insn)) { - for (rtx_expr_list *x = forced_labels; x; x = x->next ()) - make_label_edge (edge_cache, bb, x->element (), EDGE_ABNORMAL); + if (forced_labels) + { + int i; + rtx_code_label *forced_lab; + FOR_EACH_VEC_ELT (*forced_labels, i, forced_lab) + make_label_edge (edge_cache, bb, forced_lab, EDGE_ABNORMAL); + } } /* Returns create an exit out. */ diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 5e42a97..bb053de 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -117,7 +117,7 @@ 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_expr_list_p (forced_labels, label)); + && !crtl->label_forced_p (label)); } /* Delete INSN by patching it out. */ diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 28d8ff3..55802d0 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -2309,8 +2309,13 @@ create_trace_edges (rtx_insn *insn) } else if (computed_jump_p (insn)) { - for (rtx_expr_list *lab = forced_labels; lab; lab = lab->next ()) - maybe_record_trace_start (lab->insn (), insn); + if (forced_labels) + { + int i; + rtx_code_label *forced_lab; + FOR_EACH_VEC_ELT (*forced_labels, i, forced_lab) + maybe_record_trace_start (forced_lab, insn); + } } else if (returnjump_p (insn)) ; diff --git a/gcc/except.c b/gcc/except.c index 13df541..737cd2f 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1321,8 +1321,7 @@ sjlj_emit_dispatch_table (rtx_code_label *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); + crtl->mark_label_as_forced (dispatch_label); #endif /* Load up exc_ptr and filter values from the function context. */ diff --git a/gcc/function.c b/gcc/function.c index 9eee7668..a027260 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -126,6 +126,32 @@ static void prepare_function_start (void); static void do_clobber_return_reg (rtx, void *); static void do_use_return_reg (rtx, void *); + +void +rtl_data::mark_label_as_forced (rtx_code_label *lab) +{ + if (!expr.x_forced_labels) + vec_alloc (expr.x_forced_labels, 1); + + expr.x_forced_labels->quick_push (lab); +} + +bool +rtl_data::label_forced_p (const rtx_code_label *lab) const +{ + int i; + rtx_code_label *forced_lab; + + if (expr.x_forced_labels) + FOR_EACH_VEC_ELT (*expr.x_forced_labels, i, forced_lab) + if (lab == forced_lab) + return true; + + return false; +} + + + /* Stack of nested functions. */ /* Keep track of the cfun stack. */ diff --git a/gcc/function.h b/gcc/function.h index c2e0366..38909ef 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -135,7 +135,7 @@ struct GTY(()) expr_status { rtx x_apply_args_value; /* List of labels that must never be deleted. */ - rtx_expr_list *x_forced_labels; + vec *x_forced_labels; }; typedef struct call_site_record_d *call_site_record; @@ -460,6 +460,11 @@ struct GTY(()) rtl_data { to eliminable regs (like the frame pointer) are set if an asm sets them. */ HARD_REG_SET asm_clobbers; + + public: + void mark_label_as_forced (rtx_code_label *lab); + bool label_forced_p (const rtx_code_label *lab) const; + }; #define return_label (crtl->x_return_label) diff --git a/gcc/jump.c b/gcc/jump.c index be6a8fd..fdaaf0e 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -74,8 +74,6 @@ static int returnjump_p_1 (rtx *, void *); static void rebuild_jump_labels_1 (rtx_insn *f, bool count_forced) { - rtx_expr_list *insn; - timevar_push (TV_REBUILD_JUMP); init_label_info (f); mark_all_labels (f); @@ -85,9 +83,14 @@ rebuild_jump_labels_1 (rtx_insn *f, bool count_forced) count doesn't drop to zero. */ if (count_forced) - for (insn = forced_labels; insn; insn = insn->next ()) - if (LABEL_P (insn->element ())) - LABEL_NUSES (insn->element ())++; + if (forced_labels) + { + int i; + rtx_code_label *forced_lab; + FOR_EACH_VEC_ELT (*forced_labels, i, forced_lab) + if (LABEL_P (forced_lab)) + LABEL_NUSES (forced_lab)++; + } timevar_pop (TV_REBUILD_JUMP); } diff --git a/gcc/reload1.c b/gcc/reload1.c index ff9d047c..04867a0 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -3922,11 +3922,14 @@ set_initial_eh_label_offset (rtx label) static void set_initial_label_offsets (void) { + int i; + rtx_code_label *lab; memset (offsets_known_at, 0, num_labels); - for (rtx_expr_list *x = forced_labels; x; x = x->next ()) - if (x->element ()) - set_label_offsets (x->element (), NULL, 1); + if (forced_labels) + FOR_EACH_VEC_ELT (*forced_labels, i, lab) + if (lab) + set_label_offsets (lab, NULL, 1); for (rtx_expr_list *x = nonlocal_goto_handler_labels; x; x = x->next ()) if (x->element ()) diff --git a/gcc/stmt.c b/gcc/stmt.c index af74142..508ef17 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -140,12 +140,13 @@ label_rtx (tree label) rtx force_label_rtx (tree label) { - rtx ref = label_rtx (label); + rtx_code_label *ref = as_a (label_rtx (label)); tree function = decl_function_context (label); gcc_assert (function); - forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels); + crtl->mark_label_as_forced (ref); + return ref; } @@ -191,7 +192,7 @@ expand_label (tree label) } if (FORCED_LABEL (label)) - forced_labels = gen_rtx_EXPR_LIST (VOIDmode, label_r, forced_labels); + crtl->mark_label_as_forced (as_a (label_r)); if (DECL_NONLOCAL (label) || FORCED_LABEL (label)) maybe_set_first_label_num (label_r);