diff mbox

PR 53249: Multiple address modes for same address space

Message ID 87vck9duec.fsf@talisman.home
State New
Headers show

Commit Message

Richard Sandiford May 6, 2012, 6:41 p.m. UTC
x32 uses a mixture of MEM address modes for the same address space.
Some MEMs have SImode addresses, some have DImode.  This means that
the currently common idiom:

    targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem))

isn't trustworthy.  We have to use the mode of the address if it has one,
and only fall back on the above for VOIDmode (CONST_INT) addresses.

We actually already have two (identical) functions to calculate
such a mode.  The patch below puts the function in a more general place
and uses it instead of the above for rtl-level stuff.

I'm not sure whether what x32 is doing is a good thing, but I like the
patch anyway because (a) it removes a duplicated function and (b) it at
least abstracts the concept away.

Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested to
make sure that there were no differences for cc1 .ii files for MIPS
n32, o32 and n64.  (I used MIPS to get LO_SUM coverage.)  OK to install?

Richard


gcc/
	PR middle-end/53249
	* dwarf2out.h (get_address_mode): Move declaration to...
	* rtl.h: ...here.
	* dwarf2out.c (get_address_mode): Move definition to...
	* rtlanal.c: ...here.
	* var-tracking.c (get_address_mode): Delete.
	* combine.c (find_split_point): Use get_address_mode instead of
	targetm.addr_space.address_mode.
	* cselib.c (cselib_record_sets): Likewise.
	* dse.c (canon_address, record_store): Likewise.
	* emit-rtl.c (adjust_address_1, offset_address): Likewise.
	* expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
	(store_by_pieces_1, expand_assignment, store_expr, store_constructor)
	(expand_expr_real_1): Likewise.
	* ifcvt.c (noce_try_cmove_arith): Likewise.
	* optabs.c (maybe_legitimize_operand_same_code): Likewise.
	* reload.c (find_reloads): Likewise.
	* sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
	* sel-sched-dump.c (debug_mem_addr_value): Likewise.

Comments

H.J. Lu May 6, 2012, 6:50 p.m. UTC | #1
On Sun, May 6, 2012 at 11:41 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> x32 uses a mixture of MEM address modes for the same address space.
> Some MEMs have SImode addresses, some have DImode.  This means that
> the currently common idiom:
>
>    targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem))
>
> isn't trustworthy.  We have to use the mode of the address if it has one,
> and only fall back on the above for VOIDmode (CONST_INT) addresses.
>
> We actually already have two (identical) functions to calculate
> such a mode.  The patch below puts the function in a more general place
> and uses it instead of the above for rtl-level stuff.
>
> I'm not sure whether what x32 is doing is a good thing, but I like the
> patch anyway because (a) it removes a duplicated function and (b) it at
> least abstracts the concept away.
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested to
> make sure that there were no differences for cc1 .ii files for MIPS
> n32, o32 and n64.  (I used MIPS to get LO_SUM coverage.)  OK to install?
>
> Richard
>
>
> gcc/
>        PR middle-end/53249
>        * dwarf2out.h (get_address_mode): Move declaration to...
>        * rtl.h: ...here.
>        * dwarf2out.c (get_address_mode): Move definition to...
>        * rtlanal.c: ...here.
>        * var-tracking.c (get_address_mode): Delete.
>        * combine.c (find_split_point): Use get_address_mode instead of
>        targetm.addr_space.address_mode.
>        * cselib.c (cselib_record_sets): Likewise.
>        * dse.c (canon_address, record_store): Likewise.
>        * emit-rtl.c (adjust_address_1, offset_address): Likewise.
>        * expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
>        (store_by_pieces_1, expand_assignment, store_expr, store_constructor)
>        (expand_expr_real_1): Likewise.
>        * ifcvt.c (noce_try_cmove_arith): Likewise.
>        * optabs.c (maybe_legitimize_operand_same_code): Likewise.
>        * reload.c (find_reloads): Likewise.
>        * sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
>        * sel-sched-dump.c (debug_mem_addr_value): Likewise.
>

