summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline.c
diff options
context:
space:
mode:
authorrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-09 20:58:24 +0000
committerrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-09 20:58:24 +0000
commit7f4db7c80779ecbc57d1146654daf0acfe18de66 (patch)
tree3af522a3b5e149c3fd498ecb1255994daae2129a /gcc/ipa-inline.c
parent611349f0ec42a37591db2cd02974a11a48d10edb (diff)
downloadgcc-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.c89
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 */