+2019-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/59813
+ PR target/90418
+ * function.h (struct function): Add calls_eh_return member.
+ * gimplify.c (gimplify_call_expr): Set cfun->calls_eh_return when
+ gimplifying __builtin_eh_return call.
+ * tree-inline.c (initialize_cfun): Copy calls_eh_return from src_cfun
+ to cfun.
+ (expand_call_inline): Or in src_cfun->calls_eh_return into
+ dst_cfun->calls_eh_return.
+ * tree-tailcall.c (suitable_for_tail_call_opt_p): Return false if
+ cfun->calls_eh_return.
+ * lto-streamer-in.c (input_struct_function_base): Read calls_eh_return.
+ * lto-streamer-out.c (output_struct_function_base): Write
+ calls_eh_return.
+
2019-05-20 Marc Glisse <marc.glisse@inria.fr>
PR rtl-optimization/43147
either as a subroutine or builtin. */
unsigned int calls_alloca : 1;
+ /* Nonzero if function being compiled can call __builtin_eh_return. */
+ unsigned int calls_eh_return : 1;
+
/* Nonzero if function being compiled receives nonlocal gotos
from nested functions. */
unsigned int has_nonlocal_label : 1;
break;
}
+ case BUILT_IN_EH_RETURN:
+ cfun->calls_eh_return = true;
+ break;
+
default:
;
}
fn->has_forced_label_in_static = bp_unpack_value (&bp, 1);
fn->calls_alloca = bp_unpack_value (&bp, 1);
fn->calls_setjmp = bp_unpack_value (&bp, 1);
+ fn->calls_eh_return = bp_unpack_value (&bp, 1);
fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1);
fn->has_simduid_loops = bp_unpack_value (&bp, 1);
fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
bp_pack_value (&bp, fn->has_forced_label_in_static, 1);
bp_pack_value (&bp, fn->calls_alloca, 1);
bp_pack_value (&bp, fn->calls_setjmp, 1);
+ bp_pack_value (&bp, fn->calls_eh_return, 1);
bp_pack_value (&bp, fn->has_force_vectorize_loops, 1);
bp_pack_value (&bp, fn->has_simduid_loops, 1);
bp_pack_value (&bp, fn->va_list_fpr_size, 8);
cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
+ cfun->calls_eh_return = src_cfun->calls_eh_return;
cfun->stdarg = src_cfun->stdarg;
cfun->after_inlining = src_cfun->after_inlining;
cfun->can_throw_non_call_exceptions
src_properties = id->src_cfun->curr_properties & prop_mask;
if (src_properties != prop_mask)
dst_cfun->curr_properties &= src_properties | ~prop_mask;
+ dst_cfun->calls_eh_return |= id->src_cfun->calls_eh_return;
gcc_assert (!id->src_cfun->after_inlining);
return true;
}
+
/* Returns false when the function is not suitable for tail call optimization
for some reason (e.g. if it takes variable number of arguments).
This test must pass in addition to suitable_for_tail_opt_p in order to make
if (cfun->calls_setjmp)
return false;
+ /* Various targets don't handle tail calls correctly in functions
+ that call __builtin_eh_return. */
+ if (cfun->calls_eh_return)
+ return false;
+
/* ??? It is OK if the argument of a function is taken in some cases,
but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */
for (param = DECL_ARGUMENTS (current_function_decl);