diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-06-01 14:14:29 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2017-06-01 14:14:29 +0200 |
commit | c8638450abe8a406813652eae4f9e7b3cb3bece4 (patch) | |
tree | 4fddb5aa4bc1185eb3bc05e4fc510a14a8d1b53c /gcc | |
parent | 4ba66aee9e94f1bfb82fbebac661ad60cbce1176 (diff) | |
download | gcc-c8638450abe8a406813652eae4f9e7b3cb3bece4.zip gcc-c8638450abe8a406813652eae4f9e7b3cb3bece4.tar.gz gcc-c8638450abe8a406813652eae4f9e7b3cb3bece4.tar.bz2 |
[PR 80898] Propagate grp_write from disqualified SRA candidates
2017-06-01 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/80898
* tree-sra.c (process_subtree_disqualification): Removed.
(disqualify_candidate): Do not acll
process_subtree_disqualification.
(subtree_mark_written_and_enqueue): New function.
(propagate_all_subaccesses): Set grp_write of LHS subtree if the
RHS has been disqualified and re-queue LHS if necessary. Apart
from that, ignore disqualified RHS.
testsuite/
* gcc.dg/tree-ssa/pr80898.c: New test.
* gcc.dg/tree-ssa/pr80898-2.c: Likewise.
From-SVN: r248790
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr80898-2.c | 71 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr80898.c | 20 | ||||
-rw-r--r-- | gcc/tree-sra.c | 56 |
5 files changed, 143 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9cfcfad..81d8337 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-06-01 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/80898 + * tree-sra.c (process_subtree_disqualification): Removed. + (disqualify_candidate): Do not acll + process_subtree_disqualification. + (subtree_mark_written_and_enqueue): New function. + (propagate_all_subaccesses): Set grp_write of LHS subtree if the + RHS has been disqualified and re-queue LHS if necessary. Apart + from that, ignore disqualified RHS. + 2017-06-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * config/s390/s390.c (s390_emit_epilogue): Disable early return diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a1212f2..e398b31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-06-01 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/80898 + * gcc.dg/tree-ssa/pr80898.c: New test. + * gcc.dg/tree-ssa/pr80898-2.c: Likewise. + 2017-06-01 Paolo Carlini <paolo.carlini@oracle.com> PR c++/80896 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80898-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80898-2.c new file mode 100644 index 0000000..cb4799c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80898-2.c @@ -0,0 +1,71 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +struct S0 +{ + unsigned a : 15; + int b; + int c; +}; + +struct S1 +{ + struct S0 s0; + int e; +}; + +struct Z +{ + char c; + int z; +} __attribute__((packed)); + +union U +{ + struct S1 s1; + struct Z z; +}; + + +int __attribute__((noinline, noclone)) +return_zero (void) +{ + return 0; +} + +volatile union U gu; +struct S0 gs; + +int __attribute__((noinline, noclone)) +check_outcome () +{ + if (gs.a != 6 + || gs.b != 80000) + __builtin_abort (); +} + +int +main (int argc, char *argv[]) +{ + union U u; + struct S1 m; + struct S0 l; + + if (return_zero ()) + u.z.z = 20000; + else + { + u.s1.s0.a = 6; + u.s1.s0.b = 80000; + u.s1.e = 2; + + m = u.s1; + m.s0.c = 0; + l = m.s0; + gs = l; + } + + gu = u; + check_outcome (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80898.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80898.c new file mode 100644 index 0000000..ed88f2c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80898.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +struct S0 { + int f0 : 24; + int f1; + int f74; +} a, *c = &a; +struct S0 fn1() { + struct S0 b = {4, 3}; + return b; +} + +int main() { + *c = fn1(); + + if (a.f1 != 3) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 6a8a0a4..f25818f 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -694,21 +694,9 @@ static bool constant_decl_p (tree decl) return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl); } - -/* Mark LHS of assign links out of ACCESS and its children as written to. */ - -static void -process_subtree_disqualification (struct access *access) -{ - struct access *child; - for (struct assign_link *link = access->first_link; link; link = link->next) - link->lacc->grp_write = true; - for (child = access->first_child; child; child = child->next_sibling) - process_subtree_disqualification (child); -} - /* Remove DECL from candidates for SRA and write REASON to the dump file if there is one. */ + static void disqualify_candidate (tree decl, const char *reason) { @@ -723,13 +711,6 @@ disqualify_candidate (tree decl, const char *reason) print_generic_expr (dump_file, decl); fprintf (dump_file, " - %s\n", reason); } - - struct access *access = get_first_repr_for_decl (decl); - while (access) - { - process_subtree_disqualification (access); - access = access->next_grp; - } } /* Return true iff the type contains a field or an element which does not allow @@ -2679,6 +2660,26 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc) return ret; } +/* Beginning with ACCESS, traverse its whole access subtree and mark all + sub-trees as written to. If any of them has not been marked so previously + and has assignment links leading from it, re-enqueue it. */ + +static void +subtree_mark_written_and_enqueue (struct access *access) +{ + if (access->grp_write) + return; + access->grp_write = true; + if (access->first_link) + add_access_to_work_queue (access); + + struct access *child; + for (child = access->first_child; child; child = child->next_sibling) + subtree_mark_written_and_enqueue (child); +} + + + /* Propagate all subaccesses across assignment links. */ static void @@ -2698,7 +2699,20 @@ propagate_all_subaccesses (void) if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base))) continue; lacc = lacc->group_representative; - if (propagate_subaccesses_across_link (lacc, racc)) + + bool reque_parents = false; + if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base))) + { + if (!lacc->grp_write) + { + subtree_mark_written_and_enqueue (lacc); + reque_parents = true; + } + } + else if (propagate_subaccesses_across_link (lacc, racc)) + reque_parents = true; + + if (reque_parents) do { if (lacc->first_link) |