diff options
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 9db7f1c..595cb68 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -649,6 +649,16 @@ dump_inline_hints (FILE *f, inline_hints hints) hints &= ~INLINE_HINT_in_scc; fprintf (f, " in_scc"); } + if (hints & INLINE_HINT_cross_module) + { + hints &= ~INLINE_HINT_cross_module; + fprintf (f, " cross_module"); + } + if (hints & INLINE_HINT_declared_inline) + { + hints &= ~INLINE_HINT_declared_inline; + fprintf (f, " declared_inline"); + } gcc_assert (!hints); } @@ -983,6 +993,7 @@ reset_inline_summary (struct cgraph_node *node) info->stack_frame_offset = 0; info->size = 0; info->time = 0; + info->growth = 0; info->scc_no = 0; if (info->loop_iterations) { @@ -1375,6 +1386,9 @@ dump_inline_summary (FILE * f, struct cgraph_node *node) (int) s->estimated_self_stack_size); fprintf (f, " global stack: %i\n", (int) s->estimated_stack_size); + if (s->growth) + fprintf (f, " estimated growth:%i\n", + (int) s->growth); if (s->scc_no) fprintf (f, " In SCC: %i\n", (int) s->scc_no); @@ -1977,10 +1991,11 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, return p; /* Stores will stay anyway. */ - if (gimple_vdef (stmt)) + if (gimple_store_p (stmt)) return p; - is_load = gimple_vuse (stmt) != NULL; + is_load = gimple_assign_load_p (stmt); + /* Loads can be optimized when the value is known. */ if (is_load) { @@ -2857,6 +2872,8 @@ estimate_node_size_and_time (struct cgraph_node *node, hints |=INLINE_HINT_loop_stride; if (info->scc_no) hints |= INLINE_HINT_in_scc; + if (DECL_DECLARED_INLINE_P (node->symbol.decl)) + hints |= INLINE_HINT_declared_inline; estimate_calls_size_and_time (node, &size, &time, &hints, possible_truths, known_vals, known_binfos, known_aggs); @@ -2865,7 +2882,6 @@ estimate_node_size_and_time (struct cgraph_node *node, time = RDIV (time, INLINE_TIME_SCALE); size = RDIV (size, INLINE_SIZE_SCALE); - if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\n size:%i time:%i\n", (int)size, (int)time); @@ -3315,6 +3331,26 @@ inline_update_overall_summary (struct cgraph_node *node) info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE; } +/* Return hints derrived from EDGE. */ +int +simple_edge_hints (struct cgraph_edge *edge) +{ + int hints = 0; + struct cgraph_node *to = (edge->caller->global.inlined_to + ? edge->caller->global.inlined_to + : edge->caller); + if (inline_summary (to)->scc_no + && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no + && !cgraph_edge_recursive_p (edge)) + hints |= INLINE_HINT_same_scc; + + if (to->symbol.lto_file_data && edge->callee->symbol.lto_file_data + && to->symbol.lto_file_data != edge->callee->symbol.lto_file_data) + hints |= INLINE_HINT_cross_module; + + return hints; +} + /* Estimate the time cost for the caller when inlining EDGE. Only to be called via estimate_edge_time, that handles the caching mechanism. @@ -3328,7 +3364,6 @@ do_estimate_edge_time (struct cgraph_edge *edge) int time; int size; inline_hints hints; - gcov_type ret; struct cgraph_node *callee; clause_t clause; VEC (tree, heap) *known_vals; @@ -3347,33 +3382,26 @@ do_estimate_edge_time (struct cgraph_edge *edge) VEC_free (tree, heap, known_vals); VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); - - ret = RDIV ((gcov_type)time * edge->frequency, - CGRAPH_FREQ_BASE); + gcc_checking_assert (size >= 0); + gcc_checking_assert (time >= 0); /* When caching, update the cache entry. */ if (edge_growth_cache) { - struct cgraph_node *to = (edge->caller->global.inlined_to - ? edge->caller->global.inlined_to - : edge->caller); if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid) VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache, cgraph_edge_max_uid); VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).time - = ret + (ret >= 0); + = time + (time >= 0); VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size = size + (size >= 0); - if (inline_summary (to)->scc_no - && inline_summary (to)->scc_no == inline_summary (callee)->scc_no - && !cgraph_edge_recursive_p (edge)) - hints |= INLINE_HINT_same_scc; + hints |= simple_edge_hints (edge); VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints = hints + 1; } - return ret; + return time; } @@ -3430,9 +3458,6 @@ do_estimate_edge_hints (struct cgraph_edge *edge) VEC (tree, heap) *known_vals; VEC (tree, heap) *known_binfos; VEC (ipa_agg_jump_function_p, heap) *known_aggs; - struct cgraph_node *to = (edge->caller->global.inlined_to - ? edge->caller->global.inlined_to - : edge->caller); /* When we do caching, use do_estimate_edge_time to populate the entry. */ @@ -3458,10 +3483,7 @@ do_estimate_edge_hints (struct cgraph_edge *edge) VEC_free (tree, heap, known_vals); VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); - if (inline_summary (to)->scc_no - && inline_summary (to)->scc_no == inline_summary (callee)->scc_no - && !cgraph_edge_recursive_p (edge)) - hints |= INLINE_HINT_same_scc; + hints |= simple_edge_hints (edge); return hints; } @@ -3549,10 +3571,11 @@ do_estimate_growth (struct cgraph_node *node) return zero or negative growths. */ if (d.self_recursive) d.growth = d.growth < info->size ? info->size : d.growth; + else if (DECL_EXTERNAL (node->symbol.decl)) + ; else { - if (!DECL_EXTERNAL (node->symbol.decl) - && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) + if (cgraph_will_be_removed_from_program_if_no_direct_calls (node)) d.growth -= info->size; /* COMDAT functions are very often not shared across multiple units since they come from various template instantiations. |