public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RS6000 0/7] rtx_cost patches
@ 2015-06-24  0:50 Alan Modra
  2015-06-24  0:51 ` [RS6000 1/7] Hide insns not needing to be public Alan Modra
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This series fixes a number of problems in the rs6000 backend, building
on top of https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01396.html.
Patch 5,6,7 really need the fixed rtx_cost function to be applied
first, the others are independent of that change (if you're willing to
allow a failing testcase).

Bootstrapped and regression tested powerpc64le-linux and
powerpc64-linux.

Alan Modra (7):
  [RS6000] Hide insns not needing to be public
  [RS6000] Tidy rotates
  [RS6000] rtx_costs for ROTATE/ASHIFT inside AND
  [RS6000] rldic in rotate and mask patterns
  [RS6000] Split mask64_2_operand rotates early
  [RS6000] Cost multi-insn constants
  [RS6000] Address cost

 gcc/config/rs6000/predicates.md            |  23 +--
 gcc/config/rs6000/rs6000.c                 | 151 +++++++++++------
 gcc/config/rs6000/rs6000.md                | 249 +++++++++++------------------
 gcc/testsuite/gcc.target/powerpc/rotmask.c |   8 +
 4 files changed, 208 insertions(+), 223 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/rotmask.c

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 1/7] Hide insns not needing to be public
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
@ 2015-06-24  0:51 ` Alan Modra
  2015-06-25  3:12   ` David Edelsohn
  2015-06-24  0:52 ` [RS6000 2/7] Tidy rotates Alan Modra
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

	* config/rs6000/rs6000.md (addsi3_high, bswaphi2_internal,
	ashldi3_internal5, ashldi3_internal8): Prefix with '*'.

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6a14ee8..243a151 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1515,7 +1515,7 @@
    addis %0,%1,%v2"
   [(set_attr "type" "add")])
 
-(define_insn "addsi3_high"
+(define_insn "*addsi3_high"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
                  (high:SI (match_operand 2 "" ""))))]
@@ -2173,7 +2173,7 @@
     operands[1] = force_reg (HImode, operands[1]);
 })
 
