except.c (for_each_eh_region): New function.

* 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
This commit is contained in:
Steven Bosscher 2004-06-04 12:31:26 +00:00 committed by Steven Bosscher
parent 72fab00611
commit f698d2175a
4 changed files with 59 additions and 4 deletions

View 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.

View 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);
}
}
/* This section describes CFG exception edges for flow. */

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

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