From patchwork Sun Nov 11 19:01:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 198289 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 575ED2C0087 for ; Mon, 12 Nov 2012 06:01:25 +1100 (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=1353265286; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=kFTWKDp 1jAv01aEY4usExxDXbUU=; b=pjAAxIShU0RBdeBXhnmMmObl3eVdtR+BzBBy13U 8Gv1b2EIXW408phK3lPvySPxR0Vgu77g/9NOCp6dnkJ8VqzZ1MAbcF7izgJPfbxU 0ONq2SmHWsOSvl1N/hw2+Nd65ZlWJr0xaYbqBRJXg6adbRcBv7EWj61mflDtsi7F sT7U= 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:Date:Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=myKrG0AL+4TiXdn1KOFU+PV0PvrH+MaTH9nXcuvdz5OK7xjFmfjpYjj3Uiod6F Zbk3fmA8s0ikuDiVnJiKz9UBfBFO9sukRx1xLXFUV8Ja/0Q7LppHgeF9QycqqJnd HwwPmYlsITIMCZX7ATH2TRYYMbmEprXkYyOgS+spdmImA=; Received: (qmail 30456 invoked by alias); 11 Nov 2012 19:01:22 -0000 Received: (qmail 30444 invoked by uid 22791); 11 Nov 2012 19:01:21 -0000 X-SWARE-Spam-Status: No, hits=-4.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_AV, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-pa0-f47.google.com (HELO mail-pa0-f47.google.com) (209.85.220.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 11 Nov 2012 19:01:16 +0000 Received: by mail-pa0-f47.google.com with SMTP id fa11so3587582pad.20 for ; Sun, 11 Nov 2012 11:01:16 -0800 (PST) MIME-Version: 1.0 Received: by 10.68.197.71 with SMTP id is7mr44759633pbc.79.1352660475956; Sun, 11 Nov 2012 11:01:15 -0800 (PST) Received: by 10.66.246.232 with HTTP; Sun, 11 Nov 2012 11:01:15 -0800 (PST) Date: Sun, 11 Nov 2012 20:01:15 +0100 Message-ID: Subject: [PATCH, i386]: Determine AVX256 registers more reliably From: Uros Bizjak To: gcc-patches@gcc.gnu.org Cc: Vladimir Yakovlev 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 Hello! Attached patch uses for_each_rtx function to find AVX256 registers in the RTX. The patch also implements better MODE_AFTER handling: we already switched to DIRTY state if AVX256 is referenced through MODE_NEEDED. We just force CLEAN state after vzeroupper/vzero and for call instructions without AVX256 register returns. 2012-11-10 Uros Bizjak PR target/47440 * config/i386/i386.c (check_avx256_stores): Remove. (ix86_check_avx256_register): New. (ix86_avx_u128_mode_needed): Use ix86_check_avx256_register. Check the whole RTX for 256bit registers using for_each_rtx. (ix86_check_avx_stores): New. (ix86_avx_u128_mode_after): Change mode of CALL RTX to AVX_U128_CLEAN if there are no 256bit registers used in the function return register. (ix86_avx_u128_mode_entry): Use ix86_check_avx256_register. (ix86_avx_u128_mode_exit): Ditto. Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu, tested by Vladimir on SPEC2000/2006 and will be committed to mainline SVN after a re-bootstrap. Uros. Index: i386.c =================================================================== --- i386.c (revision 193407) +++ i386.c (working copy) @@ -14942,20 +14942,16 @@ output_387_binary_op (rtx insn, rtx *operands) return buf; } -/* Check if a 256bit AVX register is referenced in stores. */ +/* Check if a 256bit AVX register is referenced inside of EXP. */ -static void -check_avx256_stores (rtx dest, const_rtx set, void *data) +static int +ix86_check_avx256_register (rtx *exp, void *data ATTRIBUTE_UNUSED) { - if (((REG_P (dest) || MEM_P (dest)) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (dest))) - || (GET_CODE (set) == SET - && (REG_P (SET_SRC (set)) || MEM_P (SET_SRC (set))) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (SET_SRC (set))))) - { - bool *used = (bool *) data; - *used = true; - } + if (REG_P (*exp) + && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (*exp))) + return 1; + + return 0; } /* Return needed mode for entity in optimize_mode_switching pass. */ @@ -14963,8 +14959,6 @@ output_387_binary_op (rtx insn, rtx *operands) static int ix86_avx_u128_mode_needed (rtx insn) { - bool avx_u128_used; - if (CALL_P (insn)) { rtx link; @@ -14979,8 +14973,7 @@ ix86_avx_u128_mode_needed (rtx insn) { rtx arg = XEXP (XEXP (link, 0), 0); - if (REG_P (arg) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (arg))) + if (ix86_check_avx256_register (&arg, NULL)) return AVX_U128_ANY; } } @@ -14988,10 +14981,11 @@ ix86_avx_u128_mode_needed (rtx insn) return AVX_U128_CLEAN; } - /* Check if a 256bit AVX register is referenced in stores. */ - avx_u128_used = false; - note_stores (PATTERN (insn), check_avx256_stores, &avx_u128_used); - if (avx_u128_used) + /* Require DIRTY mode if a 256bit AVX register is referenced. Hardware + changes state only when a 256bit register is written to, but we need + to prevent the compiler from moving optimal insertion point above + eventual read from 256bit register. */ + if (for_each_rtx (&PATTERN (insn), ix86_check_avx256_register, NULL)) return AVX_U128_DIRTY; return AVX_U128_ANY; @@ -15071,28 +15065,42 @@ ix86_mode_needed (int entity, rtx insn) return 0; } +/* Check if a 256bit AVX register is referenced in stores. */ + +static void +ix86_check_avx256_stores (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data) + { + if (ix86_check_avx256_register (&dest, NULL)) + { + bool *used = (bool *) data; + *used = true; + } + } + /* Calculate mode of upper 128bit AVX registers after the insn. */ static int ix86_avx_u128_mode_after (int mode, rtx insn) { rtx pat = PATTERN (insn); - bool avx_u128_used; if (vzeroupper_operation (pat, VOIDmode) || vzeroall_operation (pat, VOIDmode)) return AVX_U128_CLEAN; - /* Check if a 256bit AVX register is referenced in stores. */ - avx_u128_used = false; - note_stores (pat, check_avx256_stores, &avx_u128_used); - if (avx_u128_used) - return AVX_U128_DIRTY; /* We know that state is clean after CALL insn if there are no - 256bit modes used in the function return register. */ - else if (CALL_P (insn)) - return AVX_U128_CLEAN; + 256bit registers used in the function return register. */ + if (CALL_P (insn)) + { + bool avx_reg256_found = false; + note_stores (pat, ix86_check_avx256_stores, &avx_reg256_found); + if (!avx_reg256_found) + return AVX_U128_CLEAN; + } + /* Otherwise, return current mode. Remember that if insn + references AVX 256bit registers, the mode was already changed + to DIRTY from MODE_NEEDED. */ return mode; } @@ -15127,8 +15135,7 @@ ix86_avx_u128_mode_entry (void) { rtx incoming = DECL_INCOMING_RTL (arg); - if (incoming && REG_P (incoming) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (incoming))) + if (incoming && ix86_check_avx256_register (&incoming, NULL)) return AVX_U128_DIRTY; } @@ -15162,7 +15169,7 @@ ix86_avx_u128_mode_exit (void) /* Exit mode is set to AVX_U128_DIRTY if there are 256bit modes used in the function return register. */ - if (reg && REG_P (reg) && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg))) + if (reg && ix86_check_avx256_register (®, NULL)) return AVX_U128_DIRTY; return AVX_U128_CLEAN;