[PATCH] convert nonlocal_goto_handler_labels to a VEC
Nathan Froyd
froydnj@codesourcery.com
Fri Apr 29 14:56:00 GMT 2011
As $SUBJECT suggests. The memory savings from this conversion is
negligible; the real benefit, IMHO, is use of a proper container instead
of EXPR_LIST.
remove_node_from_expr_list is unused after this patch; I will delete it
as an obvious followon patch if this patch is approved.
Tested on x86_64-unknown-linux-gnu. OK to commit?
-Nathan
* function.h (struct rtl_data) [x_nonlocal_goto_handler_labels]:
Convert to a VEC.
(note_nonlocal_goto_handler_label): New function.
(remove_from_nonlocal_goto_handler_labels): New function.
* builtins.c (expand_builtin): Call them.
* cfgrtl.c (delete_insn): Call
remove_from_nonlocal_goto_handler_labels.
* stmt.c (expand_label): Call note_nonlocal_goto_handler_label.
* cfgbuild.c (make_edges): Adjust for new type of
nonlocal_goto_handler_labels.
* cfglayout.c (cfg_layout_initialize): Likewise.
* except.c (insn_nothrow_p): Likewise.
* recog.c (peep2_attempt): Likewise.
* sched-rgn.c (is_cfg_nonregular): Likewise.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index b2534ce..839b212 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6168,9 +6168,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
/* This is copied from the handling of non-local gotos. */
expand_builtin_setjmp_setup (buf_addr, label_r);
- nonlocal_goto_handler_labels
- = gen_rtx_EXPR_LIST (VOIDmode, label_r,
- nonlocal_goto_handler_labels);
+ note_nonlocal_goto_handler_label (label_r);
/* ??? Do not let expand_label treat us as such since we would
not want to be both on the list of non-local labels and on
the list of forced labels. */
@@ -6188,7 +6186,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
/* Remove the dispatcher label from the list of non-local labels
since the receiver labels have been added to it above. */
- remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
+ remove_from_nonlocal_goto_handler_labels (label_r);
return const0_rtx;
}
break;
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 6f0d69e..82b5e63 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -338,7 +338,8 @@ make_edges (basic_block min, basic_block max, int update_p)
/* Add any appropriate EH edges. */
rtl_make_eh_edge (edge_cache, bb, insn);
- if (code == CALL_INSN && nonlocal_goto_handler_labels)
+ if (code == CALL_INSN
+ && !VEC_empty (rtx, nonlocal_goto_handler_labels))
{
/* ??? This could be made smarter: in some cases it's possible
to tell that certain calls will not do a nonlocal goto.
@@ -347,9 +348,13 @@ make_edges (basic_block min, basic_block max, int update_p)
those functions or to other nested functions that use them
could possibly do nonlocal gotos. */
if (can_nonlocal_goto (insn))
- for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
- make_label_edge (edge_cache, bb, XEXP (x, 0),
- EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+ {
+ unsigned int ix;
+ FOR_EACH_VEC_ELT_REVERSE (rtx, nonlocal_goto_handler_labels,
+ ix, x)
+ make_label_edge (edge_cache, bb, x,
+ EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+ }
}
}
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 548e21f..38db3f4 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -1291,6 +1291,7 @@ cfg_layout_initialize (unsigned int flags)
{
rtx x;
basic_block bb;
+ unsigned int ix;
initialize_original_copy_tables ();
@@ -1299,9 +1300,9 @@ cfg_layout_initialize (unsigned int flags)
record_effective_endpoints ();
/* Make sure that the targets of non local gotos are marked. */
- for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
+ FOR_EACH_VEC_ELT_REVERSE (rtx, nonlocal_goto_handler_labels, ix, x)
{
- bb = BLOCK_FOR_INSN (XEXP (x, 0));
+ bb = BLOCK_FOR_INSN (x);
bb->flags |= BB_NON_LOCAL_GOTO_TARGET;
}
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index c450ca0..a3e1202 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -134,7 +134,7 @@ delete_insn (rtx insn)
NOTE_DELETED_LABEL_NAME (insn) = name;
}
- remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+ remove_from_nonlocal_goto_handler_labels (insn);
}
if (really_delete)
diff --git a/gcc/except.c b/gcc/except.c
index 5c6359e..c8da137 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1819,7 +1819,7 @@ insn_nothrow_p (const_rtx insn)
bool
can_nonlocal_goto (const_rtx insn)
{
- if (nonlocal_goto_handler_labels && CALL_P (insn))
+ if (!VEC_empty (rtx, nonlocal_goto_handler_labels) && CALL_P (insn))
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
diff --git a/gcc/function.h b/gcc/function.h
index fa44958..7d91994 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -268,9 +268,8 @@ struct GTY(()) rtl_data {
Used for detecting stack clobbers. */
tree stack_protect_guard;
- /* List (chain of EXPR_LIST) of labels heading the current handlers for
- nonlocal gotos. */
- rtx x_nonlocal_goto_handler_labels;
+ /* List of labels heading the current handlers for nonlocal gotos. */
+ VEC(rtx,gc) *x_nonlocal_goto_handler_labels;
/* Label that will go on function epilogue.
Jumping to this label serves as a "return" instruction
@@ -463,6 +462,30 @@ extern GTY(()) struct rtl_data x_rtl;
want to do differently. */
#define crtl (&x_rtl)
+/* Add X to the nonlocal_goto_handler_labels list. */
+
+static inline void
+note_nonlocal_goto_handler_label (rtx x)
+{
+ VEC_safe_push (rtx, gc, nonlocal_goto_handler_labels, x);
+}
+
+/* Remove X from the nonlocal_goto_handler_labels list. */
+
+static inline void
+remove_from_nonlocal_goto_handler_labels (rtx label)
+{
+ unsigned ix;
+ rtx x;
+
+ FOR_EACH_VEC_ELT_REVERSE (rtx, nonlocal_goto_handler_labels, ix, x)
+ if (x == label)
+ {
+ VEC_unordered_remove (rtx, nonlocal_goto_handler_labels, ix);
+ return;
+ }
+}
+
struct GTY(()) stack_usage
{
/* # of bytes of static stack space allocated by the function. */
diff --git a/gcc/recog.c b/gcc/recog.c
index afe985e..1c4db90 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3291,7 +3291,7 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
delete_insn_chain (insn, peep2_insn_data[i].insn, false);
/* Re-insert the EH_REGION notes. */
- if (note || (was_call && nonlocal_goto_handler_labels))
+ if (note || (was_call && !VEC_empty (rtx, nonlocal_goto_handler_labels)))
{
edge eh_edge;
edge_iterator ei;
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 2c00907..cf4c5f6 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -255,7 +255,7 @@ is_cfg_nonregular (void)
/* If we have a label that could be the target of a nonlocal goto, then
the cfg is not well structured. */
- if (nonlocal_goto_handler_labels)
+ if (!VEC_empty (rtx, nonlocal_goto_handler_labels))
return 1;
/* If we have any forced labels, then the cfg is not well structured. */
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 1a9f9e5..9c303de 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -212,9 +212,7 @@ expand_label (tree label)
if (DECL_NONLOCAL (label))
{
expand_nl_goto_receiver ();
- nonlocal_goto_handler_labels
- = gen_rtx_EXPR_LIST (VOIDmode, label_r,
- nonlocal_goto_handler_labels);
+ note_nonlocal_goto_handler_label (label_r);
}
if (FORCED_LABEL (label))
More information about the Gcc-patches
mailing list