Commit 591d4f4a by Martin Jambor Committed by Martin Jambor

re PR tree-optimization/44258 (possible SRA wrong-code generation.)

2010-06-10  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/44258
	* tree-sra.c (build_access_subtree): Return false iff there is a
	partial overlap.
	(build_access_trees): Likewise.
	(analyze_all_variable_accesses): Disqualify candidates if
	build_access_trees returns true for them.

	* testsuite/gcc.dg/tree-ssa/pr44258.c: New test.

From-SVN: r160561
parent c63a4676
2010-06-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44258
* tree-sra.c (build_access_subtree): Return false iff there is a
partial overlap.
(build_access_trees): Likewise.
(analyze_all_variable_accesses): Disqualify candidates if
build_access_trees returns true for them.
2010-06-10 Alexandre Oliva <aoliva@redhat.com>
PR debug/41371
......
2010-06-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44258
* gcc.dg/tree-ssa/pr44258.c: New test.
2010-06-10 Daniel Kraft <d@domob.eu>
PR fortran/38936
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-esra-details" } */
struct blah
{
char a[4];
};
struct str
{
struct blah b1;
char x;
};
struct val
{
char y;
struct blah b2;
};
union U
{
struct str str;
struct val val;
};
extern struct blah e_b1, e_b2;
extern union U *e_u;
int foo (int b)
{
union U u;
u.str.b1 = e_b1;
u.val.b2 = e_b2;
u.str.b1.a[3] = 0;
*e_u = u;
}
/* { dg-final { scan-tree-dump-times "Created a replacement" 0 "esra"} } */
/* { dg-final { cleanup-tree-dump "esra" } } */
......@@ -1689,9 +1689,10 @@ get_unrenamed_access_replacement (struct access *access)
/* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
linked list along the way. Stop when *ACCESS is NULL or the access pointed
to it is not "within" the root. */
to it is not "within" the root. Return false iff some accesses partially
overlap. */
static void
static bool
build_access_subtree (struct access **access)
{
struct access *root = *access, *last_child = NULL;
......@@ -1706,24 +1707,32 @@ build_access_subtree (struct access **access)
last_child->next_sibling = *access;
last_child = *access;
build_access_subtree (access);
if (!build_access_subtree (access))
return false;
}
if (*access && (*access)->offset < limit)
return false;
return true;
}
/* Build a tree of access representatives, ACCESS is the pointer to the first
one, others are linked in a list by the next_grp field. Decide about scalar
replacements on the way, return true iff any are to be created. */
one, others are linked in a list by the next_grp field. Return false iff
some accesses partially overlap. */
static void
static bool
build_access_trees (struct access *access)
{
while (access)
{
struct access *root = access;
build_access_subtree (&access);
if (!build_access_subtree (&access))
return false;
root->next_grp = access;
}
return true;
}
/* Return true if expr contains some ARRAY_REFs into a variable bounded
......@@ -2062,9 +2071,7 @@ analyze_all_variable_accesses (void)
struct access *access;
access = sort_and_splice_var_accesses (var);
if (access)
build_access_trees (access);
else
if (!access || !build_access_trees (access))
disqualify_candidate (var,
"No or inhibitingly overlapping accesses.");
}
......
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