diff options
author | Richard Guenther <rguenther@suse.de> | 2010-09-06 13:26:13 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-09-06 13:26:13 +0000 |
commit | be1ac4ecae4317082e9a45c86f3b90e0e429e78f (patch) | |
tree | ae7fc5c26853d1f5d2558a8bfd07474392012be4 /gcc/expr.c | |
parent | 863a75787c5765257e516afa538dee2e22d6d0ad (diff) | |
download | gcc-be1ac4ecae4317082e9a45c86f3b90e0e429e78f.zip gcc-be1ac4ecae4317082e9a45c86f3b90e0e429e78f.tar.gz gcc-be1ac4ecae4317082e9a45c86f3b90e0e429e78f.tar.bz2 |
tree.def (MISALIGNED_INDIRECT_REF): Remove.
2010-09-06 Richard Guenther <rguenther@suse.de>
* tree.def (MISALIGNED_INDIRECT_REF): Remove.
* tree.h (INDIRECT_REF_P): Only check for INDIRECT_REF.
(build_aligned_type): Declare.
* tree.c (check_qualified_type): Also compare TYPE_ALIGN.
(check_aligned_type): New function.
(build_aligned_type): Likewise.
* expr.c (expand_assignment): Handle misaligned stores via
TARGET_MEM_REF and MEM_REF using movmisalign_optab.
(expand_expr_real_1): Likewise.
(safe_from_p): Remove MISALIGNED_INDIRECT_REF handling.
* tree-vect-stmts.c (vectorizable_store): Do not build
MISALIGNED_INDIRECT_REF but initialize alignment information.
(vectorizable_load): Likewise.
* builtins.c (get_object_alignment): Remove MISALIGNED_INDIRECT_REF
handling.
* cfgexpand.c (expand_debug_expr): Likewise.
* dwarf2out.c (loc_list_from_tree): Likewise.
* fold-const.c (maybe_lvalue_p): Likewise.
(operand_equal_p): Likewise.
(build_fold_addr_expr_with_type_loc): Likewise.
* gimplify.c (gimplify_addr_expr): Likewise.
(gimplify_expr): Likewise.
* tree-cfg.c (verify_types_in_gimple_min_lval): Likewise.
(verify_gimple_assign_single): Likewise.
* tree-dump.c (dequeue_and_dump): Likewise.
(tree_could_trap_p): Likewise.
* tree-predcom.c (ref_at_iteration): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
(op_code_prio): Likewise.
(op_symbol_code): Likewise.
* tree-ssa-ccp.c (get_value_from_alignment): Likewise.
* tree-ssa-loop-im.c (for_each_index): Likewise.
(gen_lsm_tmp_name): Likewise.
* tree-ssa-loop-ivopts.c (idx_find_step): Likewise.
(find_interesting_uses_address): Likewise.
* tree-ssa-loop-prefetch.c (idx_analyze_ref): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
(ao_ref_init_from_vn_reference): Likewise.
* tree.c (staticp): Likewise.
(build1_stat): Likewise.
(reference_alias_ptr_type): Likewise.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
* config/rs6000/rs6000.c (rs6000_check_sdmode): Remove
MISALIGNED_INDIRECT_REF handling.
From-SVN: r163915
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 193 |
1 files changed, 107 insertions, 86 deletions
@@ -4151,6 +4151,8 @@ expand_assignment (tree to, tree from, bool nontemporal) { rtx to_rtx = 0; rtx result; + enum machine_mode mode; + int align, icode; /* Don't crash if the lhs of the assignment was erroneous. */ if (TREE_CODE (to) == ERROR_MARK) @@ -4163,6 +4165,68 @@ expand_assignment (tree to, tree from, bool nontemporal) if (operand_equal_p (to, from, 0)) return; + mode = TYPE_MODE (TREE_TYPE (to)); + if ((TREE_CODE (to) == MEM_REF + || TREE_CODE (to) == TARGET_MEM_REF) + && mode != BLKmode + && ((align = MAX (TYPE_ALIGN (TREE_TYPE (to)), + get_object_alignment (to, BIGGEST_ALIGNMENT))) + < (signed) GET_MODE_ALIGNMENT (mode)) + && ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing)) + { + enum machine_mode address_mode, op_mode1; + rtx insn, reg, op0, mem; + + reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL); + reg = force_not_mem (reg); + + if (TREE_CODE (to) == MEM_REF) + { + addr_space_t as + = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 1)))); + tree base = TREE_OPERAND (to, 0); + address_mode = targetm.addr_space.address_mode (as); + op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL); + op0 = convert_memory_address_addr_space (address_mode, op0, as); + if (!integer_zerop (TREE_OPERAND (to, 1))) + { + rtx off + = immed_double_int_const (mem_ref_offset (to), address_mode); + op0 = simplify_gen_binary (PLUS, address_mode, op0, off); + } + op0 = memory_address_addr_space (mode, op0, as); + mem = gen_rtx_MEM (mode, op0); + set_mem_attributes (mem, to, 0); + set_mem_addr_space (mem, as); + } + else if (TREE_CODE (to) == TARGET_MEM_REF) + { + addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (to)); + struct mem_address addr; + + get_address_description (to, &addr); + op0 = addr_for_mem_ref (&addr, as, true); + op0 = memory_address_addr_space (mode, op0, as); + mem = gen_rtx_MEM (mode, op0); + set_mem_attributes (mem, to, 0); + set_mem_addr_space (mem, as); + } + else + gcc_unreachable (); + if (TREE_THIS_VOLATILE (to)) + MEM_VOLATILE_P (mem) = 1; + + op_mode1 = insn_data[icode].operand[1].mode; + if (! (*insn_data[icode].operand[1].predicate) (reg, op_mode1) + && op_mode1 != VOIDmode) + reg = copy_to_mode_reg (op_mode1, reg); + + insn = GEN_FCN (icode) (mem, reg); + emit_insn (insn); + return; + } + /* Assignment of a structure component needs special treatment if the structure component's rtx is not simply a MEM. Assignment of an array element at a constant index, and assignment of @@ -4297,41 +4361,6 @@ expand_assignment (tree to, tree from, bool nontemporal) return; } - 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_addr_space (mode, addr, as); - mem = gen_rtx_MEM (mode, addr); - - set_mem_attributes (mem, to, 0); - set_mem_addr_space (mem, as); - - icode = optab_handler (movmisalign_optab, mode); - gcc_assert (icode != CODE_FOR_nothing); - - op_mode1 = insn_data[icode].operand[1].mode; - if (! (*insn_data[icode].operand[1].predicate) (reg, op_mode1) - && op_mode1 != VOIDmode) - reg = copy_to_mode_reg (op_mode1, reg); - - insn = GEN_FCN (icode) (mem, reg); - emit_insn (insn); - return; - } - /* If the rhs is a function call and its value is not an aggregate, call the function before we start to compute the lhs. This is needed for correct code for cases such as @@ -6659,8 +6688,7 @@ safe_from_p (const_rtx x, tree exp, int top_p) } break; - case MISALIGNED_INDIRECT_REF: - case INDIRECT_REF: + case MEM_REF: if (MEM_P (x) && alias_sets_conflict_p (MEM_ALIAS_SET (x), get_alias_set (exp))) @@ -8598,46 +8626,29 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, return expand_constructor (exp, target, modifier, false); - case MISALIGNED_INDIRECT_REF: - case INDIRECT_REF: + case TARGET_MEM_REF: { - tree exp1 = treeop0; - addr_space_t as = ADDR_SPACE_GENERIC; - - if (modifier != EXPAND_WRITE) - { - tree t; - - t = fold_read_from_constant_string (exp); - if (t) - return expand_expr (t, target, tmode, modifier); - } - - if (POINTER_TYPE_P (TREE_TYPE (exp1))) - as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1))); + addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); + struct mem_address addr; + int icode, align; - op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM); + get_address_description (exp, &addr); + op0 = addr_for_mem_ref (&addr, as, true); 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. */ - if (code == MISALIGNED_INDIRECT_REF) + align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), + get_object_alignment (exp, BIGGEST_ALIGNMENT)); + if (mode != BLKmode + && (unsigned) align < GET_MODE_ALIGNMENT (mode) + /* If the target does not have special handling for unaligned + loads of mode then it can use regular moves for them. */ + && ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing)) { - int icode; rtx reg, insn; - gcc_assert (modifier == EXPAND_NORMAL - || modifier == EXPAND_STACK_PARM); - - /* The vectorizer should have already checked the mode. */ - icode = optab_handler (movmisalign_optab, mode); - gcc_assert (icode != CODE_FOR_nothing); - /* We've already validated the memory, and we're creating a new pseudo destination. The predicates really can't fail. */ reg = gen_reg_rtx (mode); @@ -8648,24 +8659,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, return reg; } - return temp; } - 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, as, true); - 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); - } - return temp; - case MEM_REF: { addr_space_t as @@ -8673,6 +8669,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, enum machine_mode address_mode; tree base = TREE_OPERAND (exp, 0); gimple def_stmt; + int icode, align; /* Handle expansion of non-aliased memory with non-BLKmode. That might end up in a register. */ if (TREE_CODE (base) == ADDR_EXPR) @@ -8717,9 +8714,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, address_mode = targetm.addr_space.address_mode (as); base = TREE_OPERAND (exp, 0); if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR))) - base = build2 (BIT_AND_EXPR, TREE_TYPE (base), - gimple_assign_rhs1 (def_stmt), - gimple_assign_rhs2 (def_stmt)); + { + tree mask = gimple_assign_rhs2 (def_stmt); + base = build2 (BIT_AND_EXPR, TREE_TYPE (base), + gimple_assign_rhs1 (def_stmt), mask); + TREE_OPERAND (exp, 0) = base; + } + align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), + get_object_alignment (exp, BIGGEST_ALIGNMENT)); op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL); op0 = convert_memory_address_addr_space (address_mode, op0, as); if (!integer_zerop (TREE_OPERAND (exp, 1))) @@ -8734,6 +8736,25 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, set_mem_addr_space (temp, as); if (TREE_THIS_VOLATILE (exp)) MEM_VOLATILE_P (temp) = 1; + if (mode != BLKmode + && (unsigned) align < GET_MODE_ALIGNMENT (mode) + /* If the target does not have special handling for unaligned + loads of mode then it can use regular moves for them. */ + && ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing)) + { + rtx reg, insn; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail. */ + reg = gen_reg_rtx (mode); + + /* Nor can the insn generator. */ + insn = GEN_FCN (icode) (reg, temp); + emit_insn (insn); + + return reg; + } return temp; } |