From 632b4f8e8bf2de1177605fe274e11dc411d8be7b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 22 Apr 2011 22:04:42 +0200 Subject: gengtype.c (open_base_files): Add ipa-inline.h include. * gengtype.c (open_base_files): Add ipa-inline.h include. * ipa-cp.c (ipcp_get_lattice, ipcp_lattice_from_jfunc): Move to ipa-prop.c update all uses. * ipa-prop.c: (ipa_get_lattice, ipa_lattice_from_jfunc): ... here. * ipa-inline-transform.c (inline_call): Use inline_merge_summary to merge summary of inlined function into former caller. * ipa-inline.c (max_benefit): Remove. (edge_badness): Compensate for removal of benefits. (update_caller_keys): Use reset_node_growth_cache/reset_edge_growth_cache. (update_callee_keys): Likewise. (update_all_callee_keys): Likewise. (inline_small_functions): Do not collect max_benefit; do not reset stimated_growth; call free_growth_caches and initialize_growth_caches. * ipa-inline.h (struct condition, type clause_t, struct predicate, struct size_time_entry): New structures. (INLINE_SIZE_SCALE, INLINE_TIME_SCALE, MAX_CLAUSES): New constants. (inline_summary): Remove size_inlining_benefit, time_inlining_benefit and estimated_growth. (edge_growth_cache_entry): New structure. (node_growth_cache, edge_growth_cache): New global vars. (estimate_growth): Turn into inline. (inline_merge_summary, do_estimate_edge_growth, do_estimate_edge_time, initialize_growth_caches, free_growth_caches): Declare. (estimate_edge_growth): Rewrite. (estimate_edge_time): Implement as inline cache lookup. (reset_node_growth_cache, reset_edge_growth_cache): New inline functions. (MAX_TIME): Reduce to allow multiplicatoin by INLINE_SIZE_SCALE. (NUM_CONDITIONS): New constant. (predicate_conditions): New enum. (IS_NOT_CONSTANT): New constant. (edge_removal_hook_holder): New var. (node_growth_cache, edge_growth_cache): New global vars. (true_predicate, single_cond_predicate, false_predicate, not_inlined_predicate, add_condition, add_clause, and_predicates, or_predicates, predicates_equal_p, evaulate_predicate, dump_condition, dump_clause, dump_predicate, account_size_time, evaulate_conditions_for_edge): New functions. (inline_summary_alloc): Move to heap. (inline_node_removal_hook): Clear condition and entry vectors. (inline_edge_removal_hook): New function. (initialize_growth_caches, free_growth_caches): New function. (dump_inline_summary): Update. (edge_execution_predicate): New function. (will_be_nonconstant_predicate): New function. (estimate_function_body_sizes): Compute BB and constantness predicates. (compute_inline_parameters): Do not clear estimated_growth. (estimate_edge_size_and_time): New function. (estimate_calls_size_and_time): New function. (estimate_callee_size_and_time): New function. (remap_predicate): New function. (inline_merge_summary): New function. (do_estimate_edge_time): New function based on... (estimate_edge_time): ... this one. (do_estimate_edge_growth): New function. (do_estimate_growth): New function based on.... (estimate_growth): ... this one. (inline_analyze_function): Analyze after deciding on jump functions. (inline_read_section): New function. (inline_read_summary): Use it. (inline_write_summary): Write all the new data. * ipa-prop.c (ipa_get_param_decl_index): Export. (ipa_lattice_from_jfunc): Move here from ipa-cp.c * ipa-prop.h (ipa_get_param_decl_index, ipa_lattice_from_jfunc): Declare. (ipa_get_lattice): Move hre from ipa-cp.c * Makefile.in (GTFILES): Add ipa-inline.h and ipa-inline-analysis.c * params.def (PARAM_EARLY_INLINING_INSNS): Set to 11. * cgraph.h (cgraph_clone_inlined_nodes, compute_inline_parameters, cgraph_edge_inlinable_p): Remove. * cgraphunit.c: Include ipainline.h (cgraph_process_new_functions): Update call of compute_inline_parameters. * gcc.dg/tree-ssa/pr38699.c: Fix testcase. From-SVN: r172873 --- gcc/ipa-inline.c | 78 ++++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 42 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 48d3898..02cc773 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -117,7 +117,7 @@ along with GCC; see the file COPYING3. If not see /* Statistics we collect about inlining algorithm. */ static int overall_size; -static gcov_type max_count, max_benefit; +static gcov_type max_count; /* Return false when inlining edge E would lead to violating limits on function unit growth or stack usage growth. @@ -633,27 +633,23 @@ static int edge_badness (struct cgraph_edge *edge, bool dump) { gcov_type badness; - int growth; + int growth, time_growth; struct inline_summary *callee_info = inline_summary (edge->callee); if (DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl)) return INT_MIN; growth = estimate_edge_growth (edge); + time_growth = estimate_edge_time (edge); if (dump) { fprintf (dump_file, " Badness calculation for %s -> %s\n", cgraph_node_name (edge->caller), cgraph_node_name (edge->callee)); - fprintf (dump_file, " growth %i, time %i-%i, size %i-%i\n", + fprintf (dump_file, " growth size %i, time %i\n", growth, - callee_info->time, - callee_info->time_inlining_benefit - + edge->call_stmt_time, - callee_info->size, - callee_info->size_inlining_benefit - + edge->call_stmt_size); + time_growth); } /* Always prefer inlining saving code size. */ @@ -669,11 +665,16 @@ edge_badness (struct cgraph_edge *edge, bool dump) So we optimize for overall number of "executed" inlined calls. */ else if (max_count) { + int benefitperc; + benefitperc = (((gcov_type)callee_info->time + * edge->frequency / CGRAPH_FREQ_BASE - time_growth) * 100 + / (callee_info->time + 1) + 1); + benefitperc = MIN (benefitperc, 100); + benefitperc = MAX (benefitperc, 0); badness = ((int) - ((double) edge->count * INT_MIN / max_count / (max_benefit + 1)) * - (callee_info->time_inlining_benefit - + edge->call_stmt_time + 1)) / growth; + ((double) edge->count * INT_MIN / max_count / 100) * + benefitperc) / growth; /* Be sure that insanity of the profile won't lead to increasing counts in the scalling and thus to overflow in the computation above. */ @@ -685,9 +686,7 @@ edge_badness (struct cgraph_edge *edge, bool dump) " * Relative benefit %f\n", (int) badness, (double) badness / INT_MIN, (double) edge->count / max_count, - (double) (inline_summary (edge->callee)-> - time_inlining_benefit - + edge->call_stmt_time + 1) / (max_benefit + 1)); + (double) benefitperc); } } @@ -706,11 +705,11 @@ edge_badness (struct cgraph_edge *edge, bool dump) int benefitperc; int growth_for_all; badness = growth * 10000; - benefitperc = - 100 * (callee_info->time_inlining_benefit - + edge->call_stmt_time) - / (callee_info->time + 1) + 1; + benefitperc = (((gcov_type)callee_info->time + * edge->frequency / CGRAPH_FREQ_BASE - time_growth) * 100 + / (callee_info->time + 1) + 1); benefitperc = MIN (benefitperc, 100); + benefitperc = MAX (benefitperc, 0); div *= benefitperc; /* Decrease badness if call is nested. */ @@ -822,7 +821,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, return; if (!bitmap_set_bit (updated_nodes, node->uid)) return; - inline_summary (node)->estimated_growth = INT_MIN; + reset_node_growth_cache (node); /* See if there is something to do. */ for (edge = node->callers; edge; edge = edge->next_caller) @@ -834,6 +833,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, for (; edge; edge = edge->next_caller) if (edge->inline_failed) { + reset_edge_growth_cache (edge); if (can_inline_edge_p (edge, false) && want_inline_small_function_p (edge, false)) update_edge_key (heap, edge); @@ -857,7 +857,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node, { struct cgraph_edge *e = node->callees; - inline_summary (node)->estimated_growth = INT_MIN; + reset_node_growth_cache (node); if (!e) return; @@ -866,12 +866,13 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node, e = e->callee->callees; else { + reset_edge_growth_cache (e); if (e->inline_failed && inline_summary (e->callee)->inlinable && cgraph_function_body_availability (e->callee) >= AVAIL_AVAILABLE && !bitmap_bit_p (updated_nodes, e->callee->uid)) { - inline_summary (node)->estimated_growth = INT_MIN; + reset_node_growth_cache (node); update_edge_key (heap, e); } if (e->next_callee) @@ -899,7 +900,7 @@ update_all_callee_keys (fibheap_t heap, struct cgraph_node *node, { struct cgraph_edge *e = node->callees; - inline_summary (node)->estimated_growth = INT_MIN; + reset_node_growth_cache (node); if (!e) return; @@ -1131,7 +1132,7 @@ inline_small_functions (void) metrics. */ max_count = 0; - max_benefit = 0; + initialize_growth_caches (); for (node = cgraph_nodes; node; node = node->next) if (node->analyzed @@ -1139,20 +1140,12 @@ inline_small_functions (void) { struct inline_summary *info = inline_summary (node); - info->estimated_growth = INT_MIN; - if (!DECL_EXTERNAL (node->decl)) initial_size += info->size; for (edge = node->callers; edge; edge = edge->next_caller) - { - int benefit = (info->time_inlining_benefit - + edge->call_stmt_time); - if (max_count < edge->count) - max_count = edge->count; - if (max_benefit < benefit) - max_benefit = benefit; - } + if (max_count < edge->count) + max_count = edge->count; } overall_size = initial_size; @@ -1354,14 +1347,15 @@ inline_small_functions (void) } } + free_growth_caches (); if (new_indirect_edges) VEC_free (cgraph_edge_p, heap, new_indirect_edges); fibheap_delete (heap); if (dump_file) fprintf (dump_file, "Unit growth for small function inlining: %i->%i (%i%%)\n", - overall_size, initial_size, - overall_size * 100 / (initial_size + 1) - 100); + initial_size, overall_size, + initial_size ? overall_size * 100 / (initial_size) - 100: 0); BITMAP_FREE (updated_nodes); } @@ -1369,7 +1363,7 @@ inline_small_functions (void) at IPA inlining time. */ static void -flatten_function (struct cgraph_node *node) +flatten_function (struct cgraph_node *node, bool early) { struct cgraph_edge *e; @@ -1398,14 +1392,14 @@ flatten_function (struct cgraph_node *node) it in order to fully flatten the leaves. */ if (!e->inline_failed) { - flatten_function (e->callee); + flatten_function (e->callee, early); continue; } /* Flatten attribute needs to be processed during late inlining. For extra code quality we however do flattening during early optimization, too. */ - if (cgraph_state != CGRAPH_STATE_IPA_SSA + if (!early ? !can_inline_edge_p (e, true) : !can_early_inline_edge_p (e)) continue; @@ -1435,7 +1429,7 @@ flatten_function (struct cgraph_node *node) inline_call (e, true, NULL, NULL); if (e->callee != orig_callee) orig_callee->aux = (void *) node; - flatten_function (e->callee); + flatten_function (e->callee, early); if (e->callee != orig_callee) orig_callee->aux = NULL; } @@ -1488,7 +1482,7 @@ ipa_inline (void) if (dump_file) fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node)); - flatten_function (node); + flatten_function (node, false); } } @@ -1696,7 +1690,7 @@ early_inliner (void) if (dump_file) fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node)); - flatten_function (node); + flatten_function (node, true); inlined = true; } else -- cgit v1.1