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