aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.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/expr.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/expr.c')
-rw-r--r--gcc/expr.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 5d18435..5e8fae1 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1215,7 +1215,9 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
else if (emit_block_move_via_movmem (x, y, size, align,
expected_align, expected_size))
;
- else if (may_use_call)
+ else if (may_use_call
+ && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
+ && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
retval = emit_block_move_via_libcall (x, y, size,
method == BLOCK_OP_TAILCALL);
else
@@ -2641,9 +2643,11 @@ clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
else if (set_storage_via_setmem (object, size, const0_rtx, align,
expected_align, expected_size))
;
- else
+ else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
return set_storage_via_libcall (object, size, const0_rtx,
method == BLOCK_OP_TAILCALL);
+ else
+ gcc_unreachable ();
return NULL;
}
@@ -3432,12 +3436,14 @@ emit_move_insn (rtx x, rtx y)
/* If X or Y are memory references, verify that their addresses are valid
for the machine. */
if (MEM_P (x)
- && (! memory_address_p (GET_MODE (x), XEXP (x, 0))
+ && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
+ MEM_ADDR_SPACE (x))
&& ! push_operand (x, GET_MODE (x))))
x = validize_mem (x);
if (MEM_P (y)
- && ! memory_address_p (GET_MODE (y), XEXP (y, 0)))
+ && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
+ MEM_ADDR_SPACE (y)))
y = validize_mem (y);
gcc_assert (mode != BLKmode);
@@ -4298,20 +4304,25 @@ expand_assignment (tree to, tree from, bool nontemporal)
else if (TREE_CODE (to) == MISALIGNED_INDIRECT_REF)
{
+ addr_space_t as = ADDR_SPACE_GENERIC;
enum machine_mode mode, op_mode1;
enum insn_code icode;
rtx reg, addr, mem, insn;
+ if (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (to, 0))))
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0))));
+
reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
reg = force_not_mem (reg);
mode = TYPE_MODE (TREE_TYPE (to));
addr = expand_expr (TREE_OPERAND (to, 0), NULL_RTX, VOIDmode,
EXPAND_SUM);
- addr = memory_address (mode, addr);
+ addr = memory_address_addr_space (mode, addr, as);
mem = gen_rtx_MEM (mode, addr);
set_mem_attributes (mem, to, 0);
+ set_mem_addr_space (mem, as);
icode = movmisalign_optab->handlers[mode].insn_code;
gcc_assert (icode != CODE_FOR_nothing);
@@ -4400,6 +4411,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
the place the value is being stored, use a safe function when copying
a value through a pointer into a structure value return block. */
if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
+ && ADDR_SPACE_GENERIC_P
+ (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
&& cfun->returns_struct
&& !cfun->returns_pcc_struct)
{
@@ -7343,6 +7356,39 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
return REDUCE_BIT_FIELD (op0);
+ case ADDR_SPACE_CONVERT_EXPR:
+ {
+ tree treeop0_type = TREE_TYPE (treeop0);
+ addr_space_t as_to;
+ addr_space_t as_from;
+
+ gcc_assert (POINTER_TYPE_P (type));
+ gcc_assert (POINTER_TYPE_P (treeop0_type));
+
+ as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
+
+ /* Conversions between pointers to the same address space should
+ have been implemented via CONVERT_EXPR / NOP_EXPR. */
+ gcc_assert (as_to != as_from);
+
+ /* Ask target code to handle conversion between pointers
+ to overlapping address spaces. */
+ if (targetm.addr_space.subset_p (as_to, as_from)
+ || targetm.addr_space.subset_p (as_from, as_to))
+ {
+ op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
+ op0 = targetm.addr_space.convert (op0, treeop0_type, type);
+ gcc_assert (op0);
+ return op0;
+ }
+
+ /* For disjoint address spaces, converting anything but
+ a null pointer invokes undefined behaviour. We simply
+ always return a null pointer here. */
+ return CONST0_RTX (mode);
+ }
+
case POINTER_PLUS_EXPR:
/* Even though the sizetype mode and the pointer's mode can be different
expand is able to handle this correctly and get the correct result out
@@ -8431,7 +8477,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
decl_rtl = use_anchored_address (decl_rtl);
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_SUM
- && !memory_address_p (DECL_MODE (exp), XEXP (decl_rtl, 0)))
+ && !memory_address_addr_space_p (DECL_MODE (exp),
+ XEXP (decl_rtl, 0),
+ MEM_ADDR_SPACE (decl_rtl)))
temp = replace_equiv_address (decl_rtl,
copy_rtx (XEXP (decl_rtl, 0)));
}
@@ -8551,7 +8599,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
&& modifier != EXPAND_SUM
- && ! memory_address_p (mode, XEXP (temp, 0)))
+ && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
+ MEM_ADDR_SPACE (temp)))
return replace_equiv_address (temp,
copy_rtx (XEXP (temp, 0)));
return temp;
@@ -8607,6 +8656,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case INDIRECT_REF:
{
tree exp1 = treeop0;
+ addr_space_t as = ADDR_SPACE_GENERIC;
if (modifier != EXPAND_WRITE)
{
@@ -8617,19 +8667,23 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return expand_expr (t, target, tmode, modifier);
}
+ if (POINTER_TYPE_P (TREE_TYPE (exp1)))
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
+
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
- op0 = memory_address (mode, op0);
+ op0 = memory_address_addr_space (mode, op0, as);
if (code == ALIGN_INDIRECT_REF)
{
int align = TYPE_ALIGN_UNIT (type);
op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
- op0 = memory_address (mode, op0);
+ op0 = memory_address_addr_space (mode, op0, as);
}
temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, exp, 0);
+ set_mem_addr_space (temp, as);
/* Resolve the misalignment now, so that we don't have to remember
to resolve it later. Of course, this only works for reads. */
@@ -8661,13 +8715,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case TARGET_MEM_REF:
{
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
struct mem_address addr;
get_address_description (exp, &addr);
op0 = addr_for_mem_ref (&addr, true);
- op0 = memory_address (mode, op0);
+ op0 = memory_address_addr_space (mode, op0, as);
temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
+ set_mem_addr_space (temp, as);
}
return temp;