From 9f61be58cec631ded93e6b71940dacd14ce3f3f5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 3 Jan 2018 07:19:14 +0000 Subject: [PATCH] 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 Alan Hayward David Sherwood 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 Co-Authored-By: David Sherwood From-SVN: r256163 --- gcc/ChangeLog | 9 +++++++ gcc/alias.c | 68 +++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3f3f0dcd182..31092fbf2ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * 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 Alan Hayward David Sherwood diff --git a/gcc/alias.c b/gcc/alias.c index 16f82240174..7f3e4d25c53 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; } -- 2.30.2