poly_int: memrefs_conflict_p

The xsize and ysize arguments to memrefs_conflict_p are encode such
that:

- 0 means the size is unknown
- >0 means the size is known
- <0 means that the negative of the size is a worst-case size after
  alignment

In other words, the sign effectively encodes a boolean; it isn't
meant to be taken literally.  With poly_ints these correspond to:

- must_eq (..., 0)
- may_gt (..., 0)
- may_lt (..., 0)

respectively.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* alias.c (addr_side_effect_eval): Take the size as a poly_int64
	rather than an int.  Use plus_constant.
	(memrefs_conflict_p): Take the sizes as poly_int64s rather than ints.
	Take the offset "c" as a poly_int64 rather than a HOST_WIDE_INT.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r256163
This commit is contained in:
Richard Sandiford 2018-01-03 07:19:14 +00:00 committed by Richard Sandiford
parent 5c8e61cfa2
commit 9f61be58ce
2 changed files with 43 additions and 34 deletions

View File

@ -1,3 +1,12 @@
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* alias.c (addr_side_effect_eval): Take the size as a poly_int64
rather than an int. Use plus_constant.
(memrefs_conflict_p): Take the sizes as poly_int64s rather than ints.
Take the offset "c" as a poly_int64 rather than a HOST_WIDE_INT.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>

View File

@ -148,7 +148,6 @@ struct GTY(()) alias_set_entry {
};
static int rtx_equal_for_memref_p (const_rtx, const_rtx);
static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
static void record_set (rtx, const_rtx, void *);
static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode,
machine_mode);
@ -2297,9 +2296,9 @@ get_addr (rtx x)
is not modified by the memory reference then ADDR is returned. */
static rtx
addr_side_effect_eval (rtx addr, int size, int n_refs)
addr_side_effect_eval (rtx addr, poly_int64 size, int n_refs)
{
int offset = 0;
poly_int64 offset = 0;
switch (GET_CODE (addr))
{
@ -2320,11 +2319,7 @@ addr_side_effect_eval (rtx addr, int size, int n_refs)
return addr;
}
if (offset)
addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
gen_int_mode (offset, GET_MODE (addr)));
else
addr = XEXP (addr, 0);
addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset);
addr = canon_rtx (addr);
return addr;
@ -2374,7 +2369,8 @@ offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize)
If that is fixed the TBAA hack for union type-punning can be removed. */
static int
memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
poly_int64 c)
{
if (GET_CODE (x) == VALUE)
{
@ -2419,13 +2415,13 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1);
else
x = addr_side_effect_eval (x, abs (xsize), 0);
x = addr_side_effect_eval (x, maybe_lt (xsize, 0) ? -xsize : xsize, 0);
if (GET_CODE (y) == HIGH)
y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1);
else
y = addr_side_effect_eval (y, abs (ysize), 0);
y = addr_side_effect_eval (y, maybe_lt (ysize, 0) ? -ysize : ysize, 0);
if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF)
{
@ -2438,7 +2434,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
through alignment adjustments (i.e., that have negative
sizes), because we can't know how far they are from each
other. */
if (xsize < 0 || ysize < 0)
if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0))
return -1;
/* If decls are different or we know by offsets that there is no overlap,
we win. */
@ -2469,6 +2465,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
else if (x1 == y)
return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c);
poly_int64 cx1, cy1;
if (GET_CODE (y) == PLUS)
{
/* The fact that Y is canonicalized means that this
@ -2485,22 +2482,21 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
return memrefs_conflict_p (xsize, x0, ysize, y0, c);
if (rtx_equal_for_memref_p (x0, y0))
return memrefs_conflict_p (xsize, x1, ysize, y1, c);
if (CONST_INT_P (x1))
if (poly_int_rtx_p (x1, &cx1))
{
if (CONST_INT_P (y1))
if (poly_int_rtx_p (y1, &cy1))
return memrefs_conflict_p (xsize, x0, ysize, y0,
c - INTVAL (x1) + INTVAL (y1));
c - cx1 + cy1);
else
return memrefs_conflict_p (xsize, x0, ysize, y,
c - INTVAL (x1));
return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
}
else if (CONST_INT_P (y1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
else if (poly_int_rtx_p (y1, &cy1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
return -1;
}
else if (CONST_INT_P (x1))
return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
else if (poly_int_rtx_p (x1, &cx1))
return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
}
else if (GET_CODE (y) == PLUS)
{
@ -2514,8 +2510,9 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
if (x == y1)
return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c);
if (CONST_INT_P (y1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
poly_int64 cy1;
if (poly_int_rtx_p (y1, &cy1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
else
return -1;
}
@ -2539,11 +2536,11 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
return offset_overlap_p (c, xsize, ysize);
/* Can't properly adjust our sizes. */
if (!CONST_INT_P (x1))
if (!CONST_INT_P (x1)
|| !can_div_trunc_p (xsize, INTVAL (x1), &xsize)
|| !can_div_trunc_p (ysize, INTVAL (x1), &ysize)
|| !can_div_trunc_p (c, INTVAL (x1), &c))
return -1;
xsize /= INTVAL (x1);
ysize /= INTVAL (x1);
c /= INTVAL (x1);
return memrefs_conflict_p (xsize, x0, ysize, y0, c);
}
@ -2564,9 +2561,9 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
unsigned HOST_WIDE_INT uc = sc;
if (sc < 0 && pow2_or_zerop (-uc))
{
if (xsize > 0)
if (maybe_gt (xsize, 0))
xsize = -xsize;
if (xsize)
if (maybe_ne (xsize, 0))
xsize += sc + 1;
c -= sc + 1;
return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
@ -2579,9 +2576,9 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
unsigned HOST_WIDE_INT uc = sc;
if (sc < 0 && pow2_or_zerop (-uc))
{
if (ysize > 0)
if (maybe_gt (ysize, 0))
ysize = -ysize;
if (ysize)
if (maybe_ne (ysize, 0))
ysize += sc + 1;
c += sc + 1;
return memrefs_conflict_p (xsize, x,
@ -2591,9 +2588,10 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
if (CONSTANT_P (x))
{
if (CONST_INT_P (x) && CONST_INT_P (y))
poly_int64 cx, cy;
if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
{
c += (INTVAL (y) - INTVAL (x));
c += cy - cx;
return offset_overlap_p (c, xsize, ysize);
}
@ -2615,7 +2613,9 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
sizes), because we can't know how far they are from each
other. */
if (CONSTANT_P (y))
return (xsize < 0 || ysize < 0 || offset_overlap_p (c, xsize, ysize));
return (maybe_lt (xsize, 0)
|| maybe_lt (ysize, 0)
|| offset_overlap_p (c, xsize, ysize));
return -1;
}