except.c (current_function_has_exception_handlers): New.

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

From-SVN: r51054
This commit is contained in:
Richard Henderson 2002-03-19 16:49:13 -08:00 committed by Richard Henderson
parent ed4fbfa016
commit 93f82d6080
4 changed files with 37 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2002-03-19 Richard Henderson <rth@redhat.com>
* 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 <hainque@act-europe.fr>
* varasm.c (output_constant_def): Don't call ENCODE_SECTION_INFO

View File

@ -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)

View File

@ -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));

View File

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