GCC Middle and Back End API Reference
|
Variables | |
static int | overall_size |
static gcov_type | max_count |
|
static |
Compute badness of all edges in NEW_EDGES and add them to the HEAP.
References cgraph_edge::aux, can_inline_edge_p(), edge_badness(), cgraph_edge::inline_failed, and want_inline_small_function_p().
Referenced by inline_small_functions().
|
static |
Return true if the speedup for inlining E is bigger than PARAM_MAX_INLINE_MIN_SPEEDUP.
References cgraph_edge::callee, compute_inlined_call_time(), compute_uninlined_call_time(), and estimate_edge_time().
Referenced by edge_badness(), and want_inline_small_function_p().
|
static |
Return false when inlining edge E would lead to violating limits on function unit growth or stack usage growth. The relative function body growth limit is present generally to avoid problems with non-linear behavior of the compiler. To allow inlining huge functions into tiny wrapper, the limit is always based on the bigger of the two functions considered. For stack growth limits we always base the growth in stack usage of the callers. We want to prevent applications from segfaulting on stack overflow when functions with huge stack frames gets inlined.
References cgraph_edge::callee, cgraph_edge::caller, cgraph_node::callers, cgraph_function_or_thunk_node(), estimate_size_after_inlining(), inline_summary::estimated_self_stack_size, inline_summary::estimated_stack_size, cgraph_node::global, HOST_WIDE_INT, cgraph_edge::inline_failed, inline_summary(), cgraph_global_info::inlined_to, limit, inline_summary::self_size, inline_summary::size, and inline_summary::stack_frame_offset.
Referenced by can_inline_edge_p().
|
static |
Return true if the edge E is inlinable during early inlining.
References cgraph_edge::callee, cgraph_edge::caller, can_inline_edge_p(), cgraph_function_or_thunk_node(), symtab_node_base::decl, dump_file, gimple_has_body_p(), gimple_in_ssa_p(), cgraph_edge::inline_failed, and cgraph_node::symbol.
Referenced by early_inline_small_functions(), flatten_function(), and inline_always_inline_functions().
|
static |
Decide if we can inline the edge and possibly update inline_failed reason. We check whether inlining is possible at all and whether caller growth limits allow doing so. if REPORT is true, output reason to the dump file. if DISREGARD_LIMITES is true, ignore size limits.
References AVAIL_OVERWRITABLE, cgraph_edge::call_stmt_cannot_inline_p, cgraph_edge::callee, cgraph_edge::caller, caller_growth_limits(), function::can_throw_non_call_exceptions, cgraph_function_or_thunk_node(), cgraph_node::clone_of, symtab_node_base::decl, symtab_node_base::definition, cgraph_node::global, inline_summary::inlinable, cgraph_edge::inline_failed, cgraph_global_info::inlined_to, is_tm_pure(), lookup_attribute(), report_inline_failed_reason(), cgraph_node::symbol, and targetm.
Referenced by add_new_edges_to_heap(), can_early_inline_edge_p(), flatten_function(), inline_small_functions(), recursive_inlining(), speculation_useful_p(), update_callee_keys(), update_caller_keys(), and want_inline_function_to_all_callers_p().
|
static |
Return true when NODE has caller other than EDGE. Worker for cgraph_for_node_and_aliases.
References cgraph_node::callers.
Referenced by want_inline_function_to_all_callers_p().
|
inline |
Same as compute_uinlined_call_time but compute time when inlining does happen.
References cgraph_edge::caller, cgraph_edge::frequency, cgraph_node::global, inline_summary(), cgraph_global_info::inlined_to, and inline_summary::time.
Referenced by big_speedup_p(), edge_badness(), and relative_time_benefit().
|
static |
Given whole compilation unit estimate of INSNS, compute how large we can allow the unit to grow.
References HOST_WIDEST_INT.
Referenced by inline_small_functions().
|
inline |
Compute time of the edge->caller + edge->callee execution when inlining does not happen.
References cgraph_edge::caller, cgraph_edge::frequency, cgraph_node::global, inline_summary(), cgraph_global_info::inlined_to, and inline_summary::time.
Referenced by big_speedup_p(), edge_badness(), and relative_time_benefit().
|
static |
Decide on the inlining. We do so in the topological order to avoid expenses on updating data structures.
References cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, can_early_inline_edge_p(), cgraph_edge_recursive_p(), cgraph_function_or_thunk_node(), cgraph_node_name(), symtab_node_base::decl, dump_file, inline_call(), cgraph_edge::inline_failed, cgraph_edge::next_callee, cgraph_node::symbol, and want_early_inline_function_p().
Referenced by early_inliner().
|
static |
Do inlining of small functions. Doing so early helps profiling and other passes to be somewhat more effective and avoids some code duplication in later real inlining pass for testcases with very many function calls.
References function::always_inline_functions_inlined, cgraph_edge::call_stmt, cgraph_edge::call_stmt_cannot_inline_p, inline_edge_summary::call_stmt_size, inline_edge_summary::call_stmt_time, cgraph_edge::callee, cgraph_node::callees, cfun, cgraph_get_node(), cgraph_node_name(), current_function_decl, symtab_node_base::decl, dump_file, early_inline_small_functions(), eni_size_weights, eni_time_weights, estimate_num_insns(), flatten_function(), gimple_check_call_matching_types(), inline_always_inline_functions(), inline_edge_summary(), ipa_node_params_vector, ipa_remove_all_references(), lookup_attribute(), cgraph_edge::next_callee, optimize_inline_calls(), symtab_node_base::ref_list, seen_error(), cgraph_node::symbol, timevar_pop(), timevar_push(), and verify_cgraph_node().
|
static |
A cost model driving the inlining heuristics in a way so the edges with smallest badness are inlined first. After each inlining is performed the costs of all caller edges of nodes affected are recomputed so the metrics may accurately depend on values such as number of inlinable callers of the function or function body size.
References big_speedup_p(), cgraph_edge::callee, cgraph_edge::caller, cgraph_edge_recursive_p(), cgraph_function_or_thunk_node(), cgraph_node_name(), compute_inlined_call_time(), compute_uninlined_call_time(), cgraph_edge::count, symtab_node_base::decl, dump_file, dump_inline_hints(), estimate_edge_growth(), estimate_edge_hints(), estimate_edge_time(), estimate_growth(), cgraph_edge::frequency, inline_summary::growth, INLINE_HINT_array_index, INLINE_HINT_cross_module, INLINE_HINT_declared_inline, INLINE_HINT_in_scc, INLINE_HINT_indirect_call, INLINE_HINT_loop_iterations, INLINE_HINT_loop_stride, INLINE_HINT_same_scc, inline_summary(), loop_depth(), max_count, symtab_node_base::order, relative_time_benefit(), inline_summary::size, cgraph_node::symbol, and inline_summary::time.
Referenced by add_new_edges_to_heap(), inline_small_functions(), and update_edge_key().
|
static |
Flatten NODE. Performed both during early inlining and at IPA inlining time.
References symtab_node_base::aux, cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, can_early_inline_edge_p(), can_inline_edge_p(), cgraph_edge_recursive_p(), cgraph_function_or_thunk_node(), cgraph_node_name(), symtab_node_base::decl, dump_file, gimple_in_ssa_p(), cgraph_node::global, inline_call(), cgraph_edge::inline_failed, inline_update_overall_summary(), cgraph_global_info::inlined_to, cgraph_edge::next_callee, and cgraph_node::symbol.
Referenced by early_inliner(), and ipa_inline().
|
static |
When to run IPA inlining. Inlining of always-inline functions happens during early inlining. Enable inlining unconditoinally at -flto. We need size estimates to drive partitioning.
|
static |
Remove EDGE from the fibheap.
References cgraph_edge::aux, cgraph_edge::callee, and reset_node_growth_cache().
Referenced by inline_small_functions().
|
static |
Inline always-inline function calls in NODE.
References cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, can_early_inline_edge_p(), cgraph_edge_recursive_p(), cgraph_function_or_thunk_node(), cgraph_node_name(), symtab_node_base::decl, dump_file, inline_call(), cgraph_edge::inline_failed, inline_update_overall_summary(), lookup_attribute(), cgraph_edge::next_callee, and cgraph_node::symbol.
Referenced by early_inliner().
|
static |
We use greedy algorithm for inlining of small functions: All inline candidates are put into prioritized heap ordered in increasing badness. The inlining of small functions is bounded by unit growth parameters.
References add_new_edges_to_heap(), symtab_node_base::aux, cgraph_edge::aux, bitmap_clear(), cgraph_edge::call_stmt, cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, can_inline_edge_p(), cgraph_add_edge_removal_hook(), cgraph_edge_recursive_p(), cgraph_function_or_thunk_node(), cgraph_function_with_gimple_body_p(), cgraph_n_nodes, cgraph_node_name(), cgraph_remove_edge_removal_hook(), cgraph_resolve_speculation(), compute_max_insns(), count, cgraph_edge::count, symtab_node_base::decl, dump_file, dump_flags, edge_badness(), edge_removal_hook_holder, estimate_edge_growth(), estimate_growth(), free(), free_growth_caches(), cgraph_edge::frequency, gimple_filename(), gimple_lineno(), cgraph_node::global, inline_summary::growth, heap_edge_removal_hook(), HOST_WIDEST_INT_PRINT_DEC, initialize_growth_caches(), inline_call(), cgraph_edge::inline_failed, inline_summary(), inline_update_overall_summary(), cgraph_global_info::inlined_to, ipa_free_postorder_info(), ipa_reduced_postorder(), max_count, cgraph_edge::next_callee, cgraph_edge::next_caller, ipa_dfs_info::next_cycle, symtab_node_base::order, order, overall_size, profile_info, recursive_inlining(), report_inline_failed_reason(), reset_edge_caches(), reset_edge_growth_cache(), reset_node_growth_cache(), resolve_noninline_speculation(), ipa_dfs_info::scc_no, inline_summary::scc_no, inline_summary::size, speculation_useful_p(), cgraph_edge::speculative, cgraph_node::symbol, cgraph_node::thunk, cgraph_thunk_info::thunk_p, inline_summary::time, update_callee_keys(), update_caller_keys(), update_edge_key(), vNULL, want_inline_self_recursive_call_p(), and want_inline_small_function_p().
Referenced by ipa_inline().
|
static |
Decide on the inlining. We do so in the topological order to avoid expenses on updating data structures.
References symtab_node_base::aux, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, cgraph_n_nodes, cgraph_node_name(), cgraph_resolve_speculation(), symtab_node_base::decl, dump_file, dump_inline_summaries(), flatten_function(), free(), cgraph_node::global, inline_call(), inline_free_summary(), inline_small_functions(), inline_update_overall_summary(), cgraph_global_info::inlined_to, ipa_free_all_structures_after_iinln(), ipa_reverse_postorder(), ipa_update_after_lto_read(), lookup_attribute(), ncalls_inlined, cgraph_edge::next_callee, cgraph_edge::next_caller, nfunctions_inlined, nnodes, num_calls(), order, reset_edge_caches(), reset_node_growth_cache(), inline_summary::size, speculation_useful_p(), cgraph_edge::speculative, cgraph_node::symbol, symtab_remove_unreachable_nodes(), and want_inline_function_to_all_callers_p().
|
static |
Enqueue all recursive calls from NODE into priority queue depending on how likely we want to recursively inline the call.
References AVAIL_OVERWRITABLE, cgraph_edge::callee, cgraph_node::callees, cgraph_function_or_thunk_node(), cgraph_edge::count, cgraph_edge::frequency, cgraph_edge::inline_failed, max_count, and cgraph_edge::next_callee.
Referenced by recursive_inlining().
gimple_opt_pass* make_pass_early_inline | ( | ) |
ipa_opt_pass_d* make_pass_ipa_inline | ( | ) |
|
static |
Return number of calls in N. Ignore cheap builtins.
References cgraph_edge::callee, cgraph_node::callees, symtab_node_base::decl, is_inexpensive_builtin(), cgraph_edge::next_callee, and cgraph_node::symbol.
Referenced by fixup_match_2(), ipa_inline(), regmove_backward_pass(), and want_early_inline_function_p().
|
static |
Decide on recursive inlining: in the case function has recursive calls, inline until body size reaches given argument. If any new indirect edges are discovered in the process, add them to *NEW_EDGES, unless NEW_EDGES is NULL.
References cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, can_inline_edge_p(), cgraph_clone_node(), cgraph_first_function(), cgraph_function_or_thunk_node(), cgraph_next_function(), cgraph_node_name(), cgraph_redirect_edge_callee(), cgraph_remove_node(), clone_inlined_nodes(), cgraph_node::count, cgraph_edge::count, symtab_node_base::decl, dump_file, estimate_size_after_inlining(), cgraph_node::global, inline_call(), cgraph_edge::inline_failed, cgraph_global_info::inlined_to, limit, lookup_recursive_calls(), cgraph_edge::next_callee, overall_size, reset_edge_growth_cache(), cgraph_node::symbol, vNULL, and want_inline_self_recursive_call_p().
Referenced by inline_small_functions().
|
inlinestatic |
Return relative time improvement for inlining EDGE in range 1...RELATIVE_TIME_BENEFIT_RANGE
References cgraph_edge::caller, compute_inlined_call_time(), compute_uninlined_call_time(), symtab_node_base::decl, cgraph_node::global, cgraph_global_info::inlined_to, and cgraph_node::symbol.
Referenced by edge_badness().
|
static |
Dump info about why inlining has failed.
References cgraph_edge::callee, cgraph_edge::caller, cgraph_inline_failed_string(), cgraph_node_name(), dump_file, cgraph_edge::inline_failed, symtab_node_base::order, and cgraph_node::symbol.
Referenced by can_inline_edge_p(), inline_small_functions(), update_callee_keys(), update_caller_keys(), want_early_inline_function_p(), and want_inline_small_function_p().
|
static |
NODE was inlined. All caller edges needs to be resetted because size estimates change. Similarly callees needs reset because better context may be known.
References cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, cgraph_node::global, cgraph_edge::inline_failed, cgraph_global_info::inlined_to, IPA_REF_ALIAS, ipa_ref_referring_node(), cgraph_edge::next_callee, cgraph_edge::next_caller, symtab_node_base::ref_list, reset_edge_growth_cache(), reset_node_growth_cache(), and cgraph_node::symbol.
Referenced by inline_small_functions(), ipa_inline(), and resolve_noninline_speculation().
|
static |
We know that EDGE is not going to be inlined. See if we can remove speculation.
References cgraph_edge::caller, cgraph_resolve_speculation(), cgraph_node::global, inline_update_overall_summary(), cgraph_global_info::inlined_to, reset_edge_caches(), speculation_useful_p(), cgraph_edge::speculative, update_callee_keys(), and update_caller_keys().
Referenced by inline_small_functions().
bool speculation_useful_p | ( | ) |
Return true if speculation of edge E seems useful. If ANTICIPATE_INLINING is true, be conservative and hope that E may get inlined.
References AVAIL_AVAILABLE, cgraph_edge::callee, can_inline_edge_p(), cgraph_function_or_thunk_node(), cgraph_maybe_hot_edge_p(), cgraph_speculative_call_info(), symtab_node_base::decl, cgraph_indirect_call_info::ecf_flags, flags_from_decl_or_type(), cgraph_edge::indirect_info, cgraph_edge::indirect_unknown_callee, cgraph_edge::inline_failed, cgraph_local_info::local, cgraph_node::local, cgraph_edge::speculative, and cgraph_node::symbol.
Referenced by clone_inlined_nodes(), inline_small_functions(), ipa_inline(), and resolve_noninline_speculation().
|
static |
Recompute HEAP nodes for each uninlined call in NODE. This is used when we know that edge badnesses are going only to increase (we introduced new call site) and thus all we need is to insert newly created edges into heap.
References cgraph_edge::aux, AVAIL_AVAILABLE, bitmap_bit_p(), cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, can_inline_edge_p(), cgraph_function_or_thunk_node(), cgraph_edge::inline_failed, cgraph_edge::next_callee, report_inline_failed_reason(), cgraph_node::uid, update_edge_key(), and want_inline_small_function_p().
Referenced by inline_small_functions(), and resolve_noninline_speculation().
|
static |
Recompute HEAP nodes for each of caller of NODE. UPDATED_NODES track nodes we already visited, to avoid redundant work. When CHECK_INLINABLITY_FOR is set, re-check for specified edge that it is inlinable. Otherwise check all edges.
References symtab_node_base::alias, cgraph_edge::aux, bitmap_set_bit(), cgraph_node::callers, can_inline_edge_p(), cgraph_node::global, cgraph_edge::inline_failed, cgraph_global_info::inlined_to, IPA_REF_ALIAS, ipa_ref_referring_node(), cgraph_edge::next_caller, symtab_node_base::ref_list, report_inline_failed_reason(), cgraph_node::symbol, cgraph_node::uid, update_edge_key(), and want_inline_small_function_p().
Referenced by inline_small_functions(), and resolve_noninline_speculation().
|
inlinestatic |
Recompute badness of EDGE and update its key in HEAP if needed.
References cgraph_edge::aux, cgraph_edge::callee, cgraph_edge::caller, cgraph_node_name(), dump_file, dump_flags, edge_badness(), symtab_node_base::order, and cgraph_node::symbol.
Referenced by inline_small_functions(), update_callee_keys(), and update_caller_keys().
|
static |
Return true if we are interested in inlining small function.
References cgraph_edge::callee, cgraph_edge::caller, cgraph_function_or_thunk_node(), cgraph_maybe_hot_edge_p(), cgraph_node_name(), symtab_node_base::decl, dump_file, estimate_edge_growth(), cgraph_edge::inline_failed, num_calls(), symtab_node_base::order, report_inline_failed_reason(), and cgraph_node::symbol.
Referenced by early_inline_small_functions().
|
static |
Decide if inlining NODE would reduce unit size by eliminating the offline copy of function. When COLD is true the cold calls are considered, too.
References cgraph_node::callers, can_inline_edge_p(), cgraph_for_node_and_aliases(), cgraph_function_or_thunk_node(), cgraph_maybe_hot_edge_p(), check_caller_edge(), estimate_growth(), and cgraph_edge::next_caller.
Referenced by ipa_inline().
|
static |
EDGE is self recursive edge. We hand two cases - when function A is inlining into itself or when function A is being inlined into another inliner copy of function A within function B. In first case OUTER_NODE points to the toplevel copy of A, while in the second case OUTER_NODE points to the outermost copy of A in B. In both cases we want to be extra selective since inlining the call will just introduce new recursive calls to appear.
References cgraph_edge::caller, cgraph_node::callers, cgraph_maybe_hot_edge_p(), cgraph_node::count, cgraph_edge::count, symtab_node_base::decl, dump_file, cgraph_edge::frequency, cgraph_node::global, cgraph_global_info::inlined_to, max_count, max_depth, and cgraph_node::symbol.
Referenced by inline_small_functions(), and recursive_inlining().
|
static |
Return true if we are interested in inlining small function. When REPORT is true, report reason to dump file.
References big_speedup_p(), cgraph_edge::callee, cgraph_can_remove_if_no_direct_calls_p(), cgraph_function_or_thunk_node(), cgraph_maybe_hot_edge_p(), symtab_node_base::decl, estimate_edge_growth(), estimate_edge_hints(), estimate_growth(), cgraph_edge::inline_failed, INLINE_HINT_array_index, INLINE_HINT_indirect_call, INLINE_HINT_loop_iterations, INLINE_HINT_loop_stride, report_inline_failed_reason(), and cgraph_node::symbol.
Referenced by add_new_edges_to_heap(), inline_small_functions(), update_callee_keys(), and update_caller_keys().
|
static |
Referenced by edge_badness(), inline_small_functions(), lookup_recursive_calls(), and want_inline_self_recursive_call_p().
|
static |
@verbatim Inlining decision heuristics.
Copyright (C) 2003-2013 Free Software Foundation, Inc. Contributed by Jan Hubicka
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/.
Inlining decision heuristics The implementation of inliner is organized as follows: inlining heuristics limits can_inline_edge_p allow to check that particular inlining is allowed by the limits specified by user (allowed function growth, growth and so on). Functions are inlined when it is obvious the result is profitable (such as functions called once or when inlining reduce code size). In addition to that we perform inlining of small functions and recursive inlining. inlining heuristics The inliner itself is split into two passes: pass_early_inlining Simple local inlining pass inlining callees into current function. This pass makes no use of whole unit analysis and thus it can do only very simple decisions based on local properties. The strength of the pass is that it is run in topological order (reverse postorder) on the callgraph. Functions are converted into SSA form just before this pass and optimized subsequently. As a result, the callees of the function seen by the early inliner was already optimized and results of early inlining adds a lot of optimization opportunities for the local optimization. The pass handle the obvious inlining decisions within the compilation unit - inlining auto inline functions, inlining for size and flattening. main strength of the pass is the ability to eliminate abstraction penalty in C++ code (via combination of inlining and early optimization) and thus improve quality of analysis done by real IPA optimizers. Because of lack of whole unit knowledge, the pass can not really make good code size/performance tradeoffs. It however does very simple speculative inlining allowing code size to grow by EARLY_INLINING_INSNS when callee is leaf function. In this case the optimizations performed later are very likely to eliminate the cost. pass_ipa_inline This is the real inliner able to handle inlining with whole program knowledge. It performs following steps: 1) inlining of small functions. This is implemented by greedy algorithm ordering all inlinable cgraph edges by their badness and inlining them in this order as long as inline limits allows doing so. This heuristics is not very good on inlining recursive calls. Recursive calls can be inlined with results similar to loop unrolling. To do so, special purpose recursive inliner is executed on function when recursive edge is met as viable candidate. 2) Unreachable functions are removed from callgraph. Inlining leads to devirtualization and other modification of callgraph so functions may become unreachable during the process. Also functions declared as extern inline or virtual functions are removed, since after inlining we no longer need the offline bodies. 3) Functions called once and not exported from the unit are inlined. This should almost always lead to reduction of code size by eliminating the need for offline copy of the function.
Statistics we collect about inlining algorithm.
Referenced by inline_small_functions(), and recursive_inlining().