From: James Greenhalgh Date: Fri, 16 May 2014 08:59:07 +0000 (+0000) Subject: [AArch64 costs 9/18] Better cost logical operations X-Git-Tag: releases/gcc-5.1.0~7545 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=268c3b4758fd7fc54f8cc8220f0a6193ed862a42;p=thirdparty%2Fgcc.git [AArch64 costs 9/18] Better cost logical operations gcc/ * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for logical operations. Co-Authored-By: Philipp Tomsich From-SVN: r210501 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a084ca98aecb..e648140387b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-05-16 James Greenhalgh + Philipp Tomsich + + * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for + logical operations. + 2014-05-16 James Greenhalgh Philipp Tomsich diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d0a5e49eb901..6b20d4a757f0 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -5206,25 +5206,80 @@ cost_minus: op0 = XEXP (x, 0); op1 = XEXP (x, 1); + if (code == AND + && GET_CODE (op0) == MULT + && CONST_INT_P (XEXP (op0, 1)) + && CONST_INT_P (op1) + && aarch64_uxt_size (exact_log2 (INTVAL (XEXP (op0, 1))), + INTVAL (op1)) != 0) + { + /* This is a UBFM/SBFM. */ + *cost += rtx_cost (XEXP (op0, 0), ZERO_EXTRACT, 0, speed); + if (speed) + *cost += extra_cost->alu.bfx; + return true; + } + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) { + /* We possibly get the immediate for free, this is not + modelled. */ if (CONST_INT_P (op1) && aarch64_bitmask_imm (INTVAL (op1), GET_MODE (x))) { - *cost += rtx_cost (op0, AND, 0, speed); + *cost += rtx_cost (op0, (enum rtx_code) code, 0, speed); + + if (speed) + *cost += extra_cost->alu.logical; + + return true; } else { + rtx new_op0 = op0; + + /* Handle ORN, EON, or BIC. */ if (GET_CODE (op0) == NOT) op0 = XEXP (op0, 0); - op0 = aarch64_strip_shift (op0); - *cost += (rtx_cost (op0, AND, 0, speed) - + rtx_cost (op1, AND, 1, speed)); + + new_op0 = aarch64_strip_shift (op0); + + /* If we had a shift on op0 then this is a logical-shift- + by-register/immediate operation. Otherwise, this is just + a logical operation. */ + if (speed) + { + if (new_op0 != op0) + { + /* Shift by immediate. */ + if (CONST_INT_P (XEXP (op0, 1))) + *cost += extra_cost->alu.log_shift; + else + *cost += extra_cost->alu.log_shift_reg; + } + else + *cost += extra_cost->alu.logical; + } + + /* In both cases we want to cost both operands. */ + *cost += rtx_cost (new_op0, (enum rtx_code) code, 0, speed) + + rtx_cost (op1, (enum rtx_code) code, 1, speed); + + return true; } - return true; } return false; + case NOT: + /* MVN. */ + if (speed) + *cost += extra_cost->alu.logical; + + /* The logical instruction could have the shifted register form, + but the cost is the same if the shift is processed as a separate + instruction, so we don't bother with it here. */ + return false; + case ZERO_EXTEND: if ((GET_MODE (x) == DImode && GET_MODE (XEXP (x, 0)) == SImode)