-(define_insn "bswaphi2_internal"
+(define_insn "*bswaphi2_internal"
   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
 	(bswap:HI
 	 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
@@ -5873,7 +5873,7 @@
   "rldic %0,%1,%H2,%W3"
   [(set_attr "type" "shift")])
 
-(define_insn "ashldi3_internal5"
+(define_insn "*ashldi3_internal5"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
@@ -5952,7 +5952,7 @@
   "rldicr %0,%1,%H2,%S3"
   [(set_attr "type" "shift")])
 
-(define_insn "ashldi3_internal8"
+(define_insn "*ashldi3_internal8"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 2/7] Tidy rotates
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
  2015-06-24  0:51 ` [RS6000 1/7] Hide insns not needing to be public Alan Modra
@ 2015-06-24  0:52 ` Alan Modra
  2015-06-24  0:53 ` [RS6000 3/7] rtx_costs for ROTATE/ASHIFT inside AND Alan Modra
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Besides various tidies this fixes the wrong mode used for a number of
rotate pattern shift counts.  Since every other shift and rotate
pattern uses SImode for the shift count, these combine patterns won't
match anything.  The testcase exercises one of these rotate patterns.
It requires rtx_cost const_int mode fix to pass, since without that
the combine pattern is not seen as profitable.

See notes interspersed with changelog.

gcc/
	* config/rs6000/predicates.md (logical_const_operand): Correct
	comment.
	(mask_operand): Note failure to exclude masks only valid in 64-bit
	insns when used in 'T' constraint.
	* config/rs6000/rs6000.md (and<mode>3_imm_dot): Comment.
	(and<mode>3_imm_dot2): Comment.
	(and<mode>3_mask): Use 'n' constraint rather than 'T'.
May as well use 'n' as all we need is something to mop up the leftover
cases that match the operand predicate but don't match 'S'.  'T' is
ineffective as a constraint anyway.  You can't put 'T' before 'S' as
per the comment added to mask_operand.
	(and<mode>3_mask_dot): Likewise.  Remove redundant insn predicate test.
	(and<mode>3_mask_dot2): Likewise.
	(andsi3_internal0_nomc): Delete.
Covered by and<mode>3_mask and bool<mode>3, so redundant.
	(rotldi3_internal4): Use SImode for shift count.
	(rotldi3_internal5, +split): Likewise.
	(rotldi3_internal6, +split): Likewise.
	(ashldi3_internal7): Don't repeat operand predicate test covered
	by insn predicate.
includes_rldicr_lshift_p constrains the operand to a subset of
mask64_operand.
	(ashldi3_internal8, +split): Likewise.
	(ashldi3_internal9, +split): Likewise.
	* config/rs6000/rs6000.c (includes_rldic_lshift_p): Remove redundant
	CONST_INT test.  Don't reject all 1's.
All 1's is supported by the machine instructions and doesn't cause a
problem in print_operand.
	(includes_rldicr_lshift_p): Likewise.
gcc/testsuite/
    	* gcc.target/powerpc/rotmask.c: New.

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index fd293ab..c408b0f 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -726,7 +726,7 @@
 		    && !satisfies_constraint_L (op)")))
 
 ;; Return 1 if the operand is a constant that can be used as the operand
-;; of an OR or XOR.
+;; of an AND, OR or XOR.
 (define_predicate "logical_const_operand"
   (match_code "const_int")
 {
@@ -764,7 +764,11 @@
 
   if (TARGET_POWERPC64)
     {
-      /* Fail if the mask is not 32-bit.  */
+      /* Fail if the mask is not 32-bit.  Note: If constraints are
+	 implemented using mask_operand then they will never fail this
+	 test.  const_ints are VOIDmode, which is what is seen here
+	 when called from a constraint.  When called as a predicate,
+	 the match_operand mode is seen.  */
       if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0)
 	return 0;
 
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index c7c24db..5f42192 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -16444,36 +16444,30 @@ includes_rshift_p (rtx shiftop, rtx andop)
 int
 includes_rldic_lshift_p (rtx shiftop, rtx andop)
 {
-  if (GET_CODE (andop) == CONST_INT)
-    {
-      unsigned HOST_WIDE_INT c, lsb, shift_mask;
+  unsigned HOST_WIDE_INT c, lsb, shift_mask;
 
-      c = INTVAL (andop);
-      if (c == 0 || c == HOST_WIDE_INT_M1U)
-	return 0;
+  c = INTVAL (andop);
+  if (c == 0)
+    return 0;
 
-      shift_mask = HOST_WIDE_INT_M1U;
-      shift_mask <<= INTVAL (shiftop);
+  shift_mask = HOST_WIDE_INT_M1U << INTVAL (shiftop);
 
-      /* Find the least significant one bit.  */
-      lsb = c & -c;
+  /* Find the least significant one bit.  */
+  lsb = c & -c;
 
-      /* It must coincide with the LSB of the shift mask.  */
-      if (-lsb != shift_mask)
-	return 0;
+  /* It must coincide with the LSB of the shift mask.  */
+  if (-lsb != shift_mask)
+    return 0;
 
-      /* Invert to look for the next transition (if any).  */
-      c = ~c;
+  /* Invert to look for the next transition (if any).  */
+  c = ~c;
 
-      /* Remove the low group of ones (originally low group of zeros).  */
-      c &= -lsb;
+  /* Remove the low group of ones (originally low group of zeros).  */
+  c &= -lsb;
 
-      /* Again find the lsb, and check we have all 1's above.  */
-      lsb = c & -c;
-      return c == -lsb;
-    }
-  else
-    return 0;
+  /* Again find the lsb, and check we have all 1's above.  */
+  lsb = c & -c;
+  return c == -lsb;
 }
 
 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
@@ -16483,27 +16477,21 @@ includes_rldic_lshift_p (rtx shiftop, rtx andop)
 int
 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
 {
-  if (GET_CODE (andop) == CONST_INT)
-    {
-      unsigned HOST_WIDE_INT c, lsb, shift_mask;
+  unsigned HOST_WIDE_INT c, lsb, shift_mask;
 
-      shift_mask = HOST_WIDE_INT_M1U;
-      shift_mask <<= INTVAL (shiftop);
-      c = INTVAL (andop);
+  shift_mask = HOST_WIDE_INT_M1U << INTVAL (shiftop);
+  c = INTVAL (andop);
 
-      /* Find the least significant one bit.  */
-      lsb = c & -c;
-
-      /* It must be covered by the shift mask.
-	 This test also rejects c == 0.  */
-      if ((lsb & shift_mask) == 0)
-	return 0;
+  /* Find the least significant one bit.  */
+  lsb = c & -c;
 
-      /* Check we have all 1's above the transition, and reject all 1's.  */
-      return c == -lsb && lsb != 1;
-    }
-  else
+  /* It must be covered by the shift mask.
+     This test also rejects c == 0.  */
+  if ((lsb & shift_mask) == 0)
     return 0;
+
+  /* Check we have all 1's above the transition.  */
+  return c == -lsb;
 }
 
 /* Return 1 if operands will generate a valid arguments to rlwimi
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 243a151..f28d48e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2921,6 +2921,9 @@
   [(set_attr "type" "logical")
    (set_attr "dot" "yes")])
 
+;; Differs from and<mode>3_imm_mask_dot in that if cr0 is not allocated
+;; the splitter will need to trash cr0.  So choose and<mode>3_imm_mask_dot
+;; if possible.
 (define_insn_and_split "*and<mode>3_imm_dot"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
@@ -2947,6 +2950,9 @@
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
+;; Differs from and<mode>3_imm_mask_dot2 in that if cr0 is not allocated
+;; the splitter will need to trash cr0.  So choose and<mode>3_imm_mask_dot2
+;; if possible.
 (define_insn_and_split "*and<mode>3_imm_dot2"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
@@ -3029,7 +3035,7 @@
 (define_insn "*and<mode>3_mask"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
 	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
-		 (match_operand:GPR 2 "any_mask_operand" "S,T")))]
+		 (match_operand:GPR 2 "any_mask_operand" "S,n")))]
   ""
   "@
    rldic%B2 %0,%1,0,%S2
@@ -3039,12 +3045,11 @@
 (define_insn_and_split "*and<mode>3_mask_dot"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
-			     (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
+			     (match_operand:GPR 2 "any_mask_operand" "S,n,S,n"))
 		    (const_int 0)))
    (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
-   && rs6000_gen_cell_microcode
-   && !logical_const_operand (operands[2], <MODE>mode)"
+   && rs6000_gen_cell_microcode"
   "@
    rldic%B2. %0,%1,0,%S2
    rlwinm. %0,%1,0,%m2,%M2
@@ -3065,14 +3070,13 @@
 (define_insn_and_split "*and<mode>3_mask_dot2"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
-			     (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
+			     (match_operand:GPR 2 "any_mask_operand" "S,n,S,n"))
 		    (const_int 0)))
    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
 	(and:GPR (match_dup 1)
 		 (match_dup 2)))]
   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
-   && rs6000_gen_cell_microcode
-   && !logical_const_operand (operands[2], <MODE>mode)"
+   && rs6000_gen_cell_microcode"
   "@
    rldic%B2. %0,%1,0,%S2
    rlwinm. %0,%1,0,%m2,%M2
@@ -3091,18 +3095,6 @@
    (set_attr "length" "4,4,8,8")])
 
 
-
-(define_insn "andsi3_internal0_nomc"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-        (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
-                (match_operand:SI 2 "and_operand" "?r,T")))]
-  "!rs6000_gen_cell_microcode"
-  "@
-   and %0,%1,%2
-   rlwinm %0,%1,0,%m2,%M2"
-  [(set_attr "type" "logical,shift")])
-
-
 ;; Handle the PowerPC64 rlwinm corner case
 
 (define_insn_and_split "*andsi3_internal6"
@@ -5786,7 +5778,7 @@
 (define_insn "*rotldi3_internal4"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-			   (match_operand:DI 2 "reg_or_cint_operand" "rn"))
+			   (match_operand:SI 2 "reg_or_cint_operand" "rn"))
 		(match_operand:DI 3 "mask64_operand" "n")))]
   "TARGET_POWERPC64"
   "rld%I2c%B3 %0,%1,%H2,%S3"
@@ -5797,7 +5789,7 @@
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				(match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
+				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
 		     (match_operand:DI 3 "mask64_operand" "n,n"))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 "=r,r"))]
@@ -5814,7 +5806,7 @@
   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				(match_operand:DI 2 "reg_or_cint_operand" ""))
+				(match_operand:SI 2 "reg_or_cint_operand" ""))
 		     (match_operand:DI 3 "mask64_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
@@ -5832,7 +5824,7 @@
   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-				(match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
+				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
 		     (match_operand:DI 3 "mask64_operand" "n,n"))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
@@ -5850,7 +5842,7 @@
   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
-				(match_operand:DI 2 "reg_or_cint_operand" ""))
+				(match_operand:SI 2 "reg_or_cint_operand" ""))
 		     (match_operand:DI 3 "mask64_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -5947,7 +5939,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
 			   (match_operand:SI 2 "const_int_operand" "i"))
-		(match_operand:DI 3 "mask64_operand" "n")))]
+		(match_operand:DI 3 "const_int_operand" "n")))]
   "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
   "rldicr %0,%1,%H2,%S3"
   [(set_attr "type" "shift")])
@@ -5957,7 +5949,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 			    (match_operand:SI 2 "const_int_operand" "i,i"))
-		 (match_operand:DI 3 "mask64_operand" "n,n"))
+		 (match_operand:DI 3 "const_int_operand" "n,n"))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 "=r,r"))]
   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
@@ -5973,7 +5965,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:DI 3 "mask64_operand" ""))
+		 (match_operand:DI 3 "const_int_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed
@@ -5991,7 +5983,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 			    (match_operand:SI 2 "const_int_operand" "i,i"))
-		    (match_operand:DI 3 "mask64_operand" "n,n"))
+		    (match_operand:DI 3 "const_int_operand" "n,n"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
@@ -6008,7 +6000,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:DI 3 "mask64_operand" ""))
+		 (match_operand:DI 3 "const_int_operand" ""))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
diff --git a/gcc/testsuite/gcc.target/powerpc/rotmask.c b/gcc/testsuite/gcc.target/powerpc/rotmask.c
new file mode 100644
index 0000000..4d1b917
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/rotmask.c
@@ -0,0 +1,8 @@
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "rotldi" } } */
+
+unsigned long f (unsigned long x)
+{
+  return ((x << 1) | (x >> 63)) & 0xffffffff;
+}

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 3/7] rtx_costs for ROTATE/ASHIFT inside AND
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
  2015-06-24  0:51 ` [RS6000 1/7] Hide insns not needing to be public Alan Modra
  2015-06-24  0:52 ` [RS6000 2/7] Tidy rotates Alan Modra
@ 2015-06-24  0:53 ` Alan Modra
  2015-06-24  0:54 ` [RS6000 4/7] rldic in rotate and mask patterns Alan Modra
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:53 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

The odd patterns for rldic and rldicr that require an insn predicate
that examines both the shift count and the mask, must be costed at a
point where both count and mask are available.

Also tidies the mode passed to a couple of predicates.

	* config/rs6000/rs6000.c (rs6000_rtx_costs): Pass mode to
	reg_or_add_cint_operand and reg_or_sub_cint_operand.  Handle
	rldic and rldicr insns under AND.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5f42192..a4a72f3 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -30681,9 +30681,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       else if ((outer_code == PLUS
-		&& reg_or_add_cint_operand (x, VOIDmode))
+		&& reg_or_add_cint_operand (x, mode))
 	       || (outer_code == MINUS
-		   && reg_or_sub_cint_operand (x, VOIDmode))
+		   && reg_or_sub_cint_operand (x, mode))
 	       || ((outer_code == SET
 		    || outer_code == IOR
 		    || outer_code == XOR)
@@ -30801,7 +30801,6 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	}
       /* FALLTHRU */
 
-    case AND:
     case CLZ:
     case IOR:
     case XOR:
@@ -30809,6 +30808,24 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
       *total = COSTS_N_INSNS (1);
       return false;
 
+    case AND:
+      *total = COSTS_N_INSNS (1);
+      if (mode == DImode)
+	{
+	  rtx op0 = XEXP (x, 0);
+	  if ((GET_CODE (op0) == ASHIFT || GET_CODE (op0) == ROTATE)
+	      && CONST_INT_P (XEXP (op0, 1)))
+	    {
+	      rtx op1 = XEXP (x, 1);
+	      if (includes_rldic_lshift_p (XEXP (op0, 1), op1))
+		return true;
+	      if (GET_CODE (op0) == ASHIFT
+		  && includes_rldicr_lshift_p (XEXP (op0, 1), op1))
+		return true;
+	    }
+	}
+      return false;
+
     case ASHIFT:
     case ASHIFTRT:
     case LSHIFTRT:

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 5/7] Split mask64_2_operand rotates early
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
                   ` (3 preceding siblings ...)
  2015-06-24  0:54 ` [RS6000 4/7] rldic in rotate and mask patterns Alan Modra
@ 2015-06-24  0:54 ` Alan Modra
  2015-06-24  0:55 ` [RS6000 6/7] Cost multi-insn constants Alan Modra
  2015-06-24  1:02 ` [RS6000 7/7] Address cost Alan Modra
  6 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This gets rid of some patterns I added a long time ago for ANDs that
can be performed by two rotate and mask insns.

	* config/rs6000/preficates.md (and64_2_operand): Delete.
	(and_2rld_operand): Delete.
	* config/rs6000/rs6000.md (and<mode>3): Expand two insn
	mask_operand_wrap and mask64_2_operand AND/ROTATE.
	(andsi3_internal6): Delete.
	(anddi3_2rld, anddi3_2rld_dot, anddi3_2rld_dot2): Delete.
	* config/rs6000/rs6000.md (rs6000_rtx_costs): Cost AND constants
	matching mask64_2_operand.

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index c408b0f..44eca2a 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -902,14 +902,6 @@
        (and (match_test "TARGET_POWERPC64 && mode == DImode")
 	    (match_operand 0 "mask64_operand"))))
 
-;; Like and_operand, but also match constants that can be implemented
-;; with two rldicl or rldicr insns.
-(define_predicate "and64_2_operand"
-  (ior (match_operand 0 "mask64_2_operand")
-       (if_then_else (match_test "fixed_regs[CR0_REGNO]")
-	 (match_operand 0 "gpc_reg_operand")
-	 (match_operand 0 "logical_operand"))))
-
 ;; Return 1 if the operand is either a non-special register or a
 ;; constant that can be used as the operand of a logical AND.
 (define_predicate "and_operand"
@@ -920,13 +912,6 @@
 	 (match_operand 0 "gpc_reg_operand")
 	 (match_operand 0 "logical_operand"))))
 
