diff options
author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-02 17:52:18 +0000 |
---|---|---|
committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-02 17:52:18 +0000 |
commit | c79d6ecf5563140990af3fd6597e57aecefa4f92 (patch) | |
tree | 98148830f4cfbf1657daafe9c739844729ce140b /gcc | |
parent | 2a50bfcf98249aff98c8ad8383d0d419f06fd9b2 (diff) | |
download | gcc-c79d6ecf5563140990af3fd6597e57aecefa4f92.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151345 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/unit-1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/memcpy-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/sra-8.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/uninit-I.c | 2 | ||||
-rw-r--r-- | gcc/tree-sra.c | 51 |
7 files changed, 93 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f623607af83..6cb7e9c7c33 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67c54c3efb6..de4a9665194 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/warn/unit-1.C b/gcc/testsuite/g++.dg/warn/unit-1.C index 1bfe75b2f6c..9c09d3f53cb 100644 --- a/gcc/testsuite/g++.dg/warn/unit-1.C +++ b/gcc/testsuite/g++.dg/warn/unit-1.C @@ -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; } diff --git a/gcc/testsuite/gcc.dg/memcpy-1.c b/gcc/testsuite/gcc.dg/memcpy-1.c index 2b11098b286..0952a261ad0 100644 --- a/gcc/testsuite/gcc.dg/memcpy-1.c +++ b/gcc/testsuite/gcc.dg/memcpy-1.c @@ -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) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-8.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-8.c new file mode 100644 index 00000000000..d43bbe0d8a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-8.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-I.c b/gcc/testsuite/gcc.dg/uninit-I.c index 7be60d786b8..064e42d55d0 100644 --- a/gcc/testsuite/gcc.dg/uninit-I.c +++ b/gcc/testsuite/gcc.dg/uninit-I.c @@ -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; } diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 33be0f6aaca..8d4dc90d179 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -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); |