diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2014-05-16 08:59:07 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2014-05-16 08:59:07 +0000 |
commit | 268c3b4758fd7fc54f8cc8220f0a6193ed862a42 (patch) | |
tree | ab3cdc8e42487dfb04ea965a4b20d8364c6497d1 | |
parent | 2961177e7d5bd857c4809e6b4a6c655f0bb963cc (diff) | |
download | gcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.zip gcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.tar.gz gcc-268c3b4758fd7fc54f8cc8220f0a6193ed862a42.tar.bz2 |
[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 <philipp.tomsich@theobroma-systems.com>
From-SVN: r210501
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 65 |
2 files changed, 66 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a084ca98..e648140 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2014-05-16 James Greenhalgh <james.greenhalgh@arm.com> Philipp Tomsich <philipp.tomsich@theobroma-systems.com> + * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for + logical operations. + +2014-05-16 James Greenhalgh <james.greenhalgh@arm.com> + Philipp Tomsich <philipp.tomsich@theobroma-systems.com> + * config/aarch64/aarch64.c (aarch64_rtx_costs): Use address costs when costing loads and stores to memory. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d0a5e49..6b20d4a 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) |