Commit 9f61be58 by Richard Sandiford Committed by Richard Sandiford

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
parent 5c8e61cf
...@@ -2,6 +2,15 @@ ...@@ -2,6 +2,15 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@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>
* calls.c (emit_call_1, expand_call): Change struct_value_size from * calls.c (emit_call_1, expand_call): Change struct_value_size from
a HOST_WIDE_INT to a poly_int64. a HOST_WIDE_INT to a poly_int64.
...@@ -148,7 +148,6 @@ struct GTY(()) alias_set_entry { ...@@ -148,7 +148,6 @@ struct GTY(()) alias_set_entry {
}; };
static int rtx_equal_for_memref_p (const_rtx, const_rtx); 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 void record_set (rtx, const_rtx, void *);
static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode, static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode,
machine_mode); machine_mode);
...@@ -2297,9 +2296,9 @@ get_addr (rtx x) ...@@ -2297,9 +2296,9 @@ get_addr (rtx x)
is not modified by the memory reference then ADDR is returned. */ is not modified by the memory reference then ADDR is returned. */
static rtx 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)) switch (GET_CODE (addr))
{ {
...@@ -2320,11 +2319,7 @@ addr_side_effect_eval (rtx addr, int size, int n_refs) ...@@ -2320,11 +2319,7 @@ addr_side_effect_eval (rtx addr, int size, int n_refs)
return addr; return addr;
} }
if (offset) addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset);
addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
gen_int_mode (offset, GET_MODE (addr)));
else
addr = XEXP (addr, 0);
addr = canon_rtx (addr); addr = canon_rtx (addr);
return addr; return addr;
...@@ -2374,7 +2369,8 @@ offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize) ...@@ -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. */ If that is fixed the TBAA hack for union type-punning can be removed. */
static int 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) if (GET_CODE (x) == VALUE)
{ {
...@@ -2419,13 +2415,13 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -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) else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1); x = XEXP (x, 1);
else 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) if (GET_CODE (y) == HIGH)
y = XEXP (y, 0); y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM) else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1); y = XEXP (y, 1);
else 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) 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) ...@@ -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 through alignment adjustments (i.e., that have negative
sizes), because we can't know how far they are from each sizes), because we can't know how far they are from each
other. */ other. */
if (xsize < 0 || ysize < 0) if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0))
return -1; return -1;
/* If decls are different or we know by offsets that there is no overlap, /* If decls are different or we know by offsets that there is no overlap,
we win. */ we win. */
...@@ -2469,6 +2465,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -2469,6 +2465,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
else if (x1 == y) else if (x1 == y)
return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c); return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c);
poly_int64 cx1, cy1;
if (GET_CODE (y) == PLUS) if (GET_CODE (y) == PLUS)
{ {
/* The fact that Y is canonicalized means that this /* 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) ...@@ -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); return memrefs_conflict_p (xsize, x0, ysize, y0, c);
if (rtx_equal_for_memref_p (x0, y0)) if (rtx_equal_for_memref_p (x0, y0))
return memrefs_conflict_p (xsize, x1, ysize, y1, c); 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, return memrefs_conflict_p (xsize, x0, ysize, y0,
c - INTVAL (x1) + INTVAL (y1)); c - cx1 + cy1);
else else
return memrefs_conflict_p (xsize, x0, ysize, y, return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
c - INTVAL (x1));
} }
else if (CONST_INT_P (y1)) else if (poly_int_rtx_p (y1, &cy1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
return -1; return -1;
} }
else if (CONST_INT_P (x1)) else if (poly_int_rtx_p (x1, &cx1))
return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
} }
else if (GET_CODE (y) == PLUS) 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) ...@@ -2514,8 +2510,9 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
if (x == y1) if (x == y1)
return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c); return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c);
if (CONST_INT_P (y1)) poly_int64 cy1;
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); if (poly_int_rtx_p (y1, &cy1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
else else
return -1; return -1;
} }
...@@ -2539,11 +2536,11 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -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); return offset_overlap_p (c, xsize, ysize);
/* Can't properly adjust our sizes. */ /* 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; return -1;
xsize /= INTVAL (x1);
ysize /= INTVAL (x1);
c /= INTVAL (x1);
return memrefs_conflict_p (xsize, x0, ysize, y0, c); 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) ...@@ -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; unsigned HOST_WIDE_INT uc = sc;
if (sc < 0 && pow2_or_zerop (-uc)) if (sc < 0 && pow2_or_zerop (-uc))
{ {
if (xsize > 0) if (maybe_gt (xsize, 0))
xsize = -xsize; xsize = -xsize;
if (xsize) if (maybe_ne (xsize, 0))
xsize += sc + 1; xsize += sc + 1;
c -= sc + 1; c -= sc + 1;
return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), 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) ...@@ -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; unsigned HOST_WIDE_INT uc = sc;
if (sc < 0 && pow2_or_zerop (-uc)) if (sc < 0 && pow2_or_zerop (-uc))
{ {
if (ysize > 0) if (maybe_gt (ysize, 0))
ysize = -ysize; ysize = -ysize;
if (ysize) if (maybe_ne (ysize, 0))
ysize += sc + 1; ysize += sc + 1;
c += sc + 1; c += sc + 1;
return memrefs_conflict_p (xsize, x, 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) ...@@ -2591,9 +2588,10 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
if (CONSTANT_P (x)) 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); 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) ...@@ -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 sizes), because we can't know how far they are from each
other. */ other. */
if (CONSTANT_P (y)) 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; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment