This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
EH flow patch
- To: gcc-patches at gcc dot gnu dot org
- Subject: EH flow patch
- From: Jason Merrill <jason at cygnus dot com>
- Date: Wed, 8 Mar 2000 13:28:02 -0800
The flow changes fix many failures in the g++ testsuite when run with
-O. The other changes fix misleading comments.
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.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.228
diff -c -p -r1.228 flow.c
*** flow.c 2000/03/05 22:35:27 1.228
--- flow.c 2000/03/08 21:25:01
*************** count_basic_blocks (f)
*** 469,476 ****
prev_call = insn;
call_had_abnormal_edge = 0;
! /* If there is a specified EH region, we have an edge. */
! if (eh_region && region > 0)
call_had_abnormal_edge = 1;
else
{
--- 469,477 ----
prev_call = insn;
call_had_abnormal_edge = 0;
! /* If there is an EH region or rethrow, we have an edge. */
! if ((eh_region && region > 0)
! || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_had_abnormal_edge = 1;
else
{
*************** find_basic_blocks_1 (f)
*** 541,548 ****
int region = (note ? XWINT (XEXP (note, 0), 0) : 1);
call_has_abnormal_edge = 0;
! /* If there is an EH region, we have an edge. */
! if (eh_list && region > 0)
call_has_abnormal_edge = 1;
else
{
--- 542,550 ----
int region = (note ? XWINT (XEXP (note, 0), 0) : 1);
call_has_abnormal_edge = 0;
! /* If there is an EH region or rethrow, we have an edge. */
! if ((eh_list && region > 0)
! || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_has_abnormal_edge = 1;
else
{
*************** make_edges (label_value_list)
*** 983,992 ****
if (code == CALL_INSN || asynchronous_exceptions)
{
! /* If there's an EH region active at the end of a block,
! add the appropriate edges. */
! if (bb->eh_end >= 0)
! make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end);
/* If we have asynchronous exceptions, do the same for *all*
exception regions active in the block. */
--- 985,994 ----
if (code == CALL_INSN || asynchronous_exceptions)
{
! /* Add any appropriate EH edges. We do this unconditionally
! since there may be a REG_EH_REGION or REG_EH_RETHROW note
! 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);
/* If we have asynchronous exceptions, do the same for *all*
exception regions active in the block. */
*************** delete_eh_regions ()
*** 1778,1784 ****
{
int num = NOTE_EH_HANDLER (insn);
/* A NULL handler indicates a region is no longer needed,
! as long as it isn't the target of a rethrow. */
if (get_first_handler (num) == NULL && ! rethrow_used (num))
{
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
--- 1780,1786 ----
{
int num = NOTE_EH_HANDLER (insn);
/* A NULL handler indicates a region is no longer needed,
! as long as its rethrow label isn't used. */
if (get_first_handler (num) == NULL && ! rethrow_used (num))
{
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.119
diff -c -p -r1.119 except.c
*** except.c 2000/03/07 11:41:18 1.119
--- except.c 2000/03/08 21:25:05
*************** static int eh_region_from_symbol PARAMS
*** 495,500 ****
--- 495,501 ----
extern struct obstack permanent_obstack;
/* Generate a SYMBOL_REF for rethrow to use */
+
static rtx
create_rethrow_ref (region_num)
int region_num;
*************** top_label_entry (stack)
*** 566,572 ****
return (*stack)->u.tlabel;
}
! /* get an exception label. These must be on the permanent obstack */
rtx
gen_exception_label ()
--- 567,573 ----
return (*stack)->u.tlabel;
}
! /* Get an exception label. */
rtx
gen_exception_label ()
*************** push_eh_entry (stack)
*** 601,608 ****
node->chain = stack->top;
stack->top = node;
}
- /* push an existing entry onto a stack. */
static void
push_entry (stack, entry)
struct eh_stack *stack;
--- 602,610 ----
node->chain = stack->top;
stack->top = node;
}
+
+ /* Push an existing entry onto a stack. */
static void
push_entry (stack, entry)
struct eh_stack *stack;
*************** struct func_eh_entry
*** 695,701 ****
{
int range_number; /* EH region number from EH NOTE insn's. */
rtx rethrow_label; /* Label for rethrow. */
! int rethrow_ref; /* Is rethrow referenced? */
struct handler_info *handlers;
};
--- 697,703 ----
{
int range_number; /* EH region number from EH NOTE insn's. */
rtx rethrow_label; /* Label for rethrow. */
! int rethrow_ref; /* Is rethrow_label referenced? */
struct handler_info *handlers;
};
*************** duplicate_eh_handlers (old_note_eh_regio
*** 969,974 ****
--- 971,977 ----
/* Given a rethrow symbol, find the EH region number this is for. */
+
static int
eh_region_from_symbol (sym)
rtx sym;
*************** eh_region_from_symbol (sym)
*** 984,989 ****
--- 987,993 ----
/* Like find_func_region, but using the rethrow symbol for the region
rather than the region number itself. */
+
static int
find_func_region_from_symbol (sym)
rtx sym;
*************** find_func_region_from_symbol (sym)
*** 995,1006 ****
--- 999,1015 ----
__rethrow as well. This performs the remap. If a symbol isn't foiund,
the original one is returned. This is not an efficient routine,
so don't call it on everything!! */
+
rtx
rethrow_symbol_map (sym, map)
rtx sym;
rtx (*map) PARAMS ((rtx));
{
int x, y;
+
+ if (! flag_new_exceptions)
+ return sym;
+
for (x = 0; x < current_func_eh_entry; x++)
if (function_eh_regions[x].rethrow_label == sym)
{
*************** rethrow_symbol_map (sym, map)
*** 1021,1026 ****
--- 1030,1039 ----
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
rethrow_used (region)
int region;
*************** expand_rethrow (label)
*** 2011,2017 ****
label = last_rethrow_symbol;
emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
region = find_func_region (eh_region_from_symbol (label));
! /* If the region is -1, it doesn't exist yet. We should be
trying to rethrow there yet. */
if (region == -1)
abort ();
--- 2024,2030 ----
label = last_rethrow_symbol;
emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
region = find_func_region (eh_region_from_symbol (label));
! /* If the region is -1, it doesn't exist yet. We shouldn't be
trying to rethrow there yet. */
if (region == -1)
abort ();
*************** output_exception_table_entry (file, n)
*** 2194,2207 ****
int index = find_func_region (n);
rtx rethrow;
! /* form and emit the rethrow label, if needed */
! rethrow = function_eh_regions[index].rethrow_label;
! if (rethrow != NULL_RTX && !flag_new_exceptions)
! rethrow = NULL_RTX;
! if (rethrow != NULL_RTX && handler == NULL)
! if (! function_eh_regions[index].rethrow_ref)
! rethrow = NULL_RTX;
!
for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
{
--- 2207,2218 ----
int index = find_func_region (n);
rtx rethrow;
! /* 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;
! else
! rethrow = NULL_RTX;
for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
{
*************** output_exception_table ()
*** 2301,2307 ****
if (i != 0)
assemble_integer (const0_rtx, i , 1);
! /* Generate the label for offset calculations on rethrows */
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
assemble_label(buf);
}
--- 2312,2318 ----
if (i != 0)
assemble_integer (const0_rtx, i , 1);
! /* Generate the label for offset calculations on rethrows. */
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
assemble_label(buf);
}
*************** output_exception_table ()
*** 2318,2324 ****
assemble_label(buf);
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
! /* for binary compatability, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */
if (! flag_new_exceptions)
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
--- 2329,2335 ----
assemble_label(buf);
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
! /* For binary compatibility, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */
if (! flag_new_exceptions)
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
*************** scan_region (insn, n, delete_outer)
*** 2666,2672 ****
/* Assume we can delete the region. */
int delete = 1;
! /* Can't delete something which is rethrown to. */
if (rethrow_used (n))
delete = 0;
--- 2677,2683 ----
/* Assume we can delete the region. */
int delete = 1;
! /* Can't delete something which is rethrown from. */
if (rethrow_used (n))
delete = 0;
*************** exception_optimize ()
*** 2782,2791 ****
}
}
}
- /* This function determines whether any of the exception regions in the
- current function are targets of a rethrow or not, and set the
- reference flag according. */
void
update_rethrow_references ()
{
--- 2793,2803 ----
}
}
}
+
+ /* This function determines whether the rethrow labels for any of the
+ exception regions in the current function are used or not, and set
+ the reference flag according. */
void
update_rethrow_references ()
{
*************** update_rethrow_references ()
*** 2800,2806 ****
saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int));
/* Determine what regions exist, and whether there are any rethrows
! to those regions or not. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
{
--- 2812,2818 ----
saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int));
/* Determine what regions exist, and whether there are any rethrows
! from those regions or not. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
{
*************** reachable_handlers (block, info, insn, h
*** 3336,3342 ****
if (insn && GET_CODE (insn) == CALL_INSN)
{
/* RETHROWs specify a region number from which we are going to rethrow.
! This means we wont pass control to handlers in the specified
region, but rather any region OUTSIDE the specified region.
We accomplish this by setting block to the outer_index of the
specified region. */
--- 3348,3354 ----
if (insn && GET_CODE (insn) == CALL_INSN)
{
/* RETHROWs specify a region number from which we are going to rethrow.
! This means we won't pass control to handlers in the specified
region, but rather any region OUTSIDE the specified region.
We accomplish this by setting block to the outer_index of the
specified region. */