rs6000: Improve isel

Message ID 0bbd4c59e27c280692651fc1ec3b7607a40f552c.1507759790.git.segher@kernel.crashing.org
State New
Headers show
Series
  • rs6000: Improve isel
Related show

Commit Message

Segher Boessenkool Oct. 11, 2017, 10:25 p.m.
This removes output_isel.  Instead, the define_insn's now output the
isel instructions directly.

It adds a reg_or_zero operand predicate, too, because the reg_or_cint
predicate is too lax here.  Also use it in the "reversed" variants of
the instructions.

Tested on powerpc64-linux {-m32,-m64}; committing to trunk.


Segher


2017-10-11  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/predicates.md (zero_constant, all_ones_constant):
	Move up in file.
	(reg_or_cint_operand): Fix comment.
	(reg_or_zero_operand): New predicate.
	* config/rs6000/rs6000-protos.h (output_isel): Delete.
	* config/rs6000/rs6000.c (output_isel): Delete.
	* config/rs6000/rs6000.md (isel_signed_<mode>): Use reg_or_zero_operand
	instead of reg_or_cint_operand.  Output instruction directly (not via
	output_isel).
	(isel_unsigned_<mode>): Ditto.
	(*isel_reversed_signed_<mode>): Use reg_or_zero_operand instead of
	gpc_reg_operand.  Add an instruction alternative for this.  Output
	instruction directly.
	(*isel_reversed_unsigned_<mode>): Ditto.

---
 gcc/config/rs6000/predicates.md   | 28 ++++++++++++----------
 gcc/config/rs6000/rs6000-protos.h |  1 -
 gcc/config/rs6000/rs6000.c        | 18 --------------
 gcc/config/rs6000/rs6000.md       | 50 +++++++++++++++++++--------------------
 4 files changed, 40 insertions(+), 57 deletions(-)

Patch

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 237b432..569158f 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -199,6 +199,16 @@  (define_predicate "ca_operand"
   return CA_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if operand is constant zero (scalars and vectors).
+(define_predicate "zero_constant"
+  (and (match_code "const_int,const_double,const_wide_int,const_vector")
+       (match_test "op == CONST0_RTX (mode)")))
+
+;; Return 1 if operand is constant -1 (scalars and vectors).
+(define_predicate "all_ones_constant"
+  (and (match_code "const_int,const_double,const_wide_int,const_vector")
+       (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
+
 ;; Return 1 if op is a signed 5-bit constant integer.
 (define_predicate "s5bit_cint_operand"
   (and (match_code "const_int")
@@ -543,12 +553,16 @@  (define_predicate "reg_or_u_short_operand"
     (match_operand 0 "u_short_cint_operand")
     (match_operand 0 "gpc_reg_operand")))
 
-;; Return 1 if op is any constant integer 
-;; or non-special register.
+;; Return 1 if op is any constant integer or a non-special register.
 (define_predicate "reg_or_cint_operand"
   (ior (match_code "const_int")
        (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if op is constant zero or a non-special register.
+(define_predicate "reg_or_zero_operand"
+  (ior (match_operand 0 "zero_constant")
+       (match_operand 0 "gpc_reg_operand")))
+
 ;; Return 1 if op is a constant integer valid for addition with addis, addi.
 (define_predicate "add_cint_operand"
   (and (match_code "const_int")
@@ -744,16 +758,6 @@  (define_predicate "easy_vector_constant_vsldoi"
 	    (and (match_test "easy_altivec_constant (op, mode)")
 		 (match_test "vspltis_shifted (op) != 0")))))
 
-;; Return 1 if operand is constant zero (scalars and vectors).
-(define_predicate "zero_constant"
-  (and (match_code "const_int,const_double,const_wide_int,const_vector")
-       (match_test "op == CONST0_RTX (mode)")))
-
-;; Return 1 if operand is constant -1 (scalars and vectors).
-(define_predicate "all_ones_constant"
-  (and (match_code "const_int,const_double,const_wide_int,const_vector")
-       (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
-
 ;; Return 1 if operand is a vector int register or is either a vector constant
 ;; of all 0 bits of a vector constant of all 1 bits.
 (define_predicate "vector_int_reg_or_same_bit"
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c6be5b1..db0e692 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -209,7 +209,6 @@  extern void rs6000_emit_epilogue (int);
 extern void rs6000_expand_split_stack_prologue (void);
 extern void rs6000_split_stack_space_check (rtx, rtx);
 extern void rs6000_emit_eh_reg_restore (rtx, rtx);
-extern const char * output_isel (rtx *);
 extern void rs6000_call_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8b014e7..e868482 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -23255,24 +23255,6 @@  rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
   return 1;
 }
 
-const char *
-output_isel (rtx *operands)
-{
-  enum rtx_code code;
-
-  code = GET_CODE (operands[1]);
-
-  if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
-    {
-      gcc_assert (GET_CODE (operands[2]) == REG
-		  && GET_CODE (operands[3]) == REG);
-      PUT_CODE (operands[1], reverse_condition (code));
-      return "isel %0,%3,%2,%j1";
-    }
-
-  return "isel %0,%2,%3,%j1";
-}
-
 void
 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
 {
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e3d0b1b..7e1566a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4938,13 +4938,11 @@  (define_insn "isel_signed_<mode>"
 	 (match_operator 1 "scc_comparison_operator"
 			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
 			  (const_int 0)])
-	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
+	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
 	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+  "isel %0,%2,%3,%j1"
+  [(set_attr "type" "isel")])
 
 (define_insn "isel_unsigned_<mode>"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
@@ -4952,45 +4950,45 @@  (define_insn "isel_unsigned_<mode>"
 	 (match_operator 1 "scc_comparison_operator"
 			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
 			  (const_int 0)])
-	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
+	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
 	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+  "isel %0,%2,%3,%j1"
+  [(set_attr "type" "isel")])
 
 ;; These patterns can be useful for combine; they let combine know that
 ;; isel can handle reversed comparisons so long as the operands are
 ;; registers.
 
 (define_insn "*isel_reversed_signed_<mode>"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
 	(if_then_else:GPR
 	 (match_operator 1 "scc_rev_comparison_operator"
-			 [(match_operand:CC 4 "cc_reg_operand" "y")
+			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
 			  (const_int 0)])
-	 (match_operand:GPR 2 "gpc_reg_operand" "b")
-	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
+	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+{
+  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+  return "isel %0,%3,%2,%j1";
+}
+  [(set_attr "type" "isel")])
 
 (define_insn "*isel_reversed_unsigned_<mode>"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
 	(if_then_else:GPR
 	 (match_operator 1 "scc_rev_comparison_operator"
-			 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
+			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
 			  (const_int 0)])
-	 (match_operand:GPR 2 "gpc_reg_operand" "b")
-	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
+	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+{
+  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+  return "isel %0,%3,%2,%j1";
+}
+  [(set_attr "type" "isel")])
 
 ;; Floating point conditional move
 (define_expand "mov<mode>cc"