diff mbox

[PR,80622] Treat const pools as initialized in SRA

Message ID 20170504150915.zlbbzestx7ykbiri@virgil.suse.cz
State New
Headers show

Commit Message

Martin Jambor May 4, 2017, 3:09 p.m. UTC
Hi,

PR 80622 happens because when setting grp_write lazily, the code does
not acknowledge that constant pool bases come initialized and so
contain data even when not written to.  The patch below fixes that but
it also puts a test for pre-initialization into a special function,
uses it at all appropriate places and moves the test in question to an
earlier time, which is a tiny bit cheaper because it may avoid
unnecessary re-invocation of propagate_subaccesses_across_link.

Bootstrapped and tested on x86_64-linux, OK for trunk?

Thanks,

Martin



2017-05-04  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/80622
	* tree-sra.c (comes_initialized_p): New function.
	(build_accesses_from_assign): Only set write lazily when
	comes_initialized_p is false.
	(analyze_access_subtree): Use comes_initialized_p.
	(propagate_subaccesses_across_link): Assert !comes_initialized_p
	instead of testing for PARM_DECL.

testsuite/
	* gcc.dg/tree-ssa/pr80622.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/pr80622.c | 19 +++++++++++++++++++
 gcc/tree-sra.c                          | 29 +++++++++++++++++++++--------
 2 files changed, 40 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr80622.c

Comments

Richard Biener May 4, 2017, 3:55 p.m. UTC | #1
On May 4, 2017 5:09:15 PM GMT+02:00, Martin Jambor <mjambor@suse.cz> wrote:
>Hi,
>
>PR 80622 happens because when setting grp_write lazily, the code does
>not acknowledge that constant pool bases come initialized and so
>contain data even when not written to.  The patch below fixes that but
>it also puts a test for pre-initialization into a special function,
>uses it at all appropriate places and moves the test in question to an
>earlier time, which is a tiny bit cheaper because it may avoid
>unnecessary re-invocation of propagate_subaccesses_across_link.
>
>Bootstrapped and tested on x86_64-linux, OK for trunk?

OK.

Richard.

