summaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-16 10:01:51 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-16 10:01:51 +0000
commit40f9e245ee4986ab7dd13df3c0a480437a564810 (patch)
tree0832d31463edaca75ce0c6fd27a925217d7df290 /gcc/alias.c
parentcd584ef87c4d4e8308e135adbe6bcea2dcaec489 (diff)
downloadgcc-40f9e245ee4986ab7dd13df3c0a480437a564810.tar.gz
2010-02-16 Richard Guenther <rguenther@suse.de>
* alias.c (memrefs_conflict_p): Distinguish must-alias from don't know. (true_dependence): If memrefs_conflict_p computes must-alias trust it. Move TBAA check after offset-based disambiguation. (canon_true_dependence): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156797 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 41a2f2318f7..71a34a29265 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1759,8 +1759,12 @@ addr_side_effect_eval (rtx addr, int size, int n_refs)
return addr;
}
-/* Return nonzero if X and Y (memory addresses) could reference the
- same location in memory. C is an offset accumulator. When
+/* Return one if X and Y (memory addresses) reference the
+ same location in memory or if the references overlap.
+ Return zero if they do not overlap, else return
+ minus one in which case they still might reference the same location.
+
+ C is an offset accumulator. When
C is nonzero, we are testing aliases between X and Y + C.
XSIZE is the size in bytes of the X reference,
similarly YSIZE is the size in bytes for Y.
@@ -1775,7 +1779,11 @@ addr_side_effect_eval (rtx addr, int size, int n_refs)
align memory references, as is done on the Alpha.
Nice to notice that varying addresses cannot conflict with fp if no
- local variables had their addresses taken, but that's too hard now. */
+ local variables had their addresses taken, but that's too hard now.
+
+ ??? Contrary to the tree alias oracle this does not return
+ one for X + non-constant and Y + non-constant when X and Y are equal.
+ 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)
@@ -1841,7 +1849,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
else if (CONST_INT_P (y1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
- return 1;
+ return -1;
}
else if (CONST_INT_P (x1))
return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
@@ -1856,7 +1864,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
if (CONST_INT_P (y1))
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
else
- return 1;
+ return -1;
}
if (GET_CODE (x) == GET_CODE (y))
@@ -1871,7 +1879,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
rtx x1 = canon_rtx (XEXP (x, 1));
rtx y1 = canon_rtx (XEXP (y, 1));
if (! rtx_equal_for_memref_p (x1, y1))
- return 1;
+ return -1;
x0 = canon_rtx (XEXP (x, 0));
y0 = canon_rtx (XEXP (y, 0));
if (rtx_equal_for_memref_p (x0, y0))
@@ -1880,7 +1888,7 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
/* Can't properly adjust our sizes. */
if (!CONST_INT_P (x1))
- return 1;
+ return -1;
xsize /= INTVAL (x1);
ysize /= INTVAL (x1);
c /= INTVAL (x1);
@@ -1939,9 +1947,10 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
|| (rtx_equal_for_memref_p (x, y)
&& ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
- return 1;
+ return -1;
}
- return 1;
+
+ return -1;
}
/* Functions to compute memory dependencies.
@@ -2294,6 +2303,7 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
{
rtx x_addr, mem_addr;
rtx base;
+ int ret;
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
@@ -2308,18 +2318,12 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- if (DIFFERENT_ALIAS_SETS_P (x, mem))
- return 0;
-
/* Read-only memory is by definition never modified, and therefore can't
conflict with anything. We don't expect to find read-only set on MEM,
but stupid user tricks can produce them, so don't die. */
if (MEM_READONLY_P (x))
return 0;
- if (nonoverlapping_memrefs_p (mem, x))
- return 0;
-
/* If we have MEMs refering to different address spaces (which can
potentially overlap), we cannot easily tell from the addresses
whether the references overlap. */
@@ -2344,8 +2348,14 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
x_addr = canon_rtx (x_addr);
mem_addr = canon_rtx (mem_addr);
- if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
- SIZE_FOR_MODE (x), x_addr, 0))
+ if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
+ SIZE_FOR_MODE (x), x_addr, 0)) != -1)
+ return ret;
+
+ if (DIFFERENT_ALIAS_SETS_P (x, mem))
+ return 0;
+
+ if (nonoverlapping_memrefs_p (mem, x))
return 0;
if (aliases_everything_p (x))
@@ -2378,6 +2388,8 @@ int
canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool))
{
+ int ret;
+
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
@@ -2391,18 +2403,12 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- if (DIFFERENT_ALIAS_SETS_P (x, mem))
- return 0;
-
/* Read-only memory is by definition never modified, and therefore can't
conflict with anything. We don't expect to find read-only set on MEM,
but stupid user tricks can produce them, so don't die. */
if (MEM_READONLY_P (x))
return 0;
- if (nonoverlapping_memrefs_p (x, mem))
- return 0;
-
/* If we have MEMs refering to different address spaces (which can
potentially overlap), we cannot easily tell from the addresses
whether the references overlap. */
@@ -2416,8 +2422,14 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
return 0;
x_addr = canon_rtx (x_addr);
- if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
- SIZE_FOR_MODE (x), x_addr, 0))
+ if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
+ SIZE_FOR_MODE (x), x_addr, 0)) != -1)
+ return ret;
+
+ if (DIFFERENT_ALIAS_SETS_P (x, mem))
+ return 0;
+
+ if (nonoverlapping_memrefs_p (x, mem))
return 0;
if (aliases_everything_p (x))
@@ -2448,6 +2460,7 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
rtx x_addr, mem_addr;
const_rtx fixed_scalar;
rtx base;
+ int ret;
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
@@ -2466,9 +2479,6 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
if (!writep && MEM_READONLY_P (mem))
return 0;
- if (nonoverlapping_memrefs_p (x, mem))
- return 0;
-
/* If we have MEMs refering to different address spaces (which can
potentially overlap), we cannot easily tell from the addresses
whether the references overlap. */
@@ -2494,8 +2504,11 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
x_addr = canon_rtx (x_addr);
mem_addr = canon_rtx (mem_addr);
- if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
- SIZE_FOR_MODE (x), x_addr, 0))
+ if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
+ SIZE_FOR_MODE (x), x_addr, 0)) != -1)
+ return ret;
+
+ if (nonoverlapping_memrefs_p (x, mem))
return 0;
fixed_scalar