-;; Return 1 if the operand is a constant that can be used as the operand
-;; of a logical AND, implemented with two rld* insns, and it cannot be done
-;; using just one insn.
-(define_predicate "and_2rld_operand"
-  (and (match_operand 0 "and64_2_operand")
-       (not (match_operand 0 "and_operand"))))
-
 ;; Return 1 if the operand is either a logical operand or a short cint operand.
 (define_predicate "scc_eq_operand"
   (ior (match_operand 0 "logical_operand")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a4a72f3..941ad02 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -30688,7 +30688,10 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 		    || outer_code == IOR
 		    || outer_code == XOR)
 		   && (INTVAL (x)
-		       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
+		       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
+	       || (outer_code == AND
+		   && mode == DImode
+		   && mask64_2_operand (x, mode)))
 	{
 	  *total = COSTS_N_INSNS (1);
 	  return true;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dafb04f..420441b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2906,9 +2906,53 @@
 	operands[2] = force_reg (<MODE>mode, operands[2]);
     }
 
-  if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
-      || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
-    operands[2] = force_reg (<MODE>mode, operands[2]);
+  if (!and_operand (operands[2], <MODE>mode))
+    {
+      if (TARGET_POWERPC64
+	  && <MODE>mode == SImode && mask_operand_wrap (operands[2], SImode))
+	{
+	  /* Handle the PowerPC64 rlwinm corner case.  */
+	  rtx out[3];
+	  rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
+	  int mb = extract_MB (operands[2]);
+	  int me = extract_ME (operands[2]);
+	  out[0] = GEN_INT (me + 1);
+	  out[1] = GEN_INT (~((unsigned HOST_WIDE_INT) -1 << (33 + me - mb)));
+	  out[2] = GEN_INT (32 - (me + 1));
+	  emit_insn (gen_rtx_SET (tmp,
+				  gen_rtx_AND (SImode,
+					       gen_rtx_ROTATE (SImode,
+							       operands[1],
+							       out[0]),
+					       out[1])));
+	  emit_insn (gen_rtx_SET (operands[0],
+				  gen_rtx_ROTATE (SImode,
+						  tmp,
+						  out[2])));
+	  DONE;
+	}
+      if (TARGET_POWERPC64
+	  && <MODE>mode == DImode && mask64_2_operand (operands[2], DImode))
+	{
+	  rtx out[4];
+	  rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[0];
+	  build_mask64_2_operands (operands[2], out);
+	  emit_insn (gen_rtx_SET (tmp,
+				  gen_rtx_AND (DImode,
+					       gen_rtx_ROTATE (DImode,
+							       operands[1],
+							       out[0]),
+					       out[1])));
+	  emit_insn (gen_rtx_SET (operands[0],
+				  gen_rtx_AND (DImode,
+					       gen_rtx_ROTATE (DImode,
+							       tmp,
+							       out[2]),
+					       out[3])));
+	  DONE;
+	}
+      operands[2] = force_reg (<MODE>mode, operands[2]);
+    }
 })
 
 
