diff options
author | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-26 21:57:10 +0000 |
---|---|---|
committer | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-26 21:57:10 +0000 |
commit | 98155838dbd82b97bb7bb16dfcbf98fa2ab27ca9 (patch) | |
tree | 0b006fa60cd37b4bd974ed32a7adc7f005e9eb0b /gcc/tree-ssa-address.c | |
parent | bd1a81f7e1665d2e33cc824dd05dd7988da9f1a8 (diff) | |
download | gcc-98155838dbd82b97bb7bb16dfcbf98fa2ab27ca9.tar.gz |
2009-10-26 Ben Elliston <bje@au.ibm.com>
Michael Meissner <meissner@linux.vnet.ibm.com>
Ulrich Weigand <uweigand@de.ibm.com>
* doc/tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
* target.h (struct target_def): Add pointer_mode, address_mode,
and valid_pointer_mode to addr_space substructure.
* target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): Define.
(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
(TARGET_ADDR_SPACE_HOOKS): Add them.
* targhooks.c (target_default_pointer_address_modes_p): New function.
* target.h (target_default_pointer_address_modes_p): Add prototype.
* targhooks.c (default_addr_space_pointer_mode): New function.
(default_addr_space_address_mode): Likewise.
(default_addr_space_valid_pointer_mode): Likewise.
* targhooks.h (default_addr_space_pointer_mode): Add prototype.
(default_addr_space_address_mode): Likewise.
(default_addr_space_valid_pointer_mode): Likewise.
* output.h (default_valid_pointer_mode): Move to ...
* targhooks.h (default_valid_pointer_mode): ... here.
* varasm.c (default_valid_pointer_mode): Move to ...
* targhooks.c (default_valid_pointer_mode): ... here.
* varasm.c (output_constant): Use targetm.addr_space.valid_pointer_mode
instead of targetm.valid_pointer_mode.
* fold-const.c (fit_double_type): Use int_or_pointer_precision.
* tree.c (integer_pow2p): Likewise.
(tree_log2): Likewise.
(tree_floor_log2): Likewise.
(signed_or_unsigned_type_for): Support pointer type of different size.
(int_or_pointer_precision): New function.
* tree.h (int_or_pointer_precision): Add prototype.
* stor-layout.c (layout_type): Set TYPE_PRECISION for offset types.
* varasm.c (initializer_constant_valid_p): Use TYPE_PRECISION of
incoming pointer type instead of POINTER_SIZE.
* tree.c (build_pointer_type): Use appropriate pointer mode
instead of ptr_mode.
(build_reference_type): Likewise.
* expr.c (store_expr): Likewise.
(expand_expr_addr_expr): Likewise.
* tree-vect-data-refs.c (vect_create_data_ref_ptr): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* auto-inc-dec.c: Include "target.h".
(try_merge): Use appropriate address mode instead of Pmode.
(find_inc): Likewise.
* combine.c (find_split_point): Likewise.
* cselib.c (cselib_record_sets): Likewise.
* dse.c (replace_inc_dec): Likewise.
(canon_address): Likewise.
* var-tracking.c (replace_expr_with_values): Likewise.
(count_uses): Likewise.
(add_uses): Likewise.
(add_stores): Likewise.
* emit-rtl.c: Include "target.h".
(adjust_address_1): Use appropriate address mode instead of Pmode.
(offset_address): Likewise.
* explow.c (break_out_memory_refs): Likewise.
(memory_address_addr_space): Likewise.
(promote_mode): Likewise.
* expr.c (move_by_pieces): Likewise.
(emit_block_move_via_loop): Likewise.
(store_by_pieces): Likewise.
(store_by_pieces_1): Likewise.
(expand_assignment): Likewise.
(store_constructor): Likewise.
(expand_expr_addr_expr): Likewise.
(expand_expr_real_1): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* ifcvt.c (noce_try_cmove_arith): Likewise.
* regcprop.c (kill_autoinc_value): Likewise.
* regmove.c (try_auto_increment): Likewise.
* reload.c (find_reloads): Likewise.
(find_reloads_address): Likewise.
(find_reloads_address_1): Likewise.
* sched-deps.c: Include "target.h".
(sched_analyze_1): Use appropriate address mode instead of Pmode.
(sched_analyze_2): Likewise.
* sel-sched-dump.c: Include "target.h".
(debug_mem_addr_value): Use appropriate address mode instead of Pmode.
* stor-layout.c (layout_type): Likewise.
* tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise.
(multiplier_allowed_in_address_p): Likewise.
(get_address_cost): Likewise.
* varasm.c (make_decl_rtl): Likewise.
* expr.c (expand_assignment): Always convert offsets to appropriate
address mode.
(store_expr): Likewise.
(store_constructor): Likewise.
(expand_expr_real_1): Likewise.
* reload.h (form_sum): Add MODE argument.
* reload.c (form_sum): Add MODE argument, use it instead of Pmode.
Update recursive calls.
(subst_indexed_address): Update calls to form_sum.
* tree-flow.h (addr_for_mem_ref): Add ADDRSPACE argument.
* tree-ssa-address.c: Include "target.h".
(templates): Replace by ...
(mem_addr_template_list): ... this new vector.
(TEMPL_IDX): Handle address space numbers.
(gen_addr_rtx): Add address mode argument, use it instead of Pmode.
(addr_for_mem_ref): Add ADDRSPACE argument. Use per-address-space
instead of global cache. Update call to gen_addr_rtx.
(valid_mem_ref_p): Update call to addr_for_mem_ref.
* expr.c (expand_expr_real_1): Update call to addr_for_mem_ref.
* rtl.h (convert_memory_address_addr_space): Add prototype.
(convert_memory_address): Define as macro.
* explow.c (convert_memory_address): Rename to ...
(convert_memory_address_addr_space): ... this. Add ADDRSPACE argument.
Use appropriate pointer and address modes instead of ptr_mode / Pmode.
Update recursive calls.
(memory_address_addr_space): Call convert_memory_address_addr_space.
* expmed.c (make_tree): Likewise.
* expr.c (expand_assignment): Likewise.
(expand_expr_addr_expr_1): Likewise. Also, add ADDRSPACE argument.
(expand_expr_addr_expr): Likewise. Also, update call.
* alias.c (find_base_value): Guard pointer size optimizations.
(find_base_term): Likewise.
* rtlanal.c (nonzero_bits1): Likewise.
(num_sign_bit_copies1): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
* Makefile.in (tree-ssa-address.o): Add $(TARGET_H) dependency.
(emit-rtl.o): Likewise.
(auto-inc-dec.o): Likewise.
(sched-deps.o): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153573 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-address.c')
-rw-r--r-- | gcc/tree-ssa-address.c | 106 |
1 files changed, 61 insertions, 45 deletions
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index c5e34229bf6..1428803272f 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "ggc.h" #include "tree-affine.h" +#include "target.h" /* TODO -- handling of symbols (according to Richard Hendersons comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): @@ -70,32 +71,38 @@ along with GCC; see the file COPYING3. If not see /* A "template" for memory address, used to determine whether the address is valid for mode. */ -struct GTY (()) mem_addr_template { +typedef struct GTY (()) mem_addr_template { rtx ref; /* The template. */ rtx * GTY ((skip)) step_p; /* The point in template where the step should be filled in. */ rtx * GTY ((skip)) off_p; /* The point in template where the offset should be filled in. */ -}; +} mem_addr_template; -/* The templates. Each of the five bits of the index corresponds to one - component of TARGET_MEM_REF being present, see TEMPL_IDX. */ +DEF_VEC_O (mem_addr_template); +DEF_VEC_ALLOC_O (mem_addr_template, gc); -static GTY (()) struct mem_addr_template templates[32]; +/* The templates. Each of the low five bits of the index corresponds to one + component of TARGET_MEM_REF being present, while the high bits identify + the address space. See TEMPL_IDX. */ -#define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \ - (((SYMBOL != 0) << 4) \ +static GTY(()) VEC (mem_addr_template, gc) *mem_addr_template_list; + +#define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \ + (((int) (AS) << 5) \ + | ((SYMBOL != 0) << 4) \ | ((BASE != 0) << 3) \ | ((INDEX != 0) << 2) \ | ((STEP != 0) << 1) \ | (OFFSET != 0)) /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX, - STEP and OFFSET to *ADDR. Stores pointers to where step is placed to - *STEP_P and offset to *OFFSET_P. */ + STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers + to where step is placed to *STEP_P and offset to *OFFSET_P. */ static void -gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, +gen_addr_rtx (enum machine_mode address_mode, + rtx symbol, rtx base, rtx index, rtx step, rtx offset, rtx *addr, rtx **step_p, rtx **offset_p) { rtx act_elem; @@ -111,7 +118,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, act_elem = index; if (step) { - act_elem = gen_rtx_MULT (Pmode, act_elem, step); + act_elem = gen_rtx_MULT (address_mode, act_elem, step); if (step_p) *step_p = &XEXP (act_elem, 1); @@ -123,7 +130,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, if (base) { if (*addr) - *addr = simplify_gen_binary (PLUS, Pmode, base, *addr); + *addr = simplify_gen_binary (PLUS, address_mode, base, *addr); else *addr = base; } @@ -133,7 +140,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, act_elem = symbol; if (offset) { - act_elem = gen_rtx_PLUS (Pmode, act_elem, offset); + act_elem = gen_rtx_PLUS (address_mode, act_elem, offset); if (offset_p) *offset_p = &XEXP (act_elem, 1); @@ -141,11 +148,11 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, if (GET_CODE (symbol) == SYMBOL_REF || GET_CODE (symbol) == LABEL_REF || GET_CODE (symbol) == CONST) - act_elem = gen_rtx_CONST (Pmode, act_elem); + act_elem = gen_rtx_CONST (address_mode, act_elem); } if (*addr) - *addr = gen_rtx_PLUS (Pmode, *addr, act_elem); + *addr = gen_rtx_PLUS (address_mode, *addr, act_elem); else *addr = act_elem; } @@ -153,7 +160,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, { if (*addr) { - *addr = gen_rtx_PLUS (Pmode, *addr, offset); + *addr = gen_rtx_PLUS (address_mode, *addr, offset); if (offset_p) *offset_p = &XEXP (*addr, 1); } @@ -169,55 +176,64 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset, *addr = const0_rtx; } -/* Returns address for TARGET_MEM_REF with parameters given by ADDR. +/* Returns address for TARGET_MEM_REF with parameters given by ADDR + in address space AS. If REALLY_EXPAND is false, just make fake registers instead of really expanding the operands, and perform the expansion in-place by using one of the "templates". */ rtx -addr_for_mem_ref (struct mem_address *addr, bool really_expand) +addr_for_mem_ref (struct mem_address *addr, addr_space_t as, + bool really_expand) { + enum machine_mode address_mode = targetm.addr_space.address_mode (as); rtx address, sym, bse, idx, st, off; - static bool templates_initialized = false; struct mem_addr_template *templ; if (addr->step && !integer_onep (addr->step)) st = immed_double_const (TREE_INT_CST_LOW (addr->step), - TREE_INT_CST_HIGH (addr->step), Pmode); + TREE_INT_CST_HIGH (addr->step), address_mode); else st = NULL_RTX; if (addr->offset && !integer_zerop (addr->offset)) off = immed_double_const (TREE_INT_CST_LOW (addr->offset), - TREE_INT_CST_HIGH (addr->offset), Pmode); + TREE_INT_CST_HIGH (addr->offset), address_mode); else off = NULL_RTX; if (!really_expand) { + unsigned int templ_index + = TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off); + + if (templ_index + >= VEC_length (mem_addr_template, mem_addr_template_list)) + VEC_safe_grow_cleared (mem_addr_template, gc, mem_addr_template_list, + templ_index + 1); + /* Reuse the templates for addresses, so that we do not waste memory. */ - if (!templates_initialized) + templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index); + if (!templ->ref) { - unsigned i; - - templates_initialized = true; - sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup ("test_symbol")); - bse = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1); - idx = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2); - - for (i = 0; i < 32; i++) - gen_addr_rtx ((i & 16 ? sym : NULL_RTX), - (i & 8 ? bse : NULL_RTX), - (i & 4 ? idx : NULL_RTX), - (i & 2 ? const0_rtx : NULL_RTX), - (i & 1 ? const0_rtx : NULL_RTX), - &templates[i].ref, - &templates[i].step_p, - &templates[i].off_p); + sym = (addr->symbol ? + gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol")) + : NULL_RTX); + bse = (addr->base ? + gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1) + : NULL_RTX); + idx = (addr->index ? + gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2) + : NULL_RTX); + + gen_addr_rtx (address_mode, sym, bse, idx, + st? const0_rtx : NULL_RTX, + off? const0_rtx : NULL_RTX, + &templ->ref, + &templ->step_p, + &templ->off_p); } - templ = templates + TEMPL_IDX (addr->symbol, addr->base, addr->index, - st, off); if (st) *templ->step_p = st; if (off) @@ -229,16 +245,16 @@ addr_for_mem_ref (struct mem_address *addr, bool really_expand) /* Otherwise really expand the expressions. */ sym = (addr->symbol ? expand_expr (build_addr (addr->symbol, current_function_decl), - NULL_RTX, Pmode, EXPAND_NORMAL) + NULL_RTX, address_mode, EXPAND_NORMAL) : NULL_RTX); bse = (addr->base - ? expand_expr (addr->base, NULL_RTX, Pmode, EXPAND_NORMAL) + ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL) : NULL_RTX); idx = (addr->index - ? expand_expr (addr->index, NULL_RTX, Pmode, EXPAND_NORMAL) + ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL) : NULL_RTX); - gen_addr_rtx (sym, bse, idx, st, off, &address, NULL, NULL); + gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL); return address; } @@ -310,7 +326,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as, { rtx address; - address = addr_for_mem_ref (addr, false); + address = addr_for_mem_ref (addr, as, false); if (!address) return false; |