diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-20 12:52:58 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-20 12:52:58 +0000 |
commit | b9c257340bd20ec0e7debffc62ed3e3901c2908d (patch) | |
tree | dcbb7292f9ffa26eed52e3bf4b9f6f183f9df8cd /gcc/tree-ssa-alias.c | |
parent | 5ffca72c5db83f53562a968a30d3955126f044f2 (diff) | |
download | gcc-b9c257340bd20ec0e7debffc62ed3e3901c2908d.zip gcc-b9c257340bd20ec0e7debffc62ed3e3901c2908d.tar.gz gcc-b9c257340bd20ec0e7debffc62ed3e3901c2908d.tar.bz2 |
poly_int: ao_ref and vn_reference_op_t
This patch changes the offset, size and max_size fields
of ao_ref from HOST_WIDE_INT to poly_int64 and propagates
the change through the code that references it. This includes
changing the off field of vn_reference_op_struct in the same way.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* inchash.h (inchash::hash::add_poly_int): New function.
* tree-ssa-alias.h (ao_ref::offset, ao_ref::size, ao_ref::max_size):
Use poly_int64 rather than HOST_WIDE_INT.
(ao_ref::max_size_known_p): New function.
* tree-ssa-sccvn.h (vn_reference_op_struct::off): Use poly_int64_pod
rather than HOST_WIDE_INT.
* tree-ssa-alias.c (ao_ref_base): Apply get_ref_base_and_extent
to temporaries until its interface is adjusted to match.
(ao_ref_init_from_ptr_and_size): Handle polynomial offsets and sizes.
(aliasing_component_refs_p, decl_refs_may_alias_p)
(indirect_ref_may_alias_decl_p, indirect_refs_may_alias_p): Take
the offsets and max_sizes as poly_int64s instead of HOST_WIDE_INTs.
(refs_may_alias_p_1, stmt_kills_ref_p): Adjust for changes to
ao_ref fields.
* alias.c (ao_ref_from_mem): Likewise.
* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.
* tree-ssa-dse.c (valid_ao_ref_for_dse, normalize_ref)
(clear_bytes_written_by, setup_live_bytes_from_ref, compute_trims)
(maybe_trim_complex_store, maybe_trim_constructor_store)
(live_bytes_read, dse_classify_store): Likewise.
* tree-ssa-sccvn.c (vn_reference_compute_hash, vn_reference_eq):
(copy_reference_ops_from_ref, ao_ref_init_from_vn_reference)
(fully_constant_vn_reference_p, valueize_refs_1): Likewise.
(vn_reference_lookup_3): Likewise.
* tree-ssa-uninit.c (warn_uninitialized_vars): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255872
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 105 |
1 files changed, 52 insertions, 53 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 8717a1f..ce63cc1 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -635,11 +635,15 @@ tree ao_ref_base (ao_ref *ref) { bool reverse; + HOST_WIDE_INT offset, size, max_size; if (ref->base) return ref->base; - ref->base = get_ref_base_and_extent (ref->ref, &ref->offset, &ref->size, - &ref->max_size, &reverse); + ref->base = get_ref_base_and_extent (ref->ref, &offset, &size, + &max_size, &reverse); + ref->offset = offset; + ref->size = size; + ref->max_size = max_size; return ref->base; } @@ -679,7 +683,8 @@ ao_ref_alias_set (ao_ref *ref) void ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size) { - HOST_WIDE_INT t, size_hwi, extra_offset = 0; + HOST_WIDE_INT t; + poly_int64 size_hwi, extra_offset = 0; ref->ref = NULL_TREE; if (TREE_CODE (ptr) == SSA_NAME) { @@ -689,11 +694,10 @@ ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size) ptr = gimple_assign_rhs1 (stmt); else if (is_gimple_assign (stmt) && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR - && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST) + && ptrdiff_tree_p (gimple_assign_rhs2 (stmt), &extra_offset)) { ptr = gimple_assign_rhs1 (stmt); - extra_offset = BITS_PER_UNIT - * int_cst_value (gimple_assign_rhs2 (stmt)); + extra_offset *= BITS_PER_UNIT; } } @@ -717,8 +721,8 @@ ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size) } ref->offset += extra_offset; if (size - && tree_fits_shwi_p (size) - && (size_hwi = tree_to_shwi (size)) <= HOST_WIDE_INT_MAX / BITS_PER_UNIT) + && poly_int_tree_p (size, &size_hwi) + && coeffs_in_range_p (size_hwi, 0, HOST_WIDE_INT_MAX / BITS_PER_UNIT)) ref->max_size = ref->size = size_hwi * BITS_PER_UNIT; else ref->max_size = ref->size = -1; @@ -779,11 +783,11 @@ static bool aliasing_component_refs_p (tree ref1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, - HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, + poly_int64 offset1, poly_int64 max_size1, tree ref2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, - HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, + poly_int64 offset2, poly_int64 max_size2, bool ref2_is_decl) { /* If one reference is a component references through pointers try to find a @@ -825,7 +829,7 @@ aliasing_component_refs_p (tree ref1, offset2 -= offadj; get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp, &reverse); offset1 -= offadj; - return ranges_overlap_p (offset1, max_size1, offset2, max_size2); + return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2); } /* If we didn't find a common base, try the other way around. */ refp = &ref1; @@ -844,7 +848,7 @@ aliasing_component_refs_p (tree ref1, offset1 -= offadj; get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp, &reverse); offset2 -= offadj; - return ranges_overlap_p (offset1, max_size1, offset2, max_size2); + return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2); } /* If we have two type access paths B1.path1 and B2.path2 they may @@ -1090,9 +1094,9 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y) static bool decl_refs_may_alias_p (tree ref1, tree base1, - HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, + poly_int64 offset1, poly_int64 max_size1, tree ref2, tree base2, - HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2) + poly_int64 offset2, poly_int64 max_size2) { gcc_checking_assert (DECL_P (base1) && DECL_P (base2)); @@ -1102,7 +1106,7 @@ decl_refs_may_alias_p (tree ref1, tree base1, /* If both references are based on the same variable, they cannot alias if the accesses do not overlap. */ - if (!ranges_overlap_p (offset1, max_size1, offset2, max_size2)) + if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2)) return false; /* For components with variable position, the above test isn't sufficient, @@ -1124,12 +1128,11 @@ decl_refs_may_alias_p (tree ref1, tree base1, static bool indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, - HOST_WIDE_INT offset1, - HOST_WIDE_INT max_size1 ATTRIBUTE_UNUSED, + poly_int64 offset1, poly_int64 max_size1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, tree ref2 ATTRIBUTE_UNUSED, tree base2, - HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, + poly_int64 offset2, poly_int64 max_size2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, bool tbaa_p) { @@ -1185,14 +1188,15 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, is bigger than the size of the decl we can't possibly access the decl via that pointer. */ if (DECL_SIZE (base2) && COMPLETE_TYPE_P (TREE_TYPE (ptrtype1)) - && TREE_CODE (DECL_SIZE (base2)) == INTEGER_CST - && TREE_CODE (TYPE_SIZE (TREE_TYPE (ptrtype1))) == INTEGER_CST + && poly_int_tree_p (DECL_SIZE (base2)) + && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (ptrtype1))) /* ??? This in turn may run afoul when a decl of type T which is a member of union type U is accessed through a pointer to type U and sizeof T is smaller than sizeof U. */ && TREE_CODE (TREE_TYPE (ptrtype1)) != UNION_TYPE && TREE_CODE (TREE_TYPE (ptrtype1)) != QUAL_UNION_TYPE - && tree_int_cst_lt (DECL_SIZE (base2), TYPE_SIZE (TREE_TYPE (ptrtype1)))) + && known_lt (wi::to_poly_widest (DECL_SIZE (base2)), + wi::to_poly_widest (TYPE_SIZE (TREE_TYPE (ptrtype1))))) return false; if (!ref2) @@ -1203,8 +1207,8 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, dbase2 = ref2; while (handled_component_p (dbase2)) dbase2 = TREE_OPERAND (dbase2, 0); - HOST_WIDE_INT doffset1 = offset1; - offset_int doffset2 = offset2; + poly_int64 doffset1 = offset1; + poly_offset_int doffset2 = offset2; if (TREE_CODE (dbase2) == MEM_REF || TREE_CODE (dbase2) == TARGET_MEM_REF) doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT; @@ -1252,11 +1256,11 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, static bool indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, - HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, + poly_int64 offset1, poly_int64 max_size1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, tree ref2 ATTRIBUTE_UNUSED, tree base2, - HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, + poly_int64 offset2, poly_int64 max_size2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, bool tbaa_p) { @@ -1330,7 +1334,7 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, /* But avoid treating arrays as "objects", instead assume they can overlap by an exact multiple of their element size. */ && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE) - return ranges_overlap_p (offset1, max_size1, offset2, max_size2); + return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2); /* Do type-based disambiguation. */ if (base1_alias_set != base2_alias_set @@ -1365,8 +1369,8 @@ bool refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) { tree base1, base2; - HOST_WIDE_INT offset1 = 0, offset2 = 0; - HOST_WIDE_INT max_size1 = -1, max_size2 = -1; + poly_int64 offset1 = 0, offset2 = 0; + poly_int64 max_size1 = -1, max_size2 = -1; bool var1_p, var2_p, ind1_p, ind2_p; gcc_checking_assert ((!ref1->ref @@ -2442,14 +2446,17 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) handling constant offset and size. */ /* For a must-alias check we need to be able to constrain the access properly. */ - if (ref->max_size == -1) + if (!ref->max_size_known_p ()) return false; - HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset; + HOST_WIDE_INT size, max_size, const_offset; + poly_int64 ref_offset = ref->offset; bool reverse; tree base - = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse); + = get_ref_base_and_extent (lhs, &const_offset, &size, &max_size, + &reverse); /* We can get MEM[symbol: sZ, index: D.8862_1] here, so base == ref->base does not always hold. */ + poly_int64 offset = const_offset; if (base != ref->base) { /* Try using points-to info. */ @@ -2466,18 +2473,13 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) if (!tree_int_cst_equal (TREE_OPERAND (base, 1), TREE_OPERAND (ref->base, 1))) { - offset_int off1 = mem_ref_offset (base); + poly_offset_int off1 = mem_ref_offset (base); off1 <<= LOG2_BITS_PER_UNIT; off1 += offset; - offset_int off2 = mem_ref_offset (ref->base); + poly_offset_int off2 = mem_ref_offset (ref->base); off2 <<= LOG2_BITS_PER_UNIT; off2 += ref_offset; - if (wi::fits_shwi_p (off1) && wi::fits_shwi_p (off2)) - { - offset = off1.to_shwi (); - ref_offset = off2.to_shwi (); - } - else + if (!off1.to_shwi (&offset) || !off2.to_shwi (&ref_offset)) size = -1; } } @@ -2486,12 +2488,9 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) } /* For a must-alias check we need to be able to constrain the access properly. */ - if (size != -1 && size == max_size) - { - if (offset <= ref_offset - && offset + size >= ref_offset + ref->max_size) - return true; - } + if (size == max_size + && known_subrange_p (ref_offset, ref->max_size, offset, size)) + return true; } if (is_gimple_call (stmt)) @@ -2524,19 +2523,19 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) { /* For a must-alias check we need to be able to constrain the access properly. */ - if (ref->max_size == -1) + if (!ref->max_size_known_p ()) return false; tree dest = gimple_call_arg (stmt, 0); tree len = gimple_call_arg (stmt, 2); - if (!tree_fits_shwi_p (len)) + if (!poly_int_tree_p (len)) return false; tree rbase = ref->base; - offset_int roffset = ref->offset; + poly_offset_int roffset = ref->offset; ao_ref dref; ao_ref_init_from_ptr_and_size (&dref, dest, len); tree base = ao_ref_base (&dref); - offset_int offset = dref.offset; - if (!base || dref.size == -1) + poly_offset_int offset = dref.offset; + if (!base || !known_size_p (dref.size)) return false; if (TREE_CODE (base) == MEM_REF) { @@ -2549,9 +2548,9 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) rbase = TREE_OPERAND (rbase, 0); } if (base == rbase - && offset <= roffset - && (roffset + ref->max_size - <= offset + (wi::to_offset (len) << LOG2_BITS_PER_UNIT))) + && known_subrange_p (roffset, ref->max_size, offset, + wi::to_poly_offset (len) + << LOG2_BITS_PER_UNIT)) return true; break; } |