Hi,
this patch prepares support for iterative dataflow in ipa-modref-tree.h by
making inserts to track if anyting has changed at all.

Bootstrapped/regtested x86_64-linux and also tested with the actual iterative
dataflow in modref. I plan to commit it later today unless there are comments.

Honza

gcc/ChangeLog:

2020-09-24  Jan Hubicka  <hubi...@ucw.cz>

        * ipa-modref-tree.h (modref_ref_node::insert_access): Track if something
        changed.
        (modref_base_node::insert_ref): Likewise (and add a new optional
        argument)
        (modref_tree::insert): Likewise.
        (modref_tree::merge): Likewise.

diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index caf5d348dd8..02ce7036b3f 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -88,17 +88,18 @@ struct GTY((user)) modref_ref_node
   }
 
   /* Insert access with OFFSET and SIZE.
-     Collapse tree if it has more than MAX_ACCESSES entries.  */
-  void insert_access (modref_access_node a, size_t max_accesses)
+     Collapse tree if it has more than MAX_ACCESSES entries.
+     Return true if record was changed.  */
+  bool insert_access (modref_access_node a, size_t max_accesses)
   {
     /* If this base->ref pair has no access information, bail out.  */
     if (every_access)
-      return;
+      return false;
 
     /* Otherwise, insert a node for the ref of the access under the base.  */
     modref_access_node *access_node = search (a);
     if (access_node)
-      return;
+      return false;
 
     /* If this base->ref pair has too many accesses stored, we will clear
        all accesses and bail out.  */
@@ -109,9 +110,10 @@ struct GTY((user)) modref_ref_node
          fprintf (dump_file,
                   "--param param=modref-max-accesses limit reached\n");
        collapse ();
-       return;
+       return true;
       }
     vec_safe_push (accesses, a);
+    return true;
   }
 };
 
@@ -139,8 +141,11 @@ struct GTY((user)) modref_base_node
     return NULL;
   }
 
