This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: Persistent IA64 (and others?) exception failure


On Thu, Mar 14, 2002 at 09:55:14AM -0800, Boehm, Hans wrote:
> The gcc back end still occasionally optimizes away saving of the return
> address at function calls that are known not to return, e.g. because they
> always raise an exception.  This was first pointed out a long time ago
> (http://gcc.gnu.org/ml/gcc/2001-11/msg00960.html).  Richard Henderson
> suggested a better approach
> (http://gcc.gnu.org/ml/gcc/2001-11/msg01290.html).  But at least as of a
> couple of days ago, this was still broken in 3.1.

Try this.


r~



	* flow.c (EH_USES): Provide default.
	(calculate_global_regs_live): Use it for EH edges and noreturn calls.
	* doc/tm.texi (EH_USES): New.

	* config/ia64/ia64.c (ia64_eh_uses): New.
	* config/ia64/ia64-protos.h: Update.
	* config/ia64/ia64.h (EH_USES): New.

Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.505
diff -c -p -d -r1.505 flow.c
*** flow.c	2002/02/19 02:53:17	1.505
--- flow.c	2002/03/17 20:30:59
*************** Software Foundation, 59 Temple Place - S
*** 167,172 ****
--- 167,175 ----
  #ifndef EPILOGUE_USES
  #define EPILOGUE_USES(REGNO)  0
  #endif
+ #ifndef EH_USES
+ #define EH_USES(REGNO)  0
+ #endif
  
  #ifdef HAVE_conditional_execution
  #ifndef REVERSE_CONDEXEC_PREDICATES_P
*************** calculate_global_regs_live (blocks_in, b
*** 1111,1131 ****
  
        /* Begin by propagating live_at_start from the successor blocks.  */
        CLEAR_REG_SET (new_live_at_end);
-       for (e = bb->succ; e; e = e->succ_next)
- 	{
- 	  basic_block sb = e->dest;
  
! 	  /* Call-clobbered registers die across exception and call edges.  */
! 	  /* ??? Abnormal call edges ignored for the moment, as this gets
! 	     confused by sibling call edges, which crashes reg-stack.  */
! 	  if (e->flags & EDGE_EH)
! 	    {
! 	      bitmap_operation (tmp, sb->global_live_at_start,
! 				call_used, BITMAP_AND_COMPL);
! 	      IOR_REG_SET (new_live_at_end, tmp);
! 	    }
! 	  else
! 	    IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
  	}
  
        /* The all-important stack pointer must always be live.  */
--- 1114,1153 ----
  
        /* Begin by propagating live_at_start from the successor blocks.  */
        CLEAR_REG_SET (new_live_at_end);
  
!       if (bb->succ)
! 	for (e = bb->succ; e; e = e->succ_next)
! 	  {
! 	    basic_block sb = e->dest;
! 
! 	    /* Call-clobbered registers die across exception and
! 	       call edges.  */
! 	    /* ??? Abnormal call edges ignored for the moment, as this gets
! 	       confused by sibling call edges, which crashes reg-stack.  */
! 	    if (e->flags & EDGE_EH)
! 	      {
! 		bitmap_operation (tmp, sb->global_live_at_start,
! 				  call_used, BITMAP_AND_COMPL);
! 		IOR_REG_SET (new_live_at_end, tmp);
! 	      }
! 	    else
! 	      IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
! 
! 	    /* If a target saves one register in another (instead of on
! 	       the stack) the save register will need to be live for EH.  */
! 	    if (e->flags & EDGE_EH)
! 	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 		if (EH_USES (i))
! 		  SET_REGNO_REG_SET (new_live_at_end, i);
! 	  }
!       else
! 	{
! 	  /* This might be a noreturn function that throws.  And
! 	     even if it isn't, getting the unwind info right helps
! 	     debugging.  */
! 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	    if (EH_USES (i))
! 	      SET_REGNO_REG_SET (new_live_at_end, i);
  	}
  
        /* The all-important stack pointer must always be live.  */
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.102
diff -c -p -d -r1.102 tm.texi
*** tm.texi	2002/02/23 12:59:09	1.102
--- tm.texi	2002/03/17 20:30:59
*************** Define this macro as a C expression that
*** 3956,3961 ****
--- 3956,3967 ----
  used by the epilogue or the @samp{return} pattern.  The stack and frame
  pointer registers are already be assumed to be used as needed.
  
+ @findex EH_USES
+ @item EH_USES (@var{regno})
+ Define this macro as a C expression that is nonzero for registers that are
+ used by the exception handling mechanism, and so should be considered live
+ on entry to an exception edge.
+ 
  @findex DELAY_SLOTS_FOR_EPILOGUE
  @item DELAY_SLOTS_FOR_EPILOGUE
  Define this macro if the function epilogue contains delay slots to which
Index: config/ia64/ia64-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64-protos.h,v
retrieving revision 1.36
diff -c -p -d -r1.36 ia64-protos.h
*** ia64-protos.h	2002/01/21 02:24:02	1.36
--- ia64-protos.h	2002/03/17 20:30:59
*************** extern void ia64_encode_section_info PAR
*** 122,127 ****
--- 122,128 ----
  extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
  					   enum reg_class));
  extern int ia64_epilogue_uses PARAMS((int));
+ extern int ia64_eh_uses PARAMS((int));
  extern void emit_safe_across_calls PARAMS((FILE *));
  extern void ia64_init_builtins PARAMS((void));
  extern void ia64_override_options PARAMS((void));
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.139.2.6
diff -c -p -d -r1.139.2.6 ia64.c
*** ia64.c	2002/03/15 06:43:17	1.139.2.6
--- ia64.c	2002/03/17 20:30:59
*************** static rtx ia64_expand_compare_and_swap 
*** 138,144 ****
  static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
  						  tree, rtx));
  static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));
