[3/3,ARM] Add table of costs for AAarch32 addressing modes.

Message ID 1505205277-26276-4-git-send-email-charles.baylis@linaro.org
State New
Headers show
Series
  • Addressing mode costs v3
Related show

Commit Message

Charles Baylis Sept. 12, 2017, 8:34 a.m.
From: Charles Baylis <charles.baylis@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.baylis@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(-)

Comments

Kyrill Tkachov Sept. 13, 2017, 9:02 a.m. | #1
Hi Charles,

On 12/09/17 09:34, charles.baylis@linaro.org wrote:
> From: Charles Baylis <charles.baylis@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.baylis@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.  */

Please add a comment here saying that the units are in COSTS_N_INSNS
so that we can reduce the temptation to use these in inappropriate contexts.

> +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];
> +       }

No need for brackets for single-statement conditionals.

This is okay once the prerequisites are committed.
Kyrill

>      }
>
>    /* Calculate cost of memory access.  */
> -- 
> 2.7.4
>
Charles Baylis Sept. 15, 2017, 3:38 p.m. | #2
On 13 September 2017 at 10:02, Kyrill  Tkachov
<kyrylo.tkachov@foss.arm.com> wrote:

>
> Please add a comment here saying that the units are in COSTS_N_INSNS
> so that we can reduce the temptation to use these in inappropriate contexts.

>> +      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];
>> +       }
>
>
> No need for brackets for single-statement conditionals.

Done.
From a35fa59f4dc3be42a52519a90bdd2d47e74db086 Mon Sep 17 00:00:00 2001
From: Charles Baylis <charles.baylis@linaro.org>
Date: Thu, 14 Sep 2017 12:47:41 +0100
Subject: [PATCH 3/3] [ARM] Add table of costs for AAarch32 addressing modes.

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.baylis@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        | 81 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 47a85cc..7769726 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 in units of COSTS_N_INSNS() 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 64230b8..7773ec3 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.  */
+  {
+    COSTS_N_INSNS (0),	/* AMO_DEFAULT.  */
+    COSTS_N_INSNS (0),	/* AMO_NO_WB.  */
+    COSTS_N_INSNS (0)	/* AMO_WB.  */
+  },
+  /* float.  */
+  {
+    COSTS_N_INSNS (0),	/* AMO_DEFAULT.  */
+    COSTS_N_INSNS (0),	/* AMO_NO_WB.  */
+    COSTS_N_INSNS (0)	/* AMO_WB.  */
+  },
+  /* vector.  */
+  {
+    COSTS_N_INSNS (0),	/* AMO_DEFAULT.  */
+    COSTS_N_INSNS (0),	/* AMO_NO_WB.  */
+    COSTS_N_INSNS (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,
@@ -9247,6 +9293,41 @@ arm_mem_costs (rtx x, const struct cpu_cost_table *extra_cost,
        below.  See arm.md:calculate_pic_address.  */
     *cost += COSTS_N_INSNS (1);
 
+  /* Calculate cost of the addressing mode.  */
+  if (speed_p)
+    {
+      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.  */
   if (speed_p)
     {
Charles Baylis Sept. 15, 2017, 3:38 p.m. | #3
On 13 September 2017 at 10:02, Kyrill  Tkachov
<kyrylo.tkachov@foss.arm.com> wrote:

>
> Please add a comment here saying that the units are in COSTS_N_INSNS
> so that we can reduce the temptation to use these in inappropriate contexts.

>> +      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];
>> +       }
>
>
> No need for brackets for single-statement conditionals.

Done.
Kyrill Tkachov Sept. 15, 2017, 4:57 p.m. | #4
On 15/09/17 16:38, Charles Baylis wrote:
> On 13 September 2017 at 10:02, Kyrill  Tkachov
> <kyrylo.tkachov@foss.arm.com> wrote:
>
>> Please add a comment here saying that the units are in COSTS_N_INSNS
>> so that we can reduce the temptation to use these in inappropriate contexts.
>>> +      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];
>>> +       }
>>
>> No need for brackets for single-statement conditionals.
> Done.

Thanks, this is ok once the prerequisites are sorted.

Kyrill

Patch

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.  */