aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-11-07 20:33:57 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-11-07 20:33:57 +0100
commitb15ef5d3f8a611af67254cdfaf126412872ca95c (patch)
tree267dcc501467af54d2c28993edcd7977a5214e4f /gcc
parentd4bc3829f139406a9b8d238d834fb1580f68e1ec (diff)
downloadgcc-b15ef5d3f8a611af67254cdfaf126412872ca95c.zip
gcc-b15ef5d3f8a611af67254cdfaf126412872ca95c.tar.gz
gcc-b15ef5d3f8a611af67254cdfaf126412872ca95c.tar.bz2
rs6000: Use isel for the cstore patterns
We currently generate (sometimes pretty long) sequences of integer insns to implement the various cstore patterns. If the CPU has a fast isel, we can use that at the same latency as of just two integer insns (you also get a load immediate of 1, and sometimes one of 0 as well, but those are not in the critical path: they don't depend on any other instruction). There are a few patterns that already are implemented with just two instructions; so don't use isel in that case (I still need to check all lt/gt/ltu/gtu/le/leu/ge/geu patterns with all SI/DI combinations, one or two might be better without isel). This introduces a new GPR2 mode iterator, for those patterns that use two independent integer modes. * config/rs6000/rs6000.md (GPR2): New mode_iterator. ("cstore<mode>4"): Don't always expand with rs6000_emit_int_cmove for eq and ne if TARGET_ISEL. (cmp): New code_iterator. (UNS, UNSU_, UNSIK): New code_attrs. (<code><GPR:mode><GPR2:mode>2_isel): New define_insn_and_split. ("eq<mode>3"): New define_expand, rename the define_insn_and_split to... ("eq<mode>3"): ... this. ("ne<mode>3"): New define_expand, rename the define_insn_and_split to... ("ne<mode>3"): ... this. From-SVN: r254508
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/rs6000/rs6000.md133
2 files changed, 134 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29c3349..9c9f0ef 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2017-11-07 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.md (GPR2): New mode_iterator.
+ ("cstore<mode>4"): Don't always expand with rs6000_emit_int_cmove for
+ eq and ne if TARGET_ISEL.
+ (cmp): New code_iterator.
+ (UNS, UNSU_, UNSIK): New code_attrs.
+ (<code><GPR:mode><GPR2:mode>2_isel): New define_insn_and_split.
+ ("eq<mode>3"): New define_expand, rename the define_insn_and_split
+ to...
+ ("eq<mode>3"): ... this.
+ ("ne<mode>3"): New define_expand, rename the define_insn_and_split
+ to...
+ ("ne<mode>3"): ... this.
+
2017-11-07 Julia Koval <julia.koval@intel.com>
PR target/82812
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index ed5ff39..b800276 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -323,6 +323,9 @@
; of whole values in GPRs.
(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
+; And again, for patterns that need two (potentially) different integer modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
+
; Any supported integer mode.
(define_mode_iterator INT [QI HI SI DI TI PTI])
@@ -11780,13 +11783,9 @@
(clobber (match_operand:GPR 0 "gpc_reg_operand"))]
""
{
- /* Use ISEL if the user asked for it. */
- if (TARGET_ISEL)
- rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
-
/* Expanding EQ and NE directly to some machine instructions does not help
but does hurt combine. So don't. */
- else if (GET_CODE (operands[1]) == EQ)
+ if (GET_CODE (operands[1]) == EQ)
emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
else if (<MODE>mode == Pmode
&& GET_CODE (operands[1]) == NE)
@@ -11798,7 +11797,11 @@
emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
}
- /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
+ /* If ISEL is fast, expand to it. */
+ else if (TARGET_ISEL)
+ rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
+
+ /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
etc. combinations magically work out just right. */
else if (<MODE>mode == Pmode
&& unsigned_comparison_operator (operands[1], VOIDmode))
@@ -12280,18 +12283,102 @@
"")
+(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
+(define_code_attr UNS [(eq "CC")
+ (ne "CC")
+ (lt "CC") (ltu "CCUNS")
+ (gt "CC") (gtu "CCUNS")
+ (le "CC") (leu "CCUNS")
+ (ge "CC") (geu "CCUNS")])
+(define_code_attr UNSu_ [(eq "")
+ (ne "")
+ (lt "") (ltu "u_")
+ (gt "") (gtu "u_")
+ (le "") (leu "u_")
+ (ge "") (geu "u_")])
+(define_code_attr UNSIK [(eq "I")
+ (ne "I")
+ (lt "I") (ltu "K")
+ (gt "I") (gtu "K")
+ (le "I") (leu "K")
+ (ge "I") (geu "K")])
+
+(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
+ (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
+ (clobber (match_scratch:GPR 3 "=r"))
+ (clobber (match_scratch:GPR 4 "=r"))
+ (clobber (match_scratch:<UNS> 5 "=y"))]
+ "TARGET_ISEL
+ && !(<CODE> == EQ && operands[2] == const0_rtx)
+ && !(<CODE> == NE && operands[2] == const0_rtx
+ && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
+ "#"
+ "&& 1"
+ [(pc)]
+{
+ if (<CODE> == NE || <CODE> == LE || <CODE> == GE
+ || <CODE> == LEU || <CODE> == GEU)
+ operands[3] = const0_rtx;
+ else
+ {
+ if (GET_CODE (operands[3]) == SCRATCH)
+ operands[3] = gen_reg_rtx (<GPR:MODE>mode);
+ emit_move_insn (operands[3], const0_rtx);
+ }
+
+ if (GET_CODE (operands[4]) == SCRATCH)
+ operands[4] = gen_reg_rtx (<GPR:MODE>mode);
+ emit_move_insn (operands[4], const1_rtx);
+
+ if (GET_CODE (operands[5]) == SCRATCH)
+ operands[5] = gen_reg_rtx (<UNS>mode);
+
+ rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
+ emit_insn (gen_rtx_SET (operands[5], c1));
+
+ rtx c2 = gen_rtx_fmt_ee (<CODE>, <GPR:MODE>mode, operands[5], const0_rtx);
+ rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
+ emit_move_insn (operands[0], x);
+
+ DONE;
+}
+ [(set (attr "cost")
+ (if_then_else (match_test "<CODE> == NE || <CODE> == LE || <CODE> == GE
+ || <CODE> == LEU || <CODE> == GEU")
+ (const_string "9")
+ (const_string "10")))])
+
(define_mode_attr scc_eq_op2 [(SI "rKLI")
(DI "rKJI")])
-(define_insn_and_split "eq<mode>3"
+(define_expand "eq<mode>3"
+ [(parallel [
+ (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+ (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
+ (clobber (match_scratch:GPR 3 "=r"))
+ (clobber (match_scratch:GPR 4 "=r"))])]
+ ""
+{
+ if (TARGET_ISEL && operands[2] != const0_rtx)
+ {
+ emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+})
+
+(define_insn_and_split "*eq<mode>3"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
(clobber (match_scratch:GPR 3 "=r"))
(clobber (match_scratch:GPR 4 "=r"))]
- ""
+ "!(TARGET_ISEL && operands[2] != const0_rtx)"
"#"
- ""
+ "&& 1"
[(set (match_dup 4)
(clz:GPR (match_dup 3)))
(set (match_dup 0)
@@ -12311,16 +12398,34 @@
(const_string "8")
(const_string "12")))])
-(define_insn_and_split "ne<mode>3"
+(define_expand "ne<mode>3"
+ [(parallel [
+ (set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
+ (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
+ (clobber (match_scratch:P 3 "=r"))
+ (clobber (match_scratch:P 4 "=r"))
+ (clobber (reg:P CA_REGNO))])]
+ ""
+{
+ if (TARGET_ISEL && operands[2] != const0_rtx)
+ {
+ emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+})
+
+(define_insn_and_split "*ne<mode>3"
[(set (match_operand:P 0 "gpc_reg_operand" "=r")
(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
(clobber (match_scratch:P 3 "=r"))
(clobber (match_scratch:P 4 "=r"))
(clobber (reg:P CA_REGNO))]
- "!TARGET_ISEL"
+ "!(TARGET_ISEL && operands[2] != const0_rtx)"
"#"
- ""
+ "&& 1"
[(parallel [(set (match_dup 4)
(plus:P (match_dup 3)
(const_int -1)))
@@ -12573,9 +12678,9 @@
(clobber (match_scratch:SI 3 "=r"))
(clobber (match_scratch:SI 4 "=r"))
(clobber (match_scratch:EXTSI 5 "=r"))]
- ""
+ "!TARGET_ISEL"
"#"
- ""
+ "&& 1"
[(set (match_dup 4)
(clz:SI (match_dup 3)))
(set (match_dup 5)