aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c133
1 files changed, 65 insertions, 68 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 4fbc2eddace..17b21d17c5f 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -1490,19 +1490,23 @@ initialize_inline_failed (struct cgraph_edge *e)
{
struct cgraph_node *callee = e->callee;
- if (e->indirect_unknown_callee)
+ if (e->inline_failed && e->inline_failed != CIF_BODY_NOT_AVAILABLE
+ && cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+ ;
+ else if (e->indirect_unknown_callee)
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
else if (!callee->definition)
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
else if (callee->local.redefined_extern_inline)
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
- else if (e->call_stmt_cannot_inline_p)
- e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
else if (cfun && fn_contains_cilk_spawn_p (cfun))
/* We can't inline if the function is spawing a function. */
- e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
+ e->inline_failed = CIF_CILK_SPAWN;
else
e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+ gcc_checking_assert (!e->call_stmt_cannot_inline_p
+ || cgraph_inline_failed_type (e->inline_failed)
+ == CIF_FINAL_ERROR);
}
/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
@@ -2916,67 +2920,70 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
info = inline_summaries->get (node);
reset_inline_summary (node, info);
- /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
- Once this happen, we will need to more curefully predict call
- statement size. */
+ /* Estimate the stack size for the function if we're optimizing. */
+ self_stack_size = optimize && !node->thunk.thunk_p
+ ? estimated_stack_frame_size (node) : 0;
+ info->estimated_self_stack_size = self_stack_size;
+ info->estimated_stack_size = self_stack_size;
+ info->stack_frame_offset = 0;
+
if (node->thunk.thunk_p)
{
struct inline_edge_summary *es = inline_edge_summary (node->callees);
struct predicate t = true_predicate ();
- info->inlinable = 0;
- node->callees->call_stmt_cannot_inline_p = true;
+ node->callees->inline_failed = CIF_THUNK;
node->local.can_change_signature = false;
- es->call_stmt_time = 1;
- es->call_stmt_size = 1;
- account_size_time (info, 0, 0, &t);
- return;
+ es->call_stmt_size = INLINE_SIZE_SCALE;
+ es->call_stmt_time = INLINE_TIME_SCALE;
+ account_size_time (info, INLINE_SIZE_SCALE * 2, INLINE_TIME_SCALE * 2, &t);
+ inline_update_overall_summary (node);
+ info->self_size = info->size;
+ info->self_time = info->time;
+ /* We can not inline instrumetnation clones. */
+ info->inlinable = !node->thunk.add_pointer_bounds_args;
}
-
- /* Even is_gimple_min_invariant rely on current_function_decl. */
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-
- /* Estimate the stack size for the function if we're optimizing. */
- self_stack_size = optimize ? estimated_stack_frame_size (node) : 0;
- info->estimated_self_stack_size = self_stack_size;
- info->estimated_stack_size = self_stack_size;
- info->stack_frame_offset = 0;
-
- /* Can this function be inlined at all? */
- if (!opt_for_fn (node->decl, optimize)
- && !lookup_attribute ("always_inline",
- DECL_ATTRIBUTES (node->decl)))
- info->inlinable = false;
- else
- info->inlinable = tree_inlinable_function_p (node->decl);
-
- info->contains_cilk_spawn = fn_contains_cilk_spawn_p (cfun);
-
- /* Type attributes can use parameter indices to describe them. */
- if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
- node->local.can_change_signature = false;
else
{
- /* Otherwise, inlinable functions always can change signature. */
- if (info->inlinable)
- node->local.can_change_signature = true;
- else
- {
- /* Functions calling builtin_apply can not change signature. */
- for (e = node->callees; e; e = e->next_callee)
- {
- tree cdecl = e->callee->decl;
- if (DECL_BUILT_IN (cdecl)
- && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
- && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
- || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
- break;
- }
- node->local.can_change_signature = !e;
- }
- }
- estimate_function_body_sizes (node, early);
-
+ /* Even is_gimple_min_invariant rely on current_function_decl. */
+ push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+
+ /* Can this function be inlined at all? */
+ if (!opt_for_fn (node->decl, optimize)
+ && !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl)))
+ info->inlinable = false;
+ else
+ info->inlinable = tree_inlinable_function_p (node->decl);
+
+ info->contains_cilk_spawn = fn_contains_cilk_spawn_p (cfun);
+
+ /* Type attributes can use parameter indices to describe them. */
+ if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
+ node->local.can_change_signature = false;
+ else
+ {
+ /* Otherwise, inlinable functions always can change signature. */
+ if (info->inlinable)
+ node->local.can_change_signature = true;
+ else
+ {
+ /* Functions calling builtin_apply can not change signature. */
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ tree cdecl = e->callee->decl;
+ if (DECL_BUILT_IN (cdecl)
+ && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
+ || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+ break;
+ }
+ node->local.can_change_signature = !e;
+ }
+ }
+ estimate_function_body_sizes (node, early);
+ pop_cfun ();
+ }
for (e = node->callees; e; e = e->next_callee)
if (e->callee->comdat_local_p ())
break;
@@ -2993,8 +3000,6 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
gcc_assert (info->time == info->self_time
&& info->size == info->self_size);
}
-
- pop_cfun ();
}
@@ -4107,17 +4112,9 @@ inline_analyze_function (struct cgraph_node *node)
{
struct cgraph_edge *e;
for (e = node->callees; e; e = e->next_callee)
- {
- if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
- e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
- e->call_stmt_cannot_inline_p = true;
- }
+ e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
for (e = node->indirect_calls; e; e = e->next_callee)
- {
- if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
- e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
- e->call_stmt_cannot_inline_p = true;
- }
+ e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
}
pop_cfun ();