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]
Other format: [Raw text]

Re: PLEASE APPROVE: patch to fix PR 5879, a serious gcc 3.1 regression


On Tue, Mar 19, 2002 at 09:27:42AM -0800, Richard Henderson wrote:
> A better solution is to do the first round of dead code elimination,
> and if there are still live exception regions, and we're using sjlj,
> then prevent all sibcalls.

This should do the trick.  Testing x86-linux with --enable-sjlj-exceptions
in progress.


r~


	* except.c (current_function_has_exception_handlers): New.
	* except.h: Declare it.
	* sibcall.c (optimize_sibling_and_tail_recursive_call): Use it.
	Combine tests that disable all sibcalls for the function.
	
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.212
diff -u -p -r1.212 except.c
--- except.c	2002/02/21 21:10:56	1.212
+++ except.c	2002/03/19 19:36:37
@@ -1401,6 +1401,23 @@ find_exception_handler_labels ()
   exception_handler_labels = list;
 }
 
+bool
+current_function_has_exception_handlers ()
+{
+  int i;
+
+  for (i = cfun->eh->last_region_number; i > 0; --i)
+    {
+      struct eh_region *region = cfun->eh->region_array[i];
+
+      if (! region || region->region_number != i)
+	continue;
+      if (region->type != ERT_THROW)
+	return true;
+    }
+
+  return false;
+}
 
 static struct eh_region *
 duplicate_eh_region_1 (o, map)
Index: except.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.h,v
retrieving revision 1.61
diff -u -p -r1.61 except.h
--- except.h	2002/01/12 13:45:38	1.61
+++ except.h	2002/03/19 19:36:37
@@ -120,6 +120,7 @@ extern void maybe_remove_eh_handler		PAR
 extern void convert_from_eh_region_ranges	PARAMS ((void));
 extern void convert_to_eh_region_ranges		PARAMS ((void));
 extern void find_exception_handler_labels	PARAMS ((void));
+extern bool current_function_has_exception_handlers PARAMS ((void));
 extern void output_function_exception_table	PARAMS ((void));
 
 extern void expand_builtin_unwind_init		PARAMS ((void));
Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sibcall.c,v
retrieving revision 1.29
diff -u -p -r1.29 sibcall.c
--- sibcall.c	2002/01/22 14:33:33	1.29
+++ sibcall.c	2002/03/19 19:36:37
@@ -572,7 +572,7 @@ optimize_sibling_and_tail_recursive_call
 {
   rtx insn, insns;
   basic_block alternate_exit = EXIT_BLOCK_PTR;
-  int current_function_uses_addressof;
+  bool no_sibcalls_this_function = false;
   int successful_sibling_call = 0;
   int replaced_call_placeholder = 0;
   edge e;
@@ -595,6 +595,12 @@ optimize_sibling_and_tail_recursive_call
   if (n_basic_blocks == 0)
     return;
 
+  /* If we are using sjlj exceptions, we may need to add a call to 
+     _Unwind_SjLj_Unregister at exit of the function.  Which means
+     that we cannot do any sibcall transformations.  */
+  if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ())
+    no_sibcalls_this_function = true;
+
   return_value_pseudo = NULL_RTX;
 
   /* Find the exit block.
@@ -655,7 +661,7 @@ optimize_sibling_and_tail_recursive_call
 
   /* If the function uses ADDRESSOF, we can't (easily) determine
      at this point if the value will end up on the stack.  */
-  current_function_uses_addressof = sequence_uses_addressof (insns);
+  no_sibcalls_this_function |= sequence_uses_addressof (insns);
 
   /* Walk the insn chain and find any CALL_PLACEHOLDER insns.  We need to
      select one of the insn sequences attached to each CALL_PLACEHOLDER.
@@ -685,11 +691,10 @@ optimize_sibling_and_tail_recursive_call
 
 	  /* See if there are any reasons we can't perform either sibling or
 	     tail call optimizations.  We must be careful with stack slots
-	     which are live at potential optimization sites.  ??? The first
-	     test is overly conservative and should be replaced.  */
-	  if (frame_offset
-	      /* Can't take address of local var if used by recursive call.  */
-	      || current_function_uses_addressof
+	     which are live at potential optimization sites.  */
+	  if (no_sibcalls_this_function
+	      /* ??? Overly conservative.  */
+	      || frame_offset
 	      /* Any function that calls setjmp might have longjmp called from
 		 any called function.  ??? We really should represent this
 		 properly in the CFG so that this needn't be special cased.  */


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