From patchwork Fri May 1 08:24:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrylo Tkachov X-Patchwork-Id: 466912 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C3C4D14076A for ; Fri, 1 May 2015 18:24:33 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=mNhfEwRe; dkim-adsp=none (unprotected policy); dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=niseL9hvvmpTcCBykA+LIQXkpObebDhe9mqvDbBYE2M xarrIhbFSVDcmbcHKfVMJbi8/JHDAi0bn4mJJuhOXTQ9YX77NOI7E/B9eUo4EDME 1e4iU2tB7Mv1/RZlDBf+/catmywwTsuM5K2sgGqFm7SZYx92aaFULbi26dk6Ti/E = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=pdtpk50IW4nVzEoXH4yULLtEvG8=; b=mNhfEwReBnXXfk3Gy PVmqHAEjXS6b43JTdMUtDymjey7AWq5cg/valfFEKb01FKCqiXUZg95Ig8rM9rbW VC2ULGEiS8S5opv5CpCv54hC10SEayY3IjoOm9tsHsr5KNnRgfbYj8FvAPgLfhIs fan/r0J6UfZu2/DrJZPIAJid2s= Received: (qmail 110668 invoked by alias); 1 May 2015 08:24:26 -0000 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 Received: (qmail 110654 invoked by uid 89); 1 May 2015 08:24:25 -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) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 01 May 2015 08:24:24 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by uk-mta-12.uk.mimecast.lan; Fri, 01 May 2015 09:24:21 +0100 Received: from [10.2.207.50] ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 1 May 2015 09:24:20 +0100 Message-ID: <55433834.10206@arm.com> Date: Fri, 01 May 2015 09:24:20 +0100 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: Marcus Shawcroft , Richard Earnshaw , James Greenhalgh , Ramana Radhakrishnan Subject: [PATCH][ARM/AArch64] Properly cost rev16 operand X-MC-Unique: koLCNHKWQlGUjx_MDD8wKQ-1 X-IsSubscribed: yes Hi all, It occurs to me that in the IOR-of-shifts form of the rev16 operation we should be costing the operand properly. For that we'd want to reuse the aarch_rev16_p function that does all the heavy lifting and get it to write the innermost operand of the rev16 for further costing. In the process we relax that function a bit to accept any rtx as the operand, not just REGs so that we can calculate the cost of moving them in a register appropriately. This patch does just that and updates the arm and aarch64 callsites appropriately so that the operands are processed properly. In practice I don't expect this to make much difference since this patterns occurs rarely anyway, but it seems like the 'right thing to do' (TM). Bootstrapped and tested on arm,aarch64. Ok for trunk? Thanks, Kyrill 2015-05-01 Kyrylo Tkachov * config/arm/aarch-common-protos.h (aarch_rev16_p): Update signature to take a second argument. * config/arm/aarch-common.c (aarch_rev16_p): Add second argument. Write inner-most rev16 argument to it if recognised. (aarch_rev16_p_1): Likewise. * config/arm/arm.c (arm_new_rtx_costs): Properly cost rev16 operand in the IOR case. * config/aarch64/aarch64.c (aarch64_rtx_costs): Likewise. commit 297534c524af2aac4c67279909c5e54221a46b22 Author: Kyrylo Tkachov Date: Mon Mar 2 17:55:30 2015 +0000 [ARM/AArch64] Properly cost rev16 operand. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 0345b93..6083fd4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -6003,9 +6003,9 @@ cost_plus: return false; case IOR: - if (aarch_rev16_p (x)) + if (aarch_rev16_p (x, &op0)) { - *cost = COSTS_N_INSNS (1); + *cost += rtx_cost (op0, BSWAP, 0, speed); if (speed) *cost += extra_cost->alu.rev; diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h index 3ee7ebf..04b1f1d 100644 --- a/gcc/config/arm/aarch-common-protos.h +++ b/gcc/config/arm/aarch-common-protos.h @@ -24,7 +24,7 @@ #define GCC_AARCH_COMMON_PROTOS_H extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *); -extern bool aarch_rev16_p (rtx); +extern bool aarch_rev16_p (rtx, rtx*); extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode); extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode); extern int arm_early_load_addr_dep (rtx, rtx); diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c index b2bb859..f1c267c 100644 --- a/gcc/config/arm/aarch-common.c +++ b/gcc/config/arm/aarch-common.c @@ -181,28 +181,31 @@ aarch_rev16_shleft_mask_imm_p (rtx val, machine_mode mode) static bool -aarch_rev16_p_1 (rtx lhs, rtx rhs, machine_mode mode) +aarch_rev16_p_1 (rtx lhs, rtx rhs, machine_mode mode, rtx *op) { if (GET_CODE (lhs) == AND && GET_CODE (XEXP (lhs, 0)) == ASHIFT && CONST_INT_P (XEXP (XEXP (lhs, 0), 1)) && INTVAL (XEXP (XEXP (lhs, 0), 1)) == 8 - && REG_P (XEXP (XEXP (lhs, 0), 0)) && CONST_INT_P (XEXP (lhs, 1)) && GET_CODE (rhs) == AND && GET_CODE (XEXP (rhs, 0)) == LSHIFTRT - && REG_P (XEXP (XEXP (rhs, 0), 0)) && CONST_INT_P (XEXP (XEXP (rhs, 0), 1)) && INTVAL (XEXP (XEXP (rhs, 0), 1)) == 8 && CONST_INT_P (XEXP (rhs, 1)) - && REGNO (XEXP (XEXP (rhs, 0), 0)) == REGNO (XEXP (XEXP (lhs, 0), 0))) + && rtx_equal_p (XEXP (XEXP (rhs, 0), 0), XEXP (XEXP (lhs, 0), 0))) { rtx lhs_mask = XEXP (lhs, 1); rtx rhs_mask = XEXP (rhs, 1); - - return aarch_rev16_shright_mask_imm_p (rhs_mask, mode) - && aarch_rev16_shleft_mask_imm_p (lhs_mask, mode); + rtx inner = XEXP (XEXP (lhs, 0), 0); + + if (aarch_rev16_shright_mask_imm_p (rhs_mask, mode) + && aarch_rev16_shleft_mask_imm_p (lhs_mask, mode)) + { + *op = inner; + return true; + } } return false; @@ -214,14 +217,18 @@ aarch_rev16_p_1 (rtx lhs, rtx rhs, machine_mode mode) | ((x << 8) & 0xff00ff00) for SImode and with similar but wider bitmasks for DImode. The two sub-expressions of the IOR can appear on either side so check both - permutations with the help of aarch_rev16_p_1 above. */ + permutations with the help of aarch_rev16_p_1 above. Write into OP the + rtx that has rev16 applied to it to be used for further operand costing. + OP will hold NULL_RTX if the operation is not recognised. */ bool -aarch_rev16_p (rtx x) +aarch_rev16_p (rtx x, rtx *op) { rtx left_sub_rtx, right_sub_rtx; bool is_rev = false; + *op = NULL_RTX; + if (GET_CODE (x) != IOR) return false; @@ -230,10 +237,10 @@ aarch_rev16_p (rtx x) /* There are no canonicalisation rules for the position of the two shifts involved in a rev, so try both permutations. */ - is_rev = aarch_rev16_p_1 (left_sub_rtx, right_sub_rtx, GET_MODE (x)); + is_rev = aarch_rev16_p_1 (left_sub_rtx, right_sub_rtx, GET_MODE (x), op); if (!is_rev) - is_rev = aarch_rev16_p_1 (right_sub_rtx, left_sub_rtx, GET_MODE (x)); + is_rev = aarch_rev16_p_1 (right_sub_rtx, left_sub_rtx, GET_MODE (x), op); return is_rev; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4081680..b3c65d5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -10389,14 +10389,19 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost = LIBCALL_COST (2); return false; case IOR: - if (mode == SImode && arm_arch6 && aarch_rev16_p (x)) - { - *cost = COSTS_N_INSNS (1); - if (speed_p) - *cost += extra_cost->alu.rev; + { + rtx inner; + if (mode == SImode && arm_arch6 && aarch_rev16_p (x, &inner)) + { + *cost = COSTS_N_INSNS (1); + *cost += rtx_cost (inner, BSWAP, 0 , speed_p); - return true; - } + if (speed_p) + *cost += extra_cost->alu.rev; + + return true; + } + } /* Fall through. */ case AND: case XOR: if (mode == SImode)