@@ -3097,31 +3141,6 @@
    (set_attr "length" "4,4,8,8")])
 
 
-;; Handle the PowerPC64 rlwinm corner case
-
-(define_insn_and_split "*andsi3_internal6"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		(match_operand:SI 2 "mask_operand_wrap" "i")))]
-  "TARGET_POWERPC64"
-  "#"
-  "TARGET_POWERPC64"
-  [(set (match_dup 0)
-	(and:SI (rotate:SI (match_dup 1) (match_dup 3))
-		(match_dup 4)))
-   (set (match_dup 0)
-	(rotate:SI (match_dup 0) (match_dup 5)))]
-  "
-{
-  int mb = extract_MB (operands[2]);
-  int me = extract_ME (operands[2]);
-  operands[3] = GEN_INT (me + 1);
-  operands[5] = GEN_INT (32 - (me + 1));
-  operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
-}"
-  [(set_attr "length" "8")])
-
-
 (define_expand "<code><mode>3"
   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
 	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
@@ -6017,87 +6036,6 @@
 		    (const_int 0)))]
   "")
 
-
-(define_insn_and_split "*anddi3_2rld"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-		(match_operand:DI 2 "and_2rld_operand" "n")))]
-  "TARGET_POWERPC64"
-  "#"
-  ""
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 0)
-			   (match_dup 6))
-		(match_dup 7)))]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "length" "8")])
-
-(define_insn_and_split "*anddi3_2rld_dot"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			    (match_operand:DI 2 "and_2rld_operand" "n,n"))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 0 "=r,r"))]
-  "TARGET_64BIT && rs6000_gen_cell_microcode"
-  "@
-   #
-   #"
-  "&& reload_completed"
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (parallel [(set (match_dup 3)
-		   (compare:CC (and:DI (rotate:DI (match_dup 0)
-						  (match_dup 6))
-				       (match_dup 7))
-			       (const_int 0)))
-	      (clobber (match_dup 0))])]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "type" "two")
-   (set_attr "dot" "yes")
-   (set_attr "length" "8,12")])
-
-(define_insn_and_split "*anddi3_2rld_dot2"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			    (match_operand:DI 2 "and_2rld_operand" "n,n"))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(and:DI (match_dup 1)
-		(match_dup 2)))]
-  "TARGET_64BIT && rs6000_gen_cell_microcode"
-  "@
-   #
-   #"
-  "&& reload_completed"
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (parallel [(set (match_dup 3)
-		   (compare:CC (and:DI (rotate:DI (match_dup 0)
-						  (match_dup 6))
-				       (match_dup 7))
-			       (const_int 0)))
-	      (set (match_dup 0)
-		   (and:DI (rotate:DI (match_dup 0)
-				      (match_dup 6))
-			   (match_dup 7)))])]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "type" "two")
-   (set_attr "dot" "yes")
-   (set_attr "length" "8,12")])
 \f
 ;; 128-bit logical operations expanders
 

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 4/7] rldic in rotate and mask patterns
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
                   ` (2 preceding siblings ...)
  2015-06-24  0:53 ` [RS6000 3/7] rtx_costs for ROTATE/ASHIFT inside AND Alan Modra
