https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63766

--- Comment #2 from Ilya Enkovich <enkovich.gnu at gmail dot com> ---
Problem caused by the fact that now all function come to local optimizations in
SSA form.  It affects inline parameters computation and therefore inlining
order.

During early SRA we call convert_callers_for_node which recomputes inline
parameters for functions in SSA form.  Previously it was computed only for
function already processed by all early local passes.  Now all functions are in
SSA form and it means we may recompute inline parameters for function not yet
processed by local optimizations.

In this test we have function marked as inlinable which is not yet processed in
do_per_function_toporder called for local_optimization_passes.  It allows this
function to be inlined and removed before it is actually processed (and still
sit in order vector).  Another cgraph_node created by SRA is allocated at the
same slot as removed one and thus the same function is processed twice, which
causes ICE in profiling pass.

Solution here would be to either use another condition for inline_parameters
recomputation or to handle nodes removal in do_per_function_toporder by
registering proper node removal hook.  Suppose the latter is better because
allows more early inlining.

Here is a possible fix (works for reproducer, not fully tested):

diff --git a/gcc/passes.c b/gcc/passes.c
index 5e91a79..4799efa 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1609,6 +1609,19 @@ do_per_function (void (*callback) (function *, void
*data), void *data)
 static int nnodes;
 static GTY ((length ("nnodes"))) cgraph_node **order;

+static void
+remove_cgraph_node_from_order (cgraph_node *node, void *)
+{
+  int i;
+
+  for (i = 0; i < nnodes; i++)
+    if (order[i] == node)
+      {
+       order[i] = NULL;
+       return;
+      }
+}
+
 /* 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.
@@ -1622,13 +1635,20 @@ do_per_function_toporder (void (*callback) (function *,
void *data), void *data)
     callback (cfun, data);
   else
     {
+      cgraph_node_hook_list *hook;
       gcc_assert (!order);
       order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
       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,
+                                             NULL);
       for (i = nnodes - 1; i >= 0; i--)
        {
+         /* Function could be inlined and removed as unreachable.  */
+         if (!order[i])
+           continue;
+
          struct cgraph_node *node = order[i];

          /* Allow possibly removed nodes to be garbage collected.  */
@@ -1637,6 +1657,7 @@ do_per_function_toporder (void (*callback) (function *,
void *data), void *data)
          if (node->has_gimple_body_p ())
            callback (DECL_STRUCT_FUNCTION (node->decl), data);
        }
+      symtab->remove_cgraph_removal_hook (hook);
     }
   ggc_free (order);
   order = NULL;

Reply via email to