Commit fef94f76 by Martin Jambor Committed by Martin Jambor

tree-sra.c (struct access): New field grp_hint.

2009-09-02  Martin Jambor  <mjambor@suse.cz>

	* tree-sra.c (struct access): New field grp_hint.
	(dump_access): Dump grp_hint.
	(sort_and_splice_var_accesses): Set grp_hint if a group is read
	multiple times.
	(analyze_access_subtree): Only scalarize accesses with grp_hint set or
	those which have been specifically read and somehow written to.
	(propagate_subacesses_accross_link): Set grp_hint of right child and
	also possibly of the left child.

	* testsuite/gcc.dg/tree-ssa/sra-8.c: New testcase.
	* testsuite/gcc.dg/memcpy-1.c: Add . to match pattern.
	* testsuite/gcc.dg/uninit-I.c: XFAIL warning test.
	* testsuite/g++.dg/warn/unit-1.C: XFAIL warning test.

From-SVN: r151345
parent fd2ab214
2009-09-02 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (struct access): New field grp_hint.
(dump_access): Dump grp_hint.
(sort_and_splice_var_accesses): Set grp_hint if a group is read
multiple times.
(analyze_access_subtree): Only scalarize accesses with grp_hint set or
those which have been specifically read and somehow written to.
(propagate_subacesses_accross_link): Set grp_hint of right child and
also possibly of the left child.
2009-09-02 Jakub Jelinek <jakub@redhat.com> 2009-09-02 Jakub Jelinek <jakub@redhat.com>
* tree-object-size.c (addr_object_size): Always use object_size_type * tree-object-size.c (addr_object_size): Always use object_size_type
......
2009-09-02 Martin Jambor <mjambor@suse.cz>
* gcc.dg/tree-ssa/sra-8.c: New testcase.
* gcc.dg/memcpy-1.c: Add . to match pattern.
* gcc.dg/uninit-I.c: XFAIL warning test.
* g++.dg/warn/unit-1.C: XFAIL warning test.
2009-09-02 Ian Lance Taylor <iant@google.com> 2009-09-02 Ian Lance Taylor <iant@google.com>
* gcc.dg/20090902-1.c: New test. * gcc.dg/20090902-1.c: New test.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
struct a { int mode; }; struct a { int mode; };
int sys_msgctl (void) int sys_msgctl (void)
{ {
struct a setbuf; /* { dg-warning "'setbuf\.a::mode' is used" } */ struct a setbuf; /* { dg-warning "'setbuf\.a::mode' is used" "" { xfail *-*-* } } */
return setbuf.mode; return setbuf.mode;
} }
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */
/* PR36598 AVR fail maybe due to cost metrics */ /* PR36598 AVR fail maybe due to cost metrics */
/* { dg-final { scan-tree-dump-times "nasty_local" 0 "optimized" { xfail { "avr-*-*" } } } } */ /* { dg-final { scan-tree-dump-times "nasty_local\\." 0 "optimized" { xfail { "avr-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
struct a {int a,b,c;} a; struct a {int a,b,c;} a;
int test(struct a a) int test(struct a a)
......
/* A testcase for PR 40744. We do not want to create replacements for object
that are dead or have only a single use, whenever it can be avoided
simply. */
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-esra-details" } */
struct X { int i; int j; };
void foo(void)
{
struct X x;
x.i = 1;
x.j = 2;
}
int bar(struct X x)
{
return x.i;
}
extern void do_something (struct X);
void bar2(int i, int j)
{
struct X x;
x.i = i;
x.j = j;
do_something (x);
}
/* { dg-final { scan-tree-dump-times "Created a replacement" 0 "esra"} } */
/* { dg-final { cleanup-tree-dump "esra" } } */
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
int sys_msgctl (void) int sys_msgctl (void)
{ {
struct { int mode; } setbuf; /* { dg-warning "'setbuf\.mode' is used" } */ struct { int mode; } setbuf; /* { dg-warning "'setbuf\.mode' is used" "" { xfail *-*-* } } */
return setbuf.mode; return setbuf.mode;
} }
...@@ -165,6 +165,10 @@ struct access ...@@ -165,6 +165,10 @@ struct access
/* Does this group contain a read access? This flag is propagated down the /* Does this group contain a read access? This flag is propagated down the
access tree. */ access tree. */
unsigned grp_read : 1; unsigned grp_read : 1;
/* Other passes of the analysis use this bit to make function
analyze_access_subtree create scalar replacements for this group if
possible. */
unsigned grp_hint : 1;
/* Is the subtree rooted in this access fully covered by scalar /* Is the subtree rooted in this access fully covered by scalar
replacements? */ replacements? */
unsigned grp_covered : 1; unsigned grp_covered : 1;
...@@ -261,12 +265,14 @@ dump_access (FILE *f, struct access *access, bool grp) ...@@ -261,12 +265,14 @@ dump_access (FILE *f, struct access *access, bool grp)
fprintf (f, ", type = "); fprintf (f, ", type = ");
print_generic_expr (f, access->type, 0); print_generic_expr (f, access->type, 0);
if (grp) if (grp)
fprintf (f, ", grp_write = %d, grp_read = %d, grp_covered = %d, " fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
"grp_unscalarizable_region = %d, grp_unscalarized_data = %d, " "grp_covered = %d, grp_unscalarizable_region = %d, "
"grp_partial_lhs = %d, grp_to_be_replaced = %d\n", "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
access->grp_write, access->grp_read, access->grp_covered, "grp_to_be_replaced = %d\n",
access->grp_unscalarizable_region, access->grp_unscalarized_data, access->grp_write, access->grp_read, access->grp_hint,
access->grp_partial_lhs, access->grp_to_be_replaced); access->grp_covered, access->grp_unscalarizable_region,
access->grp_unscalarized_data, access->grp_partial_lhs,
access->grp_to_be_replaced);
else else
fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write, fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
access->grp_partial_lhs); access->grp_partial_lhs);
...@@ -1203,8 +1209,9 @@ sort_and_splice_var_accesses (tree var) ...@@ -1203,8 +1209,9 @@ sort_and_splice_var_accesses (tree var)
while (i < access_count) while (i < access_count)
{ {
struct access *access = VEC_index (access_p, access_vec, i); struct access *access = VEC_index (access_p, access_vec, i);
bool modification = access->write; bool grp_write = access->write;
bool grp_read = !access->write; bool grp_read = !access->write;
bool multiple_reads = false;
bool grp_partial_lhs = access->grp_partial_lhs; bool grp_partial_lhs = access->grp_partial_lhs;
bool first_scalar = is_gimple_reg_type (access->type); bool first_scalar = is_gimple_reg_type (access->type);
bool unscalarizable_region = access->grp_unscalarizable_region; bool unscalarizable_region = access->grp_unscalarizable_region;
...@@ -1227,8 +1234,15 @@ sort_and_splice_var_accesses (tree var) ...@@ -1227,8 +1234,15 @@ sort_and_splice_var_accesses (tree var)
struct access *ac2 = VEC_index (access_p, access_vec, j); struct access *ac2 = VEC_index (access_p, access_vec, j);
if (ac2->offset != access->offset || ac2->size != access->size) if (ac2->offset != access->offset || ac2->size != access->size)
break; break;
modification |= ac2->write; if (ac2->write)
grp_read |= !ac2->write; grp_write = true;
else
{
if (grp_read)
multiple_reads = true;
else
grp_read = true;
}
grp_partial_lhs |= ac2->grp_partial_lhs; grp_partial_lhs |= ac2->grp_partial_lhs;
unscalarizable_region |= ac2->grp_unscalarizable_region; unscalarizable_region |= ac2->grp_unscalarizable_region;
relink_to_new_repr (access, ac2); relink_to_new_repr (access, ac2);
...@@ -1244,8 +1258,9 @@ sort_and_splice_var_accesses (tree var) ...@@ -1244,8 +1258,9 @@ sort_and_splice_var_accesses (tree var)
i = j; i = j;
access->group_representative = access; access->group_representative = access;
access->grp_write = modification; access->grp_write = grp_write;
access->grp_read = grp_read; access->grp_read = grp_read;
access->grp_hint = multiple_reads;
access->grp_partial_lhs = grp_partial_lhs; access->grp_partial_lhs = grp_partial_lhs;
access->grp_unscalarizable_region = unscalarizable_region; access->grp_unscalarizable_region = unscalarizable_region;
if (access->first_link) if (access->first_link)
...@@ -1377,6 +1392,7 @@ analyze_access_subtree (struct access *root, bool allow_replacements, ...@@ -1377,6 +1392,7 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
HOST_WIDE_INT covered_to = root->offset; HOST_WIDE_INT covered_to = root->offset;
bool scalar = is_gimple_reg_type (root->type); bool scalar = is_gimple_reg_type (root->type);
bool hole = false, sth_created = false; bool hole = false, sth_created = false;
bool direct_read = root->grp_read;
if (mark_read) if (mark_read)
root->grp_read = true; root->grp_read = true;
...@@ -1405,7 +1421,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements, ...@@ -1405,7 +1421,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
hole |= !child->grp_covered; hole |= !child->grp_covered;
} }
if (allow_replacements && scalar && !root->first_child) if (allow_replacements && scalar && !root->first_child
&& (root->grp_hint
|| (direct_read && root->grp_write)))
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -1543,7 +1561,6 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc) ...@@ -1543,7 +1561,6 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
{ {
struct access *rchild; struct access *rchild;
HOST_WIDE_INT norm_delta = lacc->offset - racc->offset; HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
bool ret = false; bool ret = false;
if (is_gimple_reg_type (lacc->type) if (is_gimple_reg_type (lacc->type)
...@@ -1570,8 +1587,13 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc) ...@@ -1570,8 +1587,13 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size, if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc)) &new_acc))
{ {
if (new_acc && rchild->first_child) if (new_acc)
ret |= propagate_subacesses_accross_link (new_acc, rchild); {
rchild->grp_hint = 1;
new_acc->grp_hint |= new_acc->grp_read;
if (rchild->first_child)
ret |= propagate_subacesses_accross_link (new_acc, rchild);
}
continue; continue;
} }
...@@ -1582,6 +1604,7 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc) ...@@ -1582,6 +1604,7 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
rchild->type, false)) rchild->type, false))
continue; continue;
rchild->grp_hint = 1;
new_acc = create_artificial_child_access (lacc, rchild, norm_offset); new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
if (racc->first_child) if (racc->first_child)
propagate_subacesses_accross_link (new_acc, rchild); propagate_subacesses_accross_link (new_acc, rchild);
......
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