diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1312ceb17fad11dea1df716155ef708a43a790bf..7813bdacd982d3ef764002fcc01ab897837de706 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-08-23 Jan Hubicka <jh@suse.cz> + + * ipa-cp.c (ipcp_analyze_node): New function. + (ipcp_update_cloned_node): Use it. + (ipcp_init_stage): Likewise. + * ipa-inline.c (function_insertion_hook_holder): New static var. + (analyze_function): Break out from .... + (inline_generate_summary): Here; register insertion hook. + (cgraph_decide_inlining): Remove hook. + (add_new_function): New function. + 2008-08-23 Jan Hubicka <jh@suse.cz> * opts.c (decode_options): Revert accidental change enabling ipa-cp. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 78a24bcb71750e9789357186f7f170ebdc9e4061..ad43298ae4e99fcde8b98d693b279ef4dfe796cd 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -159,6 +159,18 @@ ipcp_init_cloned_node (struct cgraph_node *orig_node, ipa_create_param_decls_array (new_node); } +/* Perform intraprocedrual analysis needed for ipcp. */ +static void +ipcp_analyze_node (struct cgraph_node *node) +{ + /* Unreachable nodes should have been eliminated before ipcp. */ + gcc_assert (node->needed || node->reachable); + + ipa_count_formal_params (node); + ipa_create_param_decls_array (node); + ipa_detect_param_modifications (node); +} + /* Recompute all local information since node might've got new direct calls after clonning. */ static void @@ -169,15 +181,13 @@ ipcp_update_cloned_node (struct cgraph_node *new_node) current_function_decl = new_node->decl; rebuild_cgraph_edges (); + /* Indirect inlinng rely on fact that we've already analyzed + the body.. */ if (flag_indirect_inlining) { struct cgraph_edge *cs; - ipa_check_create_node_params (); - ipa_count_formal_params (new_node); - ipa_create_param_decls_array (new_node); - ipa_detect_param_modifications (new_node); - ipa_analyze_params_uses (new_node); + ipcp_analyze_node (new_node); for (cs = new_node->callees; cs; cs = cs->next_callee) { @@ -418,18 +428,12 @@ ipcp_init_stage (void) struct cgraph_edge *cs; for (node = cgraph_nodes; node; node = node->next) - { - if (!node->analyzed) - continue; - /* Unreachable nodes should have been eliminated before ipcp. */ - gcc_assert (node->needed || node->reachable); - - ipa_count_formal_params (node); - ipa_create_param_decls_array (node); - ipcp_initialize_node_lattices (node); - ipa_detect_param_modifications (node); - ipcp_compute_node_scale (node); - } + if (node->analyzed) + { + ipcp_analyze_node (node); + ipcp_initialize_node_lattices (node); + ipcp_compute_node_scale (node); + } for (node = cgraph_nodes; node; node = node->next) { if (!node->analyzed) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d5f280fd8cb071ac59a8b4412e590618332038ec..3f44d2fca522c1e9ff15926a8857ace9be3af42c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -166,6 +166,9 @@ static int nfunctions_inlined; static int overall_insns; static gcov_type max_count; +/* Holders of ipa cgraph hooks: */ +static struct cgraph_node_hook_list *function_insertion_hook_holder; + static inline struct inline_summary * inline_summary (struct cgraph_node *node) { @@ -1073,6 +1076,8 @@ cgraph_decide_inlining (void) int i; int initial_insns = 0; + cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + max_count = 0; for (node = cgraph_nodes; node; node = node->next) if (node->analyzed && (node->needed || node->reachable)) @@ -1655,14 +1660,36 @@ inline_indirect_intraprocedural_analysis (struct cgraph_node *node) ipa_print_node_jump_functions (dump_file, node); } +/* Note function body size. */ +static void +analyze_function (struct cgraph_node *node) +{ + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); + current_function_decl = node->decl; + + compute_inline_parameters (node); + if (flag_indirect_inlining) + inline_indirect_intraprocedural_analysis (node); + + current_function_decl = NULL; + pop_cfun (); +} + +/* Called when new function is inserted to callgraph late. */ +static void +add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + analyze_function (node); +} + /* Note function body size. */ static void inline_generate_summary (void) { - struct cgraph_node **order = - XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); - int nnodes = cgraph_postorder (order); - int i; + struct cgraph_node *node; + + function_insertion_hook_holder = + cgraph_add_function_insertion_hook (&add_new_function, NULL); if (flag_indirect_inlining) { @@ -1671,27 +1698,10 @@ inline_generate_summary (void) ipa_check_create_edge_args (); } - for (i = nnodes - 1; i >= 0; i--) - { - struct cgraph_node *node = order[i]; - - /* Allow possibly removed nodes to be garbage collected. */ - order[i] = NULL; - if (node->analyzed && (node->needed || node->reachable)) - { - push_cfun (DECL_STRUCT_FUNCTION (node->decl)); - current_function_decl = node->decl; - compute_inline_parameters (node); - - if (flag_indirect_inlining) - inline_indirect_intraprocedural_analysis (node); - - pop_cfun (); - } - } + for (node = cgraph_nodes; node; node = node->next) + if (node->analyzed) + analyze_function (node); - current_function_decl = NULL; - free (order); return; }