@ 2015-06-24  0:54 ` Alan Modra
  2015-06-24  0:54 ` [RS6000 5/7] Split mask64_2_operand rotates early Alan Modra
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

rldic can support ROTATE as well as ASHIFT inside an AND, provided the
AND mask has exactly the shift count low zeros.  The added rotate
patterns are needed to support the next patch that removes the
mask64_2_operand patterns, and may be generally useful too.  Note that
the costing for the ROTATEs was handled by the last patch.

	* config/rs6000/rs6000.md (rotshift): New code iterator.
	(rldic_<code>_1, rldic_<code>_2, rldic_<code>_3, +splits): Rename
	from ashldi3_internal4..6.  Use rotshift to support both rotate
	and ashift.

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f28d48e..dafb04f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -463,6 +463,8 @@
 ; Logical operators.
 (define_code_iterator iorxor [ior xor])
 
+(define_code_iterator rotshift [rotate ashift])
+
 ; Signed/unsigned variants of ops.
 (define_code_iterator any_extend [sign_extend zero_extend])
 (define_code_attr u [(sign_extend "") (zero_extend "u")])
@@ -5856,20 +5858,20 @@
   "")
 
 
-(define_insn "*ashldi3_internal4"
+(define_insn "*rldic_<code>_1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-			   (match_operand:SI 2 "const_int_operand" "i"))
+	(and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+			     (match_operand:SI 2 "const_int_operand" "i"))
 		(match_operand:DI 3 "const_int_operand" "n")))]
   "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
   "rldic %0,%1,%H2,%W3"
   [(set_attr "type" "shift")])
 
