Properly register dead cgraph_nodes in passes.c.
authorMartin Liska <mliska@suse.cz>
Thu, 15 Aug 2019 06:58:09 +0000 (08:58 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Thu, 15 Aug 2019 06:58:09 +0000 (06:58 +0000)
2019-08-15  Martin Liska  <mliska@suse.cz>

PR ipa/91404
* passes.c (order): Remove.
(uid_hash_t): Likewise).
(remove_cgraph_node_from_order): Remove from set
of pointers (cgraph_node *).
(insert_cgraph_node_to_order): New.
(duplicate_cgraph_node_to_order): New.
(do_per_function_toporder): Register all 3 cgraph hooks.
Skip removed_nodes now as we know about all of them.

From-SVN: r274502

gcc/ChangeLog
gcc/passes.c

index 8e98678..27e09f2 100644 (file)
@@ -1,3 +1,15 @@
+2019-08-15  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/91404
+       * passes.c (order): Remove.
+       (uid_hash_t): Likewise).
+       (remove_cgraph_node_from_order): Remove from set
+       of pointers (cgraph_node *).
+       (insert_cgraph_node_to_order): New.
+       (duplicate_cgraph_node_to_order): New.
+       (do_per_function_toporder): Register all 3 cgraph hooks.
+       Skip removed_nodes now as we know about all of them.
+
 2019-08-14  Uroš Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386-expand.c (ix86_expand_vector_init_one_nonzero)
index bd56004..f715c67 100644 (file)
@@ -1646,24 +1646,39 @@ do_per_function (void (*callback) (function *, void *data), void *data)
     }
 }
 
-/* Because inlining might remove no-longer reachable nodes, we need to
-   keep the array visible to garbage collector to avoid reading collected
-   out nodes.  */
-static int nnodes;
-static GTY ((length ("nnodes"))) cgraph_node **order;
-
-#define uid_hash_t hash_set<int_hash <int, 0, -1> >
-
 /* Hook called when NODE is removed and therefore should be
    excluded from order vector.  DATA is a hash set with removed nodes.  */
 
 static void
 remove_cgraph_node_from_order (cgraph_node *node, void *data)
 {
-  uid_hash_t *removed_nodes = (uid_hash_t *)data;
-  removed_nodes->add (node->get_uid ());
+  hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+  removed_nodes->add (node);
+}
+
+/* Hook called when NODE is insert and therefore should be
+   excluded from removed_nodes.  DATA is a hash set with removed nodes.  */
+
+static void
+insert_cgraph_node_to_order (cgraph_node *node, void *data)
+{
+  hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+  removed_nodes->remove (node);
 }
 
+/* Hook called when NODE is duplicated and therefore should be
+   excluded from removed_nodes.  DATA is a hash set with removed nodes.  */
+
+static void
+duplicate_cgraph_node_to_order (cgraph_node *node, cgraph_node *node2,
+                               void *data)
+{
+  hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+  gcc_checking_assert (!removed_nodes->contains (node));
+  removed_nodes->remove (node2);
+}
+
+
 /* If we are in IPA mode (i.e., current_function_decl is NULL), call
    function CALLBACK for every function in the call graph.  Otherwise,
    call CALLBACK on the current function.
@@ -1677,26 +1692,30 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
     callback (cfun, data);
   else
     {
-      cgraph_node_hook_list *hook;
-      uid_hash_t removed_nodes;
-      gcc_assert (!order);
-      order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
+      hash_set<cgraph_node *> removed_nodes;
+      unsigned nnodes = symtab->cgraph_count;
+      cgraph_node **order = XNEWVEC (cgraph_node *, nnodes);
 
       nnodes = ipa_reverse_postorder (order);
       for (i = nnodes - 1; i >= 0; i--)
        order[i]->process = 1;
-      hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
-                                             &removed_nodes);
+      cgraph_node_hook_list *removal_hook
+       = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
+                                          &removed_nodes);
+      cgraph_node_hook_list *insertion_hook
+       = symtab->add_cgraph_insertion_hook (insert_cgraph_node_to_order,
+                                            &removed_nodes);
+      cgraph_2node_hook_list *duplication_hook
+       = symtab->add_cgraph_duplication_hook (duplicate_cgraph_node_to_order,
+                                              &removed_nodes);
       for (i = nnodes - 1; i >= 0; i--)
        {
          cgraph_node *node = order[i];
 
          /* Function could be inlined and removed as unreachable.  */
-         if (node == NULL || removed_nodes.contains (node->get_uid ()))
+         if (node == NULL || removed_nodes.contains (node))
            continue;
 
-         /* Allow possibly removed nodes to be garbage collected.  */
-         order[i] = NULL;
          node->process = 0;
          if (node->has_gimple_body_p ())
            {
@@ -1706,11 +1725,12 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
              pop_cfun ();
            }
        }
-      symtab->remove_cgraph_removal_hook (hook);
+      symtab->remove_cgraph_removal_hook (removal_hook);
+      symtab->remove_cgraph_insertion_hook (insertion_hook);
+      symtab->remove_cgraph_duplication_hook (duplication_hook);
+
+      free (order);
     }
-  ggc_free (order);
-  order = NULL;
-  nnodes = 0;
 }
 
 /* Helper function to perform function body dump.  */
@@ -3046,5 +3066,3 @@ function_called_by_processed_nodes_p (void)
     }
   return e != NULL;
 }
-
-#include "gt-passes.h"