Patchwork convert target_expmed macro accessors into inline functions

login
register
mail settings
Submitter Nathan Froyd
Date July 27, 2012, 11:41 a.m.
Message ID <1343389290-25869-1-git-send-email-froydnj@mozilla.com>
Download mbox | patch
Permalink /patch/173645/
State New
Headers show

Comments

Nathan Froyd - July 27, 2012, 11:41 a.m.
As suggested by rth here:

http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01281.html

this patch converts all the #define accessors in expmed.h to use inline
functions instead.

By itself, doing that conversion is not very exciting.  Followup patches
might:

* Move setters into expmed.c;
* Reduce space of fields by not using NUM_MACHINE_MODES, similar to the
  convert_cost case;
* Possibly moving the getters into expmed.c, assuming that LTO will take
  care of the performance hit.  Doing so enables target_expmed to not be
  exposed everywhere.
* Lazily initialize the costs.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

	* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
	smod_pow2_cheap, zero_cost, add_cost, neg_cost, shift_cost)
	shiftadd_cost, shiftsub0_cost, shiftsub1_cost, mul_cost,
	sdiv_cost, udiv_cost, mul_widen_cost, mul_highpart_cost): Delete
	macro definitions and re-purpose as inline functions.
	(alg_hash_entry_ptr, set_alg_hash_used_p, sdiv_pow2_cheap_ptr,
	set_sdiv_pow2_cheap, smod_pow2_cheap_ptr, set_smod_pow2_cheap,
	zero_cost_ptr, set_zero_cost, add_cost_ptr, set_add_cost,
	neg_cost_ptr, set_neg_cost, shift_cost_ptr, set_shift_cost,
	shiftadd_cost_ptr, set_shiftadd_cost, shiftsub0_cost_ptr,
	set_shiftsub0_cost, shiftsub1_cost_ptr, set_shiftsub1_cost,
	mul_cost_ptr, set_mul_cost, sdiv_cost_ptr, set_sdiv_cost,
	udiv_cost_ptr, set_udiv_cost, mul_widen_cost_ptr,
	set_mul_widen_cost, mul_highpart_cost_ptr, set_mul_highpart_cost):
	New functions.
	(convert_cost_ptr): New function, split out from...
	(set_convert_cost, convert_cost): ...here.
	* expmed.c, tree-ssa-loop-ivopts.c: Update for new functions.
	* gimple-ssa-strength-reduction.c: Likewise.

---
 gcc/expmed.c                        |  230 ++++++++++---------
 gcc/expmed.h                        |  441 +++++++++++++++++++++++++++++++----
 gcc/gimple-ssa-strength-reduction.c |    6 +-
 gcc/tree-ssa-loop-ivopts.c          |   24 +-
 4 files changed, 533 insertions(+), 168 deletions(-)
Richard Henderson - July 27, 2012, 6:48 p.m.
On 07/27/2012 04:41 AM, Nathan Froyd wrote:
> Tested on x86_64-unknown-linux-gnu.  OK to commit?
> 
> -Nathan
> 
> 	* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
> 	smod_pow2_cheap, zero_cost, add_cost, neg_cost, shift_cost)
> 	shiftadd_cost, shiftsub0_cost, shiftsub1_cost, mul_cost,
> 	sdiv_cost, udiv_cost, mul_widen_cost, mul_highpart_cost): Delete
> 	macro definitions and re-purpose as inline functions.
> 	(alg_hash_entry_ptr, set_alg_hash_used_p, sdiv_pow2_cheap_ptr,
> 	set_sdiv_pow2_cheap, smod_pow2_cheap_ptr, set_smod_pow2_cheap,
> 	zero_cost_ptr, set_zero_cost, add_cost_ptr, set_add_cost,
> 	neg_cost_ptr, set_neg_cost, shift_cost_ptr, set_shift_cost,
> 	shiftadd_cost_ptr, set_shiftadd_cost, shiftsub0_cost_ptr,
> 	set_shiftsub0_cost, shiftsub1_cost_ptr, set_shiftsub1_cost,
> 	mul_cost_ptr, set_mul_cost, sdiv_cost_ptr, set_sdiv_cost,
> 	udiv_cost_ptr, set_udiv_cost, mul_widen_cost_ptr,
> 	set_mul_widen_cost, mul_highpart_cost_ptr, set_mul_highpart_cost):
> 	New functions.
> 	(convert_cost_ptr): New function, split out from...
> 	(set_convert_cost, convert_cost): ...here.
> 	* expmed.c, tree-ssa-loop-ivopts.c: Update for new functions.
> 	* gimple-ssa-strength-reduction.c: Likewise.

Ok.  And thanks!


r~

Patch

