]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2010-04-23 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Apr 2010 14:52:06 +0000 (14:52 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Apr 2010 14:52:06 +0000 (14:52 +0000)
PR tree-optimization/43846
* tree-sra.c (struct access): New flag grp_assignment_read.
(build_accesses_from_assign): Set grp_assignment_read.
(sort_and_splice_var_accesses): Propagate grp_assignment_read.
(enum mark_read_status): New type.
(analyze_access_subtree): Propagate grp_assignment_read, create
accesses also if both direct_read and root->grp_assignment_read.

* testsuite/gcc.dg/tree-ssa/sra-10.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158668 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 1d454224c959c7871927edb108fb446e011e063e..45ff41d3ad664a8746cce06fc4b3b7194888adca 100644 (file)
@@ -1,3 +1,13 @@
+2010-04-23  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/43846
+       * tree-sra.c (struct access): New flag grp_assignment_read.
+       (build_accesses_from_assign): Set grp_assignment_read.
+       (sort_and_splice_var_accesses): Propagate grp_assignment_read.
+       (enum mark_read_status): New type.
+       (analyze_access_subtree): Propagate grp_assignment_read, create
+       accesses also if both direct_read and root->grp_assignment_read.
+
 2010-04-23  Martin Jambor  <mjambor@suse.cz>
 
        PR middle-end/43835
index 55581343701926bc1d1f4e43319fd34159d78d84..9dccbadd47e35a77e8500b61dae9ef355860afa8 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-23  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/43846
+       * gcc.dg/tree-ssa/sra-10.c: New test.
+
 2010-04-23  Martin Jambor  <mjambor@suse.cz>
 
        PR middle-end/43835
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-10.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-10.c
new file mode 100644 (file)
index 0000000..10e2790
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-esra-details" } */
+
+struct S
+{
+  int a[1];
+  int z[256];
+};
+
+void foo (struct S *s, int i)
+{
+  struct S disappear;
+
+  disappear.a[i] = 12;
+  *s = disappear;
+}
+
+/* { dg-final { scan-tree-dump-times "disappear" 0 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index b31820186ab4430dc08dbec3252ae3fbfeb304c4..1bfb5c2ab1253c03cc2ee1e7f7f8a671059797bd 100644 (file)
@@ -182,6 +182,10 @@ struct access
      access tree.  */
   unsigned grp_read : 1;
 
+  /* Does this group contain a read access that comes from an assignment
+     statement?  This flag is propagated down the access tree.  */
+  unsigned grp_assignment_read : 1;
+
   /* Other passes of the analysis use this bit to make function
      analyze_access_subtree create scalar replacements for this group if
      possible.  */
@@ -1031,9 +1035,13 @@ build_accesses_from_assign (gimple *stmt_ptr,
   racc = build_access_from_expr_1 (rhs_ptr, stmt, false);
   lacc = build_access_from_expr_1 (lhs_ptr, stmt, true);
 
-  if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
-      && racc && !is_gimple_reg_type (racc->type))
-    bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+  if (racc)
+    {
+      racc->grp_assignment_read = 1;
+      if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
+         && !is_gimple_reg_type (racc->type))
+       bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+    }
 
   if (lacc && racc
       && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
@@ -1580,6 +1588,7 @@ sort_and_splice_var_accesses (tree var)
       struct access *access = VEC_index (access_p, access_vec, i);
       bool grp_write = access->write;
       bool grp_read = !access->write;
+      bool grp_assignment_read = access->grp_assignment_read;
       bool multiple_reads = false;
       bool total_scalarization = access->total_scalarization;
       bool grp_partial_lhs = access->grp_partial_lhs;
@@ -1613,6 +1622,7 @@ sort_and_splice_var_accesses (tree var)
              else
                grp_read = true;
            }
+         grp_assignment_read |= ac2->grp_assignment_read;
          grp_partial_lhs |= ac2->grp_partial_lhs;
          unscalarizable_region |= ac2->grp_unscalarizable_region;
          total_scalarization |= ac2->total_scalarization;
@@ -1631,6 +1641,7 @@ sort_and_splice_var_accesses (tree var)
       access->group_representative = access;
       access->grp_write = grp_write;
       access->grp_read = grp_read;
+      access->grp_assignment_read = grp_assignment_read;
       access->grp_hint = multiple_reads || total_scalarization;
       access->grp_partial_lhs = grp_partial_lhs;
       access->grp_unscalarizable_region = unscalarizable_region;
@@ -1765,14 +1776,17 @@ expr_with_var_bounded_array_refs_p (tree expr)
   return false;
 }
 
+enum mark_read_status { SRA_MR_NOT_READ, SRA_MR_READ, SRA_MR_ASSIGN_READ};
+
 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
-   both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set
-   all sorts of access flags appropriately along the way, notably always ser
-   grp_read when MARK_READ is true and grp_write when MARK_WRITE is true.  */
+   both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set all
+   sorts of access flags appropriately along the way, notably always set
+   grp_read and grp_assign_read according to MARK_READ and grp_write when
+   MARK_WRITE is true.  */
 
 static bool
 analyze_access_subtree (struct access *root, bool allow_replacements,
-                       bool mark_read, bool mark_write)
+                       enum mark_read_status mark_read, bool mark_write)
 {
   struct access *child;
   HOST_WIDE_INT limit = root->offset + root->size;
@@ -1781,10 +1795,17 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
   bool hole = false, sth_created = false;
   bool direct_read = root->grp_read;
 
-  if (mark_read)
-    root->grp_read = true;
+  if (mark_read == SRA_MR_ASSIGN_READ)
+    {
+      root->grp_read = 1;
+      root->grp_assignment_read = 1;
+    }
+  if (mark_read == SRA_MR_READ)
+    root->grp_read = 1;
+  else if (root->grp_assignment_read)
+    mark_read = SRA_MR_ASSIGN_READ;
   else if (root->grp_read)
-    mark_read = true;
+    mark_read = SRA_MR_READ;
 
   if (mark_write)
     root->grp_write = true;
@@ -1813,7 +1834,7 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
 
   if (allow_replacements && scalar && !root->first_child
       && (root->grp_hint
-         || (direct_read && root->grp_write))
+         || (root->grp_write && (direct_read || root->grp_assignment_read)))
       /* We must not ICE later on when trying to build an access to the
         original data within the aggregate even when it is impossible to do in
         a defined way like in the PR 42703 testcase.  Therefore we check
@@ -1858,7 +1879,7 @@ analyze_access_trees (struct access *access)
 
   while (access)
     {
-      if (analyze_access_subtree (access, true, false, false))
+      if (analyze_access_subtree (access, true, SRA_MR_NOT_READ, false))
        ret = true;
       access = access->next_grp;
     }