On Thu, Jan 23, 2014 at 4:39 PM, Jan Hubicka <[email protected]> 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.