summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-01 12:14:29 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-01 12:14:29 +0000
commitaf9eb532d4c77faea7fba0f1947b564c84f16af3 (patch)
tree4fddb5aa4bc1185eb3bc05e4fc510a14a8d1b53c
parentb5e83b9bb7f744fa6d94d9b2b39d3daa63769ebc (diff)
downloadgcc-af9eb532d4c77faea7fba0f1947b564c84f16af3.tar.gz
[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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@248790 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr80898-2.c71
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr80898.c20
-rw-r--r--gcc/tree-sra.c56
5 files changed, 143 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9cfcfad9090..81d8337e050 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 a1212f24b6b..e398b31644a 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 00000000000..cb4799c5ced
--- /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 00000000000..ed88f2cbd1a
--- /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 6a8a0a4a427..f25818f4481 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)