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> 2010-06-10 Alexandre Oliva <aoliva@redhat.com>
PR debug/41371 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> 2010-06-10 Daniel Kraft <d@domob.eu>
PR fortran/38936 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) ...@@ -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 /* 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 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) build_access_subtree (struct access **access)
{ {
struct access *root = *access, *last_child = NULL; struct access *root = *access, *last_child = NULL;
...@@ -1706,24 +1707,32 @@ build_access_subtree (struct access **access) ...@@ -1706,24 +1707,32 @@ build_access_subtree (struct access **access)
last_child->next_sibling = *access; last_child->next_sibling = *access;
last_child = *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 /* 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 one, others are linked in a list by the next_grp field. Return false iff
replacements on the way, return true iff any are to be created. */ some accesses partially overlap. */
static void static bool
build_access_trees (struct access *access) build_access_trees (struct access *access)
{ {
while (access) while (access)
{ {
struct access *root = access; struct access *root = access;
build_access_subtree (&access); if (!build_access_subtree (&access))
return false;
root->next_grp = access; root->next_grp = access;
} }
return true;
} }
/* Return true if expr contains some ARRAY_REFs into a variable bounded /* Return true if expr contains some ARRAY_REFs into a variable bounded
...@@ -2062,9 +2071,7 @@ analyze_all_variable_accesses (void) ...@@ -2062,9 +2071,7 @@ analyze_all_variable_accesses (void)
struct access *access; struct access *access;
access = sort_and_splice_var_accesses (var); access = sort_and_splice_var_accesses (var);
if (access) if (!access || !build_access_trees (access))
build_access_trees (access);
else
disqualify_candidate (var, disqualify_candidate (var,
"No or inhibitingly overlapping accesses."); "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