This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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. */