+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
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;
+}
\f
static struct eh_region *
duplicate_eh_region_1 (o, map)
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));
{
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;
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.
/* 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.
/* 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. */