aboutsummaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.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/emit-rtl.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/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index b868298..baad4a8 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -193,7 +193,7 @@ static rtx lookup_const_fixed (rtx);
static hashval_t mem_attrs_htab_hash (const void *);
static int mem_attrs_htab_eq (const void *, const void *);
static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int,
- enum machine_mode);
+ addr_space_t, enum machine_mode);
static hashval_t reg_attrs_htab_hash (const void *);
static int reg_attrs_htab_eq (const void *, const void *);
static reg_attrs *get_reg_attrs (tree, int);
@@ -292,6 +292,7 @@ mem_attrs_htab_hash (const void *x)
const mem_attrs *const p = (const mem_attrs *) x;
return (p->alias ^ (p->align * 1000)
+ ^ (p->addrspace * 4000)
^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
^ (size_t) iterative_hash_expr (p->expr, 0));
@@ -309,6 +310,7 @@ mem_attrs_htab_eq (const void *x, const void *y)
return (p->alias == q->alias && p->offset == q->offset
&& p->size == q->size && p->align == q->align
+ && p->addrspace == q->addrspace
&& (p->expr == q->expr
|| (p->expr != NULL_TREE && q->expr != NULL_TREE
&& operand_equal_p (p->expr, q->expr, 0))));
@@ -320,7 +322,7 @@ mem_attrs_htab_eq (const void *x, const void *y)
static mem_attrs *
get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
- unsigned int align, enum machine_mode mode)
+ unsigned int align, addr_space_t addrspace, enum machine_mode mode)
{
mem_attrs attrs;
void **slot;
@@ -328,7 +330,7 @@ get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
/* If everything is the default, we can just return zero.
This must match what the corresponding MEM_* macros return when the
field is not present. */
- if (alias == 0 && expr == 0 && offset == 0
+ if (alias == 0 && expr == 0 && offset == 0 && addrspace == 0
&& (size == 0
|| (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
&& (STRICT_ALIGNMENT && mode != BLKmode
@@ -340,6 +342,7 @@ get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
attrs.offset = offset;
attrs.size = size;
attrs.align = align;
+ attrs.addrspace = addrspace;
slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT);
if (*slot == 0)
@@ -1386,7 +1389,9 @@ operand_subword (rtx op, unsigned int offset, int validate_address, enum machine
else if (reload_completed)
{
- if (! strict_memory_address_p (word_mode, XEXP (new_rtx, 0)))
+ if (! strict_memory_address_addr_space_p (word_mode,
+ XEXP (new_rtx, 0),
+ MEM_ADDR_SPACE (op)))
return 0;
}
else
@@ -1795,7 +1800,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
/* Now set the attributes we computed above. */
MEM_ATTRS (ref)
- = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
+ = get_mem_attrs (alias, expr, offset, size, align,
+ TYPE_ADDR_SPACE (type), GET_MODE (ref));
/* If this is already known to be a scalar or aggregate, we are done. */
if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
@@ -1827,7 +1833,17 @@ set_mem_alias_set (rtx mem, alias_set_type set)
MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
MEM_SIZE (mem), MEM_ALIGN (mem),
- GET_MODE (mem));
+ MEM_ADDR_SPACE (mem), GET_MODE (mem));
+}
+
+/* Set the address space of MEM to ADDRSPACE (target-defined). */
+
+void
+set_mem_addr_space (rtx mem, addr_space_t addrspace)
+{
+ MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
+ MEM_OFFSET (mem), MEM_SIZE (mem),
+ MEM_ALIGN (mem), addrspace, GET_MODE (mem));
}
/* Set the alignment of MEM to ALIGN bits. */
@@ -1837,7 +1853,7 @@ set_mem_align (rtx mem, unsigned int align)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
MEM_OFFSET (mem), MEM_SIZE (mem), align,
- GET_MODE (mem));
+ MEM_ADDR_SPACE (mem), GET_MODE (mem));
}
/* Set the expr for MEM to EXPR. */
@@ -1847,7 +1863,8 @@ set_mem_expr (rtx mem, tree expr)
{
MEM_ATTRS (mem)
= get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
- MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+ MEM_SIZE (mem), MEM_ALIGN (mem),
+ MEM_ADDR_SPACE (mem), GET_MODE (mem));
}
/* Set the offset of MEM to OFFSET. */
@@ -1857,7 +1874,7 @@ set_mem_offset (rtx mem, rtx offset)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
offset, MEM_SIZE (mem), MEM_ALIGN (mem),
- GET_MODE (mem));
+ MEM_ADDR_SPACE (mem), GET_MODE (mem));
}
/* Set the size of MEM to SIZE. */
@@ -1867,7 +1884,7 @@ set_mem_size (rtx mem, rtx size)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
MEM_OFFSET (mem), size, MEM_ALIGN (mem),
- GET_MODE (mem));
+ MEM_ADDR_SPACE (mem), GET_MODE (mem));
}
/* Return a memory reference like MEMREF, but with its mode changed to MODE
@@ -1879,23 +1896,25 @@ set_mem_size (rtx mem, rtx size)
static rtx
change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
{
+ addr_space_t as;
rtx new_rtx;
gcc_assert (MEM_P (memref));
+ as = MEM_ADDR_SPACE (memref);
if (mode == VOIDmode)
mode = GET_MODE (memref);
if (addr == 0)
addr = XEXP (memref, 0);
if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
- && (!validate || memory_address_p (mode, addr)))
+ && (!validate || memory_address_addr_space_p (mode, addr, as)))
return memref;
if (validate)
{
if (reload_in_progress || reload_completed)
- gcc_assert (memory_address_p (mode, addr));
+ gcc_assert (memory_address_addr_space_p (mode, addr, as));
else
- addr = memory_address (mode, addr);
+ addr = memory_address_addr_space (mode, addr, as);
}
if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
@@ -1934,7 +1953,8 @@ change_address (rtx memref, enum machine_mode mode, rtx addr)
}
MEM_ATTRS (new_rtx)
- = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
+ = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align,
+ MEM_ADDR_SPACE (memref), mmode);
return new_rtx;
}
@@ -1954,11 +1974,12 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
rtx memoffset = MEM_OFFSET (memref);
rtx size = 0;
unsigned int memalign = MEM_ALIGN (memref);
+ addr_space_t as = MEM_ADDR_SPACE (memref);
int pbits;
/* If there are no changes, just return the original memory reference. */
if (mode == GET_MODE (memref) && !offset
- && (!validate || memory_address_p (mode, addr)))
+ && (!validate || memory_address_addr_space_p (mode, addr, as)))
return memref;
/* ??? Prefer to create garbage instead of creating shared rtl.
@@ -2017,7 +2038,8 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
size = plus_constant (MEM_SIZE (memref), -offset);
MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
- memoffset, size, memalign, GET_MODE (new_rtx));
+ memoffset, size, memalign, as,
+ GET_MODE (new_rtx));
/* At some point, we should validate that this offset is within the object,
if all the appropriate values are known. */
@@ -2045,6 +2067,7 @@ rtx
offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
rtx new_rtx, addr = XEXP (memref, 0);
+ addr_space_t as = MEM_ADDR_SPACE (memref);
new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
@@ -2055,7 +2078,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
being able to recognize the magic around pic_offset_table_rtx.
This stuff is fragile, and is yet another example of why it is
bad to expose PIC machinery too early. */
- if (! memory_address_p (GET_MODE (memref), new_rtx)
+ if (! memory_address_addr_space_p (GET_MODE (memref), new_rtx, as)
&& GET_CODE (addr) == PLUS
&& XEXP (addr, 0) == pic_offset_table_rtx)
{
@@ -2075,7 +2098,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
MEM_ATTRS (new_rtx)
= get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
- GET_MODE (new_rtx));
+ as, GET_MODE (new_rtx));
return new_rtx;
}
@@ -2179,7 +2202,8 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
/* ??? Maybe use get_alias_set on any remaining expression. */
MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
- MEM_ALIGN (new_rtx), mode);
+ MEM_ALIGN (new_rtx),
+ MEM_ADDR_SPACE (new_rtx), mode);
return new_rtx;
}
@@ -2207,7 +2231,7 @@ get_spill_slot_decl (bool force_build_p)
rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
MEM_NOTRAP_P (rd) = 1;
MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx,
- NULL_RTX, 0, BLKmode);
+ NULL_RTX, 0, ADDR_SPACE_GENERIC, BLKmode);
SET_DECL_RTL (d, rd);
return d;
@@ -2240,7 +2264,7 @@ set_mem_attrs_for_spill (rtx mem)
MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset,
MEM_SIZE (mem), MEM_ALIGN (mem),
- GET_MODE (mem));
+ ADDR_SPACE_GENERIC, GET_MODE (mem));
MEM_NOTRAP_P (mem) = 1;
}