On Thu, Jan 23, 2014 at 4:39 PM, Jan Hubicka <hubi...@ucw.cz> wrote: > Hi, > this is improved patch I am testing. The basic idea is to remove push > expanders for cases where we do not have push instruction anyway. > emit_move_insns then resorts to unconditonally call move expander > with push operand. I expended ix86_expand_vector_move to handle > it gracefully and for that I borrowed emit_move_resolve_push > function from expr.c since it seemed pointless to preserve > duplicated logic in ix86_expand_push. > > I can easily imagine that scheduling around function call sequences > matters, so I also updated push/pop expanders to preserve memory attributes. > > Eventually I found the attributes to be blank because of logic in expr.c > that clears alias info when sibcall is enabled. We can now do better > by only disabling it in functions that actually do sibcalls. > > Bootstrap/regtest running on x86_64-linux, OK for the non-i386 parts > if it passes? > > Honza > > * expr.c (emit_move_resolve_push): Export; be bit more selective > on when to clear alias set. > * expr.h (emit_move_resolve_push): Declare. > * function.h (struct function): Add tail_call_marked. > * tree-tailcall.c (optimize_tail_call): Set tail_call_marked. > * config/i386/i386-protos.h (ix86_expand_push): Remove. > * config/i386/i386.md (TImode move expander): De not call > ix86_expand_push. > (FP push expanders): Preserve memory attributes. > * config/i386/sse.md (push<mode>1): Remove. > * config/i386/i386.c (ix86_expand_vector_move): Handle push > operation. > (ix86_expand_push): Remove. > * config/i386/mmx.md (push<mode>1): Remove. ...
> --- config/i386/i386.md (revision 206946) > +++ config/i386/i386.md (working copy) > @@ -1818,8 +1818,6 @@ > { > if (TARGET_64BIT) > ix86_expand_move (TImode, operands); > - else if (push_operand (operands[0], TImode)) > - ix86_expand_push (TImode, operands[1]); > else > ix86_expand_vector_move (TImode, operands); > DONE; > @@ -2665,7 +2663,11 @@ > (match_operand:TF 1 "sse_reg_operand"))] > "TARGET_SSE && reload_completed" > [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) > - (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) > + (set (match_dup 0) (match_dup 1))] > +{ > + /* Preserve memory attributes. */ > + operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); > +}) > > (define_insn "*pushxf" > [(set (match_operand:XF 0 "push_operand" "=<,<") > @@ -2691,8 +2693,12 @@ > (match_operand:XF 1 "fp_register_operand"))] > "reload_completed" > [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) > - (set (mem:XF (reg:P SP_REG)) (match_dup 1))] > - "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") > + (set (match_dup 0) (match_dup 1))] > +{ > + operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode)); > + /* Preserve memory attributes. */ > + operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); > +}) > > (define_insn "*pushdf" > [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") > @@ -2713,7 +2719,11 @@ > (match_operand:DF 1 "any_fp_register_operand"))] > "reload_completed" > [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) > - (set (mem:DF (reg:P SP_REG)) (match_dup 1))]) > + (set (match_dup 0) (match_dup 1))] > +{ > + /* Preserve memory attributes. */ > + operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); > +}) > > (define_insn "*pushsf_rex64" > [(set (match_operand:SF 0 "push_operand" "=X,X,X") > @@ -2747,8 +2757,12 @@ > (match_operand:SF 1 "any_fp_register_operand"))] > "reload_completed" > [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) > - (set (mem:SF (reg:P SP_REG)) (match_dup 1))] > - "operands[2] = GEN_INT (-<P:MODE_SIZE>);") > + (set (match_dup 0) (match_dup 1))] > +{ > + operands[2] = GEN_INT (-<P:MODE_SIZE>); > + /* Preserve memory attributes. */ > + operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); > +}) > This piece code is wrong for x32: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59929 I am testing: diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ddc3be6..92e8fd0 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2765,7 +2765,20 @@ "reload_completed" [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) (set (mem:SF (reg:P SP_REG)) (match_dup 1))] - "operands[2] = GEN_INT (-<P:MODE_SIZE>);") +{ + rtx op = XEXP (operands[0], 0); + if (GET_CODE (op) == PRE_DEC) + { + gcc_assert (!TARGET_64BIT); + op = GEN_INT (-4); + } + else + { + op = XEXP (XEXP (op, 1), 1); + gcc_assert (CONST_INT_P (op)); + } + operands[2] = op; +}) (define_split [(set (match_operand:SF 0 "push_operand") -- H.J.