Flow now removes exception regions when their handlers are all removed.

From-SVN: r20115
This commit is contained in:
Andrew MacLeod 1998-05-28 07:32:33 +00:00 committed by Andrew Macleod
parent d05a5492a5
commit 9f8e62437f
4 changed files with 65 additions and 22 deletions

View File

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

View File

@ -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. */

View File

@ -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. */

View File

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