GCC Middle and Back End API Reference
ipa-inline-transform.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "function.h"
#include "tree.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "tree-cfg.h"
#include "symbol-summary.h"
#include "tree-vrp.h"
#include "sreal.h"
#include "ipa-cp.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "ipa-inline.h"
#include "tree-inline.h"
#include "cfg.h"
#include "basic-block.h"
#include "ipa-utils.h"
#include "ipa-modref-tree.h"
#include "ipa-modref.h"
#include "symtab-thunks.h"
#include "symtab-clones.h"
Include dependency graph for ipa-inline-transform.cc:

Functions

static void update_noncloned_counts (struct cgraph_node *node, profile_count num, profile_count den)
 
static bool can_remove_node_now_p_1 (struct cgraph_node *node, struct cgraph_edge *e)
 
static bool can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
 
static bool master_clone_with_noninline_clones_p (struct cgraph_node *node)
 
void clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, bool update_original, int *overall_size)
 
static bool check_speculations_1 (cgraph_node *n, vec< cgraph_edge * > *new_edges, hash_set< cgraph_edge * > *edge_set)
 
bool push_all_edges_in_set_to_vec (cgraph_edge *const &e, vec< cgraph_edge * > *new_edges)
 
static bool check_speculations (cgraph_node *n, vec< cgraph_edge * > *new_edges)
 
static void mark_all_inlined_calls_cdtor (cgraph_node *node)
 
bool inline_call (struct cgraph_edge *e, bool update_original, vec< cgraph_edge * > *new_edges, int *overall_size, bool update_overall_summary, bool *callee_removed)
 
static struct cgraph_nodesave_inline_function_body (struct cgraph_node *node)
 
static bool preserve_function_body_p (struct cgraph_node *node)
 
static void maybe_materialize_called_clones (cgraph_node *node)
 
unsigned int inline_transform (struct cgraph_node *node)
 

Variables

int ncalls_inlined
 
int nfunctions_inlined
 
function_summary< tree * > * ipa_saved_clone_sources
 

Function Documentation

◆ can_remove_node_now_p()

static bool can_remove_node_now_p ( struct cgraph_node * node,
struct cgraph_edge * e )
static
We are going to eliminate last direct call to NODE (or alias of it) via edge E.
Verify that the NODE can be removed from unit and if it is contained in comdat
group that the whole comdat group is removable.   

References symtab_node::alias, can_remove_node_now_p_1(), symtab_node::externally_visible, ggc_alloc(), symtab_node::next, and symtab_node::same_comdat_group.

Referenced by clone_inlined_nodes(), and inline_call().

◆ can_remove_node_now_p_1()

static bool can_remove_node_now_p_1 ( struct cgraph_node * node,
struct cgraph_edge * e )
static
We removed or are going to remove the last call to NODE.
Return true if we can and want proactively remove the NODE now.
This is important to do, since we want inliner to know when offline
copy of function was removed.   

References symtab_node::address_taken, cgraph_node::callers, cgraph_node::can_remove_if_no_direct_calls_and_refs_p(), can_remove_node_now_p_1(), cgraph_new_nodes, symtab_node::decl, DECL_VIRTUAL_P, FOR_EACH_ALIAS, ggc_alloc(), opt_for_fn, and ipa_ref::referring.

Referenced by can_remove_node_now_p(), and can_remove_node_now_p_1().

◆ check_speculations()

static bool check_speculations ( cgraph_node * n,
vec< cgraph_edge * > * new_edges )
static
Check all speculations in N and if any seem useless, resolve them and remove
them from NEW_EDGES.   

References check_speculations_1(), ggc_alloc(), and push_all_edges_in_set_to_vec().

Referenced by inline_call().

◆ check_speculations_1()

static bool check_speculations_1 ( cgraph_node * n,
vec< cgraph_edge * > * new_edges,
hash_set< cgraph_edge * > * edge_set )
static
Check all speculations in N and if any seem useless, resolve them.  When a
first edge is resolved, pop all edges from NEW_EDGES and insert them to
EDGE_SET.  Then remove each resolved edge from EDGE_SET, if it is there.   

References cgraph_node::callees, check_speculations_1(), ggc_alloc(), symtab_node::next, NULL, cgraph_edge::resolve_speculation(), and speculation_useful_p().