Can you add a testcase?  You can put the testcase in

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53249#c4

in gcc.target/i386 with:

/* { dg-do compile { target { ! { ia32 } } } } */
/* { dg-options "-O2 -mx32 -ftls-model=initial-exec -maddress-mode=short" } */

Thanks.
H.J. Lu May 6, 2012, 6:55 p.m. UTC | #2
On Sun, May 6, 2012 at 11:41 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> x32 uses a mixture of MEM address modes for the same address space.
> Some MEMs have SImode addresses, some have DImode.  This means that
> the currently common idiom:
>
>    targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem))
>
> isn't trustworthy.  We have to use the mode of the address if it has one,
> and only fall back on the above for VOIDmode (CONST_INT) addresses.
>
> We actually already have two (identical) functions to calculate
> such a mode.  The patch below puts the function in a more general place
> and uses it instead of the above for rtl-level stuff.
>
> I'm not sure whether what x32 is doing is a good thing, but I like the
> patch anyway because (a) it removes a duplicated function and (b) it at
> least abstracts the concept away.
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested to
> make sure that there were no differences for cc1 .ii files for MIPS
> n32, o32 and n64.  (I used MIPS to get LO_SUM coverage.)  OK to install?
>
> Richard
>
>
> gcc/
>        PR middle-end/53249
>        * dwarf2out.h (get_address_mode): Move declaration to...
>        * rtl.h: ...here.
>        * dwarf2out.c (get_address_mode): Move definition to...
>        * rtlanal.c: ...here.
>        * var-tracking.c (get_address_mode): Delete.
>        * combine.c (find_split_point): Use get_address_mode instead of
>        targetm.addr_space.address_mode.
>        * cselib.c (cselib_record_sets): Likewise.
>        * dse.c (canon_address, record_store): Likewise.
>        * emit-rtl.c (adjust_address_1, offset_address): Likewise.
>        * expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
>        (store_by_pieces_1, expand_assignment, store_expr, store_constructor)
>        (expand_expr_real_1): Likewise.
>        * ifcvt.c (noce_try_cmove_arith): Likewise.
>        * optabs.c (maybe_legitimize_operand_same_code): Likewise.
>        * reload.c (find_reloads): Likewise.
>        * sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
>        * sel-sched-dump.c (debug_mem_addr_value): Likewise.
>

> Index: gcc/rtlanal.c
> ===================================================================
> --- gcc/rtlanal.c       2012-05-06 16:17:20.000000000 +0100
> +++ gcc/rtlanal.c       2012-05-06 16:17:20.298206160 +0100
> @@ -5279,3 +5279,17 @@ low_bitmask_len (enum machine_mode mode,
>
>   return exact_log2 (m + 1);
>  }
> +
> +/* Return the mode of MEM's address.  */
> +
> +enum machine_mode
> +get_address_mode (rtx mem)
> +{
> +  enum machine_mode mode;
> +
> +  gcc_assert (MEM_P (mem));
> +  mode = GET_MODE (XEXP (mem, 0));
> +  if (mode != VOIDmode)
> +    return mode;
> +  return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
> +}

> Index: gcc/sel-sched-dump.c
> ===================================================================
> --- gcc/sel-sched-dump.c        2012-05-06 16:17:20.000000000 +0100
> +++ gcc/sel-sched-dump.c        2012-05-06 16:17:20.316206160 +0100
> @@ -957,7 +957,7 @@ debug_mem_addr_value (rtx x)
>   enum machine_mode address_mode;
>
>   gcc_assert (MEM_P (x));

You should remove this assert since  get_address_mode does it.

