diff options
author | Ben Elliston <bje@au.ibm.com> | 2009-10-26 21:55:59 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2009-10-26 21:55:59 +0000 |
commit | 09e881c9e21a9209b2092e400ea4c38948614f78 (patch) | |
tree | ea57b1c9bc1dc4b71890b4a10a89294179e3c5e6 /gcc/expr.c | |
parent | 89c74f4afa6db154288515ed1e1cdbe8694dc4c5 (diff) | |
download | gcc-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.c | 76 |
1 files changed, 66 insertions, 10 deletions
@@ -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; |