diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-04-11 09:13:11 +0000 |
---|---|---|
committer | <> | 2014-04-23 12:05:38 +0000 |
commit | 6af3fdec2262dd94954acc5e426ef71cbd4521d3 (patch) | |
tree | 9be02de9a80f7935892a2d03741adee44723e65d /gcc/tree-ssa-address.c | |
parent | 19be2b4342ac32e9edc78ce6fed8f61b63ae98d1 (diff) | |
download | gcc-tarball-6af3fdec2262dd94954acc5e426ef71cbd4521d3.tar.gz |
Imported from /home/lorry/working-area/delta_gcc-tarball/gcc-4.7.3.tar.bz2.gcc-4.7.3
Diffstat (limited to 'gcc/tree-ssa-address.c')
-rw-r--r-- | gcc/tree-ssa-address.c | 119 |
1 files changed, 87 insertions, 32 deletions
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index 437460d95c..cf131578d2 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -189,11 +189,12 @@ 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); + enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); rtx address, sym, bse, idx, st, off; struct mem_addr_template *templ; if (addr->step && !integer_onep (addr->step)) - st = immed_double_int_const (tree_to_double_int (addr->step), address_mode); + st = immed_double_int_const (tree_to_double_int (addr->step), pointer_mode); else st = NULL_RTX; @@ -201,7 +202,7 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, off = immed_double_int_const (double_int_sext (tree_to_double_int (addr->offset), TYPE_PRECISION (TREE_TYPE (addr->offset))), - address_mode); + pointer_mode); else off = NULL_RTX; @@ -220,16 +221,16 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, if (!templ->ref) { sym = (addr->symbol ? - gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol")) + gen_rtx_SYMBOL_REF (pointer_mode, ggc_strdup ("test_symbol")) : NULL_RTX); bse = (addr->base ? - gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1) + gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 1) : NULL_RTX); idx = (addr->index ? - gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2) + gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 2) : NULL_RTX); - gen_addr_rtx (address_mode, sym, bse, idx, + gen_addr_rtx (pointer_mode, sym, bse, idx, st? const0_rtx : NULL_RTX, off? const0_rtx : NULL_RTX, &templ->ref, @@ -247,16 +248,18 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, /* Otherwise really expand the expressions. */ sym = (addr->symbol - ? expand_expr (addr->symbol, NULL_RTX, address_mode, EXPAND_NORMAL) + ? expand_expr (addr->symbol, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); bse = (addr->base - ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL) + ? expand_expr (addr->base, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); idx = (addr->index - ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL) + ? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); - gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL); + gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL); + if (pointer_mode != address_mode) + address = convert_memory_address (address_mode, address); return address; } @@ -276,7 +279,8 @@ tree_mem_ref_addr (tree type, tree mem_ref) if (act_elem) { if (step) - act_elem = fold_build2 (MULT_EXPR, sizetype, act_elem, step); + act_elem = fold_build2 (MULT_EXPR, TREE_TYPE (act_elem), + act_elem, step); addr_off = act_elem; } @@ -284,22 +288,23 @@ tree_mem_ref_addr (tree type, tree mem_ref) if (act_elem) { if (addr_off) - addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, act_elem); + addr_off = fold_build2 (PLUS_EXPR, TREE_TYPE (addr_off), + addr_off, act_elem); else addr_off = act_elem; } if (offset && !integer_zerop (offset)) { - offset = fold_convert (sizetype, offset); if (addr_off) - addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, offset); + addr_off = fold_build2 (PLUS_EXPR, TREE_TYPE (addr_off), addr_off, + fold_convert (TREE_TYPE (addr_off), offset)); else addr_off = offset; } if (addr_off) - addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off); + addr = fold_build_pointer_plus (addr_base, addr_off); else addr = addr_base; @@ -518,9 +523,7 @@ add_to_parts (struct mem_address *parts, tree elt) /* Add ELT to base. */ type = TREE_TYPE (parts->base); if (POINTER_TYPE_P (type)) - parts->base = fold_build2 (POINTER_PLUS_EXPR, type, - parts->base, - fold_convert (sizetype, elt)); + parts->base = fold_build_pointer_plus (parts->base, elt); else parts->base = fold_build2 (PLUS_EXPR, type, parts->base, elt); @@ -689,7 +692,6 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, tree alias_ptr_type, tree iv_cand, tree base_hint, bool speed) { tree mem_ref, tmp; - tree atype; struct mem_address parts; addr_to_parts (type, addr, iv_cand, base_hint, &parts, speed); @@ -728,11 +730,8 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, if (parts.index) { - atype = TREE_TYPE (tmp); parts.base = force_gimple_operand_gsi_1 (gsi, - fold_build2 (POINTER_PLUS_EXPR, atype, - tmp, - fold_convert (sizetype, parts.base)), + fold_build_pointer_plus (tmp, parts.base), is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); } else @@ -755,11 +754,8 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, /* Add index to base. */ if (parts.base) { - atype = TREE_TYPE (parts.base); parts.base = force_gimple_operand_gsi_1 (gsi, - fold_build2 (POINTER_PLUS_EXPR, atype, - parts.base, - parts.index), + fold_build_pointer_plus (parts.base, parts.index), is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); } else @@ -776,11 +772,8 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, /* Try adding offset to base. */ if (parts.base) { - atype = TREE_TYPE (parts.base); parts.base = force_gimple_operand_gsi_1 (gsi, - fold_build2 (POINTER_PLUS_EXPR, atype, - parts.base, - fold_convert (sizetype, parts.offset)), + fold_build_pointer_plus (parts.base, parts.offset), is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); } else @@ -839,6 +832,68 @@ copy_mem_ref_info (tree to, tree from) TREE_THIS_VOLATILE (to) = TREE_THIS_VOLATILE (from); } +/* Copies the reference information from OLD_REF to NEW_REF, where + NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */ + +void +copy_ref_info (tree new_ref, tree old_ref) +{ + tree new_ptr_base = NULL_TREE; + + gcc_assert (TREE_CODE (new_ref) == MEM_REF + || TREE_CODE (new_ref) == TARGET_MEM_REF); + + TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); + TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); + + new_ptr_base = TREE_OPERAND (new_ref, 0); + + /* We can transfer points-to information from an old pointer + or decl base to the new one. */ + if (new_ptr_base + && TREE_CODE (new_ptr_base) == SSA_NAME + && !SSA_NAME_PTR_INFO (new_ptr_base)) + { + tree base = get_base_address (old_ref); + if (!base) + ; + else if ((TREE_CODE (base) == MEM_REF + || TREE_CODE (base) == TARGET_MEM_REF) + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME + && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) + { + struct ptr_info_def *new_pi; + duplicate_ssa_name_ptr_info + (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); + new_pi = SSA_NAME_PTR_INFO (new_ptr_base); + /* We have to be careful about transfering alignment information. */ + if (TREE_CODE (old_ref) == MEM_REF + && !(TREE_CODE (new_ref) == TARGET_MEM_REF + && (TMR_INDEX2 (new_ref) + || (TMR_STEP (new_ref) + && (TREE_INT_CST_LOW (TMR_STEP (new_ref)) + < new_pi->align))))) + { + new_pi->misalign += double_int_sub (mem_ref_offset (old_ref), + mem_ref_offset (new_ref)).low; + new_pi->misalign &= (new_pi->align - 1); + } + else + { + new_pi->align = 1; + new_pi->misalign = 0; + } + } + else if (TREE_CODE (base) == VAR_DECL + || TREE_CODE (base) == PARM_DECL + || TREE_CODE (base) == RESULT_DECL) + { + struct ptr_info_def *pi = get_ptr_info (new_ptr_base); + pt_solution_set_var (&pi->pt, base); + } + } +} + /* Move constants in target_mem_ref REF to offset. Returns the new target mem ref if anything changes, NULL_TREE otherwise. */ @@ -880,7 +935,7 @@ maybe_fold_tmr (tree ref) (get_addr_base_and_unit_offset (TREE_OPERAND (addr.symbol, 0), &offset)); addr.offset = int_const_binop (PLUS_EXPR, - addr.offset, size_int (offset), 0); + addr.offset, size_int (offset)); changed = true; } |