-  /* Insert REF; collapse tree if there are more than MAX_REFS.  */
-  modref_ref_node <T> *insert_ref (T ref, size_t max_refs)
+  /* Insert REF; collapse tree if there are more than MAX_REFS.
+     Return inserted ref and if CHANGED is non-null set it to true if
+     something changed.  */
+  modref_ref_node <T> *insert_ref (T ref, size_t max_refs,
+                                  bool *changed = NULL)
   {
     modref_ref_node <T> *ref_node;
 
@@ -153,6 +158,9 @@ struct GTY((user)) modref_base_node
     if (ref_node)
       return ref_node;
 
+    if (changed)
+      *changed = true;
+
     /* Collapse the node if too full already.  */
     if (refs && refs->length () >= max_refs)
       {
@@ -204,7 +212,11 @@ struct GTY((user)) modref_tree
     max_accesses (max_accesses),
     every_base (false) {}
 
-  modref_base_node <T> *insert_base (T base)
+  /* Insert BASE; collapse tree if there are more than MAX_REFS.
+     Return inserted base and if CHANGED is non-null set it to true if
+     something changed.  */
+
+  modref_base_node <T> *insert_base (T base, bool *changed = NULL)
   {
     modref_base_node <T> *base_node;
 
@@ -217,6 +229,9 @@ struct GTY((user)) modref_tree
     if (base_node)
       return base_node;
 
+    if (changed)
+      *changed = true;
+
     /* Collapse the node if too full already.  */
     if (bases && bases->length () >= max_bases)
       {
@@ -232,43 +247,60 @@ struct GTY((user)) modref_tree
     return base_node;
   }
 
-  /* Insert memory access to the tree. */
-  void insert (T base, T ref, modref_access_node a)
+  /* Insert memory access to the tree.
+     Return true if something changed.  */
+  bool insert (T base, T ref, modref_access_node a)
   {
+    if (every_base)
+      return false;
+
+    bool changed = false;
+
     /* No useful information tracked; collapse everything.  */
     if (!base && !ref && !a.useful_p ())
       {
        collapse ();
-       return;
+       return true;
       }
 
-    modref_base_node <T> *base_node = insert_base (base);
+    modref_base_node <T> *base_node = insert_base (base, &changed);
     if (!base_node)
-      return;
+      return changed;
     gcc_assert (search (base) != NULL);
 
-    modref_ref_node <T> *ref_node = base_node->insert_ref (ref, max_refs);
+    modref_ref_node <T> *ref_node = base_node->insert_ref (ref, max_refs,
+                                                          &changed);
 
     /* No useful ref information and no useful base; collapse everyting.  */
     if (!base && base_node->every_ref)
       {
        collapse ();
-       return;
+       return true;
       }
     if (ref_node)
       {
        /* No useful ref and access; collapse ref.  */
        if (!ref && !a.useful_p ())
-         ref_node->collapse ();
+         {
+           if (!ref_node->every_access)
+             {
+               ref_node->collapse ();
+               changed = true;
+             }
+         }
        else
          {
-           ref_node->insert_access (a, max_accesses);
+           changed |= ref_node->insert_access (a, max_accesses);
            /* If ref has collapses and there is no useful base; collapse
               everything.  */
            if (!base && !ref && ref_node->every_access)
-             collapse ();
+             {
+               changed = true;
+               collapse ();
+             }
          }
       }
+    return changed;
   }
 
  /* Remove tree branches that are not useful (i.e. they will allways pass).  */
@@ -317,25 +349,31 @@ struct GTY((user)) modref_tree
 
   /* Merge OTHER into the tree.
      PARM_MAP, if non-NULL, maps parm indexes of callee to caller.  -2 is used
-     to signalize that parameter is local and does not need to be tracked.  */
-  void merge (modref_tree <T> *other, vec <int> *parm_map)
+     to signalize that parameter is local and does not need to be tracked.
+     Return true if something has changed.  */
+  bool merge (modref_tree <T> *other, vec <int> *parm_map)
   {
-    if (!other)
-      return;
+    if (!other || every_base)
+      return false;
     if (other->every_base)
       {
-       collapse ();
-       return;
+       if (!every_base)
+         {
+           collapse ();
+           return true;
+         }
+       return false;
       }
 
     size_t i, j, k;
+    bool changed = false;
     modref_base_node <T> *base_node, *my_base_node;
     modref_ref_node <T> *ref_node, *my_ref_node;
     modref_access_node *access_node;
     FOR_EACH_VEC_SAFE_ELT (other->bases, i, base_node)
       {
-       my_base_node = insert_base (base_node->base);
-       if (!my_base_node)
+       my_base_node = insert_base (base_node->base, &changed);
+       if (!my_base_node || my_base_node->every_ref)
          continue;
 
        if (base_node->every_ref)
@@ -346,13 +384,15 @@ struct GTY((user)) modref_tree
 
        FOR_EACH_VEC_SAFE_ELT (base_node->refs, j, ref_node)
          {
-           my_ref_node = my_base_node->insert_ref (ref_node->ref, max_refs);
-           if (!my_ref_node)
+           my_ref_node = my_base_node->insert_ref (ref_node->ref, max_refs,
+                                                   &changed);
+           if (!my_ref_node || my_ref_node->every_access)
              continue;
 
            if (ref_node->every_access)
              {
                my_ref_node->collapse ();
+               changed = true;
                continue;
              }
            FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
@@ -367,12 +407,13 @@ struct GTY((user)) modref_tree
                    else
                      a.parm_index = (*parm_map) [a.parm_index];
                  }
-               my_ref_node->insert_access (a, max_accesses);
+               changed |= my_ref_node->insert_access (a, max_accesses);
              }
          }
       }
-    if (parm_map)
+    if (parm_map && changed)
       cleanup ();
+    return changed;
   }
 
   /* Copy OTHER to THIS.  */

Reply via email to