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

Reply via email to