Commit 6814a8a0 by Jason Merrill

flow.c (count_basic_blocks, [...]): A rethrow can occur outside of an EH region.

        * flow.c (count_basic_blocks, find_basic_blocks_1): A rethrow
        can occur outside of an EH region.
        * except.c: Correct comments about rethrow behavior.
        (rethrow_symbol_map): Do nothing if !flag_new_exceptions.

        * flow.c (make_edges): Always call make_eh_edge for calls.

From-SVN: r32432
parent 2b01d2d9
2000-03-08 Jason Merrill <jason@casey.cygnus.com>
* flow.c (count_basic_blocks, find_basic_blocks_1): A rethrow
can occur outside of an EH region.
* except.c: Correct comments about rethrow behavior.
(rethrow_symbol_map): Do nothing if !flag_new_exceptions.
2000-03-08 Andrew MacLeod <amacleod@cygnus.com>
* flow.c (make_edges): Always call make_eh_edge for calls.
2000-03-08 Zack Weinberg <zack@wolery.cumb.org> 2000-03-08 Zack Weinberg <zack@wolery.cumb.org>
* cpplib.h (parse_underflow_t, CPP_NULL_BUFFER): Delete. * cpplib.h (parse_underflow_t, CPP_NULL_BUFFER): Delete.
......
...@@ -495,6 +495,7 @@ static int eh_region_from_symbol PARAMS ((rtx)); ...@@ -495,6 +495,7 @@ static int eh_region_from_symbol PARAMS ((rtx));
extern struct obstack permanent_obstack; extern struct obstack permanent_obstack;
/* Generate a SYMBOL_REF for rethrow to use */ /* Generate a SYMBOL_REF for rethrow to use */
static rtx static rtx
create_rethrow_ref (region_num) create_rethrow_ref (region_num)
int region_num; int region_num;
...@@ -566,7 +567,7 @@ top_label_entry (stack) ...@@ -566,7 +567,7 @@ top_label_entry (stack)
return (*stack)->u.tlabel; return (*stack)->u.tlabel;
} }
/* get an exception label. These must be on the permanent obstack */ /* Get an exception label. */
rtx rtx
gen_exception_label () gen_exception_label ()
...@@ -602,7 +603,8 @@ push_eh_entry (stack) ...@@ -602,7 +603,8 @@ push_eh_entry (stack)
stack->top = node; stack->top = node;
} }
/* push an existing entry onto a stack. */ /* Push an existing entry onto a stack. */
static void static void
push_entry (stack, entry) push_entry (stack, entry)
struct eh_stack *stack; struct eh_stack *stack;
...@@ -695,7 +697,7 @@ struct func_eh_entry ...@@ -695,7 +697,7 @@ struct func_eh_entry
{ {
int range_number; /* EH region number from EH NOTE insn's. */ int range_number; /* EH region number from EH NOTE insn's. */
rtx rethrow_label; /* Label for rethrow. */ rtx rethrow_label; /* Label for rethrow. */
int rethrow_ref; /* Is rethrow referenced? */ int rethrow_ref; /* Is rethrow_label referenced? */
struct handler_info *handlers; struct handler_info *handlers;
}; };
...@@ -969,6 +971,7 @@ duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map) ...@@ -969,6 +971,7 @@ duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map)
/* Given a rethrow symbol, find the EH region number this is for. */ /* Given a rethrow symbol, find the EH region number this is for. */
static int static int
eh_region_from_symbol (sym) eh_region_from_symbol (sym)
rtx sym; rtx sym;
...@@ -984,6 +987,7 @@ eh_region_from_symbol (sym) ...@@ -984,6 +987,7 @@ eh_region_from_symbol (sym)
/* Like find_func_region, but using the rethrow symbol for the region /* Like find_func_region, but using the rethrow symbol for the region
rather than the region number itself. */ rather than the region number itself. */
static int static int
find_func_region_from_symbol (sym) find_func_region_from_symbol (sym)
rtx sym; rtx sym;
...@@ -995,12 +999,17 @@ find_func_region_from_symbol (sym) ...@@ -995,12 +999,17 @@ find_func_region_from_symbol (sym)
__rethrow as well. This performs the remap. If a symbol isn't foiund, __rethrow as well. This performs the remap. If a symbol isn't foiund,
the original one is returned. This is not an efficient routine, the original one is returned. This is not an efficient routine,
so don't call it on everything!! */ so don't call it on everything!! */
rtx rtx
rethrow_symbol_map (sym, map) rethrow_symbol_map (sym, map)
rtx sym; rtx sym;
rtx (*map) PARAMS ((rtx)); rtx (*map) PARAMS ((rtx));
{ {
int x, y; int x, y;
if (! flag_new_exceptions)
return sym;
for (x = 0; x < current_func_eh_entry; x++) for (x = 0; x < current_func_eh_entry; x++)
if (function_eh_regions[x].rethrow_label == sym) if (function_eh_regions[x].rethrow_label == sym)
{ {
...@@ -1021,6 +1030,10 @@ rethrow_symbol_map (sym, map) ...@@ -1021,6 +1030,10 @@ rethrow_symbol_map (sym, map)
return sym; return sym;
} }
/* Returns nonzero if the rethrow label for REGION is referenced
somewhere (i.e. we rethrow out of REGION or some other region
masquerading as REGION). */
int int
rethrow_used (region) rethrow_used (region)
int region; int region;
...@@ -2011,7 +2024,7 @@ expand_rethrow (label) ...@@ -2011,7 +2024,7 @@ expand_rethrow (label)
label = last_rethrow_symbol; label = last_rethrow_symbol;
emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode); emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
region = find_func_region (eh_region_from_symbol (label)); region = find_func_region (eh_region_from_symbol (label));
/* If the region is -1, it doesn't exist yet. We should be /* If the region is -1, it doesn't exist yet. We shouldn't be
trying to rethrow there yet. */ trying to rethrow there yet. */
if (region == -1) if (region == -1)
abort (); abort ();
...@@ -2194,15 +2207,13 @@ output_exception_table_entry (file, n) ...@@ -2194,15 +2207,13 @@ output_exception_table_entry (file, n)
int index = find_func_region (n); int index = find_func_region (n);
rtx rethrow; rtx rethrow;
/* form and emit the rethrow label, if needed */ /* Form and emit the rethrow label, if needed */
if (flag_new_exceptions
&& (handler || function_eh_regions[index].rethrow_ref))
rethrow = function_eh_regions[index].rethrow_label; rethrow = function_eh_regions[index].rethrow_label;
if (rethrow != NULL_RTX && !flag_new_exceptions) else
rethrow = NULL_RTX;
if (rethrow != NULL_RTX && handler == NULL)
if (! function_eh_regions[index].rethrow_ref)
rethrow = NULL_RTX; rethrow = NULL_RTX;
for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next) for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
{ {
/* rethrow label should indicate the LAST entry for a region */ /* rethrow label should indicate the LAST entry for a region */
...@@ -2301,7 +2312,7 @@ output_exception_table () ...@@ -2301,7 +2312,7 @@ output_exception_table ()
if (i != 0) if (i != 0)
assemble_integer (const0_rtx, i , 1); assemble_integer (const0_rtx, i , 1);
/* Generate the label for offset calculations on rethrows */ /* Generate the label for offset calculations on rethrows. */
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0); ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
assemble_label(buf); assemble_label(buf);
} }
...@@ -2318,7 +2329,7 @@ output_exception_table () ...@@ -2318,7 +2329,7 @@ output_exception_table ()
assemble_label(buf); assemble_label(buf);
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
/* for binary compatability, the old __throw checked the second /* For binary compatibility, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */ position for a -1, so we should output at least 2 -1's */
if (! flag_new_exceptions) if (! flag_new_exceptions)
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
...@@ -2666,7 +2677,7 @@ scan_region (insn, n, delete_outer) ...@@ -2666,7 +2677,7 @@ scan_region (insn, n, delete_outer)
/* Assume we can delete the region. */ /* Assume we can delete the region. */
int delete = 1; int delete = 1;
/* Can't delete something which is rethrown to. */ /* Can't delete something which is rethrown from. */
if (rethrow_used (n)) if (rethrow_used (n))
delete = 0; delete = 0;
...@@ -2783,9 +2794,10 @@ exception_optimize () ...@@ -2783,9 +2794,10 @@ exception_optimize ()
} }
} }
/* This function determines whether any of the exception regions in the /* This function determines whether the rethrow labels for any of the
current function are targets of a rethrow or not, and set the exception regions in the current function are used or not, and set
reference flag according. */ the reference flag according. */
void void
update_rethrow_references () update_rethrow_references ()
{ {
...@@ -2800,7 +2812,7 @@ update_rethrow_references () ...@@ -2800,7 +2812,7 @@ update_rethrow_references ()
saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int)); saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int));
/* Determine what regions exist, and whether there are any rethrows /* Determine what regions exist, and whether there are any rethrows
to those regions or not. */ from those regions or not. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
{ {
...@@ -3336,7 +3348,7 @@ reachable_handlers (block, info, insn, handlers) ...@@ -3336,7 +3348,7 @@ reachable_handlers (block, info, insn, handlers)
if (insn && GET_CODE (insn) == CALL_INSN) if (insn && GET_CODE (insn) == CALL_INSN)
{ {
/* RETHROWs specify a region number from which we are going to rethrow. /* RETHROWs specify a region number from which we are going to rethrow.
This means we wont pass control to handlers in the specified This means we won't pass control to handlers in the specified
region, but rather any region OUTSIDE the specified region. region, but rather any region OUTSIDE the specified region.
We accomplish this by setting block to the outer_index of the We accomplish this by setting block to the outer_index of the
specified region. */ specified region. */
......
...@@ -469,8 +469,9 @@ count_basic_blocks (f) ...@@ -469,8 +469,9 @@ count_basic_blocks (f)
prev_call = insn; prev_call = insn;
call_had_abnormal_edge = 0; call_had_abnormal_edge = 0;
/* If there is a specified EH region, we have an edge. */ /* If there is an EH region or rethrow, we have an edge. */
if (eh_region && region > 0) if ((eh_region && region > 0)
|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_had_abnormal_edge = 1; call_had_abnormal_edge = 1;
else else
{ {
...@@ -541,8 +542,9 @@ find_basic_blocks_1 (f) ...@@ -541,8 +542,9 @@ find_basic_blocks_1 (f)
int region = (note ? XWINT (XEXP (note, 0), 0) : 1); int region = (note ? XWINT (XEXP (note, 0), 0) : 1);
call_has_abnormal_edge = 0; call_has_abnormal_edge = 0;
/* If there is an EH region, we have an edge. */ /* If there is an EH region or rethrow, we have an edge. */
if (eh_list && region > 0) if ((eh_list && region > 0)
|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_has_abnormal_edge = 1; call_has_abnormal_edge = 1;
else else
{ {
...@@ -983,9 +985,9 @@ make_edges (label_value_list) ...@@ -983,9 +985,9 @@ make_edges (label_value_list)
if (code == CALL_INSN || asynchronous_exceptions) if (code == CALL_INSN || asynchronous_exceptions)
{ {
/* If there's an EH region active at the end of a block, /* Add any appropriate EH edges. We do this unconditionally
add the appropriate edges. */ since there may be a REG_EH_REGION or REG_EH_RETHROW note
if (bb->eh_end >= 0) on the call, and this needn't be within an EH region. */
make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end); make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end);
/* If we have asynchronous exceptions, do the same for *all* /* If we have asynchronous exceptions, do the same for *all*
...@@ -1778,7 +1780,7 @@ delete_eh_regions () ...@@ -1778,7 +1780,7 @@ delete_eh_regions ()
{ {
int num = NOTE_EH_HANDLER (insn); int num = NOTE_EH_HANDLER (insn);
/* A NULL handler indicates a region is no longer needed, /* A NULL handler indicates a region is no longer needed,
as long as it isn't the target of a rethrow. */ as long as its rethrow label isn't used. */
if (get_first_handler (num) == NULL && ! rethrow_used (num)) if (get_first_handler (num) == NULL && ! rethrow_used (num))
{ {
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
......
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