Commit 393f9fed by Joern Rennecke Committed by Joern Rennecke

re PR rtl-optimization/57425 (RTL alias analysis unprepared to handle stack slot sharing)

gcc:
	PR rtl-optimization/57425
	PR rtl-optimization/57569
	* alias.c (write_dependence_p): Add new parameters mem_size,
	canon_mem_addr and mem_canonicalized.  Change type of writep to bool.
	Changed all callers.
	(canon_anti_dependence): New function.
	* cse.c (check_dependence): Use canon_anti_dependence.
	* cselib.c (cselib_invalidate_mem): Likewise.
	* rtl.h (canon_anti_dependence): Declare.
gcc/testsuite:
	PR rtl-optimization/57425
	PR rtl-optimization/57569
	* gcc.dg/torture/pr57425-1.c, gcc.dg/torture/pr57425-2.c: New files.
	* gcc.dg/torture/pr57425-3.c, gcc.dg/torture/pr57569.c: Likewise.
Index: alias.c
===================================================================
--- alias.c	(revision 200126)

From-SVN: r200133
parent b259d352
2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
* alias.c (write_dependence_p): Add new parameters mem_size,
canon_mem_addr and mem_canonicalized. Change type of writep to bool.
Changed all callers.
(canon_anti_dependence): New function.
* cse.c (check_dependence): Use canon_anti_dependence.
* cselib.c (cselib_invalidate_mem): Likewise.
* rtl.h (canon_anti_dependence): Declare.
2013-06-16 Jürgen Urban <JuergenUrban@gmx.de> 2013-06-16 Jürgen Urban <JuergenUrban@gmx.de>
* config/mips/mips.h (ISA_HAS_LL_SC): Exclude TARGET_MIPS5900. * config/mips/mips.h (ISA_HAS_LL_SC): Exclude TARGET_MIPS5900.
......
...@@ -156,7 +156,8 @@ static int insert_subset_children (splay_tree_node, void*); ...@@ -156,7 +156,8 @@ static int insert_subset_children (splay_tree_node, void*);
static alias_set_entry get_alias_set_entry (alias_set_type); static alias_set_entry get_alias_set_entry (alias_set_type);
static bool nonoverlapping_component_refs_p (const_rtx, const_rtx); static bool nonoverlapping_component_refs_p (const_rtx, const_rtx);
static tree decl_for_component_ref (tree); static tree decl_for_component_ref (tree);
static int write_dependence_p (const_rtx, const_rtx, int); static int write_dependence_p (const_rtx, enum machine_mode, rtx, const_rtx,
bool, bool);
static void memory_modified_1 (rtx, const_rtx, void *); static void memory_modified_1 (rtx, const_rtx, void *);
...@@ -2553,15 +2554,22 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, ...@@ -2553,15 +2554,22 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
} }
/* Returns nonzero if a write to X might alias a previous read from /* Returns nonzero if a write to X might alias a previous read from
(or, if WRITEP is nonzero, a write to) MEM. */ (or, if WRITEP is true, a write to) MEM.
If MEM_CANONCALIZED is nonzero, CANON_MEM_ADDR is the canonicalized
address of MEM, and MEM_MODE the mode for that access. */
static int static int
write_dependence_p (const_rtx mem, const_rtx x, int writep) write_dependence_p (const_rtx mem, enum machine_mode mem_mode,
rtx canon_mem_addr, const_rtx x,
bool mem_canonicalized, bool writep)
{ {
rtx x_addr, mem_addr; rtx x_addr, mem_addr;
rtx base; rtx base;
int ret; int ret;
gcc_checking_assert (mem_canonicalized ? (canon_mem_addr != NULL_RTX)
: (canon_mem_addr == NULL_RTX && mem_mode == VOIDmode));
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1; return 1;
...@@ -2612,9 +2620,15 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) ...@@ -2612,9 +2620,15 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
return 0; return 0;
x_addr = canon_rtx (x_addr); x_addr = canon_rtx (x_addr);
if (mem_canonicalized)
mem_addr = canon_mem_addr;
else
{
mem_addr = canon_rtx (mem_addr); mem_addr = canon_rtx (mem_addr);
mem_mode = GET_MODE (mem);
}
if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0)) != -1) SIZE_FOR_MODE (x), x_addr, 0)) != -1)
return ret; return ret;
...@@ -2629,7 +2643,20 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) ...@@ -2629,7 +2643,20 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
int int
anti_dependence (const_rtx mem, const_rtx x) anti_dependence (const_rtx mem, const_rtx x)
{ {
return write_dependence_p (mem, x, /*writep=*/0); return write_dependence_p (mem, VOIDmode, NULL_RTX, x,
/*mem_canonicalized=*/false, /*writep=*/false);
}
/* Likewise, but we already have a canonicalized MEM_ADDR for MEM.
Also, consider MEM in MEM_MODE (which might be from an enclosing
STRICT_LOW_PART / ZERO_EXTRACT). */
int
canon_anti_dependence (const_rtx mem, enum machine_mode mem_mode,
rtx mem_addr, const_rtx x)
{
return write_dependence_p (mem, mem_mode, mem_addr, x,
/*mem_canonicalized=*/true, /*writep=*/false);
} }
/* Output dependence: X is written after store in MEM takes place. */ /* Output dependence: X is written after store in MEM takes place. */
...@@ -2637,7 +2664,8 @@ anti_dependence (const_rtx mem, const_rtx x) ...@@ -2637,7 +2664,8 @@ anti_dependence (const_rtx mem, const_rtx x)
int int
output_dependence (const_rtx mem, const_rtx x) output_dependence (const_rtx mem, const_rtx x)
{ {
return write_dependence_p (mem, x, /*writep=*/1); return write_dependence_p (mem, VOIDmode, NULL_RTX, x,
/*mem_canonicalized=*/false, /*writep=*/true);
} }
......
...@@ -1824,7 +1824,7 @@ flush_hash_table (void) ...@@ -1824,7 +1824,7 @@ flush_hash_table (void)
} }
} }
/* Function called for each rtx to check whether true dependence exist. */ /* Function called for each rtx to check whether an anti dependence exist. */
struct check_dependence_data struct check_dependence_data
{ {
enum machine_mode mode; enum machine_mode mode;
...@@ -1837,7 +1837,7 @@ check_dependence (rtx *x, void *data) ...@@ -1837,7 +1837,7 @@ check_dependence (rtx *x, void *data)
{ {
struct check_dependence_data *d = (struct check_dependence_data *) data; struct check_dependence_data *d = (struct check_dependence_data *) data;
if (*x && MEM_P (*x)) if (*x && MEM_P (*x))
return canon_true_dependence (d->exp, d->mode, d->addr, *x, NULL_RTX); return canon_anti_dependence (d->exp, d->mode, d->addr, *x);
else else
return 0; return 0;
} }
......
...@@ -2263,8 +2263,8 @@ cselib_invalidate_mem (rtx mem_rtx) ...@@ -2263,8 +2263,8 @@ cselib_invalidate_mem (rtx mem_rtx)
continue; continue;
} }
if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS) if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
&& ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), && ! canon_anti_dependence (mem_rtx, GET_MODE (mem_rtx),
mem_addr, x, NULL_RTX)) mem_addr, x))
{ {
has_mem = true; has_mem = true;
num_mems++; num_mems++;
......
...@@ -2705,6 +2705,8 @@ extern int canon_true_dependence (const_rtx, enum machine_mode, rtx, ...@@ -2705,6 +2705,8 @@ extern int canon_true_dependence (const_rtx, enum machine_mode, rtx,
const_rtx, rtx); const_rtx, rtx);
extern int read_dependence (const_rtx, const_rtx); extern int read_dependence (const_rtx, const_rtx);
extern int anti_dependence (const_rtx, const_rtx); extern int anti_dependence (const_rtx, const_rtx);
extern int canon_anti_dependence (const_rtx, enum machine_mode, rtx,
const_rtx);
extern int output_dependence (const_rtx, const_rtx); extern int output_dependence (const_rtx, const_rtx);
extern int may_alias_p (const_rtx, const_rtx); extern int may_alias_p (const_rtx, const_rtx);
extern void init_alias_target (void); extern void init_alias_target (void);
......
2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
* gcc.dg/torture/pr57425-1.c, gcc.dg/torture/pr57425-2.c: New files.
* gcc.dg/torture/pr57425-3.c, gcc.dg/torture/pr57569.c: Likewise.
2013-06-15 Mikael Morin <mikael@gcc.gnu.org> 2013-06-15 Mikael Morin <mikael@gcc.gnu.org>
PR fortran/49074 PR fortran/49074
......
/* { dg-do run } */
extern void abort (void) __attribute__((noreturn));
union setconflict
{
int a[20];
long b[10];
};
int
main ()
{
int sum = 0;
{
union setconflict a;
int *c;
c = a.a;
asm ("": "=r" (c):"0" (c));
*c = 0;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
{
union setconflict a;
long *c;
c = a.b;
asm ("": "=r" (c):"0" (c));
*c = 1;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
if (sum != 1)
abort();
return 0;
}
/* { dg-do run } */
extern void abort (void) __attribute__((noreturn));
int
main ()
{
int sum = 0;
{
int a[20];
int *c;
c = a;
asm ("": "=r" (c):"0" (c));
*c = 0;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
{
long b[10];
long *c;
c = b;
asm ("": "=r" (c):"0" (c));
*c = 1;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
if (sum != 1)
abort();
return 0;
}
/* { dg-do run } */
extern void abort (void) __attribute__((noreturn));
int
main ()
{
int sum = 0;
{
long a[20];
long *c;
c = a;
asm ("": "=r" (c):"0" (c));
*c = 0;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
{
long long b[10];
long long *c;
c = b;
asm ("": "=r" (c):"0" (c));
*c = 1;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
if (sum != 1)
abort();
return 0;
}
/* { dg-do run } */
extern void abort (void) __attribute__((noreturn));
struct S { int f0; } a;
int b, e, *d = &b, f;
void
fn1 ()
{
int **g[9][6];
int ***h = &g[6][3];
for (; e < 9; e++) {
f = 0;
for (; f < 6; f++)
g[e][f] = &d;
}
***h = 0;
}
void
fn2 ()
{
fn1 ();
struct S c[4][10] = {};
a = c[3][9];
}
int
main ()
{
fn2 ();
if (a.f0 != 0)
abort ();
return 0;
}
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