except.c (for_each_eh_region): New function.
authorSteven Bosscher <stevenb@suse.de>
Fri, 4 Jun 2004 12:31:26 +0000 (12:31 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Fri, 4 Jun 2004 12:31:26 +0000 (12:31 +0000)
* except.c (for_each_eh_region): New function.
* except.h (for_each_eh_region): Add a prototype for it.
* tree-cfg.c (update_eh_labels): New function, callback for
for_each_eh_region.
(label_for_bb): Make global static, unfortunately.
(cleanup_dead_labels): Also update label references for
exception regions.

From-SVN: r82622

gcc/ChangeLog
gcc/except.c
gcc/except.h
gcc/tree-cfg.c

index 7771f78fcbafbb1a3dd9368e8c523fb1ba911f05..bb08ea4b05e9181286de0808ecb08cdf18579fa0 100644 (file)
@@ -1,3 +1,13 @@
+2004-06-04  Steven Bosscher  <stevenb@suse.de>
+
+       * except.c (for_each_eh_region): New function.
+       * except.h (for_each_eh_region): Add a prototype for it.
+       * tree-cfg.c (update_eh_labels): New function, callback for
+       for_each_eh_region.
+       (label_for_bb): Make global static, unfortunately.
+       (cleanup_dead_labels): Also update label references for
+       exception regions.
+
 2004-06-03  Chris Demetriou  <cgd@broadcom.com>
 
        * config/mips/mips.c (struct irix_section_align_entry): Fix
@@ -19,7 +29,7 @@
        documentation to reflect the new macro name and to clarify its 
        meaning.
        
-2004-06-04  Steven Bosscher  <stevenb@suse.de>
+2004-06-03  Steven Bosscher  <stevenb@suse.de>
 
        * rtl.def (VAR_LOCATION): Make RTX_EXTRA.
 
index f3bc4ef3f2c4e2af216f6c328eb416ed9ce6f445..65aa8b5c4cc27ec9115fad48d79d6398f843a644 100644 (file)
@@ -2742,6 +2742,20 @@ for_each_eh_label_1 (void **pentry, void *data)
   (*callback) (entry->label);
   return 1;
 }
+
+/* Invoke CALLBACK for every exception region in the current function.  */
+
+void
+for_each_eh_region (void (*callback) (struct eh_region *))
+{
+  int i, n = cfun->eh->last_region_number;
+  for (i = 1; i <= n; ++i)
+    {
+      struct eh_region *region = cfun->eh->region_array[i];
+      if (region)
+       (*callback) (region);
+    }
+}
 \f
 /* This section describes CFG exception edges for flow.  */
 
index 2fed79f30fbe2211fef84549de1048221e1d5f21..4c596a9df11ee7adc0b0aeb40b6fab20431efb3b 100644 (file)
@@ -90,6 +90,9 @@ extern void note_current_region_may_contain_throw (void);
    loop hackery; should not be used by new code.  */
 extern void for_each_eh_label (void (*) (rtx));
 
+/* Invokes CALLBACK for every exception region in the current function.  */
+extern void for_each_eh_region (void (*) (struct eh_region *));
+
 /* Determine if the given INSN can throw an exception.  */
 extern bool can_throw_internal_1 (int);
 extern bool can_throw_internal (rtx);
index 21277d86bf2920b9e7fc8179938c2ef92d4556c5..d6823cb5216b0bf06496e23c7a556214f18ab9a4 100644 (file)
@@ -762,13 +762,38 @@ cleanup_tree_cfg (void)
 }
 
 
-/* Cleanup useless labels from the flow graph.  */
+/* Cleanup useless labels in basic blocks.  This is something we wish
+   to do early because it allows us to group case labels before creating
+   the edges for the CFG, and it speeds up block statement iterators in
+   all passes later on.
+   We only run this pass once, running it more than once is probably not
+   profitable.  */
+
+/* A map from basic block index to the leading label of that block.  */
+static tree *label_for_bb;
+
+/* Callback for for_each_eh_region.  Helper for cleanup_dead_labels.  */
+static void
+update_eh_label (struct eh_region *region)
+{
+  tree old_label = get_eh_region_tree_label (region);
+  if (old_label)
+    {
+      tree new_label = label_for_bb[label_to_block (old_label)->index];
+      set_eh_region_tree_label (region, new_label);
+    }
+}
+
+/* Cleanup redundant labels.  This is a three-steo process:
+     1) Find the leading label for each block.
+     2) Redirect all references to labels to the leading labels.
+     3) Cleanup all useless labels.  */
 
 static void
 cleanup_dead_labels (void)
 {
   basic_block bb;
-  tree *label_for_bb = xcalloc (last_basic_block, sizeof (tree));
+  label_for_bb = xcalloc (last_basic_block, sizeof (tree));
 
   /* Find a suitable label for each block.  We use the first user-defined
      label is there is one, or otherwise just the first label we see.  */
@@ -805,7 +830,8 @@ cleanup_dead_labels (void)
        }
     }
 
-  /* Now redirect all jumps/branches to the selected label for each block.  */
+  /* Now redirect all jumps/branches to the selected label.
+     First do so for each block ending in a control statement.  */
   FOR_EACH_BB (bb)
     {
       tree stmt = last_stmt (bb);
@@ -864,6 +890,8 @@ cleanup_dead_labels (void)
       }
     }
 
+  for_each_eh_region (update_eh_label);
+
   /* Finally, purge dead labels.  All user-defined labels and labels that
      can be the target of non-local gotos are preserved.  */
   FOR_EACH_BB (bb)