tree-sra.c (struct access): Rename total_scalarization to grp_total_scalarization
authorMartin Jambor <mjambor@suse.cz>
Thu, 30 Jun 2011 21:54:29 +0000 (23:54 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Thu, 30 Jun 2011 21:54:29 +0000 (23:54 +0200)
2011-06-30  Martin Jambor  <mjambor@suse.cz>

* tree-sra.c (struct access): Rename total_scalarization to
grp_total_scalarization
(completely_scalarize_var): New function.
(sort_and_splice_var_accesses): Set total_scalarization in the
representative access.
(analyze_access_subtree): Propagate total scalarization accross the
tree, no holes in totally scalarized trees, simplify coverage
computation.
(analyze_all_variable_accesses): Call completely_scalarize_var instead
of completely_scalarize_record.

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

From-SVN: r175733

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

index 3a1b56ae3408a92a0f819387868ffb4749a9bb6a..8fc1cd55b8e5e5d8c31210edbbd048c4491f7e9f 100644 (file)
@@ -1,3 +1,16 @@
+2011-06-30  Martin Jambor  <mjambor@suse.cz>
+
+       * tree-sra.c (struct access): Rename total_scalarization to
+       grp_total_scalarization
+       (completely_scalarize_var): New function.
+       (sort_and_splice_var_accesses): Set total_scalarization in the
+       representative access.
+       (analyze_access_subtree): Propagate total scalarization accross the
+       tree, no holes in totally scalarized trees, simplify coverage
+       computation.
+       (analyze_all_variable_accesses): Call completely_scalarize_var instead
+       of completely_scalarize_record.
+
 2011-06-30  Richard Henderson  <rth@redhat.com>
 
        * config/i386/i386.h (X86_TUNE_DEEP_BRANCH_PREDICTION): Remove.
index cbcdf77e5532ce19f7c8ffb0c61d1271c3b61b74..66e980ac7e469a748311807b6f5e0b18c4d3e726 100644 (file)
@@ -1,3 +1,7 @@
+2011-06-30  Martin Jambor  <mjambor@suse.cz>
+
+       * gcc.dg/tree-ssa/sra-12.c: New test.
+
 2011-06-29  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/named.C: Test subobject of xvalue.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-12.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-12.c
new file mode 100644 (file)
index 0000000..988caec
--- /dev/null
@@ -0,0 +1,25 @@
+/* Verify that SRA total scalarization will not be confused by padding.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-release_ssa" } */
+
+struct S
+{
+  int i;
+  unsigned short f1;
+  char f2;
+  unsigned short f3, f4;
+};
+
+
+int foo (struct S *p)
+{
+  struct S l;
+
+  l = *p;
+  l.i++;
+  *p = l;
+}
+
+/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa"} } */
+/* { dg-final { cleanup-tree-dump "release_ssa" } } */
index e45ff8a027268c41f1f9cc5216da06fcf30ef82e..d244766b0e2d742663206eb771081f3e903e3735 100644 (file)
@@ -170,10 +170,6 @@ struct access
   /* Is this particular access write access? */
   unsigned write : 1;
 
-  /* Is this access an artificial one created to scalarize some record
-     entirely? */
-  unsigned total_scalarization : 1;
-
   /* Is this access an access to a non-addressable field? */
   unsigned non_addressable : 1;
 
@@ -204,6 +200,10 @@ struct access
      is not propagated in the access tree in any direction.  */
   unsigned grp_scalar_write : 1;
 
+  /* Is this access an artificial one created to scalarize some record
+     entirely? */
+  unsigned grp_total_scalarization : 1;
+
   /* Other passes of the analysis use this bit to make function
      analyze_access_subtree create scalar replacements for this group if
      possible.  */
@@ -377,26 +377,26 @@ dump_access (FILE *f, struct access *access, bool grp)
   fprintf (f, ", type = ");
   print_generic_expr (f, access->type, 0);
   if (grp)
-    fprintf (f, ", total_scalarization = %d, grp_read = %d, grp_write = %d, "
-            "grp_assignment_read = %d, grp_assignment_write = %d, "
-            "grp_scalar_read = %d, grp_scalar_write = %d, "
+    fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
+            "grp_assignment_write = %d, grp_scalar_read = %d, "
+            "grp_scalar_write = %d, grp_total_scalarization = %d, "
             "grp_hint = %d, grp_covered = %d, "
             "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
             "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
             "grp_maybe_modified = %d, "
             "grp_not_necessarilly_dereferenced = %d\n",
-            access->total_scalarization, access->grp_read, access->grp_write,
-            access->grp_assignment_read, access->grp_assignment_write,
-            access->grp_scalar_read, access->grp_scalar_write,
+            access->grp_read, access->grp_write, access->grp_assignment_read,
+            access->grp_assignment_write, access->grp_scalar_read,
+            access->grp_scalar_write, access->grp_total_scalarization,
             access->grp_hint, access->grp_covered,
             access->grp_unscalarizable_region, access->grp_unscalarized_data,
             access->grp_partial_lhs, access->grp_to_be_replaced,
             access->grp_maybe_modified,
             access->grp_not_necessarilly_dereferenced);
   else
-    fprintf (f, ", write = %d, total_scalarization = %d, "
+    fprintf (f, ", write = %d, grp_total_scalarization = %d, "
             "grp_partial_lhs = %d\n",
-            access->write, access->total_scalarization,
+            access->write, access->grp_total_scalarization,
             access->grp_partial_lhs);
 }
 
@@ -924,7 +924,7 @@ completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
            access = create_access_1 (base, pos, size);
            access->expr = nref;
            access->type = ft;
-           access->total_scalarization = 1;
+           access->grp_total_scalarization = 1;
            /* Accesses for intraprocedural SRA can have their stmt NULL.  */
          }
        else
