poly_int: memrefs_conflict_p
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 07:19:14 +0000 (07:19 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 07:19:14 +0000 (07:19 +0000)
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

gcc/ChangeLog
gcc/alias.c

index 3f3f0dcd182f690e87178e705af012c1fe51b81c..31092fbf2ae05aca8c2e73c0c67c892940cfc92b 100644 (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>
index 16f82240174e787d0fbac512556ec8d9cc79215e..7f3e4d25c539789afd60a52eddbc02ff916c1ba9 100644 (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;
     }