diff mbox series

[PATCH-6,rs6000] Split setcc to two insns after reload

Message ID f6229794-f764-449b-b62e-d9f1a330717a@linux.ibm.com
State New
Headers show
Series [PATCH-6,rs6000] Split setcc to two insns after reload | expand

Commit Message

HAO CHEN GUI May 7, 2024, 2:15 a.m. UTC
Hi,
  It's the sixth patch of a series of patches optimizing CC modes on
rs6000.

  This patch splits setcc to two separate insns after reload so that
other insns can be inserted between them. It should increase the
parallelism.

  The rotate_cr pattern still needs the info of the number of cr fields
as the pass pro_and_epilogue might change the cr register.

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

Thanks
Gui Haochen


ChangeLog
rs6000: Split setcc to two insns after reload

This patch splits setcc to two separate insns after reload so that other
insns can be inserted between them.

gcc/
	* config/rs6000/rs6000.md (c_enum unpsec): Add UNSPEC_MFCR and
	UNSPEC_ROTATE_CR.
	(*move_from_cr): New.
	(insn set<mode>_cc): Remove.
	(*rotate_cr): New.
	(insn_and_split set<mode>_cc): New.

patch.diff
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index ccf392b6409..0ad08e3111e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -159,6 +159,8 @@  (define_c_enum "unspec"
    UNSPEC_XXSPLTIW_CONST
    UNSPEC_FMAX
    UNSPEC_FMIN
+   UNSPEC_MFCR
+   UNSPEC_ROTATE_CR
   ])

 ;;
@@ -12744,26 +12746,51 @@  (define_insn_and_split "*cmp<IBM128:mode>_internal2"
     }
 })
 
-;; Now we have the scc insns.  We can do some combinations because of the
-;; way the machine works.
-;;
-;; Note that this is probably faster if we can put an insn between the
-;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
-;; cases the insns below which don't use an intermediate CR field will
-;; be used instead.
-(define_insn "set<mode>_cc"
+
+(define_insn "*move_from_cr"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
-	(match_operator:GPR 1 "scc_comparison_operator"
-			    [(match_operand 2 "cc_reg_operand" "y")
-			     (const_int 0)]))]
+	(unspec:GPR [(match_operand 1 "cc_reg_operand" "y")]
+		    UNSPEC_MFCR))]
   ""
-  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
+  "mfcr %0%Q1"
   [(set (attr "type")
      (cond [(match_test "TARGET_MFCRF")
 		(const_string "mfcrf")
 	   ]
-	(const_string "mfcr")))
-   (set_attr "length" "8")])
+	(const_string "mfcr")))])
+
+;; Split the insn after reload so that other insns can be inserted
+;; between mfcr and rlinm.
+(define_insn_and_split "set<mode>_cc"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(match_operator:GPR 1 "scc_comparison_operator"
+			    [(match_operand 2 "cc_reg_operand" "y")
+			     (const_int 0)]))]
+  "!TARGET_POWER10
+   || (GET_MODE (operands[2]) != CCmode
+       && GET_MODE (operands[2]) != CCUNSmode)"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+	(unspec:GPR [(match_dup 2)]
+		    UNSPEC_MFCR))
+   (set (match_dup 0)
+	(unspec:GPR [(match_dup 0)
+		     (match_dup 1)]
+		    UNSPEC_ROTATE_CR))]
+  ""
+  [(set_attr "length" "8")])
+
+(define_insn "*rotate_cr"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(unspec:GPR [(match_operand:GPR 3 "gpc_reg_operand" "r")
+		     (match_operator:GPR 1 "scc_comparison_operator"
+					[(match_operand 2 "cc_reg_operand" "y")
+					 (const_int 0)])]
+		    UNSPEC_ROTATE_CR))]
+  ""
+  "rlwinm %0,%3,%J1,1"
+)

 (define_insn_and_split "*set<GPR:mode><CCANY:mode>_rev"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")