From patchwork Mon Aug 13 16:54:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 176998 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 773602C0085 for ; Tue, 14 Aug 2012 02:54:48 +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=1345481689; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received: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=DOF8o7h Lf1fM7HGnZXYnCW/gq4I=; b=nwNOQGETVaT7OaR7bjuStaj/Y+EjfL9NB8hJtR7 iBAnun/5v2Ylm7LzInAhnhC1u2uBz4wXO4bqyaDvvFVbF/0IdCPPX3C/UWbEw/OP QsEhqV+pAZyovP7Brh8R5qfXhxYEflCCvvkHpt8KU7qffYGdaRZGbVTes1b8+PBK 3pYU= 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:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=HkBnus11wgQQG5xkfq/UlCVmwdVxDuRPDGKEKCQdI2Ow9CNdj4v2WVijkevzPs dnu/S7KpvchR2/jcOuN6iHeR5s7l3uodY6W1UoKmwI1Of6ailKWeL7E8oFHQLQjt MqWkYQmXXXgR241lQ8EucQyoi2h09Ny67ZAEJ6uDICnC4=; Received: (qmail 18358 invoked by alias); 13 Aug 2012 16:54:40 -0000 Received: (qmail 18343 invoked by uid 22791); 13 Aug 2012 16:54:37 -0000 X-SWARE-Spam-Status: No, hits=-4.1 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_EG, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-yw0-f47.google.com (HELO mail-yw0-f47.google.com) (209.85.213.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 13 Aug 2012 16:54:20 +0000 Received: by yhjj56 with SMTP id j56so3394966yhj.20 for ; Mon, 13 Aug 2012 09:54:20 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.222.9 with SMTP id qi9mr19121028pbc.164.1344876859624; Mon, 13 Aug 2012 09:54:19 -0700 (PDT) Received: by 10.66.251.227 with HTTP; Mon, 13 Aug 2012 09:54:19 -0700 (PDT) Date: Mon, 13 Aug 2012 18:54:19 +0200 Message-ID: Subject: [PATCH, i386]: Rewrite ix86_conditional_register_usage 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 Hello! This patch rewrites ix86_conditional_register_usage to improve following things: - Do not mark REX registers in FIXED_REGISTERS. We know that no 32bit target supports them, so we can disable REX registers at ix86_conditional_register_usage as well. - Use bitmaps in CALL_USED_REGISTERS to conditionally mark used registers for different ABIs, while still allowing -fcall-used-REG and -fcall-saved-REG options to be used. This brings TARGET_64BIT_MS_ABI to the same level as other ABIs and allows future ABIs to be handled. - Calculate CLOBBERED_REGS for 32bit targets in the same way as for 64bit targets, removing another 32bit/64bit difference. The regclass definition has to be moved just before GENERAL_REGS, since it is derived from this register class. We depend on fixed register definition to avoid allocation of ESP and REX registers for CLOBBERED_REGS class. This is the same approach as 64bit targets have to avoid ESP, and the same approach as 32bit targets have to avoid REX registers in GENERAL_REGS class. - Some trivial code reorderings, so we don't process non-existing registers. 2012-08-13 Uros Bizjak * config/i386/i386.h (FIXED_REGISTERS): Do not mark REX registers here. (CALL_USED_REGISTERS): Use bitmaps to mark call-used registers for different ABIs. (enum reg_class): Move CLOBBERED_REGS just before GENERAL_REGS. (REG_CLASS_NAMES): Update. (REG_CLASS_CONTENTS): Update. Clear CLOBBERED_REGS members. * config/i386/i386.c (ix86_conditional_register_usage): Disable REX registers on 32bit targets. Handle bitmaps from CALL_USED_REGISTERS initializer. Calculate CLOBBERED_REGS register set from GENERAL_REGS also for 32bit targets. Do not change call used register set for TARGET_64BIT_MS_ABI separately. Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32} and i686-pc-linux-gnu. Patch was committed to mainline SVN. Uros. Index: i386.c =================================================================== --- i386.c (revision 190347) +++ i386.c (working copy) @@ -4135,43 +4135,42 @@ ix86_option_override (void) static void ix86_conditional_register_usage (void) { - int i; + int i, c_mask; unsigned int j; - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - { - if (fixed_regs[i] > 1) - fixed_regs[i] = (fixed_regs[i] == (TARGET_64BIT ? 3 : 2)); - if (call_used_regs[i] > 1) - call_used_regs[i] = (call_used_regs[i] == (TARGET_64BIT ? 3 : 2)); - } - /* The PIC register, if it exists, is fixed. */ j = PIC_OFFSET_TABLE_REGNUM; if (j != INVALID_REGNUM) fixed_regs[j] = call_used_regs[j] = 1; - /* The 64-bit MS_ABI changes the set of call-used registers. */ - if (TARGET_64BIT_MS_ABI) + /* For 32-bit targets, squash the REX registers. */ + if (! TARGET_64BIT) { - call_used_regs[SI_REG] = 0; - call_used_regs[DI_REG] = 0; - call_used_regs[XMM6_REG] = 0; - call_used_regs[XMM7_REG] = 0; + for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++) + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) - call_used_regs[i] = 0; + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; } - /* The default setting of CLOBBERED_REGS is for 32-bit; add in the - other call-clobbered regs for 64-bit. */ - if (TARGET_64BIT) + /* See the definition of CALL_USED_REGISTERS in i386.h. */ + c_mask = (TARGET_64BIT_MS_ABI ? (1 << 3) + : TARGET_64BIT ? (1 << 2) + : (1 << 1)); + + CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]); + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { - CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]); + /* Set/reset conditionally defined registers from + CALL_USED_REGISTERS initializer. */ + if (call_used_regs[i] > 1) + call_used_regs[i] = !!(call_used_regs[i] & c_mask); - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i) - && call_used_regs[i]) - SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i); + /* Calculate registers of CLOBBERED_REGS register set + as call used registers from GENERAL_REGS register set. */ + if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i) + && call_used_regs[i]) + SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i); } /* If MMX is disabled, squash the registers. */ @@ -4191,15 +4190,6 @@ ix86_conditional_register_usage (void) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i)) fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; - - /* If 32-bit, squash the 64-bit registers. */ - if (! TARGET_64BIT) - { - for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++) - reg_names[i] = ""; - for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) - reg_names[i] = ""; - } } Index: i386.h =================================================================== --- i386.h (revision 190347) +++ i386.h (working copy) @@ -921,12 +921,9 @@ enum target_cpu_default and are not available for the register allocator. On the 80386, the stack pointer is such, as is the arg pointer. - The value is zero if the register is not fixed on either 32 or - 64 bit targets, one if the register if fixed on both 32 and 64 - bit targets, two if it is only fixed on 32bit targets and three - if its only fixed on 64bit targets. - Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. - */ + REX registers are disabled for 32bit targets in + TARGET_CONDITIONAL_REGISTER_USAGE. */ + #define FIXED_REGISTERS \ /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, \ @@ -937,11 +934,10 @@ enum target_cpu_default /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /* r8, r9, r10, r11, r12, r13, r14, r15*/ \ - 2, 2, 2, 2, 2, 2, 2, 2, \ + 0, 0, 0, 0, 0, 0, 0, 0, \ /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ - 2, 2, 2, 2, 2, 2, 2, 2 } + 0, 0, 0, 0, 0, 0, 0, 0 } - /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. @@ -949,25 +945,26 @@ enum target_cpu_default and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. - The value is zero if the register is not call used on either 32 or - 64 bit targets, one if the register if call used on both 32 and 64 - bit targets, two if it is only call used on 32bit targets and three - if its only call used on 64bit targets. - Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. -*/ + Value is set to 1 if the register is call used unconditionally. + Bit one is set if the register is call used on TARGET_32BIT ABI. + Bit two is set if the register is call used on TARGET_64BIT ABI. + Bit three is set if the register is call used on TARGET_64BIT_MS_ABI. + + Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. */ + #define CALL_USED_REGISTERS \ /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ -{ 1, 1, 1, 0, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ +{ 1, 1, 1, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ /*arg,flags,fpsr,fpcr,frame*/ \ 1, 1, 1, 1, 1, \ /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ + 1, 1, 1, 1, 1, 1, 6, 6, \ /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ 1, 1, 1, 1, 1, 1, 1, 1, \ /* r8, r9, r10, r11, r12, r13, r14, r15*/ \ 1, 1, 1, 1, 2, 2, 2, 2, \ /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ - 1, 1, 1, 1, 1, 1, 1, 1 } + 6, 6, 6, 6, 6, 6, 6, 6 } /* Order in which to allocate registers. Each register must be listed once, even those in FIXED_REGISTERS. List frame pointer @@ -1203,11 +1200,11 @@ enum reg_class NO_REGS, AREG, DREG, CREG, BREG, SIREG, DIREG, AD_REGS, /* %eax/%edx for DImode */ - CLOBBERED_REGS, /* call-clobbered integers */ Q_REGS, /* %eax %ebx %ecx %edx */ NON_Q_REGS, /* %esi %edi %ebp %esp */ INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ LEGACY_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */ + CLOBBERED_REGS, /* call-clobbered integer registers */ GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 */ FP_TOP_REG, FP_SECOND_REG, /* %st(0) %st(1) */ @@ -1253,10 +1250,10 @@ enum reg_class "AREG", "DREG", "CREG", "BREG", \ "SIREG", "DIREG", \ "AD_REGS", \ - "CLOBBERED_REGS", \ "Q_REGS", "NON_Q_REGS", \ "INDEX_REGS", \ "LEGACY_REGS", \ + "CLOBBERED_REGS", \ "GENERAL_REGS", \ "FP_TOP_REG", "FP_SECOND_REG", \ "FLOAT_REGS", \ @@ -1274,9 +1271,8 @@ enum reg_class /* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. - Note that the default setting of CLOBBERED_REGS is for 32-bit; this - is adjusted by TARGET_CONDITIONAL_REGISTER_USAGE for the 64-bit ABI - in effect. */ + Note that CLOBBERED_REGS are calculated by + TARGET_CONDITIONAL_REGISTER_USAGE. */ #define REG_CLASS_CONTENTS \ { { 0x00, 0x0 }, \ @@ -1284,11 +1280,11 @@ enum reg_class { 0x04, 0x0 }, { 0x08, 0x0 }, /* CREG, BREG */ \ { 0x10, 0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */ \ { 0x03, 0x0 }, /* AD_REGS */ \ - { 0x07, 0x0 }, /* CLOBBERED_REGS */ \ { 0x0f, 0x0 }, /* Q_REGS */ \ { 0x1100f0, 0x1fe0 }, /* NON_Q_REGS */ \ { 0x7f, 0x1fe0 }, /* INDEX_REGS */ \ { 0x1100ff, 0x0 }, /* LEGACY_REGS */ \ + { 0x00, 0x0 }, /* CLOBBERED_REGS */ \ { 0x1100ff, 0x1fe0 }, /* GENERAL_REGS */ \ { 0x100, 0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\ { 0xff00, 0x0 }, /* FLOAT_REGS */ \