From 005581f187d790a411a6e96e8002cb56bc1ae12c Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Tue, 18 Nov 2014 07:25:12 +0000 Subject: [PATCH] passes.c (remove_cgraph_node_from_order): New. 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 | 6 +++++ gcc/passes.c | 37 +++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/pr63766.C | 48 ++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/pr63766.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7d5cbdc538..0befede06de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-11-18 Ilya Enkovich + + * passes.c (remove_cgraph_node_from_order): New. + (do_per_function_toporder): Register cgraph removal + hook. + 2014-11-17 Terry Guo * config/arm/arm.c (arm_issue_rate): Return 2 for cortex-m7. diff --git a/gcc/passes.c b/gcc/passes.c index c818d8ad919..f6f3b9dd19f 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -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 (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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e6f11b42d52..c97fe881252 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-11-18 Ilya Enkovich + + * g++.dg/pr63766.C: New. + 2014-11-17 Michael Meissner * 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 index 00000000000..1414fbe52b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr63766.C @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11 -O2" } */ + +class A +{ + public: + void + getValueType () + { + } + void getTypeClass (); +}; +template class B +{ + public: + void + Visit (A *p1) + { + p1->getTypeClass (); + static_cast (0)->VisitAtomicType (0); + } +}; +class C : B +{ + template + void + dumpChild (Fn p1) + { + p1 (); + } + + public: + void dumpTypeAsChild (int); + void + VisitAtomicType (A *p1) + { + p1->getValueType (); + dumpTypeAsChild (0); + } +}; +void +C::dumpTypeAsChild (int) +{ + dumpChild ([=] + { + Visit (0); + }); +} -- 2.30.2