SRA: Add verification of accesses
authorMartin Jambor <mjambor@suse.cz>
Wed, 29 Jan 2020 12:13:12 +0000 (13:13 +0100)
committerMartin Jambor <mjambor@suse.cz>
Wed, 29 Jan 2020 12:13:12 +0000 (13:13 +0100)
2020-01-29  Martin Jambor  <mjambor@suse.cz>

* tree-sra.c (verify_sra_access_forest): New function.
(verify_all_sra_access_forests): Likewise.
(create_artificial_child_access): Set parent.
(analyze_all_variable_accesses): Call the verifier.

gcc/ChangeLog
gcc/tree-sra.c

index 504486cb444cca4269842eb5f22a74758b753cff..16247a59304acd39c46f40bf4c460f168b4eafb3 100644 (file)
@@ -1,3 +1,10 @@
+2020-01-29  Martin Jambor  <mjambor@suse.cz>
+
+       * tree-sra.c (verify_sra_access_forest): New function.
+       (verify_all_sra_access_forests): Likewise.
+       (create_artificial_child_access): Set parent.
+       (analyze_all_variable_accesses): Call the verifier.
+
 2020-01-28  Jan Hubicka  <hubicka@ucw.cz>
 
        * cgraph.c (cgraph_edge::resolve_speculation): Only lookup direct edge
index 875d5b21763503b40bb42d5b0adae267d228931a..36106fecaf181c7b9e2abfce6b6b9decaabbafb3 100644 (file)
@@ -2321,6 +2321,88 @@ build_access_trees (struct access *access)
   return true;
 }
 
+/* Traverse the access forest where ROOT is the first root and verify that
+   various important invariants hold true.  */
+
+DEBUG_FUNCTION void
+verify_sra_access_forest (struct access *root)
+{
+  struct access *access = root;
+  tree first_base = root->base;
+  gcc_assert (DECL_P (first_base));
+  do
+    {
+      gcc_assert (access->base == first_base);
+      if (access->parent)
+       gcc_assert (access->offset >= access->parent->offset
+                   && access->size <= access->parent->size);
+      if (access->next_sibling)
+       gcc_assert (access->next_sibling->offset
+                   >= access->offset + access->size);
+
+      poly_int64 poffset, psize, pmax_size;
+      bool reverse;
+      tree base = get_ref_base_and_extent (access->expr, &poffset, &psize,
+                                          &pmax_size, &reverse);
+      HOST_WIDE_INT offset, size, max_size;
+      if (!poffset.is_constant (&offset)
+         || !psize.is_constant (&size)
+         || !pmax_size.is_constant (&max_size))
+       gcc_unreachable ();
+      gcc_assert (base == first_base);
+      gcc_assert (offset == access->offset);
+      gcc_assert (access->grp_unscalarizable_region
+                 || size == max_size);
+      gcc_assert (max_size == access->size);
+      gcc_assert (reverse == access->reverse);
+
+      if (access->first_child)
+       {
+         gcc_assert (access->first_child->parent == access);
+         access = access->first_child;
+       }
+      else if (access->next_sibling)
+       {
+         gcc_assert (access->next_sibling->parent == access->parent);
+         access = access->next_sibling;
+       }
+      else
+       {
+         while (access->parent && !access->next_sibling)
+           access = access->parent;
+         if (access->next_sibling)
+           access = access->next_sibling;
+         else
+           {
+             gcc_assert (access == root);
+             root = root->next_grp;
+             access = root;
+           }
+       }
+    }
+  while (access);
+}
+
+/* Verify access forests of all candidates with accesses by calling
+   verify_access_forest on each on them.  */
+
+DEBUG_FUNCTION void
+verify_all_sra_access_forests (void)
+{
+  bitmap_iterator bi;
+  unsigned i;
+  EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
+    {
+      tree var = candidate (i);
+      struct access *access = get_first_repr_for_decl (var);
+      if (access)
+       {
+         gcc_assert (access->base == var);
+         verify_sra_access_forest (access);
+       }
+    }
+}
+
 /* Return true if expr contains some ARRAY_REFs into a variable bounded
    array.  */
 
@@ -2566,6 +2648,7 @@ create_artificial_child_access (struct access *parent, struct access *model,
   access->offset = new_offset;
   access->size = model->size;
   access->type = model->type;
+  access->parent = parent;
   access->grp_write = set_grp_write;
   access->grp_read = false;
   access->reverse = model->reverse;
@@ -2850,6 +2933,9 @@ analyze_all_variable_accesses (void)
 
   propagate_all_subaccesses ();
 
+  if (flag_checking)
+    verify_all_sra_access_forests ();
+
   bitmap_copy (tmp, candidate_bitmap);
   EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
     {