Fix can_throw_internal/can_throw_external
Jan Hubicka
jh@suse.cz
Fri May 27 20:04:00 GMT 2005
Hi,
this patch bring can_throw_internal/external behaviour into sync with what
make_eh_edges actually does (ie RESX throws exception one level up, so this
level needs to be unpeeled before starting the walk).
It seems noop in the current tree (since can_throw_internal is rarely called on
RESXs), but I need it for my future work.
Bootstrapped/regtested i686-pc-gnu-linux, OK?
2005-05-27 Jan Hubicka <jh@suse.cz>
* except.c (can_throw_internal_1, can_throw_external_1): Add
"is_resx" argument.
(can_throw_external, can_throw_internal): Bring into sync wrt
dealing resx.
* except.h (can_throw_internal_1, can_throw_external_1): Update
prototype.
* tree-eh.c (tree_can_throw_internal, tree_can_throw_external):
Deal properly with resx.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.306
diff -c -3 -p -r1.306 except.c
*** except.c 12 May 2005 19:29:16 -0000 1.306
--- except.c 27 May 2005 14:41:46 -0000
*************** reachable_handlers (rtx insn)
*** 2539,2545 ****
within the function. */
bool
! can_throw_internal_1 (int region_number)
{
struct eh_region *region;
tree type_thrown;
--- 2540,2546 ----
within the function. */
bool
! can_throw_internal_1 (int region_number, bool is_resx)
{
struct eh_region *region;
tree type_thrown;
*************** can_throw_internal_1 (int region_number)
*** 2547,2553 ****
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
! if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
--- 2548,2556 ----
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
! if (is_resx)
! region = region->outer;
! else if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
*************** can_throw_internal (rtx insn)
*** 2579,2585 ****
if (JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) == RESX
&& XINT (PATTERN (insn), 0) > 0)
! return can_throw_internal_1 (XINT (PATTERN (insn), 0));
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
--- 2582,2588 ----
if (JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) == RESX
&& XINT (PATTERN (insn), 0) > 0)
! return can_throw_internal_1 (XINT (PATTERN (insn), 0), true);
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
*************** can_throw_internal (rtx insn)
*** 2590,2603 ****
if (!note || INTVAL (XEXP (note, 0)) <= 0)
return false;
! return can_throw_internal_1 (INTVAL (XEXP (note, 0)));
}
/* Determine if the given INSN can throw an exception that is
visible outside the function. */
bool
! can_throw_external_1 (int region_number)
{
struct eh_region *region;
tree type_thrown;
--- 2593,2606 ----
if (!note || INTVAL (XEXP (note, 0)) <= 0)
return false;
! return can_throw_internal_1 (INTVAL (XEXP (note, 0)), false);
}
/* Determine if the given INSN can throw an exception that is
visible outside the function. */
bool
! can_throw_external_1 (int region_number, bool is_resx)
{
struct eh_region *region;
tree type_thrown;
*************** can_throw_external_1 (int region_number)
*** 2605,2611 ****
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
! if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
--- 2608,2616 ----
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
! if (is_resx)
! region = region->outer;
! else if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
*************** can_throw_external (rtx insn)
*** 2628,2633 ****
--- 2633,2643 ----
if (! INSN_P (insn))
return false;
+ if (JUMP_P (insn)
+ && GET_CODE (PATTERN (insn)) == RESX
+ && XINT (PATTERN (insn), 0) > 0)
+ return can_throw_external_1 (XINT (PATTERN (insn), 0), true);
+
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
insn = XVECEXP (PATTERN (insn), 0, 0);
*************** can_throw_external (rtx insn)
*** 2647,2653 ****
if (INTVAL (XEXP (note, 0)) <= 0)
return false;
! return can_throw_external_1 (INTVAL (XEXP (note, 0)));
}
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
--- 2657,2663 ----
if (INTVAL (XEXP (note, 0)) <= 0)
return false;
! return can_throw_external_1 (INTVAL (XEXP (note, 0)), false);
}
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
Index: except.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.h,v
retrieving revision 1.85
diff -c -3 -p -r1.85 except.h
*** except.h 12 May 2005 19:29:19 -0000 1.85
--- except.h 27 May 2005 14:41:46 -0000
*************** extern void for_each_eh_label (void (*)
*** 46,54 ****
extern void for_each_eh_region (void (*) (struct eh_region *));
/* Determine if the given INSN can throw an exception. */
! extern bool can_throw_internal_1 (int);
extern bool can_throw_internal (rtx);
! extern bool can_throw_external_1 (int);
extern bool can_throw_external (rtx);
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
--- 46,54 ----
extern void for_each_eh_region (void (*) (struct eh_region *));
/* Determine if the given INSN can throw an exception. */
! extern bool can_throw_internal_1 (int, bool);
extern bool can_throw_internal (rtx);
! extern bool can_throw_external_1 (int, bool);
extern bool can_throw_external (rtx);
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v
retrieving revision 2.39
diff -c -3 -p -r2.39 tree-eh.c
*** tree-eh.c 16 May 2005 23:14:01 -0000 2.39
--- tree-eh.c 27 May 2005 14:41:47 -0000
*************** bool
*** 2009,2037 ****
tree_can_throw_internal (tree stmt)
{
int region_nr;
if (TREE_CODE (stmt) == RESX_EXPR)
! region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return false;
! return can_throw_internal_1 (region_nr);
}
bool
tree_can_throw_external (tree stmt)
{
int region_nr;
if (TREE_CODE (stmt) == RESX_EXPR)
! region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return tree_could_throw_p (stmt);
else
! return can_throw_external_1 (region_nr);
}
/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
--- 2009,2039 ----
tree_can_throw_internal (tree stmt)
{
int region_nr;
+ bool is_resx = false;
if (TREE_CODE (stmt) == RESX_EXPR)
! region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return false;
! return can_throw_internal_1 (region_nr, is_resx);
}
bool
tree_can_throw_external (tree stmt)
{
int region_nr;
+ bool is_resx = false;
if (TREE_CODE (stmt) == RESX_EXPR)
! region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return tree_could_throw_p (stmt);
else
! return can_throw_external_1 (region_nr, is_resx);
}
/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
More information about the Gcc-patches
mailing list