@@ -932,6 +932,23 @@ completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
       }
 }
 
+/* Create total_scalarization accesses for all scalar type fields in VAR and
+   for VAR a a whole.  VAR must be of a RECORD_TYPE conforming to
+   type_consists_of_records_p.   */
+
+static void
+completely_scalarize_var (tree var)
+{
+  HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (var), 1);
+  struct access *access;
+
+  access = create_access_1 (var, 0, size);
+  access->expr = var;
+  access->type = TREE_TYPE (var);
+  access->grp_total_scalarization = 1;
+
+  completely_scalarize_record (var, var, 0, var);
+}
 
 /* Search the given tree for a declaration by skipping handled components and
    exclude it from the candidates.  */
@@ -1714,7 +1731,7 @@ sort_and_splice_var_accesses (tree var)
       bool grp_assignment_read = access->grp_assignment_read;
       bool grp_assignment_write = access->grp_assignment_write;
       bool multiple_scalar_reads = false;
-      bool total_scalarization = access->total_scalarization;
+      bool total_scalarization = access->grp_total_scalarization;
       bool grp_partial_lhs = access->grp_partial_lhs;
       bool first_scalar = is_gimple_reg_type (access->type);
       bool unscalarizable_region = access->grp_unscalarizable_region;
@@ -1758,7 +1775,7 @@ sort_and_splice_var_accesses (tree var)
          grp_assignment_write |= ac2->grp_assignment_write;
          grp_partial_lhs |= ac2->grp_partial_lhs;
          unscalarizable_region |= ac2->grp_unscalarizable_region;
-         total_scalarization |= ac2->total_scalarization;
+         total_scalarization |= ac2->grp_total_scalarization;
          relink_to_new_repr (access, ac2);
 
          /* If there are both aggregate-type and scalar-type accesses with
@@ -1779,6 +1796,7 @@ sort_and_splice_var_accesses (tree var)
       access->grp_assignment_read = grp_assignment_read;
       access->grp_assignment_write = grp_assignment_write;
       access->grp_hint = multiple_scalar_reads || total_scalarization;
+      access->grp_total_scalarization = total_scalarization;
       access->grp_partial_lhs = grp_partial_lhs;
       access->grp_unscalarizable_region = unscalarizable_region;
       if (access->first_link)
@@ -2024,6 +2042,8 @@ analyze_access_subtree (struct access *root, struct access *parent,
        root->grp_write = 1;
       if (parent->grp_assignment_write)
        root->grp_assignment_write = 1;
+      if (parent->grp_total_scalarization)
+       root->grp_total_scalarization = 1;
     }
 
   if (root->grp_unscalarizable_region)
@@ -2034,16 +2054,16 @@ analyze_access_subtree (struct access *root, struct access *parent,
 
   for (child = root->first_child; child; child = child->next_sibling)
     {
-      if (!hole && child->offset < covered_to)
-       hole = true;
-      else
-       covered_to += child->size;
-
+      hole |= covered_to < child->offset;
       sth_created |= analyze_access_subtree (child, root,
                                             allow_replacements && !scalar);
 
       root->grp_unscalarized_data |= child->grp_unscalarized_data;
-      hole |= !child->grp_covered;
+      root->grp_total_scalarization &= child->grp_total_scalarization;
+      if (child->grp_covered)
+       covered_to += child->size;
+      else
+       hole = true;
     }
 
   if (allow_replacements && scalar && !root->first_child
@@ -2064,10 +2084,16 @@ analyze_access_subtree (struct access *root, struct access *parent,
       sth_created = true;
       hole = false;
     }
-  else if (covered_to < limit)
-    hole = true;
+  else
+    {
+      if (covered_to < limit)
+       hole = true;
+      if (scalar)
+       root->grp_total_scalarization = 0;
+    }
 
-  if (sth_created && !hole)
+  if (sth_created
+      && (!hole || root->grp_total_scalarization))
     {
       root->grp_covered = 1;
       return true;
@@ -2289,7 +2315,7 @@ analyze_all_variable_accesses (void)
                <= max_total_scalarization_size)
            && type_consists_of_records_p (TREE_TYPE (var)))
          {
-           completely_scalarize_record (var, var, 0, var);
+           completely_scalarize_var (var);
            if (dump_file && (dump_flags & TDF_DETAILS))
              {
                fprintf (dump_file, "Will attempt to totally scalarize ");