i386.md (*movtf_internal): Avoid allocating general registers.
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 31 May 2011 16:14:08 +0000 (18:14 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 31 May 2011 16:14:08 +0000 (18:14 +0200)
* config/i386/i386.md (*movtf_internal): Avoid allocating general
registers.  Penalize F*r->o alternative to prevent partial memory
stalls.  Slightly penalize *roF->*r alternative.  Generate SSE
CONST_DOUBLE immediates when optimizing function for size.  Do not move
CONST_DOUBLEs directly to memory for !TARGET_MEMORY_MISMATCH_STALL.
(*movxf_internal): Slightly penalize Yx*roF->Yx*r alternative.
(*movdf_internal): Slightly penalize Yd*roF->Yd*r alternative.
(*movdf_internal_rex64): Slightly penalize rm->r, F->m and r->m
alternatives.
(*movsf_internal): Slightly penalize rmF->r and Fr->m alternatives.

(fp_register_operand splitters): Use fp_register_operand
constraint.  Do not use FP_REG_P in insn condition.
(any_fp_register_operand splitters): Use any_fp_register_operand
constraint.  Do not use ANY_FP_REG_P in insn condition.

* config/i386/i386.md (*pushxf_nointeger): Merge alternatives 1 and 2.
(FP push_operand splitters): Merge {TF,XF,DF}mode splitters.

From-SVN: r174489

gcc/ChangeLog
gcc/config/i386/i386.md

index 0057740d7e0a11dc54b63bff55d714bdee502d2e..f4346fb7ba7a2867b43c7acffb3a0ae69c42f4ca 100644 (file)
@@ -1,3 +1,26 @@
+2011-05-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (*pushxf_nointeger): Merge alternatives 1 and 2.
+       (FP push_operand splitters): Merge {TF,XF,DF}mode splitters.
+
+2011-05-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (*movtf_internal): Avoid allocating general
+       registers.  Penalize F*r->o alternative to prevent partial memory
+       stalls.  Slightly penalize *roF->*r alternative.  Generate SSE
+       CONST_DOUBLE immediates when optimizing function for size.  Do not move
+       CONST_DOUBLEs directly to memory for !TARGET_MEMORY_MISMATCH_STALL.
+       (*movxf_internal): Slightly penalize Yx*roF->Yx*r alternative.
+       (*movdf_internal): Slightly penalize Yd*roF->Yd*r alternative.
+       (*movdf_internal_rex64): Slightly penalize rm->r, F->m and r->m
+       alternatives.
+       (*movsf_internal): Slightly penalize rmF->r and Fr->m alternatives.
+
+       (fp_register_operand splitters): Use fp_register_operand
+       constraint.  Do not use FP_REG_P in insn condition.
+       (any_fp_register_operand splitters): Use any_fp_register_operand
+       constraint.  Do not use ANY_FP_REG_P in insn condition.
+
 2011-05-31  Jan Hubicka  <jh@suse.cz>
 
        * cgraph.h (cgraph_inline_failed_t): Give enum a name
@@ -39,7 +62,7 @@
 
        PR debug/49047
        * dwarf2out.c (gen_subprogram_die): Emit linkage name attribute
-       for concrete functions containing the code of cloned functions.
+       for concrete functions containing the code of cloned functions.
 
 2011-05-31  Richard Guenther  <rguenther@suse.de>
 
@@ -57,8 +80,7 @@
        (tree_ssa_forward_propagate_single_use_vars): Rename to ...
        (ssa_forward_propagate_and_combine): ... this.  Re-structure
        to do a forward forward-propagation walk on BBs and a backward
-       stmt combining walk on BBs.  Consistently re-scan changed
-       statements.
+       stmt combining walk on BBs.  Consistently re-scan changed statements.
        (pass_forwprop): Adjust.
 
 2011-05-30  Ian Lance Taylor  <iant@google.com>
        to prevent partial memory stalls.  Do not move CONST_DOUBLEs directly
        to memory for !TARGET_MEMORY_MISMATCH_STALL.
        (*movdf_internal_rex64): Do not penalize F->r alternative.
-       (*movdf_internal):  Penalize FYd*r->o alternative to prevent partial
+       (*movdf_internal): Penalize FYd*r->o alternative to prevent partial
        memory stalls.  Generate SSE and x87 CONST_DOUBLE immediates only
        when optimizing function for size.  Do not move CONST_DOUBLEs
        directly to memory for !TARGET_MEMORY_MISMATCH_STALL.
-       (FP move splitters): Merge {TF,XF,DF}mode move splitters.  Do not
-       handle SUBREGs.  Do not check for MEM_P operands in the insn condition,
+       (FP move splitters): Merge {TF,XF,DF}mode splitters.  Do not handle
+       SUBREGs.  Do not check for MEM_P operands in the insn condition,
        check for ANY_FP_REGNO_P instead.
        * config/i386/constraints.md (Yd): Enable GENERAL_REGS for
        TARGET_64BIT and for TARGET_INTEGER_DFMODE_MOVES when optimizing
 2011-05-30  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/49210
-       * ipa-split.c (split_function): Care for the case where the
-       call result is not trivially convertible to the result holding
-       variable.
+       * ipa-split.c (split_function): Care for the case where the call
+       result is not trivially convertible to the result holding variable.
 
 2011-05-30  Richard Guenther  <rguenther@suse.de>
 
index cf1e883d44be24d04eb2b6159ffa8d454d2a8aa5..204a1e60fd6479d1c88db4920de5aba1af54d06b 100644 (file)
    (set_attr "unit" "sse,*,*")
    (set_attr "mode" "TF,SI,SI")])
 
