aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2014-05-16 08:41:46 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2014-05-16 08:41:46 +0000
commit677473677aa5d85ea967c998f73fb7f50b9eb379 (patch)
tree7c872be35c8eaa51a6269b4942c1b7399210b7e0 /gcc
parenta764d66099b476db7d59829da1b86fd4a701523f (diff)
downloadgcc-677473677aa5d85ea967c998f73fb7f50b9eb379.zip
gcc-677473677aa5d85ea967c998f73fb7f50b9eb379.tar.gz
gcc-677473677aa5d85ea967c998f73fb7f50b9eb379.tar.bz2
[AArch64 costs 1/18] Refactor aarch64_address_costs.
gcc/ * config/aarch64/aarch64-protos.h (scale_addr_mode_cost): New. (cpu_addrcost_table): Use it. * config/aarch64/aarch64.c (generic_addrcost_table): Initialize it. (aarch64_address_cost): Rewrite using aarch64_classify_address, move it. From-SVN: r210493
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/aarch64/aarch64-protos.h13
-rw-r--r--gcc/config/aarch64/aarch64.c135
3 files changed, 125 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc0d973..47df09f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2014-05-16 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-protos.h (scale_addr_mode_cost): New.
+ (cpu_addrcost_table): Use it.
+ * config/aarch64/aarch64.c (generic_addrcost_table): Initialize it.
+ (aarch64_address_cost): Rewrite using aarch64_classify_address,
+ move it.
+
2014-05-16 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.c: Include tree-cfg.h and domwalk.h.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 7cf7d9f..a05605b 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -108,9 +108,22 @@ enum aarch64_symbol_type
cost models and vectors for address cost calculations, register
move costs and memory move costs. */
+/* Scaled addressing modes can vary cost depending on the mode of the
+ value to be loaded/stored. QImode values cannot use scaled
+ addressing modes. */
+
+struct scale_addr_mode_cost
+{
+ const int hi;
+ const int si;
+ const int di;
+ const int ti;
+};
+
/* Additional cost for addresses. */
struct cpu_addrcost_table
{
+ const struct scale_addr_mode_cost addr_scale_costs;
const int pre_modify;
const int post_modify;
const int register_offset;
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fabd6a9..a596f0d 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -171,6 +171,15 @@ __extension__
#endif
static const struct cpu_addrcost_table generic_addrcost_table =
{
+#if HAVE_DESIGNATED_INITIALIZERS
+ .addr_scale_costs =
+#endif
+ {
+ NAMED_PARAM (qi, 0),
+ NAMED_PARAM (hi, 0),
+ NAMED_PARAM (si, 0),
+ NAMED_PARAM (ti, 0),
+ },
NAMED_PARAM (pre_modify, 0),
NAMED_PARAM (post_modify, 0),
NAMED_PARAM (register_offset, 0),
@@ -4550,6 +4559,101 @@ aarch64_strip_shift_or_extend (rtx x)
return aarch64_strip_shift (x);
}
+static int
+aarch64_address_cost (rtx x,
+ enum machine_mode mode,
+ addr_space_t as ATTRIBUTE_UNUSED,
+ bool speed)
+{
+ enum rtx_code c = GET_CODE (x);
+ const struct cpu_addrcost_table *addr_cost = aarch64_tune_params->addr_cost;
+ struct aarch64_address_info info;
+ int cost = 0;
+ info.shift = 0;
+
+ if (!aarch64_classify_address (&info, x, mode, c, false))
+ {
+ if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
+ {
+ /* This is a CONST or SYMBOL ref which will be split
+ in a different way depending on the code model in use.
+ Cost it through the generic infrastructure. */
+ int cost_symbol_ref = rtx_cost (x, MEM, 1, speed);
+ /* Divide through by the cost of one instruction to
+ bring it to the same units as the address costs. */
+ cost_symbol_ref /= COSTS_N_INSNS (1);
+ /* The cost is then the cost of preparing the address,
+ followed by an immediate (possibly 0) offset. */
+ return cost_symbol_ref + addr_cost->imm_offset;
+ }
+ else
+ {
+ /* This is most likely a jump table from a case
+ statement. */
+ return addr_cost->register_offset;
+ }
+ }
+
+ switch (info.type)
+ {
+ case ADDRESS_LO_SUM:
+ case ADDRESS_SYMBOLIC:
+ case ADDRESS_REG_IMM:
+ cost += addr_cost->imm_offset;
+ break;
+
+ case ADDRESS_REG_WB:
+ if (c == PRE_INC || c == PRE_DEC || c == PRE_MODIFY)
+ cost += addr_cost->pre_modify;
+ else if (c == POST_INC || c == POST_DEC || c == POST_MODIFY)
+ cost += addr_cost->post_modify;
+ else
+ gcc_unreachable ();
+
+ break;
+
+ case ADDRESS_REG_REG:
+ cost += addr_cost->register_offset;
+ break;
+
+ case ADDRESS_REG_UXTW:
+ case ADDRESS_REG_SXTW:
+ cost += addr_cost->register_extend;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+
+ if (info.shift > 0)
+ {
+ /* For the sake of calculating the cost of the shifted register
+ component, we can treat same sized modes in the same way. */
+ switch (GET_MODE_BITSIZE (mode))
+ {
+ case 16:
+ cost += addr_cost->addr_scale_costs.hi;
+ break;
+
+ case 32:
+ cost += addr_cost->addr_scale_costs.si;
+ break;
+
+ case 64:
+ cost += addr_cost->addr_scale_costs.di;
+ break;
+
+ /* We can't tell, or this is a 128-bit vector. */
+ default:
+ cost += addr_cost->addr_scale_costs.ti;
+ break;
+ }
+ }
+
+ return cost;
+}
+
/* Calculate the cost of calculating X, storing it in *COST. Result
is true if the total cost of the operation has now been calculated. */
static bool
@@ -4887,37 +4991,6 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
}
static int
-aarch64_address_cost (rtx x ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED)
-{
- enum rtx_code c = GET_CODE (x);
- const struct cpu_addrcost_table *addr_cost = aarch64_tune_params->addr_cost;
-
- if (c == PRE_INC || c == PRE_DEC || c == PRE_MODIFY)
- return addr_cost->pre_modify;
-
- if (c == POST_INC || c == POST_DEC || c == POST_MODIFY)
- return addr_cost->post_modify;
-
- if (c == PLUS)
- {
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- return addr_cost->imm_offset;
- else if (GET_CODE (XEXP (x, 0)) == MULT
- || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
- || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
- return addr_cost->register_extend;
-
- return addr_cost->register_offset;
- }
- else if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
- return addr_cost->imm_offset;
-
- return 0;
-}
-
-static int
aarch64_register_move_cost (enum machine_mode mode,
reg_class_t from_i, reg_class_t to_i)
{