> -  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
> +  address_mode = get_address_mode (x);
>
>   t = shallow_copy_rtx (x);
>   if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
Richard Sandiford May 6, 2012, 7:11 p.m. UTC | #3
"H.J. Lu" <hjl.tools@gmail.com> writes:
>> Index: gcc/sel-sched-dump.c
>> ===================================================================
>> --- gcc/sel-sched-dump.c        2012-05-06 16:17:20.000000000 +0100
>> +++ gcc/sel-sched-dump.c        2012-05-06 16:17:20.316206160 +0100
>> @@ -957,7 +957,7 @@ debug_mem_addr_value (rtx x)
>>   enum machine_mode address_mode;
>>
>>   gcc_assert (MEM_P (x));
>
> You should remove this assert since  get_address_mode does it.

I think it's better to keep it.

Richard

>> -  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
>> +  address_mode = get_address_mode (x);
>>
>>   t = shallow_copy_rtx (x);
>>   if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
H.J. Lu May 7, 2012, 7:51 p.m. UTC | #4
On Sun, May 6, 2012 at 11:41 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> x32 uses a mixture of MEM address modes for the same address space.
> Some MEMs have SImode addresses, some have DImode.  This means that
> the currently common idiom:
>
>    targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem))
>
> isn't trustworthy.  We have to use the mode of the address if it has one,
> and only fall back on the above for VOIDmode (CONST_INT) addresses.
>
> We actually already have two (identical) functions to calculate
> such a mode.  The patch below puts the function in a more general place
> and uses it instead of the above for rtl-level stuff.
>
> I'm not sure whether what x32 is doing is a good thing, but I like the
> patch anyway because (a) it removes a duplicated function and (b) it at
> least abstracts the concept away.
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested to
> make sure that there were no differences for cc1 .ii files for MIPS
> n32, o32 and n64.  (I used MIPS to get LO_SUM coverage.)  OK to install?
>
> Richard
>
>
> gcc/
>        PR middle-end/53249
>        * dwarf2out.h (get_address_mode): Move declaration to...
>        * rtl.h: ...here.
>        * dwarf2out.c (get_address_mode): Move definition to...
>        * rtlanal.c: ...here.
>        * var-tracking.c (get_address_mode): Delete.
>        * combine.c (find_split_point): Use get_address_mode instead of
>        targetm.addr_space.address_mode.
>        * cselib.c (cselib_record_sets): Likewise.
>        * dse.c (canon_address, record_store): Likewise.
>        * emit-rtl.c (adjust_address_1, offset_address): Likewise.
>        * expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
>        (store_by_pieces_1, expand_assignment, store_expr, store_constructor)
>        (expand_expr_real_1): Likewise.
>        * ifcvt.c (noce_try_cmove_arith): Likewise.
>        * optabs.c (maybe_legitimize_operand_same_code): Likewise.
>        * reload.c (find_reloads): Likewise.
>        * sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
>        * sel-sched-dump.c (debug_mem_addr_value): Likewise.
>

X32 results look good:

http://gcc.gnu.org/ml/gcc-testresults/2012-05/msg00704.html

Thanks.
H.J. Lu May 8, 2012, 2:37 p.m. UTC | #5
On Sun, May 6, 2012 at 11:41 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> x32 uses a mixture of MEM address modes for the same address space.
> Some MEMs have SImode addresses, some have DImode.  This means that
> the currently common idiom:
>
>    targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem))
>
> isn't trustworthy.  We have to use the mode of the address if it has one,
> and only fall back on the above for VOIDmode (CONST_INT) addresses.
>
> We actually already have two (identical) functions to calculate
> such a mode.  The patch below puts the function in a more general place
> and uses it instead of the above for rtl-level stuff.
>
> I'm not sure whether what x32 is doing is a good thing, but I like the
> patch anyway because (a) it removes a duplicated function and (b) it at
> least abstracts the concept away.
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested to
> make sure that there were no differences for cc1 .ii files for MIPS
> n32, o32 and n64.  (I used MIPS to get LO_SUM coverage.)  OK to install?
>
> Richard
>
>
> gcc/
>        PR middle-end/53249
>        * dwarf2out.h (get_address_mode): Move declaration to...
>        * rtl.h: ...here.
>        * dwarf2out.c (get_address_mode): Move definition to...
>        * rtlanal.c: ...here.
>        * var-tracking.c (get_address_mode): Delete.
>        * combine.c (find_split_point): Use get_address_mode instead of
>        targetm.addr_space.address_mode.
>        * cselib.c (cselib_record_sets): Likewise.
>        * dse.c (canon_address, record_store): Likewise.
>        * emit-rtl.c (adjust_address_1, offset_address): Likewise.
>        * expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
>        (store_by_pieces_1, expand_assignment, store_expr, store_constructor)
>        (expand_expr_real_1): Likewise.
>        * ifcvt.c (noce_try_cmove_arith): Likewise.
>        * optabs.c (maybe_legitimize_operand_same_code): Likewise.
>        * reload.c (find_reloads): Likewise.
>        * sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
>        * sel-sched-dump.c (debug_mem_addr_value): Likewise.
>

