tree-sra: Avoid refreshing into const base decls (PR 100453)
authorMartin Jambor <mjambor@suse.cz>
Thu, 13 May 2021 21:26:32 +0000 (23:26 +0200)
committerMartin Jambor <mjambor@suse.cz>
Thu, 13 May 2021 21:26:32 +0000 (23:26 +0200)
When SRA transforms an assignment where the RHS is an aggregate decl
that it creates replacements for, the (least efficient) fallback
method of dealing with them is to store all the replacements back into
the original decl and then let the original assignment takes itc
sourse.

That of course should not need to be done for TREE_READONLY bases
which cannot change contents.  The SRA code handled this situation in
one of two necessary places but only for DECL_IN_CONSTANT_POOL const
decls, this patch modifies both to check TREE_READONLY.

gcc/ChangeLog:

2021-05-12  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/100453
* tree-sra.c (sra_modify_assign): All const base accesses do not
need refreshing, not just those from decl_pool.
(sra_modify_assign): Do not refresh into a const base decl.

gcc/testsuite/ChangeLog:

2021-05-12  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/100453
* gcc.dg/tree-ssa/pr100453.c: New test.

gcc/testsuite/gcc.dg/tree-ssa/pr100453.c [new file with mode: 0644]
gcc/tree-sra.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c
new file mode 100644 (file)
index 0000000..0cf0ad2
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+struct a {
+  int b : 4;
+} d;
+static int c, e;
+static const struct a f;
+static void g(const struct a h) {
+  for (; c < 1; c++)
+    d = h;
+  e = h.b;
+  c = h.b;
+}
+int main() {
+  g(f);
+  return 0;
+}
index 8dfc923..186cd62 100644 (file)
@@ -4244,7 +4244,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
       || stmt_ends_bb_p (stmt))
     {
       /* No need to copy into a constant-pool, it comes pre-initialized.  */
-      if (access_has_children_p (racc) && !constant_decl_p (racc->base))
+      if (access_has_children_p (racc) && !TREE_READONLY (racc->base))
        generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
                                 gsi, false, false, loc);
       if (access_has_children_p (lacc))
@@ -4333,7 +4333,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
            }
          /* Restore the aggregate RHS from its components so the
             prevailing aggregate copy does the right thing.  */
-         if (access_has_children_p (racc))
+         if (access_has_children_p (racc) && !TREE_READONLY (racc->base))
            generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
                                     gsi, false, false, loc);
          /* Re-load the components of the aggregate copy destination.