Commit 9f8e6243 by Andrew MacLeod Committed by Andrew Macleod

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

From-SVN: r20115
parent d05a5492
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> Thu May 28 09:36:39 1998 Michael Meissner <meissner@cygnus.com>
* except.h (rtx): Define rtx type correctly if needed. * except.h (rtx): Define rtx type correctly if needed.
......
...@@ -754,6 +754,34 @@ add_new_handler (region, newhandler) ...@@ -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 /* Create a new handler structure initialized with the handler label and
typeinfo fields passed in. */ typeinfo fields passed in. */
......
...@@ -191,6 +191,13 @@ int new_eh_region_entry PROTO((int)); ...@@ -191,6 +191,13 @@ int new_eh_region_entry PROTO((int));
void add_new_handler PROTO((int, struct handler_info *)); 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 /* Create a new handler structure initialized with the handler label and
typeinfo fields passed in. */ typeinfo fields passed in. */
......
...@@ -404,6 +404,7 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) ...@@ -404,6 +404,7 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
enum rtx_code prev_code, code; enum rtx_code prev_code, code;
int depth, pass; int depth, pass;
int in_libcall_block = 0; int in_libcall_block = 0;
int deleted_handler = 0;
pass = 1; pass = 1;
active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int)); 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) ...@@ -770,28 +771,9 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
XEXP (x, 1) = NULL_RTX; XEXP (x, 1) = NULL_RTX;
XEXP (x, 0) = NULL_RTX; XEXP (x, 0) = NULL_RTX;
/* Now we have to find the EH_BEG and EH_END notes /* Remove the handler from all regions */
associated with this label and remove them. */ remove_handler (insn);
deleted_handler = 1;
#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
break; break;
} }
prev = &XEXP (x, 1); prev = &XEXP (x, 1);
...@@ -861,6 +843,24 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) ...@@ -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 /* There are pathological cases where one function calling hundreds of
nested inline functions can generate lots and lots of unreachable nested inline functions can generate lots and lots of unreachable
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment