diff mbox

[SH,committed] Simplify some predicates

Message ID 1462074015.31604.95.camel@t-online.de
State New
Headers show

Commit Message

Oleg Endo May 1, 2016, 3:40 a.m. UTC
Hi,

The attached patch mainly simplifies some of the predicates.  There is
no functional change, except the removal of the "mov_nop" pattern,
which resulted in a few +- 4/8 byte code size changes in the CSiBE set,
which look like register allocation choices.  But not sure what the
original purpose or intention of that pattern was...

Tested on sh-elf with

make -k check RUNTESTFLAGS="--target_board=sh-sim\{-m2/-ml,-m2/-mb,
-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}";

Committed as r235687.

Cheers,
Oleg

gcc/ChangeLog:
	* config/sh/predicates.md (any_register_operand, zero_extend_operand,
	logical_reg_operand): Delete.
	(arith_operand, arith_reg_dest, arith_or_int_operand, cmpsi_operand,
	arith_reg_or_0_operand, arith_reg_or_0_or_1_operand, logical_operand,
	logical_and_operand, movsrc_no_disp_mem_operand): Rewrite using
	match_operand and match_test.
	(sh_const_vec, sh_1el_vec): Remove redundant checks.  Declare local
	variables on their first use.  Return bool values.
	* config/sh/sh.h (LOAD_EXTEND_OP): Update comment.
	* config/sh/sh.md (andsi3, iorsi3): Use arith_reg_dest for result and
	arith_reg_operand for input operand.  Remove empty constraints.
	(xorsi3): Delete.
	(*xorsi3_compact): Rename to xorsi3.
	(zero_extend<mode>si2): Use arith_reg_operand for input operand.
	(*zero_extend<mode>si2_disp_mem): Update comment.
	(mov_nop): Delete.

Comments

Segher Boessenkool May 1, 2016, 10:05 p.m. UTC | #1
Hi Oleg,

On Sun, May 01, 2016 at 12:40:15PM +0900, Oleg Endo wrote:
> The attached patch mainly simplifies some of the predicates.  There is
> no functional change, except the removal of the "mov_nop" pattern,
> which resulted in a few +- 4/8 byte code size changes in the CSiBE set,
> which look like register allocation choices.  But not sure what the
> original purpose or intention of that pattern was...

A long time ago (1998) there was

      /* We need something to tag possible REG_LIBCALL notes on to.  */
      if (TARGET_FPU_SINGLE && rtx_equal_function_value_matters
         && GET_CODE (operands[0]) == REG)
       emit_insn (gen_mov_nop (operands[0]));

(in movdf, movsf) but this was removed in 2000 already.


Segher
Oleg Endo May 2, 2016, 12:06 a.m. UTC | #2
On Sun, 2016-05-01 at 17:05 -0500, Segher Boessenkool wrote:

> On Sun, May 01, 2016 at 12:40:15PM +0900, Oleg Endo wrote:
> > The attached patch mainly simplifies some of the predicates.  There
> > is
> > no functional change, except the removal of the "mov_nop" pattern,
> > which resulted in a few +- 4/8 byte code size changes in the CSiBE
> > set,
> > which look like register allocation choices.  But not sure what the
> > original purpose or intention of that pattern was...
> 
> A long time ago (1998) there was
> 
>       /* We need something to tag possible REG_LIBCALL notes on to. 
>  */
>       if (TARGET_FPU_SINGLE && rtx_equal_function_value_matters
>          && GET_CODE (operands[0]) == REG)
>        emit_insn (gen_mov_nop (operands[0]));
> 
> (in movdf, movsf) but this was removed in 2000 already.

Oh good, no worries then.  Thanks for looking it up!

Cheers,
Oleg
diff mbox

Patch

diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index e050213..3e69d88 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -17,29 +17,6 @@ 
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
-;; Like register_operand, but this predicate is defined with
-;; define_special_predicate, not define_predicate.
-(define_special_predicate "any_register_operand"
-  (match_code "subreg,reg")
-{
-  return register_operand (op, mode);
-})
-
-;; Returns 1 if OP is a valid source operand for an arithmetic insn.
-(define_predicate "arith_operand"
-  (match_code "subreg,reg,const_int,truncate")
-{
-  return arith_reg_operand (op, mode) || satisfies_constraint_I08 (op);
-})
-
-;; Like above, but for DImode destinations: forbid paradoxical DImode
-;; subregs, because this would lead to missing sign extensions when
-;; truncating from DImode to SImode.
-(define_predicate "arith_reg_dest"
-  (match_code "subreg,reg")
-{
-  return arith_reg_operand (op, mode);
-})
 
 ;; Returns 1 if OP is a normal arithmetic register.
 (define_predicate "arith_reg_operand"
@@ -82,38 +59,36 @@ 
   return 0;
 })
 
-;; Likewise arith_operand but always permits const_int.
-(define_predicate "arith_or_int_operand"
-  (match_code "subreg,reg,const_int,const_vector")
-{
-  if (arith_operand (op, mode))
-    return 1;
-
-  if (CONST_INT_P (op))
-    return 1;
-
-  return 0;
-})
+;; Like above, but for DImode destinations: forbid paradoxical DImode
+;; subregs, because this would lead to missing sign extensions when
+;; truncating from DImode to SImode.
+(define_predicate "arith_reg_dest"
+  (and (match_code "subreg,reg")
+       (match_operand 0 "arith_reg_operand")))
 
-;; Returns 1 if OP is a valid source operand for a compare insn.
-(define_predicate "arith_reg_or_0_operand"
-  (match_code "subreg,reg,const_int,const_vector")
-{
-  if (arith_reg_operand (op, mode))
-    return 1;
+;; Returns true if OP is a valid source operand for an arithmetic insn.
+(define_predicate "arith_operand"
+  (and (match_code "subreg,reg,const_int,truncate")
+       (ior (match_operand 0 "arith_reg_operand")
+	    (match_test "satisfies_constraint_I08 (op)"))))
 
-  if (satisfies_constraint_Z (op))
-    return 1;
+;; Likewise arith_operand but always permits const_int.
+(define_predicate "arith_or_int_operand"
+  (and (match_code "subreg,reg,const_int,const_vector")
+       (ior (match_operand 0 "arith_operand")
+	    (match_operand 0 "const_int_operand"))))
 
-  return 0;
-})
+;; Returns true if OP is a valid source operand for a compare insn.
+(define_predicate "arith_reg_or_0_operand" 
+  (and (match_code "subreg,reg,const_int,const_vector")
+       (ior (match_operand 0 "arith_reg_operand")
+	    (match_test "satisfies_constraint_Z (op)"))))
 
 ;; Returns true if OP is either a register or constant 0 or constant 1.
 (define_predicate "arith_reg_or_0_or_1_operand"
-  (match_code "subreg,reg,const_int,const_vector")
-{
-  return arith_reg_or_0_operand (op, mode) || satisfies_constraint_M (op);
-})
+  (and (match_code "subreg,reg,const_int,const_vector")
+       (ior (match_operand 0 "arith_reg_or_0_operand")
+	    (match_test "satisfies_constraint_M (op)"))))
 
 ;; Returns true if OP is a suitable constant for the minimum value of a
 ;; clips.b or clips.w insn.
@@ -136,18 +111,6 @@ 
        (ior (match_test "INTVAL (op) == 255")
 	    (match_test "INTVAL (op) == 65535"))))
 
-;; Returns true if OP is an operand that can be used as the first operand in
-;; the cstoresi4 expander pattern.
-(define_predicate "cmpsi_operand"
-  (match_code "subreg,reg,const_int")
-{
-  if (REG_P (op) && REGNO (op) == T_REG
-      && GET_MODE (op) == SImode
-      && TARGET_SH1)
-    return 1;
-  return arith_operand (op, mode);
-})
-
 ;; Returns true if OP is a floating point register that can be used in floating
 ;; point arithmetic operations.
 (define_predicate "fp_arith_reg_operand"
@@ -274,10 +237,6 @@ 
        (ior (match_test "GET_MODE (op) == QImode")
 	    (match_test "GET_MODE (op) == HImode"))))
 
-;; Returns 1 if the operand can be used in a zero_extend.
-(define_predicate "zero_extend_operand"
-  (match_operand 0 "arith_reg_operand"))
-
 ;; Returns 1 if OP can be source of a simple move operation. Same as
 ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
 ;; are subregs of system registers.
@@ -376,12 +335,11 @@ 
   return general_operand (op, mode);
 })
 
-;; Returns 1 if OP is a MEM that does not use displacement addressing.
+;; Returns true if OP is a MEM that does not use displacement addressing.
 (define_predicate "movsrc_no_disp_mem_operand"
-  (match_code "mem")
-{
-  return general_movsrc_operand (op, mode) && satisfies_constraint_Snd (op);
-})
+  (and (match_code "mem")
+       (match_operand 0 "general_movsrc_operand")
+       (match_test "satisfies_constraint_Snd (op)")))
 
 ;; Returns 1 if OP can be a destination of a move. Same as
 ;; general_operand, but no preinc allowed.
@@ -510,12 +468,11 @@ 
 	 && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
 })
 
-;; Returns 1 if OP is a valid source operand for a logical operation.
+;; Returns true if OP is a valid source operand for a logical operation.
 (define_predicate "logical_operand"
-  (match_code "subreg,reg,const_int")
-{
-  return arith_reg_operand (op, mode) || satisfies_constraint_K08 (op);
-})
+  (and (match_code "subreg,reg,const_int")
+       (ior (match_operand 0 "arith_reg_operand")
+	    (match_test "satisfies_constraint_K08 (op)"))))
 
 ;; Returns true if OP is a valid constant source operand for a logical
 ;; operations tst/and/or/xor #imm,r0.
@@ -526,36 +483,23 @@ 
 ;; Like logical_operand but allows additional constant values which can be
 ;; done with zero extensions.  Used for the second operand of and insns.
 (define_predicate "logical_and_operand"
-  (match_code "subreg,reg,const_int")
-{
-  return logical_operand (op, mode) || satisfies_constraint_Jmb (op)
-	 || satisfies_constraint_Jmw (op);
-})
+  (and (match_code "subreg,reg,const_int")
+       (ior (match_operand 0 "logical_operand")
+	    (match_test "satisfies_constraint_Jmb (op)")
+	    (match_test "satisfies_constraint_Jmw (op)"))))
 
 ;; Returns true if OP is a logical operator.
 (define_predicate "logical_operator"
   (match_code "and,ior,xor"))
 
-(define_predicate "logical_reg_operand"
-  (match_code "subreg,reg")
-{
-  return arith_reg_operand (op, mode);
-})
-
 ;; Returns true if OP is a constant vector.
 (define_predicate "sh_const_vec"
   (match_code "const_vector")
 {
-  int i;
-
-  if (GET_CODE (op) != CONST_VECTOR
-      || (GET_MODE (op) != mode && mode != VOIDmode))
-    return 0;
-  i = XVECLEN (op, 0) - 1;
-  for (; i >= 0; i--)
+  for (int i = XVECLEN (op, 0) - 1; i >= 0; i--)
     if (!CONST_INT_P (XVECEXP (op, 0, i)))
-      return 0;
-  return 1;
+      return false;
+  return true;
 })
 
 ;; Determine if OP is a constant vector matching MODE with only one
@@ -564,32 +508,25 @@ 
 (define_predicate "sh_1el_vec"
   (match_code "const_vector")
 {
-  int unit_size;
-  int i, last, least, sign_ix;
-  rtx sign;
-
-  if (GET_CODE (op) != CONST_VECTOR
-      || (GET_MODE (op) != mode && mode != VOIDmode))
-    return 0;
   /* Determine numbers of last and of least significant elements.  */
-  last = XVECLEN (op, 0) - 1;
-  least = TARGET_LITTLE_ENDIAN ? 0 : last;
+  int last = XVECLEN (op, 0) - 1;
+  int least = TARGET_LITTLE_ENDIAN ? 0 : last;
   if (!CONST_INT_P (XVECEXP (op, 0, least)))
-    return 0;
-  sign_ix = least;
+    return false;
+  int sign_ix = least;
   if (GET_MODE_UNIT_SIZE (mode) == 1)
     sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
   if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
-    return 0;
-  unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
-  sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
-	  ? constm1_rtx : const0_rtx);
-  i = XVECLEN (op, 0) - 1;
+    return false;
+  int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
+  rtx sign = INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
+	     ? constm1_rtx : const0_rtx;
+  int i = XVECLEN (op, 0) - 1;
   do
     if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
       return 0;
   while (--i);
-  return 1;
+  return true;
 })
 
 ;; Returns true if OP is a vector which is composed of one element that is
@@ -597,27 +534,21 @@ 
 (define_predicate "sh_rep_vec"
   (match_code "const_vector,parallel")
 {
-  int i;
-  rtx x, y;
-
-  if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
-      || (GET_MODE (op) != mode && mode != VOIDmode))
-    return 0;
-  i = XVECLEN (op, 0) - 2;
-  x = XVECEXP (op, 0, i + 1);
+  int i = XVECLEN (op, 0) - 2;
+  rtx x = XVECEXP (op, 0, i + 1);
   if (GET_MODE_UNIT_SIZE (mode) == 1)
     {
-      y = XVECEXP (op, 0, i);
+      rtx y = XVECEXP (op, 0, i);
       for (i -= 2; i >= 0; i -= 2)
 	if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
 	    || ! rtx_equal_p (XVECEXP (op, 0, i), y))
-	  return 0;
+	  return false;
     }
   else
     for (; i >= 0; i--)
       if (XVECEXP (op, 0, i) != x)
-	return 0;
-  return 1;
+	return false;
+  return true;
 })
 
 ;; Returns true if OP is a valid shift count operand for shift operations.
@@ -745,6 +676,13 @@ 
     }
 })
 
+;; Returns true if OP is an operand that can be used as the first operand in
+;; the cstoresi4 expander pattern.
+(define_predicate "cmpsi_operand"
+  (and (match_code "subreg,reg,const_int")
+       (ior (match_operand:SI 0 "t_reg_operand")
+	    (match_operand 0 "arith_operand"))))
+
 ;; A predicate that returns true if OP is a valid construct around the T bit
 ;; that can be used as an operand for conditional branches.
 (define_predicate "cbranch_treg_value"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 31d75e8..719ebd3 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1523,10 +1523,7 @@  struct sh_args {
 /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
    will either zero-extend or sign-extend.  The value of this macro should
    be the code that says which one of the two operations is implicitly
-   done, UNKNOWN if none.
-   For SHmedia, we can truncate to QImode easier using zero extension.
-   FP registers can load SImode values, but don't implicitly sign-extend
-   them to DImode.  */
+   done, UNKNOWN if none.  */
 #define LOAD_EXTEND_OP(MODE) ((MODE) != SImode ? SIGN_EXTEND : UNKNOWN)
 
 /* Define if loading short immediate values into registers sign extends.  */
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index ad29426..f019d40 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -2823,14 +2823,14 @@ 
 ;; -------------------------------------------------------------------------
 
 (define_expand "andsi3"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-	(and:SI (match_operand:SI 1 "logical_reg_operand" "")
-		(match_operand:SI 2 "logical_and_operand" "")))]
+  [(set (match_operand:SI 0 "arith_reg_dest")
+	(and:SI (match_operand:SI 1 "arith_reg_operand")
+		(match_operand:SI 2 "logical_and_operand")))]
   ""
 {
   /* If it is possible to turn the and insn into a zero extension
      already, redundant zero extensions will be folded, which results
-     in better code.  
+     in better code.
      Ideally the splitter of *andsi_compact would be enough, if redundant
      zero extensions were detected after the combine pass, which does not
      happen at the moment.  */
@@ -2880,11 +2880,9 @@ 
   [(set_attr "type" "arith")])
 
 (define_expand "iorsi3"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-	(ior:SI (match_operand:SI 1 "logical_reg_operand" "")
-		(match_operand:SI 2 "logical_operand" "")))]
-  ""
-  "")
+  [(set (match_operand:SI 0 "arith_reg_dest")
+	(ior:SI (match_operand:SI 1 "arith_reg_operand")
+		(match_operand:SI 2 "logical_operand")))])
 
 (define_insn "*iorsi3_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
@@ -2903,14 +2901,7 @@ 
   "bset	%V2,%0"
   [(set_attr "type" "arith")])
 
-(define_expand "xorsi3"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-	(xor:SI (match_operand:SI 1 "logical_reg_operand" "")
-		(match_operand:SI 2 "logical_operand" "")))]
-  ""
-  "")
-
-(define_insn "*xorsi3_compact"
+(define_insn "xorsi3"
   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
 	(xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
 		(match_operand:SI 2 "logical_operand" "K08,r")))]
@@ -4784,7 +4775,7 @@ 
 
 (define_expand "zero_extend<mode>si2"
   [(set (match_operand:SI 0 "arith_reg_dest")
-	(zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
+	(zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand")))])
 
 (define_insn_and_split "*zero_extend<mode>si2_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
@@ -4819,12 +4810,11 @@ 
 ;; the displacement value to zero.  However, doing so too early results in
 ;; missed opportunities for other optimizations such as post-inc or index
 ;; addressing loads.
-;; We don't allow the zero extending loads to match during RTL expansion
-;; (see zero_extend_operand predicate), as this would pessimize other
-;; optimization opportunities such as bit extractions of unsigned mems,
-;; where the zero extraction is irrelevant.  If the zero extracting mem
-;; loads are emitted early it will be more difficult to change them back
-;; to sign extending loads (which are preferred).
+;; We don't allow the zero extending loads to match during RTL expansion,
+;; as this would pessimize other optimization opportunities such as bit
+;; extractions of unsigned mems, where the zero extraction is irrelevant.
+;; If the zero extracting mem loads are emitted early it will be more
+;; difficult to change them back to sign extending loads (which are preferred).
 ;; The combine pass will also try to combine mem loads and zero extends,
 ;; which is prevented by 'sh_legitimate_combined_insn'.
 (define_insn "*zero_extend<mode>si2_disp_mem"
@@ -6269,13 +6259,6 @@ 
     }
 })
 
-(define_insn "mov_nop"
-  [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
-  "TARGET_SH2E"
-  ""
-  [(set_attr "length" "0")
-   (set_attr "type" "nil")])
-
 (define_expand "reload_insf__frn"
   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
 		   (match_operand:SF 1 "immediate_operand" "FQ"))