gcc/gcc/rtlhooks.c
Ben Elliston 09e881c9e2 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
2009-10-26 21:55:59 +00:00

169 lines
5.1 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Generic hooks for the RTL middle-end.
Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "rtlhooks-def.h"
#include "expr.h"
#include "recog.h"
/* For speed, we will copy the RTX hooks struct member-by-member
instead of doing indirect calls. For these reason, we initialize
*two* struct rtl_hooks globals: rtl_hooks is the one that is used
to actually call the hooks, while general_rtl_hooks is used
to restore the hooks by passes that modify them. */
const struct rtl_hooks general_rtl_hooks = RTL_HOOKS_INITIALIZER;
struct rtl_hooks rtl_hooks = RTL_HOOKS_INITIALIZER;
rtx
gen_lowpart_general (enum machine_mode mode, rtx x)
{
rtx result = gen_lowpart_common (mode, x);
if (result)
return result;
/* Handle SUBREGs and hard REGs that were rejected by
simplify_gen_subreg. */
else if (REG_P (x) || GET_CODE (x) == SUBREG)
{
result = gen_lowpart_common (mode, copy_to_reg (x));
gcc_assert (result != 0);
return result;
}
else
{
int offset = 0;
/* The only additional case we can do is MEM. */
gcc_assert (MEM_P (x));
/* The following exposes the use of "x" to CSE. */
if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
&& SCALAR_INT_MODE_P (GET_MODE (x))
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (x)))
&& !reload_completed)
return gen_lowpart_general (mode, force_reg (GET_MODE (x), x));
if (WORDS_BIG_ENDIAN)
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
if (BYTES_BIG_ENDIAN)
/* Adjust the address so that the address-after-the-data
is unchanged. */
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
return adjust_address (x, mode, offset);
}
}
/* Similar to gen_lowpart, but cannot emit any instruction via
copy_to_reg or force_reg. Mainly used in simplify-rtx.c. */
rtx
gen_lowpart_no_emit_general (enum machine_mode mode, rtx x)
{
rtx result = gen_lowpart_if_possible (mode, x);
if (result)
return result;
else
return x;
}
rtx
reg_num_sign_bit_copies_general (const_rtx x ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
const_rtx known_x ATTRIBUTE_UNUSED,
enum machine_mode known_mode ATTRIBUTE_UNUSED,
unsigned int known_ret ATTRIBUTE_UNUSED,
unsigned int *result ATTRIBUTE_UNUSED)
{
return NULL;
}
rtx
reg_nonzero_bits_general (const_rtx x ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
const_rtx known_x ATTRIBUTE_UNUSED,
enum machine_mode known_mode ATTRIBUTE_UNUSED,
unsigned HOST_WIDE_INT known_ret ATTRIBUTE_UNUSED,
unsigned HOST_WIDE_INT *nonzero ATTRIBUTE_UNUSED)
{
return NULL;
}
bool
reg_truncated_to_mode_general (enum machine_mode mode ATTRIBUTE_UNUSED,
const_rtx x ATTRIBUTE_UNUSED)
{
return false;
}
/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
least-significant part of X.
MODE specifies how big a part of X to return.
If the requested operation cannot be done, 0 is returned.
This is similar to gen_lowpart_general. */
rtx
gen_lowpart_if_possible (enum machine_mode mode, rtx x)
{
rtx result = gen_lowpart_common (mode, x);
if (result)
return result;
else if (MEM_P (x))
{
/* This is the only other case we handle. */
int offset = 0;
rtx new_rtx;
if (WORDS_BIG_ENDIAN)
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
if (BYTES_BIG_ENDIAN)
/* Adjust the address so that the address-after-the-data is
unchanged. */
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
new_rtx = adjust_address_nv (x, mode, offset);
if (! memory_address_addr_space_p (mode, XEXP (new_rtx, 0),
MEM_ADDR_SPACE (x)))
return 0;
return new_rtx;
}
else if (mode != GET_MODE (x) && GET_MODE (x) != VOIDmode
&& validate_subreg (mode, GET_MODE (x), x,
subreg_lowpart_offset (mode, GET_MODE (x))))
return gen_lowpart_SUBREG (mode, x);
else
return 0;
}