passes.c (remove_cgraph_node_from_order): New.
authorIlya Enkovich <ilya.enkovich@intel.com>
Tue, 18 Nov 2014 07:25:12 +0000 (07:25 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Tue, 18 Nov 2014 07:25:12 +0000 (07:25 +0000)
gcc/

* passes.c (remove_cgraph_node_from_order): New.
(do_per_function_toporder): Register cgraph removal
hook.

gcc/testsuite/

* g++.dg/pr63766.C: New.

From-SVN: r217688

gcc/ChangeLog
gcc/passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr63766.C [new file with mode: 0644]

index c7d5cbdc538c7a32c7e71f18436242b912109825..0befede06de06f564f7c189703a242f294e027f1 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-18  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       * passes.c (remove_cgraph_node_from_order): New.
+       (do_per_function_toporder): Register cgraph removal
+       hook.
+
 2014-11-17  Terry Guo  <terry.guo@arm.com>
 
        * config/arm/arm.c (arm_issue_rate): Return 2 for cortex-m7.
index c818d8ad9191650d15e304c801ccf2e23c568c10..f6f3b9dd19ff866eaa4f6109b8992f1bc6f69a8d 100644 (file)
@@ -1609,6 +1609,24 @@ do_per_function (void (*callback) (function *, void *data), void *data)
 static int nnodes;
 static GTY ((length ("nnodes"))) cgraph_node **order;
 
+/* Hook called when NODE is removed and therefore should be
+   excluded from order vector.  DATA is an array of integers.
+   DATA[0] holds max index it may be accessed by.  For cgraph
+   node DATA[node->uid + 1] holds index of this node in order
+   vector.  */
+static void
+remove_cgraph_node_from_order (cgraph_node *node, void *data)
+{
+  int *order_idx = (int *)data;
+
+  if (node->uid >= order_idx[0])
+    return;
+
+  int idx = order_idx[node->uid + 1];
+  if (idx >= 0 && idx < nnodes && order[idx] == node)
+    order[idx] = NULL;
+}
+
 /* 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 +1640,29 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
     callback (cfun, data);
   else
     {
+      cgraph_node_hook_list *hook;
+      int *order_idx;
       gcc_assert (!order);
       order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
+
+      order_idx = XALLOCAVEC (int, symtab->cgraph_max_uid + 1);
+      memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid);
+      order_idx[0] = symtab->cgraph_max_uid;
+
       nnodes = ipa_reverse_postorder (order);
       for (i = nnodes - 1; i >= 0; i--)
-        order[i]->process = 1;
+       {
+         order[i]->process = 1;
+         order_idx[order[i]->uid + 1] = i;
+       }
+      hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
+                                             order_idx);
       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 +1671,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;
index e6f11b42d527407e1f307eeb7623b20455fe0d04..c97fe881252436630a3ca56f43a234055a66b9aa 100644 (file)
@@ -1,3 +1,7 @@
+2014-11-18  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       * g++.dg/pr63766.C: New.
+
 2014-11-17  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/p8vector-ldst.c: Rewrite to use 40 live
diff --git a/gcc/testsuite/g++.dg/pr63766.C b/gcc/testsuite/g++.dg/pr63766.C
new file mode 100644 (file)
index 0000000..1414fbe
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++11 -O2" } */
+
+class A
+{
+ public:
+  void
+    getValueType ()
+  {
+  }
+  void getTypeClass ();
+};
+template <typename ImplClass> class B
+{
+ public:
+  void
+    Visit (A *p1)
+  {
+    p1->getTypeClass ();
+    static_cast<ImplClass *> (0)->VisitAtomicType (0);
+  }
+};
+class C : B<C>
+{
+  template <typename Fn>
+  void
+    dumpChild (Fn p1)
+    {
+      p1 ();
+    }
+
+ public:
+  void dumpTypeAsChild (int);
+  void
+    VisitAtomicType (A *p1)
+  {
+    p1->getValueType ();
+    dumpTypeAsChild (0);
+  }
+};
+void
+C::dumpTypeAsChild (int)
+{
+  dumpChild ([=]
+             {
+               Visit (0);
+             });
+}