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:
Jakub Jelinek 2019-05-20 23:33:46 +02:00 committed by Jakub Jelinek
parent 3e03ed6626
commit 500e4868bf
7 changed files with 34 additions and 0 deletions

View File

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

View File

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

View File

@ -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:
;
}

View File

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

View File

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

View File

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

View File

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