From: Charles Baylis <charles.bay...@linaro.org> This patch adds support for modelling the varying costs of different addressing modes. The generic cost table treats all addressing modes as having equal cost.
gcc/ChangeLog: <date> Charles Baylis <charles.bay...@linaro.org> * config/arm/arm-protos.h (enum arm_addr_mode_op): New. (struct addr_mode_cost_table): New. (struct tune_params): Add field addr_mode_costs. * config/arm/arm.c (generic_addr_mode_costs): New. (arm_slowmul_tune): Initialise addr_mode_costs field. (arm_fastmul_tune): Likewise. (arm_strongarm_tune): Likewise. (arm_xscale_tune): Likewise. (arm_9e_tune): Likewise. (arm_marvell_pj4_tune): Likewise. (arm_v6t2_tune): Likewise. (arm_cortex_tune): Likewise. (arm_cortex_a8_tune): Likewise. (arm_cortex_a7_tune): Likewise. (arm_cortex_a15_tune): Likewise. (arm_cortex_a35_tune): Likewise. (arm_cortex_a53_tune): Likewise. (arm_cortex_a57_tune): Likewise. (arm_exynosm1_tune): Likewise. (arm_xgene1_tune): Likewise. (arm_cortex_a5_tune): Likewise. (arm_cortex_a9_tune): Likewise. (arm_cortex_a12_tune): Likewise. (arm_cortex_a73_tune): Likewise. (arm_v7m_tune): Likewise. (arm_cortex_m7_tune): Likewise. (arm_v6m_tune): Likewise. (arm_fa726te_tune): Likewise. (arm_mem_costs): Use table lookup to calculate cost of addressing mode. Change-Id: If71bd7c4f4bb876c5ed82dc28791130efb8bf89e --- gcc/config/arm/arm-protos.h | 20 +++++++++++ gcc/config/arm/arm.c | 83 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 47a85cc..3d6b515 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -261,12 +261,32 @@ struct cpu_vec_costs { struct cpu_cost_table; +/* Addressing mode operations. Used to index tables in struct + addr_mode_cost_table. */ +enum arm_addr_mode_op +{ + AMO_DEFAULT, + AMO_NO_WB, /* Offset with no writeback. */ + AMO_WB, /* Offset with writeback. */ + AMO_MAX /* For array size. */ +}; + +/* Table of additional costs when using addressing modes for each + access type. */ +struct addr_mode_cost_table +{ + const int integer[AMO_MAX]; + const int fp[AMO_MAX]; + const int vector[AMO_MAX]; +}; + /* Dump function ARM_PRINT_TUNE_INFO should be updated whenever this structure is modified. */ struct tune_params { const struct cpu_cost_table *insn_extra_cost; + const struct addr_mode_cost_table *addr_mode_costs; bool (*sched_adjust_cost) (rtx_insn *, int, rtx_insn *, int *); int (*branch_cost) (bool, bool); /* Vectorizer costs. */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index b8dbed6..0d31f5f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -1751,9 +1751,32 @@ const struct cpu_cost_table v7m_extra_costs = } }; +const struct addr_mode_cost_table generic_addr_mode_costs = +{ + /* int. */ + { + 0, /* AMO_DEFAULT. */ + 0, /* AMO_NO_WB. */ + 0 /* AMO_WB. */ + }, + /* float. */ + { + 0, /* AMO_DEFAULT. */ + 0, /* AMO_NO_WB. */ + 0 /* AMO_WB. */ + }, + /* vector. */ + { + 0, /* AMO_DEFAULT. */ + 0, /* AMO_NO_WB. */ + 0 /* AMO_WB. */ + } +}; + const struct tune_params arm_slowmul_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1777,6 +1800,7 @@ const struct tune_params arm_slowmul_tune = const struct tune_params arm_fastmul_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1803,6 +1827,7 @@ const struct tune_params arm_fastmul_tune = const struct tune_params arm_strongarm_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1826,6 +1851,7 @@ const struct tune_params arm_strongarm_tune = const struct tune_params arm_xscale_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ xscale_sched_adjust_cost, arm_default_branch_cost, &arm_default_vec_cost, @@ -1849,6 +1875,7 @@ const struct tune_params arm_xscale_tune = const struct tune_params arm_9e_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1872,6 +1899,7 @@ const struct tune_params arm_9e_tune = const struct tune_params arm_marvell_pj4_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1895,6 +1923,7 @@ const struct tune_params arm_marvell_pj4_tune = const struct tune_params arm_v6t2_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1920,6 +1949,7 @@ const struct tune_params arm_v6t2_tune = const struct tune_params arm_cortex_tune = { &generic_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1943,6 +1973,7 @@ const struct tune_params arm_cortex_tune = const struct tune_params arm_cortex_a8_tune = { &cortexa8_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1966,6 +1997,7 @@ const struct tune_params arm_cortex_a8_tune = const struct tune_params arm_cortex_a7_tune = { &cortexa7_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -1989,6 +2021,7 @@ const struct tune_params arm_cortex_a7_tune = const struct tune_params arm_cortex_a15_tune = { &cortexa15_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2012,6 +2045,7 @@ const struct tune_params arm_cortex_a15_tune = const struct tune_params arm_cortex_a35_tune = { &cortexa53_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2035,6 +2069,7 @@ const struct tune_params arm_cortex_a35_tune = const struct tune_params arm_cortex_a53_tune = { &cortexa53_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2058,6 +2093,7 @@ const struct tune_params arm_cortex_a53_tune = const struct tune_params arm_cortex_a57_tune = { &cortexa57_extra_costs, + &generic_addr_mode_costs, /* addressing mode costs */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2081,6 +2117,7 @@ const struct tune_params arm_cortex_a57_tune = const struct tune_params arm_exynosm1_tune = { &exynosm1_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2104,6 +2141,7 @@ const struct tune_params arm_exynosm1_tune = const struct tune_params arm_xgene1_tune = { &xgene1_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, @@ -2130,6 +2168,7 @@ const struct tune_params arm_xgene1_tune = const struct tune_params arm_cortex_a5_tune = { &cortexa5_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_cortex_a5_branch_cost, &arm_default_vec_cost, @@ -2153,6 +2192,7 @@ const struct tune_params arm_cortex_a5_tune = const struct tune_params arm_cortex_a9_tune = { &cortexa9_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ cortex_a9_sched_adjust_cost, arm_default_branch_cost, &arm_default_vec_cost, @@ -2176,6 +2216,7 @@ const struct tune_params arm_cortex_a9_tune = const struct tune_params arm_cortex_a12_tune = { &cortexa12_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, /* Vectorizer costs. */ @@ -2199,6 +2240,7 @@ const struct tune_params arm_cortex_a12_tune = const struct tune_params arm_cortex_a73_tune = { &cortexa57_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, /* Vectorizer costs. */ @@ -2229,6 +2271,7 @@ const struct tune_params arm_cortex_a73_tune = const struct tune_params arm_v7m_tune = { &v7m_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_cortex_m_branch_cost, &arm_default_vec_cost, @@ -2254,6 +2297,7 @@ const struct tune_params arm_v7m_tune = const struct tune_params arm_cortex_m7_tune = { &v7m_extra_costs, + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_cortex_m7_branch_cost, &arm_default_vec_cost, @@ -2280,6 +2324,7 @@ const struct tune_params arm_cortex_m7_tune = const struct tune_params arm_v6m_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ NULL, /* Sched adj cost. */ arm_default_branch_cost, &arm_default_vec_cost, /* Vectorizer costs. */ @@ -2303,6 +2348,7 @@ const struct tune_params arm_v6m_tune = const struct tune_params arm_fa726te_tune = { &generic_extra_costs, /* Insn extra costs. */ + &generic_addr_mode_costs, /* Addressing mode costs. */ fa726te_sched_adjust_cost, arm_default_branch_cost, &arm_default_vec_cost, @@ -9249,7 +9295,42 @@ arm_mem_costs (rtx x, const struct cpu_cost_table *extra_cost, /* Calculate cost of the addressing mode. */ if (speed_p) { - /* TODO: Add table-driven costs for addressing modes. (See patch 2) */ + arm_addr_mode_op op_type; + switch (GET_CODE (XEXP (x, 0))) + { + default: + case REG: + op_type = AMO_DEFAULT; + break; + case MINUS: + /* MINUS does not appear in RTL, but the architecture supports it, + so handle this case defensively. */ + /* fall through */ + case PLUS: + op_type = AMO_NO_WB; + break; + case PRE_INC: + case PRE_DEC: + case POST_INC: + case POST_DEC: + case PRE_MODIFY: + case POST_MODIFY: + op_type = AMO_WB; + break; + } + + if (VECTOR_MODE_P (mode)) + { + *cost += current_tune->addr_mode_costs->vector[op_type]; + } + else if (FLOAT_MODE_P (mode)) + { + *cost += current_tune->addr_mode_costs->fp[op_type]; + } + else + { + *cost += current_tune->addr_mode_costs->integer[op_type]; + } } /* Calculate cost of memory access. */ -- 2.7.4