From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 114940 invoked by alias); 17 Nov 2015 09:21:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 114921 invoked by uid 89); 17 Nov 2015 09:21:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 17 Nov 2015 09:21:16 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-13-CnDIp2t0QomsoFptrCJwFw-1; Tue, 17 Nov 2015 09:21:11 +0000 Received: from shawin233 ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Nov 2015 09:21:11 +0000 From: "Bin Cheng" To: Subject: [PATCH AArch64]Handle REG+REG+CONST and REG+NON_REG+CONST in legitimize address Date: Tue, 17 Nov 2015 09:21:00 -0000 Message-ID: <000001d12119$49548570$dbfd9050$@arm.com> MIME-Version: 1.0 X-MC-Unique: CnDIp2t0QomsoFptrCJwFw-1 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0001_01D1215C.577AD2B0" X-IsSubscribed: yes X-SW-Source: 2015-11/txt/msg02042.txt.bz2 This is a multipart message in MIME format. ------=_NextPart_000_0001_01D1215C.577AD2B0 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable Content-length: 2249 Hi, GIMPLE IVO needs to call backend interface to calculate costs for addr expressions like below: FORM1: "r73 + r74 + 16380" FORM2: "r73 << 2 + r74 + 16380" They are invalid address expression on AArch64, so will be legitimized by aarch64_legitimize_address. Below are what we got from that function: For FORM1, the address expression is legitimized into below insn sequence and rtx: r84:DI=3Dr73:DI+r74:DI r85:DI=3Dr84:DI+0x3000 r83:DI=3Dr85:DI "r83 + 4092" For FORM2, the address expression is legitimized into below insn sequence and rtx: r108:DI=3Dr73:DI<<0x2 r109:DI=3Dr108:DI+r74:DI r110:DI=3Dr109:DI+0x3000 r107:DI=3Dr110:DI "r107 + 4092" So the costs computed are 12/16 respectively. The high cost prevents IVO from choosing right candidates. Besides cost computation, I also think the legitmization is bad in terms of code generation. The root cause in aarch64_legitimize_address can be described by it's comment: /* Try to split X+CONST into Y=3DX+(CONST & ~mask), Y+(CONST&mask), where mask is selected by alignment and size of the offset. We try to pick as large a range for the offset as possible to maximize the chance of a CSE. However, for aligned addresses we limit the range to 4k so that structures with different sized elements are likely to use the same base. */ I think the split of CONST is intended for REG+CONST where the const offset is not in the range of AArch64's addressing modes. Unfortunately, it doesn't explicitly handle/reject "REG+REG+CONST" and "REG+REG< Jiong Wang * config/aarch64/aarch64.c (aarch64_legitimize_address): Handle address expressions like REG+REG+CONST and REG+NON_REG+CONST. ------=_NextPart_000_0001_01D1215C.577AD2B0 Content-Type: text/plain; name=aarch64_legitimize_addr-20151104.txt Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="aarch64_legitimize_addr-20151104.txt" Content-length: 1922 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 5c8604f..47875ac 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4710,6 +4710,51 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x */= , machine_mode mode) { HOST_WIDE_INT offset =3D INTVAL (XEXP (x, 1)); HOST_WIDE_INT base_offset; + rtx op0 =3D XEXP (x,0); + + if (GET_CODE (op0) =3D=3D PLUS) + { + rtx op0_ =3D XEXP (op0, 0); + rtx op1_ =3D XEXP (op0, 1); + + /* RTX pattern in the form of (PLUS (PLUS REG, REG), CONST) will + reach here, the 'CONST' may be valid in which case we should + not split. */ + if (REG_P (op0_) && REG_P (op1_)) + { + machine_mode addr_mode =3D GET_MODE (op0); + rtx addr =3D gen_reg_rtx (addr_mode); + + rtx ret =3D plus_constant (addr_mode, addr, offset); + if (aarch64_legitimate_address_hook_p (mode, ret, false)) + { + emit_insn (gen_adddi3 (addr, op0_, op1_)); + return ret; + } + } + /* RTX pattern in the form of (PLUS (PLUS REG, NON_REG), CONST) + will reach here. If (PLUS REG, NON_REG) is valid addr expr, + we split it into Y=3DREG+CONST, Y+NON_REG. */ + else if (REG_P (op0_) || REG_P (op1_)) + { + machine_mode addr_mode =3D GET_MODE (op0); + rtx addr =3D gen_reg_rtx (addr_mode); + + /* Switch to make sure that register is in op0_. */ + if (REG_P (op1_)) + std::swap (op0_, op1_); + + rtx ret =3D gen_rtx_fmt_ee (PLUS, addr_mode, addr, op1_); + if (aarch64_legitimate_address_hook_p (mode, ret, false)) + { + addr =3D force_operand (plus_constant (addr_mode, + op0_, offset), + NULL_RTX); + ret =3D gen_rtx_fmt_ee (PLUS, addr_mode, addr, op1_); + return ret; + } + } + } =20 /* Does it look like we'll need a load/store-pair operation? */ if (GET_MODE_SIZE (mode) > 16 ------=_NextPart_000_0001_01D1215C.577AD2B0--