>Thanks,
>
>Martin
>
>
>
>2017-05-04  Martin Jambor  <mjambor@suse.cz>
>
>	PR tree-optimization/80622
>	* tree-sra.c (comes_initialized_p): New function.
>	(build_accesses_from_assign): Only set write lazily when
>	comes_initialized_p is false.
>	(analyze_access_subtree): Use comes_initialized_p.
>	(propagate_subaccesses_across_link): Assert !comes_initialized_p
>	instead of testing for PARM_DECL.
>
>testsuite/
>	* gcc.dg/tree-ssa/pr80622.c: New test.
>---
> gcc/testsuite/gcc.dg/tree-ssa/pr80622.c | 19 +++++++++++++++++++
>gcc/tree-sra.c                          | 29
>+++++++++++++++++++++--------
> 2 files changed, 40 insertions(+), 8 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
>
>diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
>b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
>new file mode 100644
>index 00000000000..96dcb8fcdc0
>--- /dev/null
>+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
>@@ -0,0 +1,19 @@
>+/* { dg-do run } */
>+/* { dg-options "-O" } */
>+
>+struct S { int d; char e; int f; char g; } a;
>+char c;
>+
>+int
>+main ()
>+{
>+  struct S b[][1] = {3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4,
>3,
>+                      0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3,
>0,
>+                      3, 4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0,
>3,
>+                      4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0, 3,
>4};
>+  a = b[4][0];
>+  c = b[4][0].e;
>+  if (a.g != 4)
>+    __builtin_abort ();
>+  return 0;
>+}
>diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
>index 1606573aead..8ac9c0783ff 100644
>--- a/gcc/tree-sra.c
>+++ b/gcc/tree-sra.c
>@@ -1305,6 +1305,15 @@ disqualify_if_bad_bb_terminating_stmt (gimple
>*stmt, tree lhs, tree rhs)
>   return false;
> }
> 
>+/* Return true if the nature of BASE is such that it contains data
>even if
>+   there is no write to it in the function.  */
>+
>+static bool
>+comes_initialized_p (tree base)
>+{
>+  return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
>+}
>+
>/* Scan expressions occurring in STMT, create access structures for all
>accesses
>to candidates for scalarization and remove those candidates which occur
>in
>statements or expressions that prevent them from being split apart. 
>Return
>@@ -1364,8 +1373,10 @@ build_accesses_from_assign (gimple *stmt)
>       link->racc = racc;
>       add_link_to_rhs (racc, link);
>/* Let's delay marking the areas as written until propagation of
>accesses
>-	 across link.  */
>-      lacc->write = false;
>+	 across link, unless the nature of rhs tells us that its data comes
>+	 from elsewhere.  */
>+      if (!comes_initialized_p (racc->base))
>+	lacc->write = false;
>     }
> 
>   return lacc || racc;
>@@ -2472,8 +2483,7 @@ analyze_access_subtree (struct access *root,
>struct access *parent,
> 
>   if (!hole || root->grp_total_scalarization)
>     root->grp_covered = 1;
>-  else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL
>-	   || constant_decl_p (root->base))
>+  else if (root->grp_write || comes_initialized_p (root->base))
>     root->grp_unscalarized_data = 1; /* not covered and written to */
>   return sth_created;
> }
>@@ -2581,11 +2591,14 @@ propagate_subaccesses_across_link (struct
>access *lacc, struct access *racc)
> 
>/* IF the LHS is still not marked as being written to, we only need to
>do so
>      if the RHS at this level actually was.  */
>-  if (!lacc->grp_write &&
>-      (racc->grp_write || TREE_CODE (racc->base) == PARM_DECL))
>+  if (!lacc->grp_write)
>     {
>-      lacc->grp_write = true;
>-      ret = true;
>+      gcc_checking_assert (!comes_initialized_p (racc->base));
>+      if (racc->grp_write)
>+	{
>+	  lacc->grp_write = true;
>+	  ret = true;
>+	}
>     }
> 
>   if (is_gimple_reg_type (lacc->type)
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
new file mode 100644
index 00000000000..96dcb8fcdc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c
@@ -0,0 +1,19 @@ 
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+struct S { int d; char e; int f; char g; } a;
+char c;
+
+int
+main ()
+{
+  struct S b[][1] = {3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3,
+                      0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0,
+                      3, 4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0, 3,
+                      4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0, 3, 4};
+  a = b[4][0];
+  c = b[4][0].e;
+  if (a.g != 4)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 1606573aead..8ac9c0783ff 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1305,6 +1305,15 @@  disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
   return false;
 }
 
+/* Return true if the nature of BASE is such that it contains data even if
+   there is no write to it in the function.  */
+
+static bool
+comes_initialized_p (tree base)
+{
+  return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
+}
+
 /* Scan expressions occurring in STMT, create access structures for all accesses
    to candidates for scalarization and remove those candidates which occur in
    statements or expressions that prevent them from being split apart.  Return
@@ -1364,8 +1373,10 @@  build_accesses_from_assign (gimple *stmt)
       link->racc = racc;
       add_link_to_rhs (racc, link);
       /* Let's delay marking the areas as written until propagation of accesses
-	 across link.  */
-      lacc->write = false;
+	 across link, unless the nature of rhs tells us that its data comes
+	 from elsewhere.  */
+      if (!comes_initialized_p (racc->base))
+	lacc->write = false;
     }
 
   return lacc || racc;
@@ -2472,8 +2483,7 @@  analyze_access_subtree (struct access *root, struct access *parent,
 
   if (!hole || root->grp_total_scalarization)
     root->grp_covered = 1;
-  else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL
-	   || constant_decl_p (root->base))
+  else if (root->grp_write || comes_initialized_p (root->base))
     root->grp_unscalarized_data = 1; /* not covered and written to */
   return sth_created;
 }
@@ -2581,11 +2591,14 @@  propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
 
   /* IF the LHS is still not marked as being written to, we only need to do so
      if the RHS at this level actually was.  */
-  if (!lacc->grp_write &&
-      (racc->grp_write || TREE_CODE (racc->base) == PARM_DECL))
+  if (!lacc->grp_write)
     {
-      lacc->grp_write = true;
-      ret = true;
+      gcc_checking_assert (!comes_initialized_p (racc->base));
+      if (racc->grp_write)
+	{
+	  lacc->grp_write = true;
+	  ret = true;
+	}
     }
 
   if (is_gimple_reg_type (lacc->type)