Referenced by check_speculations(), and check_speculations_1().

◆ clone_inlined_nodes()

void clone_inlined_nodes ( struct cgraph_edge * e,
bool duplicate,
bool update_original,
int * overall_size )
E is expected to be an edge being inlined.  Clone destination node of
the edge and redirect it to the new clone.
DUPLICATE is used for bookkeeping on whether we are actually creating new
clones or re-using node originally representing out-of-line function call.
By default the offline copy is removed, when it appears dead after inlining.
UPDATE_ORIGINAL prevents this transformation.
If OVERALL_SIZE is non-NULL, the size is updated to reflect the
transformation.   

References symtab_node::alias, cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::callers, can_remove_node_now_p(), clone_inlined_nodes(), cgraph_node::count, cgraph_edge::count, cgraph_node::create_clone(), symtab_node::decl, symtab_node::definition, dump_callgraph_transformation(), symtab_node::externally_visible, gcc_assert, ggc_alloc(), inline_account_function_p(), cgraph_edge::inline_failed, cgraph_node::inlined_to, ipa_size_summaries, cgraph_node::ipa_transforms_to_apply, master_clone_with_noninline_clones_p(), symtab_node::next, cgraph_edge::next_callee, cgraph_edge::next_caller, nfunctions_inlined, NULL, overall_size, cgraph_edge::redirect_callee(), symtab_node::remove_from_same_comdat_group(), update_noncloned_counts(), cgraph_node::used_as_abstract_origin, and vNULL.

Referenced by clone_inlined_nodes(), inline_call(), and recursive_inlining().

◆ inline_call()

bool inline_call ( struct cgraph_edge * e,
bool update_original,
vec< cgraph_edge * > * new_edges,
int * overall_size,
bool update_overall_summary,
bool * callee_removed )
Mark edge E as inlined and update callgraph accordingly.  UPDATE_ORIGINAL
specify whether profile of original function should be updated.  If any new
indirect edges are discovered in the process, add them to NEW_EDGES, unless
it is NULL. If UPDATE_OVERALL_SUMMARY is false, do not bother to recompute overall
size of caller after inlining. Caller is required to eventually do it via
ipa_update_overall_fn_summary.
If callee_removed is non-NULL, set it to true if we removed callee node.

Return true iff any new callgraph edges were discovered as a
result of inlining.   

References symtab_node::alias, build_optimization_node(), symbol_table::call_cgraph_insertion_hooks(), symbol_table::call_cgraph_removal_hooks(), cgraph_edge::callee, cgraph_node::callees, cgraph_edge::caller, cgraph_node::calls_comdat_local, can_remove_node_now_p(), cfun, cgraph_node::check_calls_comdat_local_p(), check_speculations(), clone_inlined_nodes(), symtab_node::comdat_local_p(), symtab_node::decl, DECL_FUNCTION_PERSONALITY, DECL_FUNCTION_SPECIFIC_OPTIMIZATION, DECL_POSSIBLY_INLINED, DECL_STRUCT_FUNCTION, dump_file, symtab_node::dump_name(), estimate_edge_growth(), expand_thunk(), gcc_assert, thunk_info::get(), thunk_info::get_create(), cgraph_node::get_untransformed_body(), ggc_alloc(), global_options, global_options_set, cgraph_edge::in_polymorphic_cdtor, inline_account_function_p(), cgraph_edge::inline_failed, cgraph_node::inlined_to, ipa_fn_summaries, ipa_merge_fn_summary_after_inlining(), ipa_merge_modref_summary_after_inlining(), ipa_propagate_indirect_call_infos(), ipa_size_summaries, ipa_update_overall_fn_summary(), mark_all_inlined_calls_cdtor(), ncalls_inlined, cgraph_edge::next_callee, cgraph_edge::next_caller, NULL, opt_for_fn, opts_for_fn(), overall_size, cgraph_edge::prev_caller, cgraph_edge::redirect_callee(), set_cfun(), symtab, cgraph_node::thunk, thunk_expansion, and cgraph_node::ultimate_alias_target().

Referenced by autofdo::afdo_indirect_call(), early_inline_small_functions(), flatten_function(), inline_always_inline_functions(), inline_small_functions(), inline_to_all_callers_1(), and recursive_inlining().

