aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/alias.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/alias.c')
-rw-r--r--gcc-4.9/gcc/alias.c144
1 files changed, 60 insertions, 84 deletions
diff --git a/gcc-4.9/gcc/alias.c b/gcc-4.9/gcc/alias.c
index e5406123c..b81ea28c6 100644
--- a/gcc-4.9/gcc/alias.c
+++ b/gcc-4.9/gcc/alias.c
@@ -382,17 +382,9 @@ get_alias_set_entry (alias_set_type alias_set)
static inline int
mems_in_disjoint_alias_sets_p (const_rtx mem1, const_rtx mem2)
{
-/* Perform a basic sanity check. Namely, that there are no alias sets
- if we're not using strict aliasing. This helps to catch bugs
- whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
- where a MEM is allocated in some way other than by the use of
- gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to
- use alias sets to indicate that spilled registers cannot alias each
- other, we might need to remove this check. */
- gcc_assert (flag_strict_aliasing
- || (!MEM_ALIAS_SET (mem1) && !MEM_ALIAS_SET (mem2)));
-
- return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2));
+ return (flag_strict_aliasing
+ && ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1),
+ MEM_ALIAS_SET (mem2)));
}
/* Insert the NODE into the splay tree given by DATA. Used by
@@ -2454,6 +2446,7 @@ static int
true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
const_rtx x, rtx x_addr, bool mem_canonicalized)
{
+ rtx true_mem_addr;
rtx base;
int ret;
@@ -2473,17 +2466,9 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- /* 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 we have MEMs referring to different address spaces (which can
- potentially overlap), we cannot easily tell from the addresses
- whether the references overlap. */
- if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
- return 1;
+ if (! x_addr)
+ x_addr = XEXP (x, 0);
+ x_addr = get_addr (x_addr);
if (! mem_addr)
{
@@ -2491,22 +2476,23 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
if (mem_mode == VOIDmode)
mem_mode = GET_MODE (mem);
}
+ true_mem_addr = get_addr (mem_addr);
- if (! x_addr)
- {
- x_addr = XEXP (x, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- if (! mem_canonicalized)
- mem_addr = get_addr (mem_addr);
- }
- }
+ /* Read-only memory is by definition never modified, and therefore can't
+ conflict with anything. However, don't assume anything when AND
+ addresses are involved and leave to the code below to determine
+ dependence. 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)
+ && GET_CODE (x_addr) != AND
+ && GET_CODE (true_mem_addr) != AND)
+ return 0;
+
+ /* If we have MEMs referring to different address spaces (which can
+ potentially overlap), we cannot easily tell from the addresses
+ whether the references overlap. */
+ if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
+ return 1;
base = find_base_term (x_addr);
if (base && (GET_CODE (base) == LABEL_REF
@@ -2514,14 +2500,14 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
&& CONSTANT_POOL_ADDRESS_P (base))))
return 0;
- rtx mem_base = find_base_term (mem_addr);
- if (! base_alias_check (x_addr, base, mem_addr, mem_base,
+ rtx mem_base = find_base_term (true_mem_addr);
+ if (! base_alias_check (x_addr, base, true_mem_addr, mem_base,
GET_MODE (x), mem_mode))
return 0;
x_addr = canon_rtx (x_addr);
if (!mem_canonicalized)
- mem_addr = canon_rtx (mem_addr);
+ mem_addr = canon_rtx (true_mem_addr);
if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0)) != -1)
@@ -2571,6 +2557,7 @@ write_dependence_p (const_rtx mem,
bool mem_canonicalized, bool x_canonicalized, bool writep)
{
rtx mem_addr;
+ rtx true_mem_addr, true_x_addr;
rtx base;
int ret;
@@ -2591,8 +2578,20 @@ write_dependence_p (const_rtx mem,
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- /* A read from read-only memory can't conflict with read-write memory. */
- if (!writep && MEM_READONLY_P (mem))
+ if (!x_addr)
+ x_addr = XEXP (x, 0);
+ true_x_addr = get_addr (x_addr);
+
+ mem_addr = XEXP (mem, 0);
+ true_mem_addr = get_addr (mem_addr);
+
+ /* A read from read-only memory can't conflict with read-write memory.
+ Don't assume anything when AND addresses are involved and leave to
+ the code below to determine dependence. */
+ if (!writep
+ && MEM_READONLY_P (mem)
+ && GET_CODE (true_x_addr) != AND
+ && GET_CODE (true_mem_addr) != AND)
return 0;
/* If we have MEMs referring to different address spaces (which can
@@ -2601,24 +2600,7 @@ write_dependence_p (const_rtx mem,
if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
return 1;
- mem_addr = XEXP (mem, 0);
- if (!x_addr)
- {
- x_addr = XEXP (x, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- if (!mem_canonicalized)
- mem_addr = get_addr (mem_addr);
- }
- }
-
- base = find_base_term (mem_addr);
+ base = find_base_term (true_mem_addr);
if (! writep
&& base
&& (GET_CODE (base) == LABEL_REF
@@ -2626,18 +2608,18 @@ write_dependence_p (const_rtx mem,
&& CONSTANT_POOL_ADDRESS_P (base))))
return 0;
- rtx x_base = find_base_term (x_addr);
- if (! base_alias_check (x_addr, x_base, mem_addr, base, GET_MODE (x),
- GET_MODE (mem)))
+ rtx x_base = find_base_term (true_x_addr);
+ if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base,
+ GET_MODE (x), GET_MODE (mem)))
return 0;
if (!x_canonicalized)
{
- x_addr = canon_rtx (x_addr);
+ x_addr = canon_rtx (true_x_addr);
x_mode = GET_MODE (x);
}
if (!mem_canonicalized)
- mem_addr = canon_rtx (mem_addr);
+ mem_addr = canon_rtx (true_mem_addr);
if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
GET_MODE_SIZE (x_mode), x_addr, 0)) != -1)
@@ -2705,10 +2687,20 @@ may_alias_p (const_rtx mem, const_rtx x)
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
+ x_addr = XEXP (x, 0);
+ x_addr = get_addr (x_addr);
+
+ mem_addr = XEXP (mem, 0);
+ mem_addr = get_addr (mem_addr);
+
/* 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))
+ conflict with anything. However, don't assume anything when AND
+ addresses are involved and leave to the code below to determine
+ dependence. 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)
+ && GET_CODE (x_addr) != AND
+ && GET_CODE (mem_addr) != AND)
return 0;
/* If we have MEMs referring to different address spaces (which can
@@ -2717,28 +2709,12 @@ may_alias_p (const_rtx mem, const_rtx x)
if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
return 1;
- x_addr = XEXP (x, 0);
- mem_addr = XEXP (mem, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- mem_addr = get_addr (mem_addr);
- }
-
rtx x_base = find_base_term (x_addr);
rtx mem_base = find_base_term (mem_addr);
if (! base_alias_check (x_addr, x_base, mem_addr, mem_base,
GET_MODE (x), GET_MODE (mem_addr)))
return 0;
- x_addr = canon_rtx (x_addr);
- mem_addr = canon_rtx (mem_addr);
-
if (nonoverlapping_memrefs_p (mem, x, true))
return 0;