diff --git a/gcc/expmed.c b/gcc/expmed.c
index e660a3f..9743fc0 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -143,20 +143,24 @@  init_expmed_one_mode (struct init_expmed_rtl *all,
   PUT_MODE (&all->shift_sub1, mode);
   PUT_MODE (&all->convert, mode);
 
-  add_cost[speed][mode] = set_src_cost (&all->plus, speed);
-  neg_cost[speed][mode] = set_src_cost (&all->neg, speed);
-  mul_cost[speed][mode] = set_src_cost (&all->mult, speed);
-  sdiv_cost[speed][mode] = set_src_cost (&all->sdiv, speed);
-  udiv_cost[speed][mode] = set_src_cost (&all->udiv, speed);
-
-  sdiv_pow2_cheap[speed][mode] = (set_src_cost (&all->sdiv_32, speed)
-			          <= 2 * add_cost[speed][mode]);
-  smod_pow2_cheap[speed][mode] = (set_src_cost (&all->smod_32, speed)
-			          <= 4 * add_cost[speed][mode]);
-
-  shift_cost[speed][mode][0] = 0;
-  shiftadd_cost[speed][mode][0] = shiftsub0_cost[speed][mode][0]
-    = shiftsub1_cost[speed][mode][0] = add_cost[speed][mode];
+  set_add_cost (speed, mode, set_src_cost (&all->plus, speed));
+  set_neg_cost (speed, mode, set_src_cost (&all->neg, speed));
+  set_mul_cost (speed, mode, set_src_cost (&all->mult, speed));
+  set_sdiv_cost (speed, mode, set_src_cost (&all->sdiv, speed));
+  set_udiv_cost (speed, mode, set_src_cost (&all->udiv, speed));
+
+  set_sdiv_pow2_cheap (speed, mode, (set_src_cost (&all->sdiv_32, speed)
+				     <= 2 * add_cost (speed, mode)));
+  set_smod_pow2_cheap (speed, mode, (set_src_cost (&all->smod_32, speed)
+				     <= 4 * add_cost (speed, mode)));
+
+  set_shift_cost (speed, mode, 0, 0);
+  {
+    int cost = add_cost (speed, mode);
+    set_shiftadd_cost (speed, mode, 0, cost);
+    set_shiftsub0_cost (speed, mode, 0, cost);
+    set_shiftsub1_cost (speed, mode, 0, cost);
+  }
 
   n = MIN (MAX_BITS_PER_WORD, mode_bitsize);
   for (m = 1; m < n; m++)
@@ -164,10 +168,10 @@  init_expmed_one_mode (struct init_expmed_rtl *all,
       XEXP (&all->shift, 1) = all->cint[m];
       XEXP (&all->shift_mult, 1) = all->pow2[m];
 
-      shift_cost[speed][mode][m] = set_src_cost (&all->shift, speed);
-      shiftadd_cost[speed][mode][m] = set_src_cost (&all->shift_add, speed);
-      shiftsub0_cost[speed][mode][m] = set_src_cost (&all->shift_sub0, speed);
-      shiftsub1_cost[speed][mode][m] = set_src_cost (&all->shift_sub1, speed);
+      set_shift_cost (speed, mode, m, set_src_cost (&all->shift, speed));
+      set_shiftadd_cost (speed, mode, m, set_src_cost (&all->shift_add, speed));
+      set_shiftsub0_cost (speed, mode, m, set_src_cost (&all->shift_sub0, speed));
+      set_shiftsub1_cost (speed, mode, m, set_src_cost (&all->shift_sub1, speed));
     }
 
   if (SCALAR_INT_MODE_P (mode))
@@ -181,10 +185,8 @@  init_expmed_one_mode (struct init_expmed_rtl *all,
 	  PUT_MODE (&all->wide_lshr, wider_mode);
 	  XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize);
 
-	  mul_widen_cost[speed][wider_mode]
-	    = set_src_cost (&all->wide_mult, speed);
-	  mul_highpart_cost[speed][mode]
-	    = set_src_cost (&all->wide_trunc, speed);
+	  set_mul_widen_cost (speed, wider_mode, set_src_cost (&all->wide_mult, speed));
+	  set_mul_highpart_cost (speed, mode, set_src_cost (&all->wide_trunc, speed));
 	}
 
       for (mode_from = GET_CLASS_NARROWEST_MODE (MODE_INT);
@@ -295,7 +297,7 @@  init_expmed (void)
   for (speed = 0; speed < 2; speed++)
     {
       crtl->maybe_hot_insn_p = speed;
-      zero_cost[speed] = set_src_cost (const0_rtx, speed);
+      set_zero_cost (speed, set_src_cost (const0_rtx, speed));
 
       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
 	   mode != VOIDmode;
@@ -308,10 +310,13 @@  init_expmed (void)
 	init_expmed_one_mode (&all, mode, speed);
     }
 
-  if (alg_hash_used_p)
-    memset (alg_hash, 0, sizeof (alg_hash));
+  if (alg_hash_used_p ())
+    {
+      struct alg_hash_entry *p = alg_hash_entry_ptr (0);
+      memset (p, 0, sizeof (*p) * NUM_ALG_HASH_ENTRIES);
+    }
   else
-    alg_hash_used_p = true;
+    set_alg_hash_used_p (true);
   default_rtl_profile ();
 }
 
@@ -2259,8 +2264,9 @@  expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
       && INTVAL (op1) > 0
       && INTVAL (op1) < GET_MODE_PRECISION (mode)
       && INTVAL (op1) < MAX_BITS_PER_WORD
