diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 07:19:14 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 07:19:14 +0000 |
commit | 9f61be58cec631ded93e6b71940dacd14ce3f3f5 (patch) | |
tree | e646df49504aa965484c5c5900d2ccaa02140ec0 /gcc/alias.c | |
parent | 5c8e61cfa26622b1aa1058e61ba68acfdc038dfa (diff) | |
download | gcc-9f61be58cec631ded93e6b71940dacd14ce3f3f5.zip gcc-9f61be58cec631ded93e6b71940dacd14ce3f3f5.tar.gz gcc-9f61be58cec631ded93e6b71940dacd14ce3f3f5.tar.bz2 |
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
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index 16f8224..7f3e4d2 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -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; } |