summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-address.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-04-11 09:13:11 +0000
committer <>2014-04-23 12:05:38 +0000
commit6af3fdec2262dd94954acc5e426ef71cbd4521d3 (patch)
tree9be02de9a80f7935892a2d03741adee44723e65d /gcc/tree-ssa-address.c
parent19be2b4342ac32e9edc78ce6fed8f61b63ae98d1 (diff)
downloadgcc-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.c119
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;
}