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
This commit is contained in:
Martin Jambor 2009-09-02 19:52:18 +02:00 committed by Martin Jambor
parent fd2ab214c5
commit fef94f7680
7 changed files with 93 additions and 17 deletions

View File

@ -1,3 +1,14 @@
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>
* tree-object-size.c (addr_object_size): Always use object_size_type

View File

@ -1,3 +1,10 @@
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>
* gcc.dg/20090902-1.c: New test.

View File

@ -4,7 +4,7 @@
struct a { int mode; };
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;
}

View File

@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* 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" } } */
struct a {int a,b,c;} a;
int test(struct a a)

View File

@ -0,0 +1,35 @@
/* 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" } } */

View File

@ -3,6 +3,6 @@
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;
}

View File

@ -165,6 +165,10 @@ struct access
/* Does this group contain a read access? This flag is propagated down the
access tree. */
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
replacements? */
unsigned grp_covered : 1;
@ -261,12 +265,14 @@ dump_access (FILE *f, struct access *access, bool grp)
fprintf (f, ", type = ");
print_generic_expr (f, access->type, 0);
if (grp)
fprintf (f, ", grp_write = %d, grp_read = %d, grp_covered = %d, "
"grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
"grp_partial_lhs = %d, grp_to_be_replaced = %d\n",
access->grp_write, access->grp_read, access->grp_covered,
access->grp_unscalarizable_region, access->grp_unscalarized_data,
access->grp_partial_lhs, access->grp_to_be_replaced);
fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
"grp_covered = %d, grp_unscalarizable_region = %d, "
"grp_unscalarized_data = %d, grp_partial_lhs = %d, "
"grp_to_be_replaced = %d\n",
access->grp_write, access->grp_read, access->grp_hint,
access->grp_covered, access->grp_unscalarizable_region,
access->grp_unscalarized_data, access->grp_partial_lhs,
access->grp_to_be_replaced);
else
fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
access->grp_partial_lhs);
@ -1203,8 +1209,9 @@ sort_and_splice_var_accesses (tree var)
while (i < access_count)
{
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 multiple_reads = false;
bool grp_partial_lhs = access->grp_partial_lhs;
bool first_scalar = is_gimple_reg_type (access->type);
bool unscalarizable_region = access->grp_unscalarizable_region;
@ -1227,8 +1234,15 @@ sort_and_splice_var_accesses (tree var)
struct access *ac2 = VEC_index (access_p, access_vec, j);
if (ac2->offset != access->offset || ac2->size != access->size)
break;
modification |= ac2->write;
grp_read |= !ac2->write;
if (ac2->write)
grp_write = true;
else
{
if (grp_read)
multiple_reads = true;
else
grp_read = true;
}
grp_partial_lhs |= ac2->grp_partial_lhs;
unscalarizable_region |= ac2->grp_unscalarizable_region;
relink_to_new_repr (access, ac2);
@ -1244,8 +1258,9 @@ sort_and_splice_var_accesses (tree var)
i = j;
access->group_representative = access;
access->grp_write = modification;
access->grp_write = grp_write;
access->grp_read = grp_read;
access->grp_hint = multiple_reads;
access->grp_partial_lhs = grp_partial_lhs;
access->grp_unscalarizable_region = unscalarizable_region;
if (access->first_link)
@ -1377,6 +1392,7 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
HOST_WIDE_INT covered_to = root->offset;
bool scalar = is_gimple_reg_type (root->type);
bool hole = false, sth_created = false;
bool direct_read = root->grp_read;
if (mark_read)
root->grp_read = true;
@ -1405,7 +1421,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
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))
{
@ -1543,7 +1561,6 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
{
struct access *rchild;
HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
bool ret = false;
if (is_gimple_reg_type (lacc->type)
@ -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,
&new_acc))
{
if (new_acc && rchild->first_child)
ret |= propagate_subacesses_accross_link (new_acc, rchild);
if (new_acc)
{
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;
}
@ -1582,6 +1604,7 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
rchild->type, false))
continue;
rchild->grp_hint = 1;
new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
if (racc->first_child)
propagate_subacesses_accross_link (new_acc, rchild);