From patchwork Fri Oct 18 19:48:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 176951 Delivered-To: patch@linaro.org Received: by 2002:ac9:3c86:0:0:0:0:0 with SMTP id w6csp1293036ocf; Fri, 18 Oct 2019 12:56:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqxtggxmiadU3GCF6KUVFicRaHSgHpTkph847KBcK+J+ZfOkm9OJ0DqfTxnafilgK6oESa2q X-Received: by 2002:a50:bac2:: with SMTP id x60mr11556923ede.96.1571428581795; Fri, 18 Oct 2019 12:56:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571428581; cv=none; d=google.com; s=arc-20160816; b=WQwXzkceR0seGwNys+ch/lm1SOIo65lhiOjIK57UHcTrNOzDHfBtSihzQ4lWd0uGKt zZNFw2YcFoGe3YZJkz5JVFlgapvyRd0e2DP2+3qyOSJwgyf+niuEfKP1awO9cClCvCXh nkGUEqKwishkrUC+hh+oZ8S5Wmp7Uq8+BHXT7ri90dIwU/BHvEhAz0SBr8PWpuCszhNr QlcbcW6XQY99xsX+Cs88+iZQGpsCPPWzw9fWENWd3II9i46ScevvZJDrzvgqYQxIXm9+ 9/Z729uoC9L1hnn4ez4DAc2W/beLsLzKJr+QHQsGBMyKJTrn/wQG+1FxnhmDlHxouHqe Zc9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature; bh=f3F1jSVW9RdbYYdf0td4/cextancwUeP57HFDe8Fl+U=; b=Ay+DnCIw7nv9OSYNUdBsXyKdStEpScXLyTlT159pJPYNbiP9xWwdwoCZFM4fqBBbhp UJajHU9Q3FTDgWihnPSqHchzF9EBpXosSdH09bE+qwzbUyYNG8a3zAX7kIK4V1pwjU3d QV3KU3nHuHwztwFGLYUvFE87zQIE98ej4IjpY4G5Bz/KpFXBSnMrpOACFOEtOrDCkWaZ EjhMbaMvxf3JlGD6JpW1toF9VGaVaPVLOUOjdwX6ULufxV7nJmLBp5mpfy3DJC7+e59z 3rTRw/NyKT/AqGnAzHMikVIWHHiV5459/eZjOgUvheNQS+sRqTujnLbnfRQpdX/yQ+oO ao2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=u8Gc5X6T; spf=pass (google.com: domain of gcc-patches-return-511317-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511317-patch=linaro.org@gcc.gnu.org" Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id n4si4002421ejj.132.2019.10.18.12.56.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Oct 2019 12:56:21 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-511317-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=u8Gc5X6T; spf=pass (google.com: domain of gcc-patches-return-511317-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511317-patch=linaro.org@gcc.gnu.org" DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; q=dns; s=default; b=VBSjFvyz9KYzHF4H x0UzTTQgki1+59Ovo6exSZd8FRzOQHC7RfuyNz49UeFUso7PnjZcyIG3fvfLEPm1 cPX9wCZqWmF2qO2u9FCakpmyIQzwHcrUDLYWpWRsIrgCC4wCrR91/iO9KnYAfXHK Hd5BLPrweDdW8DqhexFtiQYjITA= 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:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=default; bh=17L78s3RW9fzbjCdbIKYc+ 6hv8o=; b=u8Gc5X6T4SB6ws1mitTq4h8GDZ+Wvu/SlhxFJM36AT3BNk+tupoEwr nhJIZlgJjj+VTqAEnxK4L0L9QKDdaX2lgo7UasvfULk97cQmvhBhoLNDh/uEc/KC 16QC0q86/+pbyQgSMMy1/gcFGqzmvHRAFD6o5jnfQsIPQ4/oAe9KY= Received: (qmail 112401 invoked by alias); 18 Oct 2019 19:55:40 -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 110383 invoked by uid 89); 18 Oct 2019 19:55:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=trickier, outer_code X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:30 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9A81F1682; Fri, 18 Oct 2019 12:49:18 -0700 (PDT) Received: from eagle.buzzard.freeserve.co.uk (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 282013F6C4; Fri, 18 Oct 2019 12:49:18 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 09/29] [arm] Correctly cost addition with a carry-in Date: Fri, 18 Oct 2019 20:48:40 +0100 Message-Id: <20191018194900.34795-10-Richard.Earnshaw@arm.com> In-Reply-To: <20191018194900.34795-1-Richard.Earnshaw@arm.com> References: <20191018194900.34795-1-Richard.Earnshaw@arm.com> MIME-Version: 1.0 The cost routine for Arm and Thumb2 was not recognising the idioms that describe the addition with carry, this results in the instructions appearing more expensive than they really are, which occasionally can lead to poor choices by combine. Recognising all the possible variants is a little trickier than normal because the expressions can become complex enough that this is no single canonical from. * config/arm/arm.c (strip_carry_operation): New function. (arm_rtx_costs_internal, case PLUS): Handle addtion with carry-in for SImode. --- gcc/config/arm/arm.c | 76 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 9a779e24cac..dfbd5cde5eb 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -9504,6 +9504,20 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) } } +/* Helper function for arm_rtx_costs. If one operand of the OP, a + PLUS, adds the carry flag, then return the other operand. If + neither is a carry, return OP unchanged. */ +static rtx +strip_carry_operation (rtx op) +{ + gcc_assert (GET_CODE (op) == PLUS); + if (arm_carry_operation (XEXP (op, 0), GET_MODE (op))) + return XEXP (op, 1); + else if (arm_carry_operation (XEXP (op, 1), GET_MODE (op))) + return XEXP (op, 0); + return op; +} + /* Helper function for arm_rtx_costs. If the operand is a valid shift operand, then return the operand that is being shifted. If the shift is not by a constant, then set SHIFT_REG to point to the operand. @@ -10253,8 +10267,41 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, return true; } + rtx op0 = XEXP (x, 0); + rtx op1 = XEXP (x, 1); + + /* Handle a side effect of adding in the carry to an addition. */ + if (GET_CODE (op0) == PLUS + && arm_carry_operation (op1, mode)) + { + op1 = XEXP (op0, 1); + op0 = XEXP (op0, 0); + } + else if (GET_CODE (op1) == PLUS + && arm_carry_operation (op0, mode)) + { + op0 = XEXP (op1, 0); + op1 = XEXP (op1, 1); + } + else if (GET_CODE (op0) == PLUS) + { + op0 = strip_carry_operation (op0); + if (swap_commutative_operands_p (op0, op1)) + std::swap (op0, op1); + } + + if (arm_carry_operation (op0, mode)) + { + /* Adding the carry to a register is a canonicalization of + adding 0 to the register plus the carry. */ + if (speed_p) + *cost += extra_cost->alu.arith; + *cost += rtx_cost (op1, mode, PLUS, 1, speed_p); + return true; + } + shift_reg = NULL; - shift_op = shifter_op_p (XEXP (x, 0), &shift_reg); + shift_op = shifter_op_p (op0, &shift_reg); if (shift_op != NULL) { if (shift_reg) @@ -10267,12 +10314,13 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost += extra_cost->alu.arith_shift; *cost += (rtx_cost (shift_op, mode, ASHIFT, 0, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } - if (GET_CODE (XEXP (x, 0)) == MULT) + + if (GET_CODE (op0) == MULT) { - rtx mul_op = XEXP (x, 0); + rtx mul_op = op0; if (TARGET_DSP_MULTIPLY && ((GET_CODE (XEXP (mul_op, 0)) == SIGN_EXTEND @@ -10296,7 +10344,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, SIGN_EXTEND, 0, speed_p) + rtx_cost (XEXP (XEXP (mul_op, 1), 0), mode, SIGN_EXTEND, 0, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } @@ -10304,24 +10352,30 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost += extra_cost->mult[0].add; *cost += (rtx_cost (XEXP (mul_op, 0), mode, MULT, 0, speed_p) + rtx_cost (XEXP (mul_op, 1), mode, MULT, 1, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } - if (CONST_INT_P (XEXP (x, 1))) + + if (CONST_INT_P (op1)) { int insns = arm_gen_constant (PLUS, SImode, NULL_RTX, - INTVAL (XEXP (x, 1)), NULL_RTX, + INTVAL (op1), NULL_RTX, NULL_RTX, 1, 0); *cost = COSTS_N_INSNS (insns); if (speed_p) *cost += insns * extra_cost->alu.arith; - *cost += rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed_p); + *cost += rtx_cost (op0, mode, PLUS, 0, speed_p); return true; } - else if (speed_p) + + if (speed_p) *cost += extra_cost->alu.arith; - return false; + /* Don't recurse here because we want to test the operands + without any carry operation. */ + *cost += rtx_cost (op0, mode, PLUS, 0, speed_p); + *cost += rtx_cost (op1, mode, PLUS, 1, speed_p); + return true; } if (mode == DImode)