From patchwork Sat Jul 28 09:19:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 173845 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 958732C0089 for ; Sat, 28 Jul 2012 19:20:34 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1344072035; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=a8Ig/s5wMZQqHneIrF63cdxF81c=; b=LKqEXrMPaAyf131 f7ML0q+5NPhSGOM1AlowWzNfXJPUTPK11uMt85FpzWTFMBXWjmBvvT1mG6dBKz/U G4/dQJcfvjxoPVnyTXmajcyvYmO7spdjO90oz121gKpGaH58n9EZxuJSwHnJ9SxI bEb1tugFXLiXCo0mhhYwo6FWGThc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=O1f8c4/MnDib1akqUbhiUbH1T0Ni7yl8K1x4j+7r1NSuLGmmTmZaZRM5Ayw64v C2aVhGNozoQtq65KKMAQEmZatelqo6w+hhCQ0LlxZaPqtd6lSoVN8pUZNgUaroi7 zQZnE0vkCyU0eRqRyrn/4Z87sZNqs+onAOu7EtrTMqeUo=; Received: (qmail 2000 invoked by alias); 28 Jul 2012 09:20:28 -0000 Received: (qmail 1990 invoked by uid 22791); 28 Jul 2012 09:20:26 -0000 X-SWARE-Spam-Status: No, hits=-4.9 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-pb0-f47.google.com (HELO mail-pb0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 28 Jul 2012 09:19:59 +0000 Received: by pbbrq2 with SMTP id rq2so6398832pbb.20 for ; Sat, 28 Jul 2012 02:19:59 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.232.170 with SMTP id tp10mr20361631pbc.59.1343467198673; Sat, 28 Jul 2012 02:19:58 -0700 (PDT) Received: by 10.66.11.130 with HTTP; Sat, 28 Jul 2012 02:19:58 -0700 (PDT) In-Reply-To: References: Date: Sat, 28 Jul 2012 11:19:58 +0200 Message-ID: Subject: [PATCH v3, i386]: Handle zero extended addresses in ix86_avoid_lea_for_addr From: Uros Bizjak To: gcc-patches@gcc.gnu.org Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Fri, Jul 27, 2012 at 7:16 PM, Uros Bizjak wrote: >> Attached patch enables ix86_avoid_lea_for_addr to process >> zero-extended addresses. This patch should help atom performance, >> especially in x32 mode. >> >> Please note the complication with insn re-recognition in >> ix86_avoid_lea_for_addr, to solve the problem as described in the >> comment: >> >> /* ix86_avoid_lea_for_addr re-recognizes insn and changes operands[] >> array behind our backs. To make things worse, zero-extended oeprands >> (zero_extend:DI (addr:SI)) are re-recognized as (addr:DI), since they >> also satisfy operand constraints of one of many *lea insn patterns. > > Actually, the instruction gets re-recognized as > *zero_extendsidi2_rex64, this is the reason why we got DImode > (addr:DI) operand. This fact further uncovers existing problem with > ix86_avoid_lea_for_addr. This function should not mark addresses > having less than two operands for splitting. These patterns are > re-recognized as MOV (and now as zero-extending MOVL) due to the > approach, described in the comment above, and due to the fact that we > define *mov{si,di} and *zero_extendsidi2_rex64 patterns before > *lea in the i386.md. > > However, here is no point messing with these patterns in splitters, > they are conditionally converted to LEAs at the insn emission phase > (see i.e. *zero_extendsidi2_rex64 change in attached patch). The > attached patch prevents splitting by a simple criteria function. > > As a bonus, the patch also includes conditional splitter for > non-destructive zero-extended adds. Here is what I have committed to mainline SVN. 2012-07-27 Uros Bizjak * config/i386/i386.c (ix86_avoid_lea_for_addr): Handle zero-extended addresses. Return false if the address has less than two components. (ix86_split_lea_for_addr): Unconditionally convert target and all address operands to requested mode. * config/i386/i386.md (*lea): Recover operands from curr_insn. Pass SImode to ix86_split_lea_for_addr when splitting zero-extended address. (zero-extended add splitter): New splitter to conditionally split non-destructive adds. (*zero_extendsidi2_rex64): Conditionally emit leal instead of movl. Uros. Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 189915) +++ config/i386/i386.c (working copy) @@ -17036,11 +17036,6 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[]) struct ix86_address parts; int ok; - /* FIXME: Handle zero-extended addresses. */ - if (GET_CODE (operands[1]) == ZERO_EXTEND - || GET_CODE (operands[1]) == AND) - return false; - /* Check we need to optimize. */ if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun)) return false; @@ -17052,6 +17047,11 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[]) ok = ix86_decompose_address (operands[1], &parts); gcc_assert (ok); + /* There should be at least two components in the address. */ + if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX) + + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2) + return false; + /* We should not split into add if non legitimate pic operand is used as displacement. */ if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp)) @@ -17124,7 +17124,7 @@ ix86_emit_binop (enum rtx_code code, enum machine_ It is assumed that it is allowed to clobber flags register at lea position. */ -extern void +void ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode) { unsigned int regno0, regno1, regno2; @@ -17135,7 +17135,7 @@ ix86_split_lea_for_addr (rtx operands[], enum mach ok = ix86_decompose_address (operands[1], &parts); gcc_assert (ok); - target = operands[0]; + target = gen_lowpart (mode, operands[0]); regno0 = true_regnum (target); regno1 = INVALID_REGNUM; @@ -17143,18 +17143,19 @@ ix86_split_lea_for_addr (rtx operands[], enum mach if (parts.base) { - if (GET_MODE (parts.base) != mode) - parts.base = gen_lowpart (mode, parts.base); + parts.base = gen_lowpart (mode, parts.base); regno1 = true_regnum (parts.base); } if (parts.index) { - if (GET_MODE (parts.index) != mode) - parts.index = gen_lowpart (mode, parts.index); + parts.index = gen_lowpart (mode, parts.index); regno2 = true_regnum (parts.index); } + if (parts.disp) + parts.disp = gen_lowpart (mode, parts.disp); + if (parts.scale > 1) { /* Case r1 = r1 + ... */ Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 189915) +++ config/i386/i386.md (working copy) @@ -3474,13 +3474,28 @@ (match_operand:SI 1 "x86_64_zext_general_operand" "rmWz,0,r ,m ,r ,m")))] "TARGET_64BIT" - "@ - mov{l}\t{%1, %k0|%k0, %1} - # - movd\t{%1, %0|%0, %1} - movd\t{%1, %0|%0, %1} - %vmovd\t{%1, %0|%0, %1} - %vmovd\t{%1, %0|%0, %1}" +{ + switch (get_attr_type (insn)) + { + case TYPE_IMOVX: + if (ix86_use_lea_for_mov (insn, operands)) + return "lea{l}\t{%E1, %k0|%k0, %E1}"; + else + return "mov{l}\t{%1, %k0|%k0, %1}"; + + case TYPE_MULTI: + return "#"; + + case TYPE_MMXMOV: + return "movd\t{%1, %0|%0, %1}"; + + case TYPE_SSEMOV: + return "%vmovd\t{%1, %0|%0, %1}"; + + default: + gcc_unreachable (); + } +} [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov") (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex") (set_attr "prefix_0f" "0,*,*,*,*,*") @@ -5479,7 +5494,23 @@ "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" [(const_int 0)] { - ix86_split_lea_for_addr (operands, mode); + enum machine_mode mode = mode; + rtx pat; + + /* ix86_avoid_lea_for_addr re-recognizes insn and may + change operands[] array behind our back. */ + pat = PATTERN (curr_insn); + + operands[0] = SET_DEST (pat); + operands[1] = SET_SRC (pat); + + /* Emit all operations in SImode for zero-extended addresses. Recall + that x86_64 inheretly zero-extends SImode operations to DImode. */ + if (GET_CODE (operands[1]) == ZERO_EXTEND + || GET_CODE (operands[1]) == AND) + mode = SImode; + + ix86_split_lea_for_addr (operands, mode); DONE; } [(set_attr "type" "lea") @@ -5807,11 +5838,11 @@ (define_split [(set (match_operand:SWI48 0 "register_operand") (plus:SWI48 (match_operand:SWI48 1 "register_operand") - (match_operand:SWI48 2 "nonmemory_operand"))) + (match_operand:SWI48 2 "x86_64_nonmemory_operand"))) (clobber (reg:CC FLAGS_REG))] "reload_completed && ix86_avoid_lea_for_add (insn, operands)" [(set (match_dup 0) (match_dup 1)) - (parallel [(set (match_dup 0) (plus: (match_dup 0) (match_dup 2))) + (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])]) ;; Convert add to the lea pattern to avoid flags dependency. @@ -5840,6 +5871,21 @@ DONE; }) +;; Split non destructive adds if we cannot use lea. +(define_split + [(set (match_operand:DI 0 "register_operand") + (zero_extend:DI + (plus:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "x86_64_nonmemory_operand")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && reload_completed && ix86_avoid_lea_for_add (insn, operands)" + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (match_dup 0) + (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2)))) + (clobber (reg:CC FLAGS_REG))])] + "operands[3] = gen_lowpart (SImode, operands[0]);") + ;; Convert add to the lea pattern to avoid flags dependency. (define_split [(set (match_operand:DI 0 "register_operand")