On 12/06/2017 02:04 PM, Jakub Jelinek wrote:
> Hi!
> 
> Aggregate assignments and clears aren't in GIMPLE represented as calls,
> and while often they expand inline, sometimes we emit libcalls for them.
> This patch allows us to tail call those libcalls if there is nothing
> after them.  The patch changes the tailcall pass, so that it recognizes
> a = b; and c = {}; statements under certain conditions as potential tail
> calls returning void, and if it finds good tail call candidates, it marks
> them specially.  Because we have only a single bit left for GIMPLE_ASSIGN,
> I've decided to wrap the rhs1 into a new internal call, so
> a = b; will be transformed into a = TAILCALL_ASSIGN (b); and
> c = {}; will be transformed into c = TAILCALL_ASSIGN ();
> The rest of the patch is about propagating the flag (may use tailcall if
> the emit_block_move or clear_storage is the last thing emitted) down
> through expand_assignment and functions it calls.
> 
> Those functions use 1-3 other flags, so instead of adding another bool
> to all of them (next to nontemporal, call_param_p, reverse) I've decided
> to pass around a bitmask of flags.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2017-12-06  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR target/41455
>       PR target/82935
>       * internal-fn.def (TAILCALL_ASSIGN): New internal function.
>       * internal-fn.c (expand_LAUNDER): Pass EXPAND_FLAG_NORMAL to
>       expand_assignment.
>       (expand_TAILCALL_ASSIGN): New function.
>       * tree-tailcall.c (struct tailcall): Adjust comment.
>       (find_tail_calls): Recognize also aggregate assignments and
>       aggregate clearing as possible tail calls.  Use is_gimple_assign
>       instead of gimple_code check.
>       (optimize_tail_call): Rewrite aggregate assignments or aggregate
>       clearing in tail call positions using IFN_TAILCALL_ASSIGN
>       internal function.
>       * tree-outof-ssa.c (insert_value_copy_on_edge): Adjust store_expr
>       caller.
>       * tree-chkp.c (chkp_expand_bounds_reset_for_mem): Adjust
>       expand_assignment caller.
>       * function.c (assign_parm_setup_reg): Likewise.
>       * ubsan.c (ubsan_encode_value): Likewise.
>       * cfgexpand.c (expand_call_stmt, expand_asm_stmt): Likewise.
>       (expand_gimple_stmt_1): Likewise.  Fix up formatting.
>       * calls.c (initialize_argument_information): Adjust store_expr caller.
>       * expr.h (enum expand_flag): New.
>       (expand_assignment): Replace bool argument with enum expand_flag.
>       (store_expr_with_bounds, store_expr): Replace int, bool, bool arguments
>       with enum expand_flag.
>       * expr.c (expand_assignment): Replace nontemporal argument with flags.
>       Assert no bits other than EXPAND_FLAG_NONTEMPORAL and
>       EXPAND_FLAG_TAILCALL are set.  Adjust store_expr, store_fields and
>       store_expr_with_bounds callers.
>       (store_expr_with_bounds): Replace call_param_p, nontemporal and
>       reverse args with flags argument.  Adjust recursive calls.  Pass
>       BLOCK_OP_TAILCALL to clear_storage and expand_block_move if
>       EXPAND_FLAG_TAILCALL is set.  Call clear_storage directly for
>       EXPAND_FLAG_TAILCALL assignments from emtpy CONSTRUCTOR.
>       (store_expr): Replace call_param_p, nontemporal and reverse args
>       with flags argument.  Adjust store_expr_with_bounds caller.
>       (store_constructor_field): Adjust store_field caller.
>       (store_constructor): Adjust store_expr and expand_assignment callers.
>       (store_field): Replace nontemporal and reverse arguments with flags
>       argument.  Adjust store_expr callers.  Pass BLOCK_OP_TAILCALL to
>       emit_block_move if EXPAND_FLAG_TAILCALL is set.
>       (expand_expr_real_2): Adjust store_expr and store_field callers.
>       (expand_expr_real_1): Adjust store_expr and expand_assignment callers.
> 
>       * gcc.target/i386/pr41455.c: New test.
This looks pretty reasonable to me.  Is it big?  Yes, but a fair amount
is changing how we pass flags into the expanders.

I think you just need to merge back to the trunk retest and this should
be good to go.

jeff

Reply via email to