re PR c++/59813 (tail-call elimination didn't fire for left-shift of char to cout)
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. From-SVN: r271440
This commit is contained in:
parent
3e03ed6626
commit
500e4868bf
|
@ -1,3 +1,20 @@
|
|||
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
|
||||
|
|
|
@ -327,6 +327,9 @@ struct GTY(()) function {
|
|||
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;
|
||||
|
|
|
@ -3297,6 +3297,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
break;
|
||||
}
|
||||
|
||||
case BUILT_IN_EH_RETURN:
|
||||
cfun->calls_eh_return = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1005,6 +1005,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
|
|||
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);
|
||||
|
|
|
@ -2029,6 +2029,7 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
|
|||
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);
|
||||
|
|
|
@ -2662,6 +2662,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count)
|
|||
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
|
||||
|
@ -4778,6 +4779,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
|
|||
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);
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ suitable_for_tail_opt_p (void)
|
|||
|
||||
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
|
||||
|
@ -168,6 +169,11 @@ suitable_for_tail_call_opt_p (void)
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue