This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

EH flow patch


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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]