Commit c02f035f by Richard Henderson Committed by Jeff Law

alias.c (base_alias_check): Two symbols can conflict if they are accessed via AND.

        * alias.c (base_alias_check): Two symbols can conflict if they
        are accessed via AND.
        (memrefs_conflict_p): Likewise.

From-SVN: r15785
parent 7a14fdc5
Mon Sep 29 00:18:16 1997 Richard Henderson (rth@cygnus.com) Mon Sep 29 00:18:16 1997 Richard Henderson (rth@cygnus.com)
* alias.c (base_alias_check): Two symbols can conflict if they
are accessed via AND.
(memrefs_conflict_p): Likewise.
* alpha.h (SETUP_INCOMING_VARARGS): Emit a blockage insn * alpha.h (SETUP_INCOMING_VARARGS): Emit a blockage insn
after flushing argument registers to the stack. after flushing argument registers to the stack.
......
...@@ -509,10 +509,17 @@ base_alias_check (x, y) ...@@ -509,10 +509,17 @@ base_alias_check (x, y)
return 1; return 1;
/* The base addresses of the read and write are different /* The base addresses of the read and write are different
expressions. If they are both symbols there is no expressions. If they are both symbols and they are not accessed
conflict. */ via AND, there is no conflict. */
/* XXX: We can bring knowledge of object alignment and offset into
play here. For example, on alpha, "char a, b;" can alias one
another, though "char a; long b;" cannot. Similarly, offsets
into strutures may be brought into play. Given "char a, b[40];",
a and b[1] may overlap, but a and b[20] do not. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS) if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
return 0; {
return GET_CODE (x) == AND || GET_CODE (y) == AND;
}
/* If one address is a stack reference there can be no alias: /* If one address is a stack reference there can be no alias:
stack references using different base registers do not alias, stack references using different base registers do not alias,
...@@ -542,6 +549,10 @@ base_alias_check (x, y) ...@@ -542,6 +549,10 @@ base_alias_check (x, y)
referenced (the reference was BLKmode), so make the most pessimistic referenced (the reference was BLKmode), so make the most pessimistic
assumptions. assumptions.
If XSIZE or YSIZE is negative, we may access memory outside the object
being referenced as a side effect. This can happen when using AND to
align memory references, as is done on the Alpha.
We recognize the following cases of non-conflicting memory: We recognize the following cases of non-conflicting memory:
(1) addresses involving the frame pointer cannot conflict (1) addresses involving the frame pointer cannot conflict
...@@ -573,7 +584,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -573,7 +584,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
if (rtx_equal_for_memref_p (x, y)) if (rtx_equal_for_memref_p (x, y))
{ {
if (xsize == 0 || ysize == 0) if (xsize <= 0 || ysize <= 0)
return 1; return 1;
if (c >= 0 && xsize > c) if (c >= 0 && xsize > c)
return 1; return 1;
...@@ -605,7 +616,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -605,7 +616,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
&& GET_CODE (y1) == CONST_INT) && GET_CODE (y1) == CONST_INT)
{ {
c += INTVAL (y1); c += INTVAL (y1);
return (xsize == 0 || ysize == 0 return (xsize <= 0 || ysize <= 0
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
} }
...@@ -703,16 +714,22 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -703,16 +714,22 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
/* Treat an access through an AND (e.g. a subword access on an Alpha) /* Treat an access through an AND (e.g. a subword access on an Alpha)
as an access with indeterminate size. */ as an access with indeterminate size. */
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT) if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
return memrefs_conflict_p (0, XEXP (x, 0), ysize, y, c); return memrefs_conflict_p (-1, XEXP (x, 0), ysize, y, c);
if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT) if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
return memrefs_conflict_p (xsize, x, 0, XEXP (y, 0), c); {
/* XXX: If we are indexing far enough into the array/structure, we
may yet be able to determine that we can not overlap. But we
also need to that we are far enough from the end not to overlap
a following reference, so we do nothing for now. */
return memrefs_conflict_p (xsize, x, -1, XEXP (y, 0), c);
}
if (CONSTANT_P (x)) if (CONSTANT_P (x))
{ {
if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT) if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
{ {
c += (INTVAL (y) - INTVAL (x)); c += (INTVAL (y) - INTVAL (x));
return (xsize == 0 || ysize == 0 return (xsize <= 0 || ysize <= 0
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
} }
...@@ -730,9 +747,10 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -730,9 +747,10 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
canon_rtx (XEXP (y, 0)), c); canon_rtx (XEXP (y, 0)), c);
if (CONSTANT_P (y)) if (CONSTANT_P (y))
return (rtx_equal_for_memref_p (x, y) return (xsize < 0 || ysize < 0
&& (xsize == 0 || ysize == 0 || (rtx_equal_for_memref_p (x, y)
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))); && (xsize == 0 || ysize == 0
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
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