aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authorBen Elliston <bje@au.ibm.com>2009-10-26 21:55:59 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2009-10-26 21:55:59 +0000
commit09e881c9e21a9209b2092e400ea4c38948614f78 (patch)
treeea57b1c9bc1dc4b71890b4a10a89294179e3c5e6 /gcc/reload.c
parent89c74f4afa6db154288515ed1e1cdbe8694dc4c5 (diff)
downloadgcc-09e881c9e21a9209b2092e400ea4c38948614f78.zip
gcc-09e881c9e21a9209b2092e400ea4c38948614f78.tar.gz
gcc-09e881c9e21a9209b2092e400ea4c38948614f78.tar.bz2
extend.texi (Named Address Spaces): New section.
2009-10-26 Ben Elliston <bje@au.ibm.com> Michael Meissner <meissner@linux.vnet.ibm.com> Ulrich Weigand <uweigand@de.ibm.com> * doc/extend.texi (Named Address Spaces): New section. * coretypes.h (addr_space_t): New type. (ADDR_SPACE_GENERIC): New define. (ADDR_SPACE_GENERIC_P): New macro. * doc/tm.texi (Named Address Spaces): New section. (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Document. (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Document. (TARGET_ADDR_SPACE_SUBSET_P): Document. (TARGET_ADDR_SPACE_CONVERT): Document. * target.h (struct gcc_target): Add addr_space substructure. * target-def.h (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define. (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Likewise. (TARGET_ADDR_SPACE_SUBSET_P): Likewise. (TARGET_ADDR_SPACE_CONVERT): Likewise. (TARGET_ADDR_SPACE_HOOKS): Likewise. (TARGET_INITIALIZER): Initialize addr_space hooks. * targhooks.c (default_addr_space_legitimate_address_p): New function. (default_addr_space_legitimize_address): Likewise. (default_addr_space_subset_p): Likewise. (default_addr_space_convert): Likewise. * targhooks.h (default_addr_space_legitimate_address_p): Add prototype. (default_addr_space_legitimize_address): Likewise. (default_addr_space_subset_p): Likewise. (default_addr_space_convert): Likewise. * doc/rtl.texi (MEM_ADDR_SPACE): Document. * rtl.h (mem_attrs): Add ADDRSPACE memory attribute. (MEM_ADDR_SPACE): New macro. * emit-rtl.c (get_mem_attrs): Add ADDRSPACE argument and set address space memory attribute. (mem_attrs_htab_hash): Handle address space memory attribute. (mem_attrs_htab_eq): Likewise. (set_mem_attributes_minus_bitpos): Likewise. (set_mem_alias_set): Likewise. (set_mem_align): Likewise. (set_mem_expr): Likewise. (set_mem_offset): Likewise. (set_mem_size): Likewise. (adjust_address_1): Likewise. (offset_address): Likewise. (widen_memoy_address): Likewise. (get_spill_slot_decl): Likewise. (set_mem_attrs_for_spill): Likewise. (set_mem_addr_space): New function. * emit-rtl.h (set_mem_addr_space): Add prototype. * print-rtl.c (print_rtx): Print address space memory attribute. * expr.c (expand_assignment): Set address space memory attribute of generated MEM RTXes as appropriate. (expand_expr_real_1): Likewise. * cfgexpand.c (expand_debug_expr): Likewise. * tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise. * tree.h (struct tree_base): Add address_space bitfield. Reduce size of "spare" bitfield. (TYPE_ADDR_SPACE): New macro. (ENCODE_QUAL_ADDR_SPACE): Likewise. (DECODE_QUAL_ADDR_SPACE): Likewise. (CLEAR_QUAL_ADDR_SPACE): Likewise. (KEEP_QUAL_ADDR_SPACE): Likewise. (TYPE_QUALS): Encode type address space. (TYPE_QUALS_NO_ADDR_SPACE): New macro. * tree.c (set_type_quals): Set type address space. (build_array_type): Inherit array address space from element type. * print-tree.c (print_node_brief): Print type address space. (print_node): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * explow.c (memory_address): Rename to ... (memory_address_addr_space): ... this. Add ADDRSPACE argument. Use address-space aware variants of memory address routines. * recog.c (memory_address_p): Rename to ... (memory_address_addr_space_p): ... this. Add ADDSPACE argument. Use address-space aware variants of memory address routines. (offsettable_address_p): Rename to ... (offsettable_address_addr_space_p): ... this. Add ADDRSPACE argument. Use address-space aware variants of memory address routines. * reload.c (strict_memory_address_p): Rename to ... (strict_memory_address_addr_space_p): ... this. Add ADDSPACE argument. Use address-space aware variants of memory address routines. (maybe_memory_address_p): Rename to ... (maybe_memory_address_addr_space_p): ... this. Add ADDSPACE argument. Use address-space aware variants of memory address routines. * expr.h (memory_address_addr_space): Add prototype. (memory_address): Define as macro. * recog.h (memory_address_addr_space_p): Add prototype. (memory_address_p): Define as macro. (offsettable_address_addr_space_p): Add prototype. (offsettable_address_p): Define as macro. (strict_memory_address_addr_space_p): Add prototype. (strict_memory_address_p): Define as macro. * combine.c (find_split_point): Use address-space aware variants of memory address routines. * emit-rtl.c (operand_subword): Likewise. (change_address_1): Likewise. (adjust_address_1): Likewise. (offset_address): Likewise. * expr.c (emit_move_insn): Likewise. (expand_assignment): Likewise. (expand_expr_real_1): Likewise. * recog.c (verify_changes): Likewise. (general_operand): Likewise. (offsettable_memref_p): Likewise. (offsettable_nonstrict_memref_p): Likewise. (constrain_operands): Likewise. * reload.c (get_secondary_mem): Likewise. (find_reloads_toplev): Likewise. (find_reloads_address): Likewise. (find_reloads_subreg_address): Likewise. * reload1.c (reload): Likewise. * rtlhooks.c (gen_lowpart_if_possible): Likewise. * rtl.h (address_cost): Add ADDRSPACE argument. * rtlanal.c (address_cost): Add ADDRSPACE argument. Use address-space aware variant of memory address routines. * loop-invariant.c (create_new_invariant): Update address_cost call. * tree-ssa-loop-ivopts.c (computation_cost): Likewise. * fwprop.c (should_replace_address): Add ADDRSPACE argument. Use address-space aware variant of memory address routines. (propagate_rtx_1): Update call to should_replace_address. * tree-flow.h (multiplier_allowed_in_address_p): Add ADDRSPACE argument. * tree-ssa-loop-ivopts.c (multiplier_allowed_in_address_p): Add ADDRSPACE argument. Use per-address-space instead of global cache. Use address-space aware variant of memory address routines. (get_address_cost): Likewise. (get_computation_cost_at): Update calls. * tree-ssa-address.c (valid_mem_ref_p): Add ADDRSPACE argument. Use address-space aware variant of memory address routines. (create_mem_ref_raw): Update call to valid_mem_ref_p. (most_expensive_mult_to_index): Update call to multiplier_allowed_in_address_p. * dwarf2out.c (modified_type_die): Output DW_AT_address_class attribute to indicate named address spaces. * varasm.c (get_variable_section): DECLs in named address spaces cannot be "common". * reload.c (find_reloads_address): Do not use LEGITIMIZE_RELOAD_ADDRESS for addresses in a non-generic address space. * expr.c (emit_block_move_hints): Do not use libcalls for memory in non-generic address spaces. (clear_storage_hints): Likewise. (expand_assignment): Likewise. * fold-const.c (operand_equal_p): Expressions refering to different address spaces are not equivalent. * rtl.c (rtx_equal_p_cb): MEMs refering to different address spaces are not equivalent. (rtx_equal_p): Likewise. * cse.c (exp_equiv_p): Likewise. * jump.c (rtx_renumbered_equal_p): Likewise. * reload.c (operands_match_p): Likewise. * alias.c (nonoverlapping_memrefs_p): MEMs refering to different address spaces may alias. (true_dependence): Likewise. (canon_true_dependence): Likewise. (write_dependence_p): Likewise. * dse.c (canon_address): Handle named address spaces. * ifcvt.c (noce_try_cmove_arith): Likewise. * tree.def (ADDR_SPACE_CONVERT_EXPR): New tree code. * expr.c (expand_expr_real_2): Expand ADDR_SPACE_CONVERT_EXPR. * convert.c (convert_to_pointer): Generate ADDR_SPACE_CONVERT_EXPR to handle conversions between different address spaces. * fold-const.c (fold_convert_loc): Likewise. (fold_unary_loc): Handle ADDR_SPACE_CONVERT_EXPR. * tree-pretty-print.c (dump_generic_node): Likewise. * gimple-pretty-print.c (dump_unary_rhs): Likewise. * tree-cfg.c (verify_gimple_assign_unary): Likewise. * tree-inline.c (estimate_operator_cost): Likewise. * tree-ssa.c (useless_type_conversion_p): Conversions between pointers to different address spaces are not useless. Co-Authored-By: Michael Meissner <meissner@linux.vnet.ibm.com> Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com> From-SVN: r153572
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 1435945..166bcb9 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -268,7 +268,8 @@ static bool alternative_allows_const_pool_ref (rtx, const char *, int);
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx,
int *);
static rtx make_memloc (rtx, int);
-static int maybe_memory_address_p (enum machine_mode, rtx, rtx *);
+static int maybe_memory_address_addr_space_p (enum machine_mode, rtx,
+ addr_space_t, rtx *);
static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int, rtx);
static rtx subst_reg_equivs (rtx, rtx);
@@ -612,7 +613,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSED, enum machine_mode mode,
didn't give us a new MEM, make a new one if it isn't valid. */
loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
- mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
+ mem_valid = strict_memory_address_addr_space_p (mode, XEXP (loc, 0),
+ MEM_ADDR_SPACE (loc));
if (! mem_valid && loc == secondary_memlocs[(int) mode])
loc = copy_rtx (loc);
@@ -2129,21 +2131,23 @@ hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
return 0;
}
-/* Return 1 if ADDR is a valid memory address for mode MODE,
- and check that each pseudo reg has the proper kind of
- hard reg. */
+/* Return 1 if ADDR is a valid memory address for mode MODE
+ in address space AS, and check that each pseudo reg has the
+ proper kind of hard reg. */
int
-strict_memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
+strict_memory_address_addr_space_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
+ gcc_assert (ADDR_SPACE_GENERIC_P (as));
GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
return 0;
win:
return 1;
#else
- return targetm.legitimate_address_p (mode, addr, 1);
+ return targetm.addr_space.legitimate_address_p (mode, addr, 1, as);
#endif
}
@@ -2247,6 +2251,10 @@ operands_match_p (rtx x, rtx y)
if (GET_MODE (x) != GET_MODE (y))
return 0;
+ /* MEMs refering to different address space are not equivalent. */
+ if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
+ return 0;
+
switch (code)
{
case CONST_INT:
@@ -4760,8 +4768,9 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
#endif
&& (reg_equiv_address[regno] != 0
|| (reg_equiv_mem[regno] != 0
- && (! strict_memory_address_p (GET_MODE (x),
- XEXP (reg_equiv_mem[regno], 0))
+ && (! strict_memory_address_addr_space_p
+ (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
+ MEM_ADDR_SPACE (reg_equiv_mem[regno]))
|| ! offsettable_memref_p (reg_equiv_mem[regno])
|| num_not_at_initial_offset))))
x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
@@ -4819,18 +4828,19 @@ make_memloc (rtx ad, int regno)
}
/* Returns true if AD could be turned into a valid memory reference
- to mode MODE by reloading the part pointed to by PART into a
- register. */
+ to mode MODE in address space AS by reloading the part pointed to
+ by PART into a register. */
static int
-maybe_memory_address_p (enum machine_mode mode, rtx ad, rtx *part)
+maybe_memory_address_addr_space_p (enum machine_mode mode, rtx ad,
+ addr_space_t as, rtx *part)
{
int retv;
rtx tem = *part;
rtx reg = gen_rtx_REG (GET_MODE (tem), max_reg_num ());
*part = reg;
- retv = memory_address_p (mode, ad);
+ retv = memory_address_addr_space_p (mode, ad, as);
*part = tem;
return retv;
@@ -4866,6 +4876,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx insn)
{
+ addr_space_t as = memrefloc? MEM_ADDR_SPACE (*memrefloc)
+ : ADDR_SPACE_GENERIC;
int regno;
int removed_and = 0;
int op_index;
@@ -4893,7 +4905,9 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
{
tem = make_memloc (ad, regno);
- if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
+ if (! strict_memory_address_addr_space_p (GET_MODE (tem),
+ XEXP (tem, 0),
+ MEM_ADDR_SPACE (tem)))
{
rtx orig = tem;
@@ -4909,7 +4923,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
address: only reg or reg+constant. */
if (ind_levels > 0
- && strict_memory_address_p (mode, tem)
+ && strict_memory_address_addr_space_p (mode, tem, as)
&& (REG_P (XEXP (tem, 0))
|| (GET_CODE (XEXP (tem, 0)) == PLUS
&& REG_P (XEXP (XEXP (tem, 0), 0))
@@ -4953,7 +4967,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
return 1;
}
- if (strict_memory_address_p (mode, ad))
+ if (strict_memory_address_addr_space_p (mode, ad, as))
{
/* The address appears valid, so reloads are not needed.
But the address may contain an eliminable register.
@@ -4976,14 +4990,14 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
return 0;
/* Check result for validity after substitution. */
- if (strict_memory_address_p (mode, ad))
+ if (strict_memory_address_addr_space_p (mode, ad, as))
return 0;
}
#ifdef LEGITIMIZE_RELOAD_ADDRESS
do
{
- if (memrefloc)
+ if (memrefloc && ADDR_SPACE_GENERIC_P (as))
{
LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
ind_levels, win);
@@ -5160,8 +5174,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|| operand == arg_pointer_rtx
#endif
|| operand == stack_pointer_rtx)
- && ! maybe_memory_address_p (mode, ad,
- &XEXP (XEXP (ad, 0), 1 - op_index)))
+ && ! maybe_memory_address_addr_space_p
+ (mode, ad, as, &XEXP (XEXP (ad, 0), 1 - op_index)))
{
rtx offset_reg;
enum reg_class cls;
@@ -5199,7 +5213,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
tem = ad;
if (GET_CODE (ad) == PLUS)
tem = subst_indexed_address (ad);
- if (tem != ad && strict_memory_address_p (mode, tem))
+ if (tem != ad && strict_memory_address_addr_space_p (mode, tem, as))
{
/* Ok, we win that way. Replace any additional eliminable
registers. */
@@ -5209,7 +5223,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
/* Make sure that didn't make the address invalid again. */
- if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
+ if (! subst_reg_equivs_changed
+ || strict_memory_address_addr_space_p (mode, tem, as))
{
*loc = tem;
return 0;
@@ -5218,7 +5233,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
/* If constants aren't valid addresses, reload the constant address
into a register. */
- if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
+ if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
{
/* If AD is an address in the constant pool, the MEM rtx may be shared.
Unshare it so we can safely alter it. */
@@ -6180,8 +6195,9 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
the address, there is nothing further to do. */
if (reloaded == 0
&& reg_equiv_mem[regno] != 0
- && !strict_memory_address_p (GET_MODE (x),
- XEXP (reg_equiv_mem[regno], 0)))
+ && !strict_memory_address_addr_space_p
+ (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
+ MEM_ADDR_SPACE (reg_equiv_mem[regno])))
push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
base_reg_class (GET_MODE (tem), MEM, SCRATCH),
GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,