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