-      && shift_cost[speed][mode][INTVAL (op1)] > INTVAL (op1) * add_cost[speed][mode]
-      && shift_cost[speed][mode][INTVAL (op1)] != MAX_COST)
+      && (shift_cost (speed, mode, INTVAL (op1))
+	  > INTVAL (op1) * add_cost (speed, mode))
+      && shift_cost (speed, mode, INTVAL (op1)) != MAX_COST)
     {
       int i;
       for (i = 0; i < INTVAL (op1); i++)
@@ -2436,6 +2442,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
   enum alg_code cache_alg = alg_zero;
   bool speed = optimize_insn_for_speed_p ();
   enum machine_mode imode;
+  struct alg_hash_entry *entry_ptr;
 
   /* Indicate that no algorithm is yet found.  If no algorithm
      is found, this value will be returned and indicate failure.  */
@@ -2470,13 +2477,13 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
      fail now.  */
   if (t == 0)
     {
-      if (MULT_COST_LESS (cost_limit, zero_cost[speed]))
+      if (MULT_COST_LESS (cost_limit, zero_cost (speed)))
 	return;
       else
 	{
 	  alg_out->ops = 1;
-	  alg_out->cost.cost = zero_cost[speed];
-	  alg_out->cost.latency = zero_cost[speed];
+	  alg_out->cost.cost = zero_cost (speed);
+	  alg_out->cost.latency = zero_cost (speed);
 	  alg_out->op[0] = alg_zero;
 	  return;
 	}
@@ -2492,19 +2499,20 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
   hash_index = (t ^ (unsigned int) mode ^ (speed * 256)) % NUM_ALG_HASH_ENTRIES;
 
   /* See if we already know what to do for T.  */
-  if (alg_hash[hash_index].t == t
-      && alg_hash[hash_index].mode == mode
-      && alg_hash[hash_index].mode == mode
-      && alg_hash[hash_index].speed == speed
-      && alg_hash[hash_index].alg != alg_unknown)
+  entry_ptr = alg_hash_entry_ptr (hash_index);
+  if (entry_ptr->t == t
+      && entry_ptr->mode == mode
+      && entry_ptr->mode == mode
+      && entry_ptr->speed == speed
+      && entry_ptr->alg != alg_unknown)
     {
-      cache_alg = alg_hash[hash_index].alg;
+      cache_alg = entry_ptr->alg;
 
       if (cache_alg == alg_impossible)
 	{
 	  /* The cache tells us that it's impossible to synthesize
-	     multiplication by T within alg_hash[hash_index].cost.  */
-	  if (!CHEAPER_MULT_COST (&alg_hash[hash_index].cost, cost_limit))
+	     multiplication by T within entry_ptr->cost.  */
+	  if (!CHEAPER_MULT_COST (&entry_ptr->cost, cost_limit))
 	    /* COST_LIMIT is at least as restrictive as the one
 	       recorded in the hash table, in which case we have no
 	       hope of synthesizing a multiplication.  Just
@@ -2518,7 +2526,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	}
       else
 	{
-	  if (CHEAPER_MULT_COST (cost_limit, &alg_hash[hash_index].cost))
+	  if (CHEAPER_MULT_COST (cost_limit, &entry_ptr->cost))
 	    /* The cached algorithm shows that this multiplication
 	       requires more cost than COST_LIMIT.  Just return.  This
 	       way, we don't clobber this cache entry with
@@ -2564,10 +2572,10 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	  q = t >> m;
 	  /* The function expand_shift will choose between a shift and
 	     a sequence of additions, so the observed cost is given as
-	     MIN (m * add_cost[speed][mode], shift_cost[speed][mode][m]).  */
-	  op_cost = m * add_cost[speed][mode];
-	  if (shift_cost[speed][mode][m] < op_cost)
-	    op_cost = shift_cost[speed][mode][m];
+	     MIN (m * add_cost(speed, mode), shift_cost(speed, mode, m)).  */
+	  op_cost = m * add_cost (speed, mode);
+	  if (shift_cost (speed, mode, m) < op_cost)
+	    op_cost = shift_cost (speed, mode, m);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, q, &new_limit, mode);
@@ -2594,11 +2602,11 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	      q = ~(~orig_t >> m);
 	      /* The function expand_shift will choose between a shift
 		 and a sequence of additions, so the observed cost is
-		 given as MIN (m * add_cost[speed][mode],
-		 shift_cost[speed][mode][m]).  */
-	      op_cost = m * add_cost[speed][mode];
-	      if (shift_cost[speed][mode][m] < op_cost)
-		op_cost = shift_cost[speed][mode][m];
+		 given as MIN (m * add_cost(speed, mode),
+		 shift_cost(speed, mode, m)).  */
+	      op_cost = m * add_cost (speed, mode);
+	      if (shift_cost (speed, mode, m) < op_cost)
+		op_cost = shift_cost (speed, mode, m);
 	      new_limit.cost = best_cost.cost - op_cost;
 	      new_limit.latency = best_cost.latency - op_cost;
 	      synth_mult (alg_in, q, &new_limit, mode);
@@ -2640,7 +2648,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	{
 	  /* T ends with ...111.  Multiply by (T + 1) and subtract 1.  */
 
-	  op_cost = add_cost[speed][mode];
+	  op_cost = add_cost (speed, mode);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, t + 1, &new_limit, mode);
@@ -2660,7 +2668,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	{
 	  /* T ends with ...01 or ...011.  Multiply by (T - 1) and add 1.  */
 
-	  op_cost = add_cost[speed][mode];
+	  op_cost = add_cost (speed, mode);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, t - 1, &new_limit, mode);
@@ -2682,7 +2690,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
       m = exact_log2 (-orig_t + 1);
       if (m >= 0 && m < maxm)
 	{
-	  op_cost = shiftsub1_cost[speed][mode][m];
+	  op_cost = shiftsub1_cost (speed, mode, m);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m,
@@ -2729,14 +2737,14 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	     equal to its cost, otherwise assume that on superscalar
 	     hardware the shift may be executed concurrently with the
 	     earlier steps in the algorithm.  */
-	  op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m];
-	  if (shiftadd_cost[speed][mode][m] < op_cost)
+	  op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
+	  if (shiftadd_cost (speed, mode, m) < op_cost)
 	    {
-	      op_cost = shiftadd_cost[speed][mode][m];
+	      op_cost = shiftadd_cost (speed, mode, m);
 	      op_latency = op_cost;
 	    }
 	  else
-	    op_latency = add_cost[speed][mode];
+	    op_latency = add_cost (speed, mode);
 
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_latency;
@@ -2768,14 +2776,14 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	     equal to it's cost, otherwise assume that on superscalar
 	     hardware the shift may be executed concurrently with the
 	     earlier steps in the algorithm.  */
-	  op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m];
-	  if (shiftsub0_cost[speed][mode][m] < op_cost)
+	  op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
+	  if (shiftsub0_cost (speed, mode, m) < op_cost)
 	    {
-	      op_cost = shiftsub0_cost[speed][mode][m];
+	      op_cost = shiftsub0_cost (speed, mode, m);
 	      op_latency = op_cost;
 	    }
 	  else
-	    op_latency = add_cost[speed][mode];
+	    op_latency = add_cost (speed, mode);
 
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_latency;
@@ -2809,7 +2817,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
       m = exact_log2 (q);
       if (m >= 0 && m < maxm)
 	{
-	  op_cost = shiftadd_cost[speed][mode][m];
+	  op_cost = shiftadd_cost (speed, mode, m);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, (t - 1) >> m, &new_limit, mode);
@@ -2834,7 +2842,7 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
       m = exact_log2 (q);
       if (m >= 0 && m < maxm)
 	{
-	  op_cost = shiftsub0_cost[speed][mode][m];
+	  op_cost = shiftsub0_cost (speed, mode, m);
 	  new_limit.cost = best_cost.cost - op_cost;
 	  new_limit.latency = best_cost.latency - op_cost;
 	  synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
@@ -2863,23 +2871,23 @@  synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
 	 we are asked to find an algorithm for T within the same or
 	 lower COST_LIMIT, we can immediately return to the
 	 caller.  */
-      alg_hash[hash_index].t = t;
-      alg_hash[hash_index].mode = mode;
-      alg_hash[hash_index].speed = speed;
-      alg_hash[hash_index].alg = alg_impossible;
-      alg_hash[hash_index].cost = *cost_limit;
+      entry_ptr->t = t;
+      entry_ptr->mode = mode;
+      entry_ptr->speed = speed;
+      entry_ptr->alg = alg_impossible;
+      entry_ptr->cost = *cost_limit;
       return;
     }
 
   /* Cache the result.  */
   if (!cache_hit)
     {
-      alg_hash[hash_index].t = t;
-      alg_hash[hash_index].mode = mode;
-      alg_hash[hash_index].speed = speed;
-      alg_hash[hash_index].alg = best_alg->op[best_alg->ops];
-      alg_hash[hash_index].cost.cost = best_cost.cost;
-      alg_hash[hash_index].cost.latency = best_cost.latency;
+      entry_ptr->t = t;
+      entry_ptr->mode = mode;
+      entry_ptr->speed = speed;
+      entry_ptr->alg = best_alg->op[best_alg->ops];
+      entry_ptr->cost.cost = best_cost.cost;
+      entry_ptr->cost.latency = best_cost.latency;
     }
 
   /* If we are getting a too long sequence for `struct algorithm'
@@ -2925,7 +2933,7 @@  choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
   /* Ensure that mult_cost provides a reasonable upper bound.
      Any constant multiplication can be performed with less
      than 2 * bits additions.  */
-  op_cost = 2 * GET_MODE_UNIT_BITSIZE (mode) * add_cost[speed][mode];
+  op_cost = 2 * GET_MODE_UNIT_BITSIZE (mode) * add_cost (speed, mode);
   if (mult_cost > op_cost)
     mult_cost = op_cost;
 
@@ -2938,7 +2946,7 @@  choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
      `unsigned int' */
   if (HOST_BITS_PER_INT >= GET_MODE_UNIT_BITSIZE (mode))
     {
-      op_cost = neg_cost[speed][mode];
+      op_cost = neg_cost(speed, mode);
       if (MULT_COST_LESS (&alg->cost, mult_cost))
 	{
 	  limit.cost = alg->cost.cost - op_cost;
@@ -2958,7 +2966,7 @@  choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
     }
 
   /* This proves very useful for division-by-constant.  */
-  op_cost = add_cost[speed][mode];
+  op_cost = add_cost (speed, mode);
   if (MULT_COST_LESS (&alg->cost, mult_cost))
     {
       limit.cost = alg->cost.cost - op_cost;
@@ -3249,7 +3257,7 @@  expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
 	     Exclude cost of op0 from max_cost to match the cost
 	     calculation of the synth_mult.  */
 	  max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), speed)
-		      - neg_cost[speed][mode]);
+		      - neg_cost(speed, mode));
 	  if (max_cost > 0
 	      && choose_mult_variant (mode, -coeff, &algorithm,
 				      &variant, max_cost))
@@ -3350,7 +3358,7 @@  expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
 
       /* Exclude cost of op0 from max_cost to match the cost
 	 calculation of the synth_mult.  */
-      max_cost = mul_widen_cost[speed][mode];
+      max_cost = mul_widen_cost (speed, mode);
       if (choose_mult_variant (mode, coeff, &algorithm, &variant,
 			       max_cost))
 	{
@@ -3564,7 +3572,7 @@  expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
 
   /* Firstly, try using a multiplication insn that only generates the needed
      high part of the product, and in the sign flavor of unsignedp.  */
-  if (mul_highpart_cost[speed][mode] < max_cost)
+  if (mul_highpart_cost (speed, mode) < max_cost)
     {
       moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
       tem = expand_binop (mode, moptab, op0, narrow_op1, target,
@@ -3576,8 +3584,9 @@  expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
   /* Secondly, same as above, but use sign flavor opposite of unsignedp.
      Need to adjust the result after the multiplication.  */
   if (size - 1 < BITS_PER_WORD
-      && (mul_highpart_cost[speed][mode] + 2 * shift_cost[speed][mode][size-1]
-	  + 4 * add_cost[speed][mode] < max_cost))
+      && (mul_highpart_cost (speed, mode)
+	  + 2 * shift_cost (speed, mode, size-1)
+	  + 4 * add_cost (speed, mode) < max_cost))
     {
       moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
       tem = expand_binop (mode, moptab, op0, narrow_op1, target,
@@ -3591,7 +3600,7 @@  expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
   /* Try widening multiplication.  */
   moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
   if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
-      && mul_widen_cost[speed][wider_mode] < max_cost)
+      && mul_widen_cost (speed, wider_mode) < max_cost)
     {
       tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
 			  unsignedp, OPTAB_WIDEN);
@@ -3602,7 +3611,8 @@  expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
   /* Try widening the mode and perform a non-widening multiplication.  */
   if (optab_handler (smul_optab, wider_mode) != CODE_FOR_nothing
       && size - 1 < BITS_PER_WORD
-      && mul_cost[speed][wider_mode] + shift_cost[speed][mode][size-1] < max_cost)
+      && (mul_cost (speed, wider_mode) + shift_cost (speed, mode, size-1)
+	  < max_cost))
     {
       rtx insns, wop0, wop1;
 
@@ -3629,8 +3639,9 @@  expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
   moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
   if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
       && size - 1 < BITS_PER_WORD
-      && (mul_widen_cost[speed][wider_mode] + 2 * shift_cost[speed][mode][size-1]
-	  + 4 * add_cost[speed][mode] < max_cost))
+      && (mul_widen_cost (speed, wider_mode)
+	  + 2 * shift_cost (speed, mode, size-1)
+	  + 4 * add_cost (speed, mode) < max_cost))
     {
       tem = expand_binop (wider_mode, moptab, op0, narrow_op1,
 			  NULL_RTX, ! unsignedp, OPTAB_WIDEN);
@@ -3684,13 +3695,13 @@  expmed_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
     return expmed_mult_highpart_optab (mode, op0, op1, target,
 				       unsignedp, max_cost);
 
-  extra_cost = shift_cost[speed][mode][GET_MODE_BITSIZE (mode) - 1];
+  extra_cost = shift_cost (speed, mode, GET_MODE_BITSIZE (mode) - 1);
 
   /* Check whether we try to multiply by a negative constant.  */
   if (!unsignedp && ((cnst1 >> (GET_MODE_BITSIZE (mode) - 1)) & 1))
     {
       sign_adjust = true;
-      extra_cost += add_cost[speed][mode];
+      extra_cost += add_cost (speed, mode);
     }
 
   /* See whether shift/add multiplication is cheap enough.  */
@@ -3880,7 +3891,8 @@  expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
 
       temp = gen_reg_rtx (mode);
       temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1);
-      if (shift_cost[optimize_insn_for_speed_p ()][mode][ushift] > COSTS_N_INSNS (1))
+      if (shift_cost (optimize_insn_for_speed_p (), mode, ushift)
+	  > COSTS_N_INSNS (1))
 	temp = expand_binop (mode, and_optab, temp, GEN_INT (d - 1),
 			     NULL_RTX, 0, OPTAB_LIB_WIDEN);
       else
@@ -4083,10 +4095,13 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
   /* Only deduct something for a REM if the last divide done was
      for a different constant.   Then set the constant of the last
      divide.  */
-  max_cost = unsignedp ? udiv_cost[speed][compute_mode] : sdiv_cost[speed][compute_mode];
+  max_cost = (unsignedp 
+	      ? udiv_cost (speed, compute_mode)
+	      : sdiv_cost (speed, compute_mode));
   if (rem_flag && ! (last_div_const != 0 && op1_is_constant
 		     && INTVAL (op1) == last_div_const))
-    max_cost -= mul_cost[speed][compute_mode] + add_cost[speed][compute_mode];
+    max_cost -= (mul_cost (speed, compute_mode)
+		 + add_cost (speed, compute_mode));
 
   last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0;
 
@@ -4200,9 +4215,9 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 			      goto fail1;
 
 			    extra_cost
-			      = (shift_cost[speed][compute_mode][post_shift - 1]
-				 + shift_cost[speed][compute_mode][1]
-				 + 2 * add_cost[speed][compute_mode]);
+			      = (shift_cost (speed, compute_mode, post_shift - 1)
+				 + shift_cost (speed, compute_mode, 1)
+				 + 2 * add_cost (speed, compute_mode));
 			    t1 = expmed_mult_highpart (compute_mode, op0,
 						       GEN_INT (ml),
 						       NULL_RTX, 1,
@@ -4233,8 +4248,8 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 			      (RSHIFT_EXPR, compute_mode, op0,
 			       pre_shift, NULL_RTX, 1);
 			    extra_cost
-			      = (shift_cost[speed][compute_mode][pre_shift]
-				 + shift_cost[speed][compute_mode][post_shift]);
+			      = (shift_cost (speed, compute_mode, pre_shift)
+				 + shift_cost (speed, compute_mode, post_shift));
 			    t2 = expmed_mult_highpart (compute_mode, t1,
 						       GEN_INT (ml),
 						       NULL_RTX, 1,
@@ -4293,8 +4308,9 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 		      goto fail1;
 		  }
 		else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
-			 && (rem_flag ? smod_pow2_cheap[speed][compute_mode]
-				      : sdiv_pow2_cheap[speed][compute_mode])
+			 && (rem_flag
+			     ? smod_pow2_cheap (speed, compute_mode)
+			     : sdiv_pow2_cheap (speed, compute_mode))
 			 /* We assume that cheap metric is true if the
 			    optab has an expander for this mode.  */
 			 && ((optab_handler ((rem_flag ? smod_optab
@@ -4314,7 +4330,7 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 			  return gen_lowpart (mode, remainder);
 		      }
 
-		    if (sdiv_pow2_cheap[speed][compute_mode]
+		    if (sdiv_pow2_cheap (speed, compute_mode)
 			&& ((optab_handler (sdiv_optab, compute_mode)
 			     != CODE_FOR_nothing)
 			    || (optab_handler (sdivmod_optab, compute_mode)
@@ -4358,9 +4374,9 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 			    || size - 1 >= BITS_PER_WORD)
 			  goto fail1;
 
-			extra_cost = (shift_cost[speed][compute_mode][post_shift]
-				      + shift_cost[speed][compute_mode][size - 1]
-				      + add_cost[speed][compute_mode]);
+			extra_cost = (shift_cost (speed, compute_mode, post_shift)
+				      + shift_cost (speed, compute_mode, size - 1)
+				      + add_cost (speed, compute_mode));
 			t1 = expmed_mult_highpart (compute_mode, op0,
 						   GEN_INT (ml), NULL_RTX, 0,
 						   max_cost - extra_cost);
@@ -4393,9 +4409,9 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 
 			ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
 			mlr = gen_int_mode (ml, compute_mode);
-			extra_cost = (shift_cost[speed][compute_mode][post_shift]
-				      + shift_cost[speed][compute_mode][size - 1]
-				      + 2 * add_cost[speed][compute_mode]);
+			extra_cost = (shift_cost (speed, compute_mode, post_shift)
+				      + shift_cost (speed, compute_mode, size - 1)
+				      + 2 * add_cost (speed, compute_mode));
 			t1 = expmed_mult_highpart (compute_mode, op0, mlr,
 						   NULL_RTX, 0,
 						   max_cost - extra_cost);
@@ -4481,9 +4497,9 @@  expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 			   size - 1, NULL_RTX, 0);
 			t2 = expand_binop (compute_mode, xor_optab, op0, t1,
 					   NULL_RTX, 0, OPTAB_WIDEN);
-			extra_cost = (shift_cost[speed][compute_mode][post_shift]
-				      + shift_cost[speed][compute_mode][size - 1]
-				      + 2 * add_cost[speed][compute_mode]);
+			extra_cost = (shift_cost (speed, compute_mode, post_shift)
+				      + shift_cost (speed, compute_mode, size - 1)
+				      + 2 * add_cost (speed, compute_mode));
 			t3 = expmed_mult_highpart (compute_mode, t2,
 						   GEN_INT (ml), NULL_RTX, 1,
 						   max_cost - extra_cost);
diff --git a/gcc/expmed.h b/gcc/expmed.h
index ea141bc..97e17f3 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -171,45 +171,393 @@  extern struct target_expmed *this_target_expmed;
 #define this_target_expmed (&default_target_expmed)
 #endif
 
-#define alg_hash \
-  (this_target_expmed->x_alg_hash)
-#define alg_hash_used_p \
-  (this_target_expmed->x_alg_hash_used_p)
-#define sdiv_pow2_cheap \
-  (this_target_expmed->x_sdiv_pow2_cheap)
-#define smod_pow2_cheap \
-  (this_target_expmed->x_smod_pow2_cheap)
-#define zero_cost \
-  (this_target_expmed->x_zero_cost)
-#define add_cost \
-  (this_target_expmed->x_add_cost)
-#define neg_cost \
-  (this_target_expmed->x_neg_cost)
-#define shift_cost \
-  (this_target_expmed->x_shift_cost)
-#define shiftadd_cost \
-  (this_target_expmed->x_shiftadd_cost)
-#define shiftsub0_cost \
-  (this_target_expmed->x_shiftsub0_cost)
-#define shiftsub1_cost \
-  (this_target_expmed->x_shiftsub1_cost)
-#define mul_cost \
-  (this_target_expmed->x_mul_cost)
-#define sdiv_cost \
-  (this_target_expmed->x_sdiv_cost)
-#define udiv_cost \
-  (this_target_expmed->x_udiv_cost)
-#define mul_widen_cost \
-  (this_target_expmed->x_mul_widen_cost)
-#define mul_highpart_cost \
-  (this_target_expmed->x_mul_highpart_cost)
+/* Return a pointer to the alg_hash_entry at IDX.  */
 
-/* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
+static inline struct alg_hash_entry *
+alg_hash_entry_ptr (int idx)
+{
+  return &this_target_expmed->x_alg_hash[idx];
+}
+
+/* Return true if the x_alg_hash field might have been used.  */
+
+static inline bool
+alg_hash_used_p (void)
+{
+  return this_target_expmed->x_alg_hash_used_p;
+}
+
+/* Set whether the x_alg_hash field might have been used.  */
+
+static inline void
+set_alg_hash_used_p (bool usedp)
+{
+  this_target_expmed->x_alg_hash_used_p = usedp;
+}
+
+/* Subroutine of {set_,}sdiv_pow2_cheap.  Not to be used otherwise.  */
+
+static inline bool *
+sdiv_pow2_cheap_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_sdiv_pow2_cheap[speed][mode];
+}
+
+/* Set whether a signed division by a power of 2 is cheap in MODE
+   when optimizing for SPEED.  */
+
+static inline void
+set_sdiv_pow2_cheap (bool speed, enum machine_mode mode, bool cheap_p)
+{
+  *sdiv_pow2_cheap_ptr (speed, mode) = cheap_p;
+}
+
+/* Return whether a signed division by a power of 2 is cheap in MODE
+   when optimizing for SPEED.  */
+
+static inline bool
+sdiv_pow2_cheap (bool speed, enum machine_mode mode)
+{
+  return *sdiv_pow2_cheap_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}smod_pow2_cheap.  Not to be used otherwise.  */
+
+static inline bool *
+smod_pow2_cheap_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_smod_pow2_cheap[speed][mode];
+}
+
+/* Set whether a signed modulo by a power of 2 is CHEAP in MODE when
+   optimizing for SPEED.  */
+
+static inline void
+set_smod_pow2_cheap (bool speed, enum machine_mode mode, bool cheap)
+{
+  *smod_pow2_cheap_ptr (speed, mode) = cheap;
+}
+
+/* Return whether a signed modulo by a power of 2 is cheap in MODE
+   when optimizing for SPEED.  */
+
+static inline bool
+smod_pow2_cheap (bool speed, enum machine_mode mode)
+{
+  return *smod_pow2_cheap_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}zero_cost.  Not to be used otherwise.  */
+
+static inline int *
+zero_cost_ptr (bool speed)
+{
+  return &this_target_expmed->x_zero_cost[speed];
+}
+
+/* Set the COST of loading zero when optimizing for SPEED.  */
+
+static inline void
+set_zero_cost (bool speed, int cost)
+{
+  *zero_cost_ptr (speed) = cost;
+}
+
+/* Return the COST of loading zero when optimizing for SPEED.  */
+
+static inline int
+zero_cost (bool speed)
+{
+  return *zero_cost_ptr (speed);
+}
+
+/* Subroutine of {set_,}add_cost.  Not to be used otherwise.  */
+
+static inline int *
+add_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_add_cost[speed][mode];
+}
+
+/* Set the COST of computing an add in MODE when optimizing for SPEED.  */
+
+static inline void
+set_add_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *add_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost of computing an add in MODE when optimizing for SPEED.  */
+
+static inline int
+add_cost (bool speed, enum machine_mode mode)
+{
+  return *add_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}neg_cost.  Not to be used otherwise.  */
+
+static inline int *
+neg_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_neg_cost[speed][mode];
+}
+
+/* Set the COST of computing a negation in MODE when optimizing for SPEED.  */
+
+static inline void
+set_neg_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *neg_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost of computing a negation in MODE when optimizing for
+   SPEED.  */
+
+static inline int
+neg_cost (bool speed, enum machine_mode mode)
+{
+  return *neg_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}shift_cost.  Not to be used otherwise.  */
+
+static inline int *
+shift_cost_ptr (bool speed, enum machine_mode mode, int bits)
+{
+  return &this_target_expmed->x_shift_cost[speed][mode][bits];
+}
+
+/* Set the COST of doing a shift in MODE by BITS when optimizing for SPEED.  */
+
+static inline void
+set_shift_cost (bool speed, enum machine_mode mode, int bits, int cost)
+{
+  *shift_cost_ptr (speed, mode, bits) = cost;
+}
+
+/* Return the cost of doing a shift in MODE by BITS when optimizing for
+   SPEED.  */
+
+static inline int
+shift_cost (bool speed, enum machine_mode mode, int bits)
+{
+  return *shift_cost_ptr (speed, mode, bits);
+}
+
+/* Subroutine of {set_,}shiftadd_cost.  Not to be used otherwise.  */
+
+static inline int *
+shiftadd_cost_ptr (bool speed, enum machine_mode mode, int bits)
+{
+  return &this_target_expmed->x_shiftadd_cost[speed][mode][bits];
+}
+
+/* Set the COST of doing a shift in MODE by BITS followed by an add when
+   optimizing for SPEED.  */
+
+static inline void
+set_shiftadd_cost (bool speed, enum machine_mode mode, int bits, int cost)
+{
+  *shiftadd_cost_ptr (speed, mode, bits) = cost;
+}
+
+/* Return the cost of doing a shift in MODE by BITS followed by an add
+   when optimizing for SPEED.  */
+
+static inline int
+shiftadd_cost (bool speed, enum machine_mode mode, int bits)
+{
+  return *shiftadd_cost_ptr (speed, mode, bits);
+}
+
+/* Subroutine of {set_,}shiftsub0_cost.  Not to be used otherwise.  */
+
+static inline int *
+shiftsub0_cost_ptr (bool speed, enum machine_mode mode, int bits)
+{
+  return &this_target_expmed->x_shiftsub0_cost[speed][mode][bits];
+}
+
+/* Set the COST of doing a shift in MODE by BITS and then subtracting a
+   value when optimizing for SPEED.  */
+
+static inline void
+set_shiftsub0_cost (bool speed, enum machine_mode mode, int bits, int cost)
+{
+  *shiftsub0_cost_ptr (speed, mode, bits) = cost;
+}
+
+/* Return the cost of doing a shift in MODE by BITS and then subtracting
+   a value when optimizing for SPEED.  */
+
+static inline int
+shiftsub0_cost (bool speed, enum machine_mode mode, int bits)
+{
+  return *shiftsub0_cost_ptr (speed, mode, bits);
+}
+
+/* Subroutine of {set_,}shiftsub1_cost.  Not to be used otherwise.  */
+
+static inline int *
+shiftsub1_cost_ptr (bool speed, enum machine_mode mode, int bits)
+{
+  return &this_target_expmed->x_shiftsub1_cost[speed][mode][bits];
+}
+
+/* Set the COST of subtracting a shift in MODE by BITS from a value when
+   optimizing for SPEED.  */
+
+static inline void
+set_shiftsub1_cost (bool speed, enum machine_mode mode, int bits, int cost)
+{
+  *shiftsub1_cost_ptr (speed, mode, bits) = cost;
+}
+
+/* Return the cost of subtracting a shift in MODE by BITS from a value
+   when optimizing for SPEED.  */
+
+static inline int
+shiftsub1_cost (bool speed, enum machine_mode mode, int bits)
+{
+  return *shiftsub1_cost_ptr (speed, mode, bits);
+}
+
+/* Subroutine of {set_,}mul_cost.  Not to be used otherwise.  */
+
+static inline int *
+mul_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_mul_cost[speed][mode];
+}
+
+/* Set the COST of doing a multiplication in MODE when optimizing for
+   SPEED.  */
+
+static inline void
+set_mul_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *mul_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost of doing a multiplication in MODE when optimizing
+   for SPEED.  */
+
+static inline int
+mul_cost (bool speed, enum machine_mode mode)
+{
+  return *mul_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}sdiv_cost.  Not to be used otherwise.  */
+
+static inline int *
+sdiv_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_sdiv_cost[speed][mode];
+}
+
+/* Set the COST of doing a signed division in MODE when optimizing
    for SPEED.  */
 
 static inline void
-set_convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
-		  bool speed, int cost)
+set_sdiv_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *sdiv_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost of doing a signed division in MODE when optimizing
+   for SPEED.  */
+
+static inline int
+sdiv_cost (bool speed, enum machine_mode mode)
+{
+  return *sdiv_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}udiv_cost.  Not to be used otherwise.  */
+
+static inline int *
+udiv_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_udiv_cost[speed][mode];
+}
+
+/* Set the COST of doing an unsigned division in MODE when optimizing
+   for SPEED.  */
+
+static inline void
+set_udiv_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *udiv_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost of doing an unsigned division in MODE when
+   optimizing for SPEED.  */
+
+static inline int
+udiv_cost (bool speed, enum machine_mode mode)
+{
+  return *udiv_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}mul_widen_cost.  Not to be used otherwise.  */
+
+static inline int *
+mul_widen_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_mul_widen_cost[speed][mode];
+}
+
+/* Set the COST for computing a widening multiplication in MODE when
+   optimizing for SPEED.  */
+
+static inline void
+set_mul_widen_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *mul_widen_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost for computing a widening multiplication in MODE when
+   optimizing for SPEED.  */
+
+static inline int
+mul_widen_cost (bool speed, enum machine_mode mode)
+{
+  return *mul_widen_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}mul_highpart_cost.  Not to be used otherwise.  */
+
+static inline int *
+mul_highpart_cost_ptr (bool speed, enum machine_mode mode)
+{
+  return &this_target_expmed->x_mul_highpart_cost[speed][mode];
+}
+
+/* Set the COST for computing the high part of a multiplication in MODE
+   when optimizing for SPEED.  */
+
+static inline void
+set_mul_highpart_cost (bool speed, enum machine_mode mode, int cost)
+{
+  *mul_highpart_cost_ptr (speed, mode) = cost;
+}
+
+/* Return the cost for computing the high part of a multiplication in MODE
+   when optimizing for SPEED.  */
+
+static inline int
+mul_highpart_cost (bool speed, enum machine_mode mode)
+{
+  return *mul_highpart_cost_ptr (speed, mode);
+}
+
+/* Subroutine of {set_,}convert_cost.  Not to be used otherwise.  */
+
+static inline int *
+convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode,
+		  bool speed)
 {
   int to_idx, from_idx;
 
@@ -220,7 +568,17 @@  set_convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
 
   to_idx = to_mode - MIN_MODE_INT;
   from_idx = from_mode - MIN_MODE_INT;
-  this_target_expmed->x_convert_cost[speed][to_idx][from_idx] = cost;
+  return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
+}
+
+/* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
+   for SPEED.  */
+
+static inline void
+set_convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
+		  bool speed, int cost)
+{
+  *convert_cost_ptr (to_mode, from_mode, speed) = cost;
 }
 
 /* Return the cost for converting from FROM_MODE to TO_MODE when optimizing
@@ -230,16 +588,7 @@  static inline int
 convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
 	      bool speed)
 {
-  int to_idx, from_idx;
-
-  gcc_assert (to_mode >= MIN_MODE_INT
-	      && to_mode <= MAX_MODE_INT
-	      && from_mode >= MIN_MODE_INT
-	      && from_mode <= MAX_MODE_INT);
-
-  to_idx = to_mode - MIN_MODE_INT;
-  from_idx = from_mode - MIN_MODE_INT;
-  return this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
+  return *convert_cost_ptr (to_mode, from_mode, speed);
 }
 
 extern int mult_by_coeff_cost (HOST_WIDE_INT, enum machine_mode, bool);
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index afeb70f..66ddfd7 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -344,16 +344,16 @@  stmt_cost (gimple gs, bool speed)
 	return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed);
 
       gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
-      return mul_cost[speed][lhs_mode];
+      return mul_cost (speed, lhs_mode);
 
     case PLUS_EXPR:
     case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       rhs2 = gimple_assign_rhs2 (gs);
-      return add_cost[speed][lhs_mode];
+      return add_cost (speed, lhs_mode);
 
     case NEGATE_EXPR:
-      return neg_cost[speed][lhs_mode];
+      return neg_cost (speed, lhs_mode);
 
     case NOP_EXPR:
       return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 0d3e1bf..41c811f 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -3308,7 +3308,7 @@  get_address_cost (bool symbol_present, bool var_present,
 	 If VAR_PRESENT is true, try whether the mode with
 	 SYMBOL_PRESENT = false is cheaper even with cost of addition, and
 	 if this is the case, use it.  */
-      add_c = add_cost[speed][address_mode];
+      add_c = add_cost (speed, address_mode);
       for (i = 0; i < 8; i++)
 	{
 	  var_p = i & 1;
@@ -3392,7 +3392,7 @@  get_address_cost (bool symbol_present, bool var_present,
     cost += mult_by_coeff_cost (ratio, address_mode, speed);
 
   if (s_offset && !offset_p && !symbol_present)
-    cost += add_cost[speed][address_mode];
+    cost += add_cost (speed, address_mode);
 
   if (may_autoinc)
     *may_autoinc = autoinc;
@@ -3422,10 +3422,10 @@  get_shiftadd_cost (tree expr, enum machine_mode mode, comp_cost cost0,
     return false;
 
   sa_cost = (TREE_CODE (expr) != MINUS_EXPR
-             ? shiftadd_cost[speed][mode][m]
+             ? shiftadd_cost (speed, mode, m)
              : (mult == op1
-                ? shiftsub1_cost[speed][mode][m]
-                : shiftsub0_cost[speed][mode][m]));
+                ? shiftsub1_cost (speed, mode, m)
+                : shiftsub0_cost (speed, mode, m)));
   res = new_cost (sa_cost, 0);
   res = add_costs (res, mult == op1 ? cost0 : cost1);
 
@@ -3559,7 +3559,7 @@  force_expr_to_var_cost (tree expr, bool speed)
     case PLUS_EXPR:
     case MINUS_EXPR:
     case NEGATE_EXPR:
-      cost = new_cost (add_cost[speed][mode], 0);
+      cost = new_cost (add_cost (speed, mode), 0);
       if (TREE_CODE (expr) != NEGATE_EXPR)
         {
           tree mult = NULL_TREE;
@@ -3571,8 +3571,8 @@  force_expr_to_var_cost (tree expr, bool speed)
 
           if (mult != NULL_TREE
               && cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
-              && get_shiftadd_cost (expr, mode, cost0, cost1, mult, speed,
-                                    &sa_cost))
+              && get_shiftadd_cost (expr, mode, cost0, cost1, mult,
+                                    speed, &sa_cost))
             return sa_cost;
         }
       break;
@@ -4060,7 +4060,7 @@  get_computation_cost_at (struct ivopts_data *data,
 					 &symbol_present, &var_present,
 					 &offset, depends_on));
       cost.cost /= avg_loop_niter (data->current_loop);
-      cost.cost += add_cost[data->speed][TYPE_MODE (ctype)];
+      cost.cost += add_cost (data->speed, TYPE_MODE (ctype));
     }
 
   if (inv_expr_id)
@@ -4101,14 +4101,14 @@  get_computation_cost_at (struct ivopts_data *data,
       are added once to the variable, if present.  */
   if (var_present && (symbol_present || offset))
     cost.cost += adjust_setup_cost (data,
-				    add_cost[speed][TYPE_MODE (ctype)]);
+				    add_cost (speed, TYPE_MODE (ctype)));
 
   /* Having offset does not affect runtime cost in case it is added to
      symbol, but it increases complexity.  */
   if (offset)
     cost.complexity++;
 
-  cost.cost += add_cost[speed][TYPE_MODE (ctype)];
+  cost.cost += add_cost (speed, TYPE_MODE (ctype));
 
   aratio = ratio > 0 ? ratio : -ratio;
   if (aratio != 1)
@@ -4958,7 +4958,7 @@  determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand)
      or a const set.  */
   if (cost_base.cost == 0)
     cost_base.cost = COSTS_N_INSNS (1);
-  cost_step = add_cost[data->speed][TYPE_MODE (TREE_TYPE (base))];
+  cost_step = add_cost (data->speed, TYPE_MODE (TREE_TYPE (base)));
 
   cost = cost_step + adjust_setup_cost (data, cost_base.cost);