From 7cb6ef9cb9d0e20a63da12d8a976db77d38c5e39 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 20 Mar 2002 00:49:13 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51054 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/except.c | 17 +++++++++++++++++ gcc/except.h | 1 + gcc/sibcall.c | 19 ++++++++++++------- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1306228..cd732d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-03-19 Richard Henderson + + * 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. + 2002-03-19 Olivier Hainque * varasm.c (output_constant_def): Don't call ENCODE_SECTION_INFO diff --git a/gcc/except.c b/gcc/except.c index 939610f..fa92368 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -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) diff --git a/gcc/except.h b/gcc/except.h index f543c46..27dc714 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -120,6 +120,7 @@ extern void maybe_remove_eh_handler PARAMS ((rtx)); 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)); diff --git a/gcc/sibcall.c b/gcc/sibcall.c index 6c2dc5c..5a7997c 100644 --- a/gcc/sibcall.c +++ b/gcc/sibcall.c @@ -572,7 +572,7 @@ optimize_sibling_and_tail_recursive_calls () { 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_calls () 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_calls () /* 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_calls () /* 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. */ -- 2.7.4