+;; %%% Kill this when call knows how to work this out.
 (define_split
   [(set (match_operand:TF 0 "push_operand" "")
        (match_operand:TF 1 "sse_reg_operand" ""))]
   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
 
-(define_split
-  [(set (match_operand:TF 0 "push_operand" "")
-       (match_operand:TF 1 "general_operand" ""))]
-  "TARGET_SSE2 && reload_completed
-   && !SSE_REG_P (operands[1])"
-  [(const_int 0)]
-  "ix86_split_long_move (operands); DONE;")
-
 (define_insn "*pushxf"
   [(set (match_operand:XF 0 "push_operand" "=<,<")
        (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
 ;; only once, but this ought to be handled elsewhere).
 
 (define_insn "*pushxf_nointeger"
-  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
-       (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
+  [(set (match_operand:XF 0 "push_operand" "=X,X")
+       (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
   "optimize_function_for_size_p (cfun)"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
 }
   [(set_attr "type" "multi")
-   (set_attr "unit" "i387,*,*")
-   (set_attr "mode" "XF,SI,SI")])
+   (set_attr "unit" "i387,*")
+   (set_attr "mode" "XF,SI")])
 
+;; %%% Kill this when call knows how to work this out.
 (define_split
   [(set (match_operand:XF 0 "push_operand" "")
        (match_operand:XF 1 "fp_register_operand" ""))]
    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
 
-(define_split
-  [(set (match_operand:XF 0 "push_operand" "")
-       (match_operand:XF 1 "general_operand" ""))]
-  "reload_completed
-   && !FP_REG_P (operands[1])"
-  [(const_int 0)]
-  "ix86_split_long_move (operands); DONE;")
-
 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
 ;; Size of pushdf using integer instructions is 2+2*memory operand size
 ;; On the average, pushdf using integers can be still shorter.
   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
 
-(define_split
-  [(set (match_operand:DF 0 "push_operand" "")
-       (match_operand:DF 1 "general_operand" ""))]
-  "reload_completed
-   && !ANY_FP_REG_P (operands[1])"
-  [(const_int 0)]
-  "ix86_split_long_move (operands); DONE;")
-
 (define_insn "*pushsf_rex64"
   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
        (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
    (set_attr "unit" "i387,*,*")
    (set_attr "mode" "SF,SI,SF")])
 
-(define_split
-  [(set (match_operand:SF 0 "push_operand" "")
-       (match_operand:SF 1 "memory_operand" ""))]
-  "reload_completed
-   && MEM_P (operands[1])
-   && (operands[2] = find_constant_src (insn))"
-  [(set (match_dup 0)
-       (match_dup 2))])
-
 ;; %%% Kill this when call knows how to work this out.
 (define_split
   [(set (match_operand:SF 0 "push_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 (-GET_MODE_SIZE (<MODE>mode));")
+  "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
+
+(define_split
+  [(set (match_operand:SF 0 "push_operand" "")
+       (match_operand:SF 1 "memory_operand" ""))]
+  "reload_completed
+   && (operands[2] = find_constant_src (insn))"
+  [(set (match_dup 0) (match_dup 2))])
+
+(define_split
+  [(set (match_operand 0 "push_operand" "")
+       (match_operand 1 "general_operand" ""))]
+  "reload_completed
+   && (GET_MODE (operands[0]) == TFmode
+       || GET_MODE (operands[0]) == XFmode
+       || GET_MODE (operands[0]) == DFmode)
+   && !ANY_FP_REG_P (operands[1])"
+  [(const_int 0)]
+  "ix86_split_long_move (operands); DONE;")
 \f
 ;; Floating point move instructions.
 
   "ix86_expand_move (<MODE>mode, operands); DONE;")
 
 (define_insn "*movtf_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r ,?o")
-       (match_operand:TF 1 "general_operand"      "xm,x,C,roF,Fr"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
+       (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
   "TARGET_SSE2
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
+   && (!can_create_pseudo_p ()
+       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
+       || GET_CODE (operands[1]) != CONST_DOUBLE
+       || (optimize_function_for_size_p (cfun)
+          && standard_sse_constant_p (operands[1])
+          && !memory_operand (operands[0], TFmode))
+       || (!TARGET_MEMORY_MISMATCH_STALL
+          && memory_operand (operands[0], TFmode)))"
 {
   switch (which_alternative)
     {
     case 0:
     case 1:
-      /* Handle misaligned load/store since we don't have movmisaligntf
-        pattern. */
+      /* Handle misaligned load/store since we
+         don't have movmisaligntf pattern. */
       if (misaligned_operand (operands[0], TFmode)
          || misaligned_operand (operands[1], TFmode))
        {
 
 ;; Possible store forwarding (partial memory) stall in alternative 4.
 (define_insn "*movxf_internal"
-  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r  ,!o")
+  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
        (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (!can_create_pseudo_p ()
 
 (define_insn "*movdf_internal_rex64"
   [(set (match_operand:DF 0 "nonimmediate_operand"
-               "=f,m,f,r ,m,r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
+               "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
        (match_operand:DF 1 "general_operand"
-               "fm,f,G,rm,r,F,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
+               "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (!can_create_pseudo_p ()
        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
 ;; Possible store forwarding (partial memory) stall in alternative 4.
 (define_insn "*movdf_internal"
   [(set (match_operand:DF 0 "nonimmediate_operand"
-               "=f,m,f,Yd*r  ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
+               "=f,m,f,?Yd*r ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
        (match_operand:DF 1 "general_operand"
                "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
 
 (define_insn "*movsf_internal"
   [(set (match_operand:SF 0 "nonimmediate_operand"
-         "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
+         "=f,m,f,?r ,?m,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
        (match_operand:SF 1 "general_operand"
          "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
               (const_string "SF")))])
 
 (define_split
-  [(set (match_operand 0 "register_operand" "")
+  [(set (match_operand 0 "any_fp_register_operand" "")
        (match_operand 1 "memory_operand" ""))]
   "reload_completed
    && (GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == XFmode
        || GET_MODE (operands[0]) == DFmode
        || GET_MODE (operands[0]) == SFmode)
-   && ANY_FP_REGNO_P (REGNO (operands[0]))
    && (operands[2] = find_constant_src (insn))"
   [(set (match_dup 0) (match_dup 2))]
 {
 })
 
 (define_split
-  [(set (match_operand 0 "register_operand" "")
+  [(set (match_operand 0 "any_fp_register_operand" "")
        (float_extend (match_operand 1 "memory_operand" "")))]
   "reload_completed
    && (GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == XFmode
        || GET_MODE (operands[0]) == DFmode)
-   && ANY_FP_REGNO_P (REGNO (operands[0]))
    && (operands[2] = find_constant_src (insn))"
   [(set (match_dup 0) (match_dup 2))]
 {
 
 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
 (define_split
-  [(set (match_operand:X87MODEF 0 "register_operand" "")
+  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
        (match_operand:X87MODEF 1 "immediate_operand" ""))]
-  "reload_completed && FP_REGNO_P (REGNO (operands[0]))
+  "reload_completed
    && (standard_80387_constant_p (operands[1]) == 8
        || standard_80387_constant_p (operands[1]) == 9)"
   [(set (match_dup 0)(match_dup 1))
    (set_attr "fp_int_src" "true")])
 
 (define_split
-  [(set (match_operand:X87MODEF 0 "register_operand" "")
+  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
        (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
   "TARGET_80387
    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
-   && reload_completed
-   && FP_REG_P (operands[0])"
+   && reload_completed"
   [(set (match_dup 2) (match_dup 1))
    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
 
 (define_split
-  [(set (match_operand:X87MODEF 0 "register_operand" "")
+  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
        (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
   "TARGET_80387
    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
-   && reload_completed
-   && FP_REG_P (operands[0])"
+   && reload_completed"
   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
 
 ;; Avoid store forwarding (partial memory) stall penalty
    (set_attr "fp_int_src" "true")])
 
 (define_split
-  [(set (match_operand:X87MODEF 0 "register_operand" "")
+  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
        (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
    (clobber (match_scratch:V4SI 3 ""))
    (clobber (match_scratch:V4SI 4 ""))
   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
-   && reload_completed
-   && FP_REG_P (operands[0])"
+   && reload_completed"
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
 {
 })
 
 (define_split
-  [(set (match_operand:X87MODEF 0 "register_operand" "")
+  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
        (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
    (clobber (match_scratch:V4SI 3 ""))
    (clobber (match_scratch:V4SI 4 ""))
   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
-   && reload_completed
-   && FP_REG_P (operands[0])"
+   && reload_completed"
   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
 
 ;; Avoid store forwarding (partial memory) stall penalty by extending