public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] Nonfunctioning split in rs6000 back-end
@ 2005-08-22 20:06 Paolo Bonzini
  2005-08-22 21:19 ` David Edelsohn
  2005-08-23 20:08 ` Giovanni Bajo
  0 siblings, 2 replies; 4+ messages in thread
From: Paolo Bonzini @ 2005-08-22 20:06 UTC (permalink / raw)
  To: David Edelsohn; +Cc: GCC Development

While researching who is really using flow's computed LOG_LINKS, I found 
a define_split in the rs6000 back-end that uses them through 
find_single_use.  It turns out the only users are combine, this split, 
and a function in regmove.

The split dates back to revision 1.5 of old-gcc.

;; If we are comparing a register for equality with a large constant,
;; we can do this with an XOR followed by a compare.  But we need a scratch
;; register for the result of the XOR.

(define_split
  [(set (match_operand:CC 0 "cc_reg_operand" "")
        (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
                    (match_operand:SI 2 "non_short_cint_operand" "")))
   (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
  "find_single_use (operands[0], insn, 0)
   && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
       || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
  [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
   (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]

(etc.)

This split would turn

        lis r0,0x1234
        ori r0,r0,0x5678
        cmpwi cr7,r3,r0
        beq cr7,L6

into

        xoris r0,r3,0x1234
        cmpwi cr7,r0,0x5678
        beq cr7,L6

Nice trick, but it will not trigger, because the non_short_cint_operand 
will have been split already before this pattern is matched.  I see two 
possibilities:

1) turning it into a peephole2 like the following:

(define_peephole2
  [(set (match_operand:GPR 0 "register_operand")
        (match_operand:GPR 1 "logical_operand" ""))
   (set (match_dup 0) (match_operator:GPR 3 "boolean_or_operator"
                  [(match_dup 0)
                   (match_operand:GPR 2 "logical_operand" "")]))
   (set (match_operand:CC 4 "cc_reg_operand" "")
        (compare:CC (match_operand:GPR 5 "gpc_reg_operand" "")
                    (match_dup 0)))
   (set (pc)
        (if_then_else (match_operator 6 "equality_operator"
                  [(match_dup 4) (const_int 0)])
                 (match_operand 7 "" "")
                 (match_operand 8 "" "")))]
  "peep2_reg_dead_p (3, operands[0]) && printf (\"^&\")"
 [(set (match_dup 0) (xor:GPR (match_dup 5) (match_dup 9)))
  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]

{
  /* Get the constant we are comparing against, and see what it looks like
     when sign-extended from 16 to 32 bits.  Then see what constant we could
     XOR with SEXTC to get the sign-extended value.  */
  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
                                              GET_MODE (operands[3]),
                                              operands[1], operands[2]);
  HOST_WIDE_INT c = INTVAL (cnst);
  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
  HOST_WIDE_INT xorv = c ^ sextc;

  operands[9] = GEN_INT (xorv);
  operands[10] = GEN_INT (sextc);
})

I'm testing a patch that does this replacement, and I can post it 
tomorrow morning.  It has triggered only a dozen times so far (half in 
libgcc, half in the compiler), but it may be worth keeping it.  However, 
another possibility is...

2) ... entirely getting rid of it.

What do you suggest?

Paolo

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

* Re: [RFA] Nonfunctioning split in rs6000 back-end
  2005-08-22 20:06 [RFA] Nonfunctioning split in rs6000 back-end Paolo Bonzini
@ 2005-08-22 21:19 ` David Edelsohn
  2005-08-23 14:30   ` Paolo Bonzini
  2005-08-23 20:08 ` Giovanni Bajo
  1 sibling, 1 reply; 4+ messages in thread
From: David Edelsohn @ 2005-08-22 21:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Development

>>>>> Paolo Bonzini writes:

Paolo> I'm testing a patch that does this replacement, and I can post it 
Paolo> tomorrow morning.  It has triggered only a dozen times so far (half in 
Paolo> libgcc, half in the compiler), but it may be worth keeping it.

	It would be nice to keep this type of optimization if the
re-engineered version works.

Thanks, David

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

* Re: [RFA] Nonfunctioning split in rs6000 back-end
  2005-08-22 21:19 ` David Edelsohn
@ 2005-08-23 14:30   ` Paolo Bonzini
  0 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2005-08-23 14:30 UTC (permalink / raw)
  To: David Edelsohn; +Cc: GCC Development

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

David Edelsohn wrote:

>>>>>>Paolo Bonzini writes:
>>>>>>            
>>>>>>
>
>Paolo> I'm testing a patch that does this replacement, and I can post it 
>Paolo> tomorrow morning.  It has triggered only a dozen times so far (half in 
>Paolo> libgcc, half in the compiler), but it may be worth keeping it.
>
>	It would be nice to keep this type of optimization if the
>re-engineered version works.
>
>  
>
Here it is, bootstrapped and regtested on powerpc-apple-darwin8.1.0.

Ok for mainline?

Paolo

[-- Attachment #2: rs6000-peephole2.patch --]
[-- Type: text/plain, Size: 4035 bytes --]

2005-08-22  Paolo Bonzini  <bonzini@gnu.org>

	* config/rs6000/predicates.md (equality_operator): New.
	* config/rs6000/rs6000.md: Rewrite as a peephole2 the split for
	comparison with a large constant.

Index: config/rs6000/predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/predicates.md,v
retrieving revision 1.23
diff -p -u -r1.23 predicates.md
--- config/rs6000/predicates.md	11 Aug 2005 21:18:11 -0000	1.23
+++ config/rs6000/predicates.md	22 Aug 2005 20:44:32 -0000
@@ -710,6 +710,10 @@
 (define_predicate "boolean_or_operator"
   (match_code "ior,xor"))
 
+;; Return true if operand is an equality operator.
+(define_special_predicate "equality_operator"
+  (match_code "eq,ne"))
+
 ;; Return true if operand is MIN or MAX operator.
 (define_predicate "min_max_operator"
   (match_code "smin,smax,umin,umax"))
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.400
diff -p -u -r1.400 rs6000.md
--- rs6000.md	20 Aug 2005 04:17:17 -0000	1.400
+++ rs6000.md	22 Aug 2005 20:41:44 -0000
@@ -10727,32 +10727,43 @@
   [(set_attr "type" "cmp")])
 
 ;; If we are comparing a register for equality with a large constant,
-;; we can do this with an XOR followed by a compare.  But we need a scratch
-;; register for the result of the XOR.
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_operand" "")
-	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
-		    (match_operand:SI 2 "non_short_cint_operand" "")))
-   (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
-  "find_single_use (operands[0], insn, 0)
-   && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
-       || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
-  [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
-   (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
-  "
-{
-  /* Get the constant we are comparing against, C,  and see what it looks like
-     sign-extended to 16 bits.  Then see what constant could be XOR'ed
-     with C to get the sign-extended value.  */
-
-  HOST_WIDE_INT c = INTVAL (operands[2]);
+;; we can do this with an XOR followed by a compare.  But this is profitable
+;; only if the large constant is only used for the comparison (and in this
+;; case we already have a register to reuse as scratch).
+
+(define_peephole2
+  [(set (match_operand:GPR 0 "register_operand")
+        (match_operand:GPR 1 "logical_operand" ""))
+   (set (match_dup 0) (match_operator:GPR 3 "boolean_or_operator"
+		       [(match_dup 0)
+			(match_operand:GPR 2 "logical_operand" "")]))
+   (set (match_operand:CC 4 "cc_reg_operand" "")
+        (compare:CC (match_operand:GPR 5 "gpc_reg_operand" "")
+                    (match_dup 0)))
+   (set (pc)
+        (if_then_else (match_operator 6 "equality_operator"
+                       [(match_dup 4) (const_int 0)])
+                      (match_operand 7 "" "")
+                      (match_operand 8 "" "")))]
+  "peep2_reg_dead_p (3, operands[0])"
+ [(set (match_dup 0) (xor:GPR (match_dup 5) (match_dup 9)))
+  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
+  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
+ 
+{
+  /* Get the constant we are comparing against, and see what it looks like
+     when sign-extended from 16 to 32 bits.  Then see what constant we could
+     XOR with SEXTC to get the sign-extended value.  */
+  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
+					      GET_MODE (operands[3]),
+					      operands[1], operands[2]);
+  HOST_WIDE_INT c = INTVAL (cnst);
   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
   HOST_WIDE_INT xorv = c ^ sextc;
 
-  operands[4] = GEN_INT (xorv);
-  operands[5] = GEN_INT (sextc);
-}")
+  operands[9] = GEN_INT (xorv);
+  operands[10] = GEN_INT (sextc);
+})
 
 (define_insn "*cmpsi_internal2"
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")

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

* Re: [RFA] Nonfunctioning split in rs6000 back-end
  2005-08-22 20:06 [RFA] Nonfunctioning split in rs6000 back-end Paolo Bonzini
  2005-08-22 21:19 ` David Edelsohn
@ 2005-08-23 20:08 ` Giovanni Bajo
  1 sibling, 0 replies; 4+ messages in thread
From: Giovanni Bajo @ 2005-08-23 20:08 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc

Paolo Bonzini <paolo.bonzini@lu.unisi.ch> wrote:

> While researching who is really using flow's computed LOG_LINKS, I
> found 
> a define_split in the rs6000 back-end that uses them through
> find_single_use.  It turns out the only users are combine, this split,
> and a function in regmove.


See also:
http://gcc.gnu.org/ml/gcc-patches/2004-01/msg02371.html

Giovanni Bajo

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

end of thread, other threads:[~2005-08-23 19:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-22 20:06 [RFA] Nonfunctioning split in rs6000 back-end Paolo Bonzini
2005-08-22 21:19 ` David Edelsohn
2005-08-23 14:30   ` Paolo Bonzini
2005-08-23 20:08 ` Giovanni Bajo

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).