[PATCH, i386]: Improve fop and corresponding peephole2 patterns

Uros Bizjak ubizjak@gmail.com
Thu Apr 28 12:05:00 GMT 2016


Hello!

mult_operator will never match in patterns, protected with
!COMMUTATIVE_ARITH. The patch also adds "reg = op (mem, reg)"
peephole2 to break additional cases of dependency of two loads from
x87 stack.

2016-04-28  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (*fop_<mode>_1_mixed): Do not check for
    mult_operator when calculating "type" attribute.
    (*fop_<mode>_1_i387): Ditto.
    (*fop_xf_1_i387): Ditto.
    (x87 stack loads peephole2): Add "reg = op (mem, reg)" peephole2.
    Use std::swap to swap operands.  Use RTL expressions to generate
    converted pattern.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
-------------- next part --------------
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 235544)
+++ config/i386/i386.md	(working copy)
@@ -14055,20 +14055,13 @@
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
-        (cond [(and (eq_attr "alternative" "2,3")
-	            (match_operand:MODEF 3 "mult_operator"))
-                 (const_string "ssemul")
-	       (and (eq_attr "alternative" "2,3")
-	            (match_operand:MODEF 3 "div_operator"))
-                 (const_string "ssediv")
-	       (eq_attr "alternative" "2,3")
-                 (const_string "sseadd")
-	       (match_operand:MODEF 3 "mult_operator")
-                 (const_string "fmul")
-               (match_operand:MODEF 3 "div_operator")
-                 (const_string "fdiv")
-              ]
-              (const_string "fop")))
+	(if_then_else (eq_attr "alternative" "2,3")
+	   (if_then_else (match_operand:MODEF 3 "div_operator")
+	      (const_string "ssediv")
+	      (const_string "sseadd"))
+	   (if_then_else (match_operand:MODEF 3 "div_operator")
+	      (const_string "fdiv")
+	      (const_string "fop"))))
    (set_attr "isa" "*,*,noavx,avx")
    (set_attr "prefix" "orig,orig,orig,vex")
    (set_attr "mode" "<MODE>")
@@ -14090,12 +14083,9 @@
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
-        (cond [(match_operand:MODEF 3 "mult_operator")
-                 (const_string "fmul")
-               (match_operand:MODEF 3 "div_operator")
-                 (const_string "fdiv")
-              ]
-              (const_string "fop")))
+        (if_then_else (match_operand:MODEF 3 "div_operator")
+           (const_string "fdiv")
+           (const_string "fop")))
    (set_attr "mode" "<MODE>")])
 
 ;; ??? Add SSE splitters for these!
@@ -14109,7 +14099,7 @@
    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
        || optimize_function_for_size_p (cfun))"
-  { return output_387_binary_op (insn, operands); }
+  "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
         (cond [(match_operand:MODEF 3 "mult_operator")
                  (const_string "fmul")
@@ -14130,7 +14120,7 @@
    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
        || optimize_function_for_size_p (cfun))"
-  { return output_387_binary_op (insn, operands); }
+  "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
         (cond [(match_operand:MODEF 3 "mult_operator")
                  (const_string "fmul")
@@ -14220,12 +14210,9 @@
    && !COMMUTATIVE_ARITH_P (operands[3])"
   "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
-        (cond [(match_operand:XF 3 "mult_operator")
-                 (const_string "fmul")
-               (match_operand:XF 3 "div_operator")
-                 (const_string "fdiv")
-              ]
-              (const_string "fop")))
+        (if_then_else (match_operand:XF 3 "div_operator")
+           (const_string "fdiv")
+           (const_string "fop")))
    (set_attr "mode" "XF")])
 
 (define_insn "*fop_xf_2_i387"
@@ -14236,7 +14223,7 @@
 	   (match_operand:XF 2 "register_operand" "0")]))]
   "TARGET_80387
    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
-  { return output_387_binary_op (insn, operands); }
+  "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
         (cond [(match_operand:XF 3 "mult_operator")
                  (const_string "fmul")
@@ -14255,7 +14242,7 @@
 	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
   "TARGET_80387
    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
-  { return output_387_binary_op (insn, operands); }
+  "* return output_387_binary_op (insn, operands);"
   [(set (attr "type")
         (cond [(match_operand:XF 3 "mult_operator")
                  (const_string "fmul")
@@ -17394,6 +17381,7 @@
 ;;   fmul bb             fmul %st(1), %st
 ;;
 ;; Actually we only match the last two instructions for simplicity.
+
 (define_peephole2
   [(set (match_operand 0 "fp_register_operand")
 	(match_operand 1 "fp_register_operand"))
@@ -17403,21 +17391,39 @@
 	    (match_operand 3 "memory_operand")]))]
   "REGNO (operands[0]) != REGNO (operands[1])"
   [(set (match_dup 0) (match_dup 3))
-   (set (match_dup 0) (match_dup 4))]
+   (set (match_dup 0)
+	(match_op_dup 2
+	  [(match_dup 5) (match_dup 4)]))]
+{
+  operands[4] = operands[0];
+  operands[5] = operands[1];
 
-  ;; The % modifier is not operational anymore in peephole2's, so we have to
-  ;; swap the operands manually in the case of addition and multiplication.
+  /* The % modifier is not operational anymore in peephole2's, so we have to
+     swap the operands manually in the case of addition and multiplication. */
+  if (COMMUTATIVE_ARITH_P (operands[2]))
+    std::swap (operands[4], operands[5]);
+})
+
+(define_peephole2
+  [(set (match_operand 0 "fp_register_operand")
+	(match_operand 1 "fp_register_operand"))
+   (set (match_dup 0)
+	(match_operator 2 "binary_fp_operator"
+	   [(match_operand 3 "memory_operand")
+	    (match_dup 0)]))]
+  "REGNO (operands[0]) != REGNO (operands[1])"
+  [(set (match_dup 0) (match_dup 3))
+   (set (match_dup 0)
+	(match_op_dup 2
+	  [(match_dup 4) (match_dup 5)]))]
 {
-  rtx op0, op1;
+  operands[4] = operands[0];
+  operands[5] = operands[1];
 
+  /* The % modifier is not operational anymore in peephole2's, so we have to
+     swap the operands manually in the case of addition and multiplication. */
   if (COMMUTATIVE_ARITH_P (operands[2]))
-    op0 = operands[0], op1 = operands[1];
-  else
-    op0 = operands[1], op1 = operands[0];
-
-  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
-				GET_MODE (operands[2]),
-				op0, op1);
+    std::swap (operands[4], operands[5]);
 })
 
 ;; Conditional addition patterns


More information about the Gcc-patches mailing list