except.c (remove_unreachable_regions): New.

* except.c (remove_unreachable_regions): New.
	(free_eh_status): Clear exception_handler_labels.
	(convert_from_eh_region_ranges): Call remove_unreachable_regions.
	(find_exception_handler_labels): Don't add the same label more than
	once.
	(remove_exception_handler_label): Don't die if
	find_exception_handler_labels hasn't been called for the current
	function yet.

From-SVN: r48845
This commit is contained in:
Jakub Jelinek 2002-01-14 22:06:26 +01:00 committed by Jakub Jelinek
parent e6a5e46287
commit 655dd289ba
2 changed files with 83 additions and 1 deletions

View File

@ -1,3 +1,14 @@
2002-01-14 Jakub Jelinek <jakub@redhat.com>
* except.c (remove_unreachable_regions): New.
(free_eh_status): Clear exception_handler_labels.
(convert_from_eh_region_ranges): Call remove_unreachable_regions.
(find_exception_handler_labels): Don't add the same label more than
once.
(remove_exception_handler_label): Don't die if
find_exception_handler_labels hasn't been called for the current
function yet.
Mon Jan 14 21:26:13 CET 2002 Jan Hubicka <jh@suse.cz>
* toplev.c (rest_of_compilation): Rebuild jump labels after

View File

@ -263,6 +263,7 @@ static rtx get_exception_filter PARAMS ((struct function *));
static void collect_eh_region_array PARAMS ((void));
static void resolve_fixup_regions PARAMS ((void));
static void remove_fixup_regions PARAMS ((void));
static void remove_unreachable_regions PARAMS ((rtx));
static void convert_from_eh_region_ranges_1 PARAMS ((rtx *, int *, int));
static struct eh_region *duplicate_eh_region_1 PARAMS ((struct eh_region *,
@ -632,6 +633,7 @@ free_eh_status (f)
free (eh);
f->eh = NULL;
exception_handler_labels = NULL;
}
@ -1212,6 +1214,69 @@ remove_fixup_regions ()
}
}
/* Remove all regions whose labels are not reachable from insns. */
static void
remove_unreachable_regions (insns)
rtx insns;
{
int i, *uid_region_num;
bool *reachable;
struct eh_region *r;
rtx insn;
uid_region_num = xcalloc (get_max_uid (), sizeof(int));
reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
for (i = cfun->eh->last_region_number; i > 0; --i)
{
r = cfun->eh->region_array[i];
if (!r || r->region_number != i)
continue;
if (r->resume)
{
if (uid_region_num[INSN_UID (r->resume)])
abort ();
uid_region_num[INSN_UID (r->resume)] = i;
}
if (r->label)
{
if (uid_region_num[INSN_UID (r->label)])
abort ();
uid_region_num[INSN_UID (r->label)] = i;
}
if (r->type == ERT_TRY && r->u.try.continue_label)
{
if (uid_region_num[INSN_UID (r->u.try.continue_label)])
abort ();
uid_region_num[INSN_UID (r->u.try.continue_label)] = i;
}
}
for (insn = insns; insn; insn = NEXT_INSN (insn))
reachable[uid_region_num[INSN_UID (insn)]] = true;
for (i = cfun->eh->last_region_number; i > 0; --i)
{
r = cfun->eh->region_array[i];
if (r && r->region_number == i && !reachable[i])
{
/* Don't remove ERT_THROW regions if their outer region
is reachable. */
if (r->type == ERT_THROW
&& r->outer
&& reachable[r->outer->region_number])
continue;
remove_eh_handler (r);
}
}
free (reachable);
free (uid_region_num);
}
/* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
can_throw instruction in the region. */
@ -1314,6 +1379,7 @@ convert_from_eh_region_ranges ()
free (stack);
remove_fixup_regions ();
remove_unreachable_regions (insns);
}
void
@ -1332,7 +1398,7 @@ find_exception_handler_labels ()
struct eh_region *region = cfun->eh->region_array[i];
rtx lab;
if (! region)
if (! region || region->region_number != i)
continue;
if (cfun->eh->built_landing_pads)
lab = region->landing_pad;
@ -2427,6 +2493,11 @@ remove_exception_handler_label (label)
{
rtx *pl, l;
/* If exception_handler_labels was not built yet,
there is nothing to do. */
if (exception_handler_labels == NULL)
return;
for (pl = &exception_handler_labels, l = *pl;
XEXP (l, 0) != label;
pl = &XEXP (l, 1), l = *pl)