-(define_insn "*ashldi3_internal5"
+(define_insn "*rldic_<code>_2"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC
-	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-			    (match_operand:SI 2 "const_int_operand" "i,i"))
+	 (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+			      (match_operand:SI 2 "const_int_operand" "i,i"))
 		 (match_operand:DI 3 "const_int_operand" "n,n"))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 "=r,r"))]
@@ -5884,30 +5886,30 @@
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC
-	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
-			    (match_operand:SI 2 "const_int_operand" ""))
+	 (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+			      (match_operand:SI 2 "const_int_operand" ""))
 		 (match_operand:DI 3 "const_int_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed
    && includes_rldic_lshift_p (operands[2], operands[3])"
   [(set (match_dup 4)
-	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
+	(and:DI (rotshift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
    (set (match_dup 0)
 	(compare:CC (match_dup 4)
 		    (const_int 0)))]
   "")
 
-(define_insn "*ashldi3_internal6"
+(define_insn "*rldic_<code>_3"
   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
 	(compare:CC
-	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-			    (match_operand:SI 2 "const_int_operand" "i,i"))
+	 (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+			      (match_operand:SI 2 "const_int_operand" "i,i"))
 		    (match_operand:DI 3 "const_int_operand" "n,n"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+	(and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
   "@
    rldic. %0,%1,%H2,%W3
@@ -5919,22 +5921,23 @@
 (define_split
   [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC
-	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
-			    (match_operand:SI 2 "const_int_operand" ""))
+	 (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+			      (match_operand:SI 2 "const_int_operand" ""))
 		 (match_operand:DI 3 "const_int_operand" ""))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+	(and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_POWERPC64 && reload_completed
    && includes_rldic_lshift_p (operands[2], operands[3])"
   [(set (match_dup 0)
-	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
+	(and:DI (rotshift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
    (set (match_dup 4)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
   "")
 
+
 (define_insn "*ashldi3_internal7"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 6/7] Cost multi-insn constants
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
                   ` (4 preceding siblings ...)
  2015-06-24  0:54 ` [RS6000 5/7] Split mask64_2_operand rotates early Alan Modra
@ 2015-06-24  0:55 ` Alan Modra
  2015-06-24  1:02 ` [RS6000 7/7] Address cost Alan Modra
  6 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2015-06-24  0:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

This small patch considerably improves code generated for large
constants in 64-bit code, teaching gcc that it is better to load a
constant from memory than to generate a sequence of five dependent
instructions.  Note that we already do this at expand time for plain
moves.  This change affects constants inside other RTL operations,
ie. those generated by various optimizations.

I would like to fix rtlanal.c:rtx_cost to not cost register moves at
zero, but that probably disrupts many targets.  See the comment.

	* config/rs6000/rs6000.c (rs6000_rtx_costs): Cost multi-insn
	CONST_INTs.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 941ad02..0218d0f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -30700,6 +30700,26 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
+      /* Subtract one insn here for consistency with the above code
+	 that returns one less than the actual number of insns for
+	 SETs.  This is because (set (reg1) (reg2)) is costed at zero
+	 by rtlanal.c:rtx_cost.  If we cost (set (reg) (const_int 0))
+	 at greater than the register move cost, then a call like
+	 foo (0, 0) will be implemented as li "r3,0; mr r4,r3; bl foo"
+	 rather than "li r3,0; li r4,0; bl foo".  Don't subtract one
+	 for other than SETs, because other operations will require
+	 the constant to be loaded to a register before performing
+	 the operation.
+	 FIXME: A call like foo (x - 1, x - 1) results in
+	 "addi r3,rx,-1; mr r4,r3; bl foo" rather than the better
+	 "addi r3,rx,-1; addi r4,rx,-1; bl foo" because rtx_cost
+	 returns zero for register moves.  This cannot be fixed by
+	 reducing the cost of PLUS and other arithmetic/logic codes
+	 to zero.  */
+      *total = COSTS_N_INSNS (num_insns_constant (x, mode)
+			      - (outer_code == SET ? 1 : 0));
+      return true;
+
     case CONST:
     case HIGH:
     case SYMBOL_REF:

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RS6000 7/7] Address cost
  2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
                   ` (5 preceding siblings ...)
  2015-06-24  0:55 ` [RS6000 6/7] Cost multi-insn constants Alan Modra
@ 2015-06-24  1:02 ` Alan Modra
  2015-07-08 16:53   ` Segher Boessenkool
  6 siblings, 1 reply; 10+ messages in thread
From: Alan Modra @ 2015-06-24  1:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

The rs6000 backend currently uses an address cost of zero.  This made
sense prior to -mcmodel=medium/large, but medium/large model addresses
before splitting are really two insns.  So we should cost them one
more than other addresses.

This patch also adjusts rs6000_rtx_cost to use the new address cost,
and puts CONST, HIGH and SYMBOL_REF in their own case since they are
handling memory addresses, not MEMs.

	* config/rs6000/rs6000.c (rs6000_address_cost): New function.
	(TARGET_ADDRESS_COST): Define as rs6000_address_cost.
	(rs6000_rtx_costs): Use rs6000_address_cost for MEM.  Do not
	cost CONST, HIGH and SYMBOL_REF as for MEM.  Handle LO_SUM.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0218d0f..96c23ca 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1117,6 +1117,7 @@ static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
 static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
 static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
 static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static int rs6000_address_cost (rtx, machine_mode, addr_space_t, bool);
 static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t,
 				      bool);
 static int rs6000_debug_adjust_cost (rtx_insn *, rtx, rtx_insn *, int);
@@ -1523,7 +1524,7 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS rs6000_rtx_costs
 #undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
+#define TARGET_ADDRESS_COST rs6000_address_cost
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
@@ -30720,14 +30721,20 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 			      - (outer_code == SET ? 1 : 0));
       return true;
 
-    case CONST:
-    case HIGH:
-    case SYMBOL_REF:
     case MEM:
       /* When optimizing for size, MEM should be slightly more expensive
 	 than generating address, e.g., (plus (reg) (const)).
 	 L1 cache latency is about two instructions.  */
       *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
+      *total += COSTS_N_INSNS (rs6000_address_cost (XEXP (x, 0), mode,
+						    0, speed));
+      return true;
+
+    case CONST:
+    case HIGH:
+    case LO_SUM:
+    case SYMBOL_REF:
+      *total = COSTS_N_INSNS (1);
       return true;
 
     case LABEL_REF:
@@ -31009,6 +31016,26 @@ rs6000_debug_rtx_costs (rtx x, machine_mode mode, int outer_code,
   return ret;
 }
 
+/* Say that before being split, -mcmodel=medium/large UNSPEC_TOCREL
+   addresses cost one more insn than other addresses.  */
+
+static int
+rs6000_address_cost (rtx x,
+		     machine_mode mode ATTRIBUTE_UNUSED,
+		     addr_space_t as ATTRIBUTE_UNUSED,
+		     bool speed ATTRIBUTE_UNUSED)
+{
+  if (TARGET_CMODEL == CMODEL_SMALL)
+    return 0;
+
+  if (GET_CODE (x) == PLUS)
+    x = XEXP (x, 0);
+  if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TOCREL)
+    return 1;
+
+  return 0;
+}
+
 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost.  */
 
 static int

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RS6000 1/7] Hide insns not needing to be public
  2015-06-24  0:51 ` [RS6000 1/7] Hide insns not needing to be public Alan Modra
@ 2015-06-25  3:12   ` David Edelsohn
  0 siblings, 0 replies; 10+ messages in thread
From: David Edelsohn @ 2015-06-25  3:12 UTC (permalink / raw)
  To: GCC Patches

On Tue, Jun 23, 2015 at 8:50 PM, Alan Modra <amodra@gmail.com> wrote:
>         * config/rs6000/rs6000.md (addsi3_high, bswaphi2_internal,
>         ashldi3_internal5, ashldi3_internal8): Prefix with '*'.

This patch is okay.

The rotate changes need to be discussed and coordinated with Segher.

The cost changes are okay in theory, but really should be applied in
conjunction with the rtx_cost improvements that you are discussing
with Jeff.

Thanks, David

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RS6000 7/7] Address cost
  2015-06-24  1:02 ` [RS6000 7/7] Address cost Alan Modra
@ 2015-07-08 16:53   ` Segher Boessenkool
  0 siblings, 0 replies; 10+ messages in thread
From: Segher Boessenkool @ 2015-07-08 16:53 UTC (permalink / raw)
  To: gcc-patches, David Edelsohn

On Wed, Jun 24, 2015 at 10:25:46AM +0930, Alan Modra wrote:
> @@ -30720,14 +30721,20 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
>  			      - (outer_code == SET ? 1 : 0));
>        return true;
>  
> -    case CONST:
> -    case HIGH:
> -    case SYMBOL_REF:
>      case MEM:
>        /* When optimizing for size, MEM should be slightly more expensive
>  	 than generating address, e.g., (plus (reg) (const)).
>  	 L1 cache latency is about two instructions.  */
>        *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
> +      *total += COSTS_N_INSNS (rs6000_address_cost (XEXP (x, 0), mode,
> +						    0, speed));

So the unit of address cost is whole insns?  Eww.

> +      return true;
> +
> +    case CONST:
> +    case HIGH:
> +    case LO_SUM:
> +    case SYMBOL_REF:
> +      *total = COSTS_N_INSNS (1);
>        return true;

Why is the cost of CONST only one insn?  Shouldn't you take the (address)
cost of whatever is inside it?


Segher

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-07-08 16:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-24  0:50 [RS6000 0/7] rtx_cost patches Alan Modra
2015-06-24  0:51 ` [RS6000 1/7] Hide insns not needing to be public Alan Modra
2015-06-25  3:12   ` David Edelsohn
2015-06-24  0:52 ` [RS6000 2/7] Tidy rotates Alan Modra
2015-06-24  0:53 ` [RS6000 3/7] rtx_costs for ROTATE/ASHIFT inside AND Alan Modra
2015-06-24  0:54 ` [RS6000 4/7] rldic in rotate and mask patterns Alan Modra
2015-06-24  0:54 ` [RS6000 5/7] Split mask64_2_operand rotates early Alan Modra
2015-06-24  0:55 ` [RS6000 6/7] Cost multi-insn constants Alan Modra
2015-06-24  1:02 ` [RS6000 7/7] Address cost Alan Modra
2015-07-08 16:53   ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).