Hi Richard H.

Can you take a look at this patch? It will restore x32 bootstrap.

Thanks.

H.J.
Richard Henderson May 8, 2012, 11:05 p.m. UTC | #6
On 05/06/2012 11:41 AM, Richard Sandiford wrote:
> 	PR middle-end/53249
> 	* dwarf2out.h (get_address_mode): Move declaration to...
> 	* rtl.h: ...here.
> 	* dwarf2out.c (get_address_mode): Move definition to...
> 	* rtlanal.c: ...here.
> 	* var-tracking.c (get_address_mode): Delete.
> 	* combine.c (find_split_point): Use get_address_mode instead of
> 	targetm.addr_space.address_mode.
> 	* cselib.c (cselib_record_sets): Likewise.
> 	* dse.c (canon_address, record_store): Likewise.
> 	* emit-rtl.c (adjust_address_1, offset_address): Likewise.
> 	* expr.c (move_by_pieces, emit_block_move_via_loop, store_by_pieces)
> 	(store_by_pieces_1, expand_assignment, store_expr, store_constructor)
> 	(expand_expr_real_1): Likewise.
> 	* ifcvt.c (noce_try_cmove_arith): Likewise.
> 	* optabs.c (maybe_legitimize_operand_same_code): Likewise.
> 	* reload.c (find_reloads): Likewise.
> 	* sched-deps.c (sched_analyze_1, sched_analyze_2): Likewise.
> 	* sel-sched-dump.c (debug_mem_addr_value): Likewise.

ok.


r~
diff mbox

Patch

Index: gcc/dwarf2out.h
===================================================================
--- gcc/dwarf2out.h	2012-05-06 16:17:20.000000000 +0100
+++ gcc/dwarf2out.h	2012-05-06 16:17:20.316206160 +0100
@@ -228,7 +228,6 @@  typedef struct GTY(()) dw_loc_descr_stru
   (rtx, enum machine_mode mode, enum machine_mode mem_mode,
    enum var_init_status);
 extern bool loc_descr_equal_p (dw_loc_descr_ref, dw_loc_descr_ref);
-extern enum machine_mode get_address_mode (rtx mem);
 extern dw_fde_ref dwarf2out_alloc_current_fde (void);
 
 extern unsigned long size_of_locs (dw_loc_descr_ref);
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2012-05-06 16:17:20.000000000 +0100
+++ gcc/rtl.h	2012-05-06 16:17:20.294206160 +0100
@@ -1899,6 +1899,7 @@  typedef struct replace_label_data
   bool update_label_nuses;
 } replace_label_data;
 
+extern enum machine_mode get_address_mode (rtx mem);
 extern int rtx_addr_can_trap_p (const_rtx);
 extern bool nonzero_address_p (const_rtx);
 extern int rtx_unstable_p (const_rtx);
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/dwarf2out.c	2012-05-06 16:17:20.315206160 +0100
@@ -10971,17 +10971,6 @@  parameter_ref_descriptor (rtx rtl)
   return ret;
 }
 
