aboutsummaryrefslogtreecommitdiff
path: root/gcc/passes.c
diff options
context:
space:
mode:
authorIlya Enkovich <ilya.enkovich@intel.com>2014-11-18 07:25:12 +0000
committerIlya Enkovich <ienkovich@gcc.gnu.org>2014-11-18 07:25:12 +0000
commit005581f187d790a411a6e96e8002cb56bc1ae12c (patch)
tree2becea89197e77d2686d8bdb1f690ba101490c05 /gcc/passes.c
parent92191d7b1b6b791f85039ad0b63959f53cb0afe2 (diff)
downloadgcc-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.c37
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;