From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13339 invoked by alias); 23 Aug 2005 14:09:43 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 13311 invoked by uid 22791); 23 Aug 2005 14:09:36 -0000 Received: from campus9.usilu.net (HELO campus9.usilu.net) (195.176.178.26) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 23 Aug 2005 14:09:36 +0000 Received: from [192.168.64.194] ([192.168.64.194] RDNS failed) by campus9.usilu.net over TLS secured channel with Microsoft SMTPSVC(5.0.2195.6713); Tue, 23 Aug 2005 16:09:33 +0200 Message-ID: <430B2E1D.2020200@lu.unisi.ch> Date: Tue, 23 Aug 2005 14:30:00 -0000 From: Paolo Bonzini User-Agent: Mozilla Thunderbird 0.9 (Macintosh/20041103) MIME-Version: 1.0 To: David Edelsohn CC: GCC Development Subject: Re: [RFA] Nonfunctioning split in rs6000 back-end References: <430A3040.7000007@lu.unisi.ch> <200508222106.j7ML6wd32428@makai.watson.ibm.com> In-Reply-To: <200508222106.j7ML6wd32428@makai.watson.ibm.com> Content-Type: multipart/mixed; boundary="------------010305090306050801060101" X-SW-Source: 2005-08/txt/msg00624.txt.bz2 This is a multi-part message in MIME format. --------------010305090306050801060101 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 499 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 --------------010305090306050801060101 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rs6000-peephole2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rs6000-peephole2.patch" Content-length: 4035 2005-08-22 Paolo Bonzini * 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") --------------010305090306050801060101--