◆ inline_transform()

◆ mark_all_inlined_calls_cdtor()

static void mark_all_inlined_calls_cdtor ( cgraph_node * node)
static
Mark all call graph edges coming out of NODE and all nodes that have been
inlined to it as in_polymorphic_cdtor.   

References cgraph_node::callees, cgraph_node::indirect_calls, and mark_all_inlined_calls_cdtor().

Referenced by inline_call(), and mark_all_inlined_calls_cdtor().

◆ master_clone_with_noninline_clones_p()

static bool master_clone_with_noninline_clones_p ( struct cgraph_node * node)
static
Return true if NODE is a master clone with non-inline clones.   

References cgraph_node::clone_of, cgraph_node::clones, and symtab_node::decl.

Referenced by clone_inlined_nodes().

◆ maybe_materialize_called_clones()

static void maybe_materialize_called_clones ( cgraph_node * node)
static
tree-inline can not recurse; materialize all function bodie we will need
during inlining.  This includes inlined functions, but also called functions
with param manipulation because IPA param manipulation attaches debug
statements to PARM_DECLs of called clone.  Materialize them if needed.

FIXME: This is somehwat broken by design because it does not play well
with partitioning.   

References cgraph_node::callees, cgraph_node::clone_of, clone_info::get(), cgraph_node::get(), cgraph_node::get_untransformed_body(), maybe_materialize_called_clones(), and clone_info::param_adjustments.

Referenced by inline_transform(), and maybe_materialize_called_clones().

◆ preserve_function_body_p()

static bool preserve_function_body_p ( struct cgraph_node * node)
static
Return true when function body of DECL still needs to be kept around
for later re-use.   

References symtab_node::alias, cgraph_node::clones, gcc_assert, symbol_table::global_info_ready, cgraph_node::next_sibling_clone, symtab, and cgraph_node::thunk.

Referenced by inline_transform().

◆ push_all_edges_in_set_to_vec()

bool push_all_edges_in_set_to_vec ( cgraph_edge *const & e,
vec< cgraph_edge * > * new_edges )
Push E to NEW_EDGES.  Called from hash_set traverse method, which
unfortunately means this function has to have external linkage, otherwise
the code will not compile with gcc 4.8.   

References ggc_alloc().

Referenced by check_speculations().

◆ save_inline_function_body()

static struct cgraph_node * save_inline_function_body ( struct cgraph_node * node)
static
Copy function body of NODE and redirect all inline clones to it.
This is done before inline plan is applied to NODE when there are
still some inline clones if it.

This is necessary because inline decisions are not really transitive
and the other inline clones may have different bodies.   

References cgraph_node::clone_of, cgraph_node::clones, copy_node(), symtab_node::decl, DECL_COMDAT, DECL_EXTERNAL, dump_file, symtab_node::dump_name(), cgraph_node::former_clone_of, gcc_assert, cgraph_node::get(), ggc_alloc(), ipa_saved_clone_sources, cgraph_node::next_sibling_clone, NULL, cgraph_node::prev_sibling_clone, symtab, tree_function_versioning(), and TREE_PUBLIC.

Referenced by inline_transform().

◆ update_noncloned_counts()

Variable Documentation

◆ ipa_saved_clone_sources

function_summary<tree *>* ipa_saved_clone_sources
For each node that was made the holder of function body by
save_inline_function_body, this summary contains pointer to the previous
holder of the body.   

Referenced by expand_all_functions(), cgraph_edge::redirect_call_stmt_to_callee(), and save_inline_function_body().

◆ ncalls_inlined

int ncalls_inlined
Callgraph transformations to handle inlining
   Copyright (C) 2003-2024 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/>.   
The inline decisions are stored in callgraph in "inline plan" and
applied later.

To mark given call inline, use inline_call function.
The function marks the edge inlinable and, if necessary, produces
virtual clone in the callgraph representing the new copy of callee's
function body.

The inline plan is applied on given function body by inline_transform.   

Referenced by inline_call(), and ipa_inline().

◆ nfunctions_inlined

int nfunctions_inlined

Referenced by clone_inlined_nodes(), and ipa_inline().