-/* Helper function to get mode of MEM's address.  */
-
-enum machine_mode
-get_address_mode (rtx mem)
-{
-  enum machine_mode mode = GET_MODE (XEXP (mem, 0));
-  if (mode != VOIDmode)
-    return mode;
-  return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
-}
-
 /* The following routine converts the RTL for a variable or parameter
    (resident in memory) into an equivalent Dwarf representation of a
    mechanism for getting the address of that same variable onto the top of a
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/rtlanal.c	2012-05-06 16:17:20.298206160 +0100
@@ -5279,3 +5279,17 @@  low_bitmask_len (enum machine_mode mode,
 
   return exact_log2 (m + 1);
 }
+
+/* Return the mode of MEM's address.  */
+
+enum machine_mode
+get_address_mode (rtx mem)
+{
+  enum machine_mode mode;
+
+  gcc_assert (MEM_P (mem));
+  mode = GET_MODE (XEXP (mem, 0));
+  if (mode != VOIDmode)
+    return mode;
+  return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
+}
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/var-tracking.c	2012-05-06 16:17:20.306206160 +0100
@@ -4909,17 +4909,6 @@  find_use_val (rtx x, enum machine_mode m
   return NULL;
 }
 
-/* Helper function to get mode of MEM's address.  */
-
-static inline enum machine_mode
-get_address_mode (rtx mem)
-{
-  enum machine_mode mode = GET_MODE (XEXP (mem, 0));
-  if (mode != VOIDmode)
-    return mode;
-  return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
-}
-
 /* Replace all registers and addresses in an expression with VALUE
    expressions that map back to them, unless the expression is a
    register.  If no mapping is or can be performed, returns NULL.  */
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/combine.c	2012-05-06 16:17:20.322206160 +0100
@@ -4611,8 +4611,7 @@  find_split_point (rtx *loc, rtx insn, bo
       if (GET_CODE (XEXP (x, 0)) == CONST
 	  || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
 	{
-	  enum machine_mode address_mode
-	    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+	  enum machine_mode address_mode = get_address_mode (x);
 
 	  SUBST (XEXP (x, 0),
 		 gen_rtx_LO_SUM (address_mode,
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/cselib.c	2012-05-06 16:17:20.300206160 +0100
@@ -2524,8 +2524,7 @@  cselib_record_sets (rtx insn)
 	  sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1, VOIDmode);
 	  if (MEM_P (dest))
 	    {
-	      enum machine_mode address_mode
-		= targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+	      enum machine_mode address_mode = get_address_mode (dest);
 
 	      sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0),
 						     address_mode, 1,
Index: gcc/dse.c
===================================================================
--- gcc/dse.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/dse.c	2012-05-06 16:17:20.303206160 +0100
@@ -1146,8 +1146,7 @@  canon_address (rtx mem,
 	       HOST_WIDE_INT *offset,
 	       cselib_val **base)
 {
-  enum machine_mode address_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
+  enum machine_mode address_mode = get_address_mode (mem);
   rtx mem_address = XEXP (mem, 0);
   rtx expanded_address, address;
   int expanded;
@@ -1392,7 +1391,6 @@  record_store (rtx body, bb_info_t bb_inf
   cselib_val *base = NULL;
   insn_info_t ptr, last, redundant_reason;
   bool store_is_unused;
-  enum machine_mode address_mode;
 
   if (GET_CODE (body) != SET && GET_CODE (body) != CLOBBER)
     return 0;
@@ -1455,8 +1453,6 @@  record_store (rtx body, bb_info_t bb_inf
       return 0;
     }
 
-  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
-
   if (GET_MODE (mem) == BLKmode)
     width = MEM_SIZE (mem);
   else
@@ -1564,7 +1560,7 @@  record_store (rtx body, bb_info_t bb_inf
 	  mem_addr = group->canon_base_addr;
 	}
       if (offset)
-	mem_addr = plus_constant (address_mode, mem_addr, offset);
+	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
     }
 
   while (ptr)
@@ -2181,11 +2177,7 @@  check_mem_read_rtx (rtx *loc, void *data
 	  mem_addr = group->canon_base_addr;
 	}
       if (offset)
-	{
-	  enum machine_mode address_mode
-	    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
-	  mem_addr = plus_constant (address_mode, mem_addr, offset);
-	}
+	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
     }
 
   /* We ignore the clobbers in store_info.  The is mildly aggressive,
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/emit-rtl.c	2012-05-06 16:17:20.326206159 +0100
@@ -2092,7 +2092,7 @@  adjust_address_1 (rtx memref, enum machi
 
   /* Convert a possibly large offset to a signed value within the
      range of the target address space.  */
-  address_mode = targetm.addr_space.address_mode (attrs.addrspace);
+  address_mode = get_address_mode (memref);
   pbits = GET_MODE_BITSIZE (address_mode);
   if (HOST_BITS_PER_WIDE_INT > pbits)
     {
@@ -2179,7 +2179,7 @@  offset_address (rtx memref, rtx offset,
   struct mem_attrs attrs, *defattrs;
 
   attrs = *get_mem_attrs (memref);
-  address_mode = targetm.addr_space.address_mode (attrs.addrspace);
+  address_mode = get_address_mode (memref);
   new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
 
   /* At this point we don't know _why_ the address is invalid.  It
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/expr.c	2012-05-06 16:17:20.329206159 +0100
@@ -867,8 +867,8 @@  move_by_pieces (rtx to, rtx from, unsign
 		unsigned int align, int endp)
 {
   struct move_by_pieces_d data;
-  enum machine_mode to_addr_mode, from_addr_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (from));
+  enum machine_mode to_addr_mode;
+  enum machine_mode from_addr_mode = get_address_mode (from);
   rtx to_addr, from_addr = XEXP (from, 0);
   unsigned int max_size = MOVE_MAX_PIECES + 1;
   enum insn_code icode;
@@ -879,7 +879,7 @@  move_by_pieces (rtx to, rtx from, unsign
   data.from_addr = from_addr;
   if (to)
     {
-      to_addr_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
+      to_addr_mode = get_address_mode (to);
       to_addr = XEXP (to, 0);
       data.to = to;
       data.autinc_to
@@ -1434,10 +1434,8 @@  emit_block_move_via_loop (rtx x, rtx y,
 			  unsigned int align ATTRIBUTE_UNUSED)
 {
   rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
-  enum machine_mode x_addr_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
-  enum machine_mode y_addr_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (y));
+  enum machine_mode x_addr_mode = get_address_mode (x);
+  enum machine_mode y_addr_mode = get_address_mode (y);
   enum machine_mode iter_mode;
 
   iter_mode = GET_MODE (size);
@@ -2464,8 +2462,7 @@  store_by_pieces (rtx to, unsigned HOST_W
 		 rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
 		 void *constfundata, unsigned int align, bool memsetp, int endp)
 {
-  enum machine_mode to_addr_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
+  enum machine_mode to_addr_mode = get_address_mode (to);
   struct store_by_pieces_d data;
 
   if (len == 0)
@@ -2551,8 +2548,7 @@  clear_by_pieces_1 (void *data ATTRIBUTE_
 store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
 		   unsigned int align ATTRIBUTE_UNUSED)
 {
-  enum machine_mode to_addr_mode
-    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (data->to));
+  enum machine_mode to_addr_mode = get_address_mode (data->to);
   rtx to_addr = XEXP (data->to, 0);
   unsigned int max_size = STORE_MAX_PIECES + 1;
   enum insn_code icode;
@@ -4707,8 +4703,7 @@  expand_assignment (tree to, tree from, b
 	    }
 
 	  offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
-	  address_mode
-	    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+	  address_mode = get_address_mode (to_rtx);
 	  if (GET_MODE (offset_rtx) != address_mode)
 	    offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
@@ -5247,8 +5242,7 @@  store_expr (tree exp, rtx target, int ca
 	    {
 	      enum machine_mode pointer_mode
 		= targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
-	      enum machine_mode address_mode
-		= targetm.addr_space.address_mode (MEM_ADDR_SPACE (target));
+	      enum machine_mode address_mode = get_address_mode (target);
 
 	      /* Compute the size of the data to copy from the string.  */
 	      tree copy_size
@@ -5816,8 +5810,7 @@  store_constructor (tree exp, rtx target,
 		offset_rtx = expand_normal (offset);
 		gcc_assert (MEM_P (to_rtx));
 
-		address_mode
-		  = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+		address_mode = get_address_mode (to_rtx);
 		if (GET_MODE (offset_rtx) != address_mode)
 		  offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
@@ -9937,8 +9930,7 @@  expand_expr_real_1 (tree exp, rtx target
 
 	    gcc_assert (MEM_P (op0));
 
-	    address_mode
-	      = targetm.addr_space.address_mode (MEM_ADDR_SPACE (op0));
+	    address_mode = get_address_mode (op0);
 	    if (GET_MODE (offset_rtx) != address_mode)
 	      offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
Index: gcc/ifcvt.c
===================================================================
--- gcc/ifcvt.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/ifcvt.c	2012-05-06 16:17:20.295206160 +0100
@@ -1520,8 +1520,7 @@  noce_try_cmove_arith (struct noce_if_inf
       && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
       && if_info->branch_cost >= 5)
     {
-      enum machine_mode address_mode
-	= targetm.addr_space.address_mode (MEM_ADDR_SPACE (a));
+      enum machine_mode address_mode = get_address_mode (a);
 
       a = XEXP (a, 0);
       b = XEXP (b, 0);
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/optabs.c	2012-05-06 16:17:20.332206159 +0100
@@ -8253,7 +8253,7 @@  maybe_legitimize_operand_same_code (enum
 	  enum machine_mode mode;
 
 	  last = get_last_insn ();
-	  mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
+	  mode = get_address_mode (mem);
 	  mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
 	  if (insn_operand_matches (icode, opno, mem))
 	    {
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/reload.c	2012-05-06 16:17:20.334206159 +0100
@@ -3993,10 +3993,8 @@  find_reloads (rtx insn, int replace, int
 	       as would have been done by find_reloads_address.  */
 	    addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
 	    enum machine_mode address_mode;
-	    address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
-	    if (address_mode == VOIDmode)
-	      address_mode = targetm.addr_space.address_mode (as);
 
+	    address_mode = get_address_mode (recog_data.operand[i]);
 	    operand_reloadnum[i]
 	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
 			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
Index: gcc/sched-deps.c
===================================================================
--- gcc/sched-deps.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/sched-deps.c	2012-05-06 16:17:20.299206160 +0100
@@ -2445,8 +2445,7 @@  sched_analyze_1 (struct deps_desc *deps,
 
       if (sched_deps_info->use_cselib)
 	{
-	  enum machine_mode address_mode
-	    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+	  enum machine_mode address_mode = get_address_mode (dest);
 
 	  t = shallow_copy_rtx (dest);
 	  cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
@@ -2607,8 +2606,7 @@  sched_analyze_2 (struct deps_desc *deps,
 
 	if (sched_deps_info->use_cselib)
 	  {
-	    enum machine_mode address_mode
-	      = targetm.addr_space.address_mode (MEM_ADDR_SPACE (t));
+	    enum machine_mode address_mode = get_address_mode (t);
 
 	    t = shallow_copy_rtx (t);
 	    cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
Index: gcc/sel-sched-dump.c
===================================================================
--- gcc/sel-sched-dump.c	2012-05-06 16:17:20.000000000 +0100
+++ gcc/sel-sched-dump.c	2012-05-06 16:17:20.316206160 +0100
@@ -957,7 +957,7 @@  debug_mem_addr_value (rtx x)
   enum machine_mode address_mode;
 
   gcc_assert (MEM_P (x));
-  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+  address_mode = get_address_mode (x);
 
   t = shallow_copy_rtx (x);
   if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))