diff options
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 133 |
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 (); |