- const struct attribute_spec ia64_attribute_table[];
  static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
  static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
  static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
--- 138,143 ----
*************** static int ia64_variable_issue PARAMS ((
*** 156,161 ****
--- 155,168 ----
  static rtx ia64_cycle_display PARAMS ((int, rtx));
  
  
+ /* Table of valid machine attributes.  */
+ static const struct attribute_spec ia64_attribute_table[] =
+ {
+   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+   { "syscall_linkage", 0, 0, false, true,  true,  NULL },
+   { NULL,              0, 0, false, false, false, NULL }
+ };
+ 
  /* Initialize the GCC target structure.  */
  #undef TARGET_ATTRIBUTE_TABLE
  #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
*************** ia64_epilogue_uses (regno)
*** 6808,6820 ****
      }
  }
  
! /* Table of valid machine attributes.  */
! const struct attribute_spec ia64_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
!   { "syscall_linkage", 0, 0, false, true,  true,  NULL },
!   { NULL,              0, 0, false, false, false, NULL }
! };
  
  /* For ia64, SYMBOL_REF_FLAG set means that it is a function.
  
--- 6815,6847 ----
      }
  }
  
! /* Return true if REGNO is used by the frame unwinder.  */
! 
! int
! ia64_eh_uses (regno)
!      int regno;
  {
!   if (! reload_completed)
!     return 0;
! 
!   if (current_frame_info.reg_save_b0
!       && regno == current_frame_info.reg_save_b0)
!     return 1;
!   if (current_frame_info.reg_save_pr
!       && regno == current_frame_info.reg_save_pr)
!     return 1;
!   if (current_frame_info.reg_save_ar_pfs
!       && regno == current_frame_info.reg_save_ar_pfs)
!     return 1;
!   if (current_frame_info.reg_save_ar_unat
!       && regno == current_frame_info.reg_save_ar_unat)
!     return 1;
!   if (current_frame_info.reg_save_ar_lc
!       && regno == current_frame_info.reg_save_ar_lc)
!     return 1;
! 
!   return 0;
! }
  
  /* For ia64, SYMBOL_REF_FLAG set means that it is a function.
  
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.99
diff -c -p -d -r1.99 ia64.h
*** ia64.h	2002/01/21 06:22:12	1.99
--- ia64.h	2002/03/17 20:31:00
*************** do {									\
*** 1404,1409 ****
--- 1404,1413 ----
  
  #define EPILOGUE_USES(REGNO) ia64_epilogue_uses (REGNO)
  
+ /* Nonzero for registers used by the exception handling mechanism.  */
+ 
+ #define EH_USES(REGNO) ia64_eh_uses (REGNO)
+ 
  /* Output at beginning of assembler file.  */
  
  #define ASM_FILE_START(FILE) \


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