diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-20 12:53:23 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-20 12:53:23 +0000 |
commit | d05d755107df11e675a57ac4371fd0031c7d68a4 (patch) | |
tree | 1178b6d79fbc857905717d3e51f99bd3df6cfbda /gcc/alias.c | |
parent | a02ee6ef8834a80d4692736eb340db9854fe32ce (diff) |
poly_int: MEM_OFFSET and MEM_SIZE
This patch changes the MEM_OFFSET and MEM_SIZE memory attributes
from HOST_WIDE_INT to poly_int64. Most of it is mechanical,
but there is one nonbovious change in widen_memory_access.
Previously the main while loop broke with:
/* Similarly for the decl. */
else if (DECL_P (attrs.expr)
&& DECL_SIZE_UNIT (attrs.expr)
&& TREE_CODE (DECL_SIZE_UNIT (attrs.expr)) == INTEGER_CST
&& compare_tree_int (DECL_SIZE_UNIT (attrs.expr), size) >= 0
&& (! attrs.offset_known_p || attrs.offset >= 0))
break;
but it seemed wrong to optimistically assume the best case
when the offset isn't known (and thus might be negative).
As it happens, the "! attrs.offset_known_p" condition was
always false, because we'd already nullified attrs.expr in
that case:
/* If we don't know what offset we were at within the expression, then
we can't know if we've overstepped the bounds. */
if (! attrs.offset_known_p)
attrs.expr = NULL_TREE;
The patch therefore drops "! attrs.offset_known_p ||" when
converting the offset check to the may/must interface.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* rtl.h (mem_attrs): Add a default constructor. Change size and
offset from HOST_WIDE_INT to poly_int64.
* emit-rtl.h (set_mem_offset, set_mem_size, adjust_address_1)
(adjust_automodify_address_1, set_mem_attributes_minus_bitpos)
(widen_memory_access): Take the sizes and offsets as poly_int64s
rather than HOST_WIDE_INTs.
* alias.c (ao_ref_from_mem): Handle the new form of MEM_OFFSET.
(offset_overlap_p): Take poly_int64s rather than HOST_WIDE_INTs
and ints.
(adjust_offset_for_component_ref): Change the offset from a
HOST_WIDE_INT to a poly_int64.
(nonoverlapping_memrefs_p): Track polynomial offsets and sizes.
* cfgcleanup.c (merge_memattrs): Update after mem_attrs changes.
* dce.c (find_call_stack_args): Likewise.
* dse.c (record_store): Likewise.
* dwarf2out.c (tls_mem_loc_descriptor, dw_sra_loc_expr): Likewise.
* print-rtl.c (rtx_writer::print_rtx): Likewise.
* read-rtl-function.c (test_loading_mem): Likewise.
* rtlanal.c (may_trap_p_1): Likewise.
* simplify-rtx.c (delegitimize_mem_from_attrs): Likewise.
* var-tracking.c (int_mem_offset, track_expr_p): Likewise.
* emit-rtl.c (mem_attrs_eq_p, get_mem_align_offset): Likewise.
(mem_attrs::mem_attrs): New function.
(set_mem_attributes_minus_bitpos): Change bitpos from a
HOST_WIDE_INT to poly_int64.
(set_mem_alias_set, set_mem_addr_space, set_mem_align, set_mem_expr)
(clear_mem_offset, clear_mem_size, change_address)
(get_spill_slot_decl, set_mem_attrs_for_spill): Directly
initialize mem_attrs.
(set_mem_offset, set_mem_size, adjust_address_1)
(adjust_automodify_address_1, offset_address, widen_memory_access):
Likewise. Take poly_int64s rather than HOST_WIDE_INT.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255875
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 42 |
1 files changed, 17 insertions, 25 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index b1ff8fdd887..072fba207e7 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -330,7 +330,7 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem) /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size drop ref->ref. */ - if (MEM_OFFSET (mem) < 0 + if (maybe_lt (MEM_OFFSET (mem), 0) || (ref->max_size_known_p () && maybe_gt ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT, ref->max_size))) @@ -2331,12 +2331,15 @@ addr_side_effect_eval (rtx addr, int size, int n_refs) absolute value of the sizes as the actual sizes. */ static inline bool -offset_overlap_p (HOST_WIDE_INT c, int xsize, int ysize) +offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize) { - return (xsize == 0 || ysize == 0 - || (c >= 0 - ? (abs (xsize) > c) - : (abs (ysize) > -c))); + if (known_eq (xsize, 0) || known_eq (ysize, 0)) + return true; + + if (maybe_ge (c, 0)) + return maybe_gt (maybe_lt (xsize, 0) ? -xsize : xsize, c); + else + return maybe_gt (maybe_lt (ysize, 0) ? -ysize : ysize, -c); } /* Return one if X and Y (memory addresses) reference the @@ -2667,7 +2670,7 @@ decl_for_component_ref (tree x) static void adjust_offset_for_component_ref (tree x, bool *known_p, - HOST_WIDE_INT *offset) + poly_int64 *offset) { if (!*known_p) return; @@ -2708,8 +2711,8 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) rtx rtlx, rtly; rtx basex, basey; bool moffsetx_known_p, moffsety_known_p; - HOST_WIDE_INT moffsetx = 0, moffsety = 0; - HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey; + poly_int64 moffsetx = 0, moffsety = 0; + poly_int64 offsetx = 0, offsety = 0, sizex, sizey; /* Unless both have exprs, we can't tell anything. */ if (exprx == 0 || expry == 0) @@ -2811,12 +2814,10 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) we can avoid overlap is if we can deduce that they are nonoverlapping pieces of that decl, which is very rare. */ basex = MEM_P (rtlx) ? XEXP (rtlx, 0) : rtlx; - if (GET_CODE (basex) == PLUS && CONST_INT_P (XEXP (basex, 1))) - offsetx = INTVAL (XEXP (basex, 1)), basex = XEXP (basex, 0); + basex = strip_offset_and_add (basex, &offsetx); basey = MEM_P (rtly) ? XEXP (rtly, 0) : rtly; - if (GET_CODE (basey) == PLUS && CONST_INT_P (XEXP (basey, 1))) - offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0); + basey = strip_offset_and_add (basey, &offsety); /* If the bases are different, we know they do not overlap if both are constants or if one is a constant and the other a pointer into the @@ -2837,10 +2838,10 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) declarations are necessarily different (i.e. compare_base_decls (exprx, expry) == -1) */ - sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx)) + sizex = (!MEM_P (rtlx) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtlx))) : MEM_SIZE_KNOWN_P (rtlx) ? MEM_SIZE (rtlx) : -1); - sizey = (!MEM_P (rtly) ? (int) GET_MODE_SIZE (GET_MODE (rtly)) + sizey = (!MEM_P (rtly) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtly))) : MEM_SIZE_KNOWN_P (rtly) ? MEM_SIZE (rtly) : -1); @@ -2859,16 +2860,7 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p) sizey = MEM_SIZE (y); - /* Put the values of the memref with the lower offset in X's values. */ - if (offsetx > offsety) - { - std::swap (offsetx, offsety); - std::swap (sizex, sizey); - } - - /* If we don't know the size of the lower-offset value, we can't tell - if they conflict. Otherwise, we do the test. */ - return sizex >= 0 && offsety >= offsetx + sizex; + return !ranges_maybe_overlap_p (offsetx, sizex, offsety, sizey); } /* Helper for true_dependence and canon_true_dependence. |