diff mbox

convert nonlocal_goto_handler_labels to a VEC

Message ID 20110429132327.GR23480@codesourcery.com
State New
Headers show

Commit Message

Nathan Froyd April 29, 2011, 1:23 p.m. UTC
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 mbox

Patch

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))