diff options
author | Ilya Enkovich <ilya.enkovich@intel.com> | 2014-11-18 07:25:12 +0000 |
---|---|---|
committer | Ilya Enkovich <ienkovich@gcc.gnu.org> | 2014-11-18 07:25:12 +0000 |
commit | 005581f187d790a411a6e96e8002cb56bc1ae12c (patch) | |
tree | 2becea89197e77d2686d8bdb1f690ba101490c05 /gcc/passes.c | |
parent | 92191d7b1b6b791f85039ad0b63959f53cb0afe2 (diff) | |
download | gcc-005581f187d790a411a6e96e8002cb56bc1ae12c.zip gcc-005581f187d790a411a6e96e8002cb56bc1ae12c.tar.gz gcc-005581f187d790a411a6e96e8002cb56bc1ae12c.tar.bz2 |
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
Diffstat (limited to 'gcc/passes.c')
-rw-r--r-- | gcc/passes.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/passes.c b/gcc/passes.c index c818d8a..f6f3b9d 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<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; |