Flow now removes exception regions when their handlers are all removed.
From-SVN: r20115
This commit is contained in:
parent
d05a5492a5
commit
9f8e62437f
@ -1,3 +1,11 @@
|
||||
Thu May 28 10:22:22 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
|
||||
|
||||
* except.h (remove_handler): Add new prototype.
|
||||
* except.c (remove_handler): New function to remove handlers
|
||||
from an exception region.
|
||||
* flow.c (find_basic_blocks_1): Remove handlers from regions when
|
||||
handler label is deleted; remove exception regions with no handlers.
|
||||
|
||||
Thu May 28 09:36:39 1998 Michael Meissner <meissner@cygnus.com>
|
||||
|
||||
* except.h (rtx): Define rtx type correctly if needed.
|
||||
|
28
gcc/except.c
28
gcc/except.c
@ -754,6 +754,34 @@ add_new_handler (region, newhandler)
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove a handler label. The handler label is being deleted, so all
|
||||
regions which reference this handler should have it removed from their
|
||||
list of possible handlers. Any region which has the final handler
|
||||
removed can be deleted. */
|
||||
|
||||
void remove_handler (removing_label)
|
||||
rtx removing_label;
|
||||
{
|
||||
struct handler_info *handler, *last;
|
||||
int x;
|
||||
for (x = 0 ; x < current_func_eh_entry; ++x)
|
||||
{
|
||||
last = NULL;
|
||||
handler = function_eh_regions[x].handlers;
|
||||
for ( ; handler; last = handler, handler = handler->next)
|
||||
if (handler->handler_label == removing_label)
|
||||
{
|
||||
if (last)
|
||||
{
|
||||
last->next = handler->next;
|
||||
handler = last;
|
||||
}
|
||||
else
|
||||
function_eh_regions[x].handlers = handler->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new handler structure initialized with the handler label and
|
||||
typeinfo fields passed in. */
|
||||
|
||||
|
@ -191,6 +191,13 @@ int new_eh_region_entry PROTO((int));
|
||||
|
||||
void add_new_handler PROTO((int, struct handler_info *));
|
||||
|
||||
/* Remove a handler label. The handler label is being deleted, so all
|
||||
regions which reference this handler should have it removed from their
|
||||
list of possible handlers. Any region which has the final handler
|
||||
removed can be deleted. */
|
||||
|
||||
void remove_handler PROTO((rtx));
|
||||
|
||||
/* Create a new handler structure initialized with the handler label and
|
||||
typeinfo fields passed in. */
|
||||
|
||||
|
44
gcc/flow.c
44
gcc/flow.c
@ -404,6 +404,7 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
|
||||
enum rtx_code prev_code, code;
|
||||
int depth, pass;
|
||||
int in_libcall_block = 0;
|
||||
int deleted_handler = 0;
|
||||
|
||||
pass = 1;
|
||||
active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
|
||||
@ -770,28 +771,9 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
|
||||
XEXP (x, 1) = NULL_RTX;
|
||||
XEXP (x, 0) = NULL_RTX;
|
||||
|
||||
/* Now we have to find the EH_BEG and EH_END notes
|
||||
associated with this label and remove them. */
|
||||
|
||||
#if 0
|
||||
/* Handlers and labels no longer needs to have the same values.
|
||||
If there are no references, scan_region will remove any region
|
||||
labels which are of no use. */
|
||||
for (x = get_insns (); x; x = NEXT_INSN (x))
|
||||
{
|
||||
if (GET_CODE (x) == NOTE
|
||||
&& ((NOTE_LINE_NUMBER (x)
|
||||
== NOTE_INSN_EH_REGION_BEG)
|
||||
|| (NOTE_LINE_NUMBER (x)
|
||||
== NOTE_INSN_EH_REGION_END))
|
||||
&& (NOTE_BLOCK_NUMBER (x)
|
||||
== CODE_LABEL_NUMBER (insn)))
|
||||
{
|
||||
NOTE_LINE_NUMBER (x) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (x) = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Remove the handler from all regions */
|
||||
remove_handler (insn);
|
||||
deleted_handler = 1;
|
||||
break;
|
||||
}
|
||||
prev = &XEXP (x, 1);
|
||||
@ -861,6 +843,24 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If we deleted an exception handler, we may have EH region
|
||||
begin/end blocks to remove as well. */
|
||||
if (deleted_handler)
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
{
|
||||
if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) ||
|
||||
(NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
|
||||
{
|
||||
int num = CODE_LABEL_NUMBER (insn);
|
||||
/* A NULL handler indicates a region is no longer needed */
|
||||
if (get_first_handler (num) == NULL)
|
||||
{
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are pathological cases where one function calling hundreds of
|
||||
nested inline functions can generate lots and lots of unreachable
|
||||
|
Loading…
Reference in New Issue
Block a user