diff options
author | rus <rus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-09 20:58:24 +0000 |
---|---|---|
committer | rus <rus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-09 20:58:24 +0000 |
commit | 7f4db7c80779ecbc57d1146654daf0acfe18de66 (patch) | |
tree | 3af522a3b5e149c3fd498ecb1255994daae2129a /gcc/ipa-inline.c | |
parent | 611349f0ec42a37591db2cd02974a11a48d10edb (diff) | |
download | gcc-7f4db7c80779ecbc57d1146654daf0acfe18de66.tar.gz |
merge from trunkprofile-stdlib
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/profile-stdlib@154052 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r-- | gcc/ipa-inline.c | 89 |
1 files changed, 62 insertions, 27 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 8851d605372..bc7048f51c6 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -223,7 +223,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, /* We may eliminate the need for out-of-line copy to be output. In that case just go ahead and re-use it. */ if (!e->callee->callers->next_caller - && !e->callee->needed + && cgraph_can_remove_if_no_direct_calls_p (e->callee) && !cgraph_new_nodes) { gcc_assert (!e->callee->global.inlined_to); @@ -233,6 +233,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, nfunctions_inlined++; } duplicate = false; + e->callee->local.externally_visible = false; } else { @@ -286,7 +287,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, e->callee->global.inlined = true; if (e->callee->callers->next_caller - || e->callee->needed) + || !cgraph_can_remove_if_no_direct_calls_p (e->callee)) duplicate = true; cgraph_clone_inlined_nodes (e, true, update_original); @@ -309,7 +310,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, overall_size -= orig_size; ncalls_inlined++; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) return ipa_propagate_indirect_call_infos (curr, new_edges); else return false; @@ -326,7 +327,7 @@ cgraph_mark_inline (struct cgraph_edge *edge) struct cgraph_node *what = edge->callee; struct cgraph_edge *e, *next; - gcc_assert (!gimple_call_cannot_inline_p (edge->call_stmt)); + gcc_assert (!edge->call_stmt_cannot_inline_p); /* Look for all calls, mark them inline and clone recursively all inlined functions. */ for (e = what->callers; e; e = next) @@ -368,7 +369,8 @@ cgraph_estimate_growth (struct cgraph_node *node) we decide to not inline for different reasons, but it is not big deal as in that case we will keep the body around, but we will also avoid some inlining. */ - if (!node->needed && !DECL_EXTERNAL (node->decl) && !self_recursive) + if (cgraph_only_called_directly_p (node) + && !DECL_EXTERNAL (node->decl) && !self_recursive) growth -= node->global.size; node->global.estimated_growth = growth; @@ -874,7 +876,7 @@ cgraph_decide_inlining_of_small_functions (void) int min_size, max_size; VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8); if (dump_file) @@ -1021,17 +1023,17 @@ cgraph_decide_inlining_of_small_functions (void) if (where->global.inlined_to) where = where->global.inlined_to; if (!cgraph_decide_recursive_inlining (where, - flag_indirect_inlining + flag_indirect_inlining && !flag_wpa ? &new_indirect_edges : NULL)) continue; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, where, updated_nodes); } else { struct cgraph_node *callee; - if (gimple_call_cannot_inline_p (edge->call_stmt) + if (edge->call_stmt_cannot_inline_p || !cgraph_check_inline_limits (edge->caller, edge->callee, &edge->inline_failed, true)) { @@ -1043,7 +1045,7 @@ cgraph_decide_inlining_of_small_functions (void) } callee = edge->callee; cgraph_mark_inline_edge (edge, true, &new_indirect_edges); - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, callee, updated_nodes); @@ -1112,6 +1114,8 @@ cgraph_decide_inlining (void) int initial_size = 0; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + if (in_lto_p && flag_indirect_inlining && !flag_wpa) + ipa_update_after_lto_read (); max_count = 0; max_benefit = 0; @@ -1121,7 +1125,6 @@ cgraph_decide_inlining (void) struct cgraph_edge *e; gcc_assert (inline_summary (node)->self_size == node->global.size); - gcc_assert (node->needed || node->reachable); initial_size += node->global.size; for (e = node->callees; e; e = e->next_callee) if (max_count < e->count) @@ -1129,7 +1132,9 @@ cgraph_decide_inlining (void) if (max_benefit < inline_summary (node)->time_inlining_benefit) max_benefit = inline_summary (node)->time_inlining_benefit; } - gcc_assert (!max_count || (profile_info && flag_branch_probabilities)); + gcc_assert (in_lto_p + || !max_count + || (profile_info && flag_branch_probabilities)); overall_size = initial_size; nnodes = cgraph_postorder (order); @@ -1177,8 +1182,7 @@ cgraph_decide_inlining (void) for (e = node->callers; e; e = next) { next = e->next_caller; - if (!e->inline_failed - || gimple_call_cannot_inline_p (e->call_stmt)) + if (!e->inline_failed || e->call_stmt_cannot_inline_p) continue; if (cgraph_recursive_inlining_p (e->caller, e->callee, &e->inline_failed)) @@ -1220,15 +1224,16 @@ cgraph_decide_inlining (void) if (node->callers && !node->callers->next_caller - && !node->needed + && cgraph_only_called_directly_p (node) && node->local.inlinable && node->callers->inline_failed && node->callers->caller != node && node->callers->caller->global.inlined_to != node - && !gimple_call_cannot_inline_p (node->callers->call_stmt) + && !node->callers->call_stmt_cannot_inline_p && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl)) { + cgraph_inline_failed_t reason; old_size = overall_size; if (dump_file) { @@ -1242,7 +1247,7 @@ cgraph_decide_inlining (void) } if (cgraph_check_inline_limits (node->callers->caller, node, - NULL, false)) + &reason, false)) { cgraph_mark_inline (node->callers); if (dump_file) @@ -1257,14 +1262,15 @@ cgraph_decide_inlining (void) { if (dump_file) fprintf (dump_file, - " Inline limit reached, not inlined.\n"); + " Not inlining: %s.\n", + cgraph_inline_failed_string (reason)); } } } } /* Free ipa-prop structures if they are no longer needed. */ - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) free_all_ipa_structures_after_iinln (); if (dump_file) @@ -1411,7 +1417,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, if (!e->callee->local.disregard_inline_limits && (mode != INLINE_ALL || !e->callee->local.inlinable)) continue; - if (gimple_call_cannot_inline_p (e->call_stmt)) + if (e->call_stmt_cannot_inline_p) continue; /* When the edge is already inlined, we just need to recurse into it in order to fully flatten the leaves. */ @@ -1529,7 +1535,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, } if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed, false) - || gimple_call_cannot_inline_p (e->call_stmt)) + || e->call_stmt_cannot_inline_p) { if (dump_file) { @@ -1585,10 +1591,10 @@ cgraph_early_inlining (void) if (sorrycount || errorcount) return 0; - while (cgraph_decide_inlining_incrementally (node, - iterations - ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0) - && iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS)) + while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) + && cgraph_decide_inlining_incrementally (node, + iterations + ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0)) { timevar_push (TV_INTEGRATION); todo |= optimize_inline_calls (current_function_decl); @@ -1632,6 +1638,7 @@ static bool cgraph_gate_ipa_early_inlining (void) { return (flag_early_inlining + && !in_lto_p && (flag_branch_probabilities || flag_test_coverage || profile_arc_flag)); } @@ -1963,6 +1970,34 @@ inline_transform (struct cgraph_node *node) return todo | execute_fixup_cfg (); } +/* Read inline summary. Jump functions are shared among ipa-cp + and inliner, so when ipa-cp is active, we don't need to write them + twice. */ + +static void +inline_read_summary (void) +{ + if (flag_indirect_inlining && !flag_wpa) + { + ipa_register_cgraph_hooks (); + if (!flag_ipa_cp) + ipa_prop_read_jump_functions (); + } + function_insertion_hook_holder = + cgraph_add_function_insertion_hook (&add_new_function, NULL); +} + +/* Write inline summary for node in SET. + Jump functions are shared among ipa-cp and inliner, so when ipa-cp is + active, we don't need to write them twice. */ + +static void +inline_write_summary (cgraph_node_set set) +{ + if (flag_indirect_inlining && !flag_ipa_cp) + ipa_prop_write_jump_functions (set); +} + struct ipa_opt_pass_d pass_ipa_inline = { { @@ -1982,8 +2017,8 @@ struct ipa_opt_pass_d pass_ipa_inline = | TODO_remove_functions /* todo_flags_finish */ }, inline_generate_summary, /* generate_summary */ - NULL, /* write_summary */ - NULL, /* read_summary */ + inline_write_summary, /* write_summary */ + inline_read_summary, /* read_summary */ NULL, /* function_read_summary */ 0, /* TODOs */ inline_transform, /* function_transform */ |