GCC Middle and Back End API Reference
ipa-fnsummary.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "tree-streamer.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "print-tree.h"
#include "tree-inline.h"
#include "gimple-pretty-print.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
#include "symbol-summary.h"
#include "sreal.h"
#include "ipa-cp.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "ipa-utils.h"
#include "cfgexpand.h"
#include "gimplify.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-into-ssa.h"
#include "symtab-clones.h"
#include "gimple-range.h"
#include "tree-dfa.h"
Include dependency graph for ipa-fnsummary.cc:

Data Structures

struct  record_modified_bb_info
 

Macros

#define INCLUDE_VECTOR
 

Functions

void ipa_dump_hints (FILE *f, ipa_hints hints)
 
static struct cgraph_edgeredirect_to_unreachable (struct cgraph_edge *e)
 
static void edge_set_predicate (struct cgraph_edge *e, ipa_predicate *predicate)
 
static void set_hint_predicate (ipa_predicate **p, ipa_predicate new_predicate)
 
static void add_freqcounting_predicate (vec< ipa_freqcounting_predicate, va_gc > **v, const ipa_predicate &new_predicate, sreal add_freq, unsigned max_num_predicates)
 
static void evaluate_conditions_for_known_args (struct cgraph_node *node, bool inline_p, ipa_auto_call_arg_values *avals, clause_t *ret_clause, clause_t *ret_nonspec_clause, ipa_call_summary *es)
 
static bool vrp_will_run_p (struct cgraph_node *node)
 
static bool fre_will_run_p (struct cgraph_node *node)
 
void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, clause_t *clause_ptr, clause_t *nonspec_clause_ptr, ipa_auto_call_arg_values *avals, bool compute_contexts)
 
static void ipa_fn_summary_alloc (void)
 
static vec< ipa_freqcounting_predicate, va_gc > * remap_freqcounting_preds_after_dup (vec< ipa_freqcounting_predicate, va_gc > *v, clause_t possible_truths)
 
static void dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node, class ipa_fn_summary *info)
 
void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
 
DEBUG_FUNCTION void ipa_debug_fn_summary (struct cgraph_node *node)
 
void ipa_dump_fn_summaries (FILE *f)
 
static bool mark_modified (ao_ref *ao, tree vdef, void *data)
 
static tree unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op, poly_int64 *size_p)
 
static tree unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op, poly_int64 *size_p)
 
static bool unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi, gimple *stmt, tree op, int *index_p, poly_int64 *size_p, struct agg_position_info *aggpos)
 
static int load_or_store_of_ptr_parameter (ipa_func_body_info *fbi, gimple *stmt)
 
static int eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
 
static bool decompose_param_expr (struct ipa_func_body_info *fbi, gimple *stmt, tree expr, int *index_p, tree *type_p, struct agg_position_info *aggpos, expr_eval_ops *param_ops_p=NULL)
 
static void add_builtin_constant_p_parm (class ipa_fn_summary *summary, int parm)
 
static void set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, class ipa_fn_summary *summary, class ipa_node_params *params_summary, basic_block bb)
 
static void set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, class ipa_fn_summary *summary, class ipa_node_params *params_summary, basic_block bb)
 
static void compute_bb_predicates (struct ipa_func_body_info *fbi, struct cgraph_node *node, class ipa_fn_summary *summary, class ipa_node_params *params_summary)
 
static ipa_predicate will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi, class ipa_fn_summary *summary, class ipa_node_params *params_summary, tree expr, vec< ipa_predicate > nonconstant_names)
 
static ipa_predicate will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, class ipa_fn_summary *summary, class ipa_node_params *params_summary, gimple *stmt, vec< ipa_predicate > nonconstant_names)
 
static basic_block get_minimal_bb (basic_block init_bb, basic_block use_bb)
 
static bool record_modified (ao_ref *ao, tree vdef, void *data)
 
static int param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
 
static bool phi_result_unknown_predicate (ipa_func_body_info *fbi, ipa_fn_summary *summary, class ipa_node_params *params_summary, basic_block bb, ipa_predicate *p, vec< ipa_predicate > nonconstant_names)
 
static void predicate_for_phi_result (class ipa_fn_summary *summary, gphi *phi, ipa_predicate *p, vec< ipa_predicate > nonconstant_names)
 
static gimplefind_foldable_builtin_expect (basic_block bb)
 
static bool clobber_only_eh_bb_p (basic_block bb, bool need_eh=true)
 
static bool fp_expression_p (gimple *stmt)
 
bool refs_local_or_readonly_memory_p (tree t)
 
bool points_to_local_or_readonly_memory_p (tree t)
 
static bool points_to_possible_sra_candidate_p (tree t)
 
static void analyze_function_body (struct cgraph_node *node, bool early)
 
void compute_fn_summary (struct cgraph_node *node, bool early)
 
static unsigned int compute_fn_summary_for_current (void)
 
static bool estimate_edge_devirt_benefit (struct cgraph_edge *ie, int *size, int *time, ipa_call_arg_values *avals)
 
static void estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, sreal *time, ipa_call_arg_values *avals, ipa_hints *hints)
 
static void estimate_calls_size_and_time_1 (struct cgraph_node *node, int *size, int *min_size, sreal *time, ipa_hints *hints, clause_t possible_truths, ipa_call_arg_values *avals)
 
static void summarize_calls_size_and_time (struct cgraph_node *node, ipa_fn_summary *sum)
 
static void estimate_calls_size_and_time (struct cgraph_node *node, int *size, int *min_size, sreal *time, ipa_hints *hints, clause_t possible_truths, ipa_call_arg_values *avals)
 
void estimate_ipcp_clone_size_and_time (struct cgraph_node *node, ipa_auto_call_arg_values *avals, ipa_call_estimates *estimates)
 
HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node)
 
static void inline_update_callee_summaries (struct cgraph_node *node, int depth)
 
static void remap_edge_params (struct cgraph_edge *inlined_edge, struct cgraph_edge *edge)
 
static void remap_edge_summaries (struct cgraph_edge *inlined_edge, struct cgraph_node *node, class ipa_fn_summary *info, class ipa_node_params *params_summary, class ipa_fn_summary *callee_info, const vec< int > &operand_map, const vec< HOST_WIDE_INT > &offset_map, clause_t possible_truths, ipa_predicate *toplev_predicate)
 
static void remap_freqcounting_predicate (class ipa_fn_summary *info, class ipa_node_params *params_summary, class ipa_fn_summary *callee_info, vec< ipa_freqcounting_predicate, va_gc > *v, const vec< int > &operand_map, const vec< HOST_WIDE_INT > &offset_map, clause_t possible_truths, ipa_predicate *toplev_predicate)
 
void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
 
void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset)
 
static void inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
 
void inline_analyze_function (struct cgraph_node *node)
 
static void ipa_fn_summary_generate (void)
 
static void read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e, bool prevails)
 
static void inline_read_section (struct lto_file_decl_data *file_data, const char *data, size_t len)
 
static void ipa_fn_summary_read (void)
 
static void write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
 
static void ipa_fn_summary_write (void)
 
void ipa_free_fn_summary (void)
 
void ipa_free_size_summary (void)
 
gimple_opt_passmake_pass_local_fn_summary (gcc::context *ctxt)
 
simple_ipa_opt_passmake_pass_ipa_free_fn_summary (gcc::context *ctxt)
 
ipa_opt_pass_dmake_pass_ipa_fn_summary (gcc::context *ctxt)
 
void ipa_fnsummary_cc_finalize (void)
 

Variables

fast_function_summary< ipa_fn_summary *, va_gc > * ipa_fn_summaries
 
fast_function_summary< ipa_size_summary *, va_heap > * ipa_size_summaries
 
fast_call_summary< ipa_call_summary *, va_heap > * ipa_call_summaries
 
static object_allocator< ipa_predicateedge_predicate_pool ("edge predicates")
 

Macro Definition Documentation

◆ INCLUDE_VECTOR

#define INCLUDE_VECTOR
Function summary pass.
   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/>.   
Analysis of function bodies used by inter-procedural passes

We estimate for each function
  - function body size and size after specializing into given context
  - average function execution time in a given context
  - function frame size
For each call
  - call statement size, time and how often the parameters change

ipa_fn_summary data structures store above information locally (i.e.
parameters of the function itself) and globally (i.e. parameters of
the function created by applying all the inline decisions already
present in the callgraph).

We provide access to the ipa_fn_summary data structure and
basic logic updating the parameters when inlining is performed. 

The summaries are context sensitive.  Context means
  1) partial assignment of known constant values of operands
  2) whether function is inlined into the call or not.
It is easy to add more variants.  To represent function size and time
that depends on context (i.e. it is known to be optimized away when
context is known either by inlining or from IP-CP and cloning),
we use predicates.

estimate_edge_size_and_time can be used to query
function size/time in the given context.  ipa_merge_fn_summary_after_inlining merges
properties of caller and callee after inlining.

Finally pass_inline_parameters is exported.  This is used to drive
computation of function parameters used by the early inliner. IPA
inlined performs analysis via its analyze_function method.  

Function Documentation

◆ add_builtin_constant_p_parm()

static void add_builtin_constant_p_parm ( class ipa_fn_summary * summary,
int parm )
static
Record to SUMMARY that PARM is used by builtin_constant_p.   

References ggc_alloc(), and i.

Referenced by ipa_merge_fn_summary_after_inlining(), and set_cond_stmt_execution_predicate().

◆ add_freqcounting_predicate()

static void add_freqcounting_predicate ( vec< ipa_freqcounting_predicate, va_gc > ** v,
const ipa_predicate & new_predicate,
sreal add_freq,
unsigned max_num_predicates )
static
Find if NEW_PREDICATE is already in V and if so, increment its freq.
Otherwise add a new item to the vector with this predicate and frerq equal
to add_freq, unless the number of predicates would exceed MAX_NUM_PREDICATES
in which case the function does nothing.   

References ipa_freqcounting_predicate::freq, ggc_alloc(), i, NULL, ipa_freqcounting_predicate::predicate, set_hint_predicate(), vec_safe_iterate(), vec_safe_length(), and vec_safe_push().

Referenced by analyze_function_body().

◆ analyze_function_body()

static void analyze_function_body ( struct cgraph_node * node,
bool early )
static
Analyze function body for NODE.
EARLY indicates run from early optimization pipeline.   

References ipa_fn_summary::account_size_time(), add_condition(), add_freqcounting_predicate(), basic_block_def::aux, BASIC_BLOCK_FOR_FN, bb_loop_depth(), bb_predicate(), calculate_dominance_info(), CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, clobber_only_eh_bb_p(), compute_bb_predicates(), basic_block_def::count, count, count_formal_params(), symtab_node::decl, DECL_STRUCT_FUNCTION, dump_file, dump_flags, symtab_node::dump_name(), edge_predicate_pool, edge_set_predicate(), eliminated_by_inlining_prob(), eni_size_weights, eni_time_weights, ENTRY_BLOCK_PTR_FOR_FN, estimate_num_insns(), find_foldable_builtin_expect(), flow_loops_dump(), FOR_ALL_BB_FN, FOR_EACH_EDGE, FOR_EACH_VEC_ELT, fp_expression_p(), ipa_fn_summary::fp_expressions, free(), free_dominance_info(), gcc_assert, cgraph_node::get_edge(), get_loop_body(), get_loop_exit_edges(), ggc_alloc(), gimple_assign_lhs(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_internal_p(), gimple_call_lhs(), gimple_call_num_args(), gimple_num_ops(), gimple_op(), gsi_end_p(), gsi_next(), gsi_next_nondebug(), gsi_start_bb(), gsi_start_nondebug_bb(), gsi_start_phis(), gsi_stmt(), handled_component_p(), loop::header, i, basic_block_def::index, ipa_func_body_info::info, ipa_call_summaries, ipa_check_create_node_params(), ipa_dump_fn_summary(), ipa_edge_args_sum, ipa_fn_summaries, ipa_free_all_node_params(), ipa_initialize_node_params(), ipa_node_params_sum, ipa_release_body_info(), ipa_size_summaries, is_gimple_assign(), is_gimple_call(), is_gimple_min_invariant(), last_basic_block_for_fn, load_or_store_of_ptr_parameter(), loop_containing_stmt(), ipa_fn_summary::loop_iterations, loop_optimizer_finalize(), loop_optimizer_init(), loop_preheader_edge(), ipa_fn_summary::loop_strides, loops_for_fn(), LOOPS_HAVE_RECORDED_EXITS, LOOPS_NORMAL, n_basic_blocks_for_fn, loop::next, cgraph_edge::next_speculative_call_target(), niter_desc::niter, ipa_func_body_info::node, ipa_predicate::not_inlined(), ipa_predicate::not_sra_candidate, NULL, loop::num_nodes, number_of_iterations_exit(), opt_for_fn, param_change_prob(), phi_result_unknown_predicate(), points_to_local_or_readonly_memory_p(), points_to_possible_sra_candidate_p(), pre_and_rev_post_order_compute(), predicate_for_phi_result(), print_gimple_stmt(), ptr_type_node, REG_BR_PROB_BASE, scev_finalize(), scev_initialize(), simple_iv(), ipa_fn_summary::size_scale, cgraph_edge::speculative_call_indirect_edge(), ss, SSA_NAME_VERSION, SSANAMES, iv::step, basic_block_def::succs, ipa_fn_summary::target_info, targetm, TDF_DETAILS, ipa_fn_summary::time, sreal::to_double(), profile_count::to_sreal_scale(), TREE_CODE, TREE_OPERAND, vec_free(), vNULL, will_be_nonconstant_expr_predicate(), and will_be_nonconstant_predicate().

Referenced by compute_fn_summary().

◆ clobber_only_eh_bb_p()

static bool clobber_only_eh_bb_p ( basic_block bb,
bool need_eh = true )
static
Return true when the basic blocks contains only clobbers followed by RESX.
Such BBs are kept around to make removal of dead stores possible with
presence of EH and will be optimized out by optimize_clobbers later in the
game. 

NEED_EH is used to recurse in case the clobber has non-EH predecessors
that can be clobber only, too.. When it is false, the RESX is not necessary
on the end of basic block.   

References clobber_only_eh_bb_p(), FOR_EACH_EDGE, ggc_alloc(), gimple_clobber_p(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), is_gimple_debug(), basic_block_def::preds, single_succ_p(), and record_modified_bb_info::stmt.

Referenced by analyze_function_body(), and clobber_only_eh_bb_p().

◆ compute_bb_predicates()

◆ compute_fn_summary()

void compute_fn_summary ( struct cgraph_node * node,
bool early )

◆ compute_fn_summary_for_current()

static unsigned int compute_fn_summary_for_current ( void )
static
Compute parameters of functions used by inliner using
current_function_decl.   

References compute_fn_summary(), current_function_decl, and cgraph_node::get().

◆ decompose_param_expr()

static bool decompose_param_expr ( struct ipa_func_body_info * fbi,
gimple * stmt,
tree expr,
int * index_p,
tree * type_p,
struct agg_position_info * aggpos,
expr_eval_ops * param_ops_p = NULL )
static
Analyze EXPR if it represents a series of simple operations performed on
a function parameter and return true if so.  FBI, STMT, EXPR, INDEX_P and
AGGPOS have the same meaning like in unmodified_parm_or_parm_agg_item.
Type of the parameter or load from an aggregate via the parameter is
stored in *TYPE_P.  Operations on the parameter are recorded to
PARAM_OPS_P if it is not NULL.   

References contains_bitfld_component_ref_p(), ERF_RETURN_ARG_MASK, ERF_RETURNS_ARG, gcc_assert, ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_call_arg(), gimple_call_num_args(), gimple_call_return_flags(), gimple_op(), GIMPLE_SINGLE_RHS, GIMPLE_TERNARY_RHS, GIMPLE_UNARY_RHS, i, is_gimple_assign(), is_gimple_ip_invariant(), NULL, NULL_TREE, opt_for_fn, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, TREE_CODE, TREE_TYPE, type(), TYPE_P, unmodified_parm_or_parm_agg_item(), vec_free(), and vec_safe_insert().

Referenced by set_cond_stmt_execution_predicate(), set_switch_stmt_execution_predicate(), and will_be_nonconstant_predicate().

◆ dump_ipa_call_summary()

◆ edge_set_predicate()

◆ eliminated_by_inlining_prob()

static int eliminated_by_inlining_prob ( ipa_func_body_info * fbi,
gimple * stmt )
static
See if statement might disappear after inlining.
0 - means not eliminated
1 - half of statements goes away
2 - for sure it is eliminated.
We are not terribly sophisticated, basically looking for simple abstraction
penalty wrappers.   

References CONVERT_EXPR_CODE_P, get_base_address(), ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), gimple_num_ops(), GIMPLE_SINGLE_RHS, is_gimple_min_invariant(), is_gimple_reg(), NULL, SSA_NAME_VAR, TREE_CODE, TREE_OPERAND, and unmodified_parm().

Referenced by analyze_function_body().

◆ estimate_calls_size_and_time()

◆ estimate_calls_size_and_time_1()

static void estimate_calls_size_and_time_1 ( struct cgraph_node * node,
int * size,
int * min_size,
sreal * time,
ipa_hints * hints,
clause_t possible_truths,
ipa_call_arg_values * avals )
static
Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
calls in NODE.  POSSIBLE_TRUTHS and AVALS describe the context of the call
site.

Helper for estimate_calls_size_and_time which does the same but
(in most cases) faster.   

References cgraph_edge::callee, cgraph_node::callees, estimate_calls_size_and_time_1(), estimate_edge_size_and_time(), gcc_checking_assert, ggc_alloc(), cgraph_node::indirect_calls, cgraph_edge::inline_failed, ipa_call_summaries, cgraph_edge::next_callee, and NULL.

Referenced by estimate_calls_size_and_time(), and estimate_calls_size_and_time_1().

◆ estimate_edge_devirt_benefit()

static bool estimate_edge_devirt_benefit ( struct cgraph_edge * ie,
int * size,
int * time,
ipa_call_arg_values * avals )
static
Estimate benefit devirtualizing indirect edge IE and return true if it can
be devirtualized and inlined, provided m_known_vals, m_known_contexts and
m_known_aggs in AVALS.  Return false straight away if AVALS is NULL.   

References AVAIL_AVAILABLE, eni_weights::call_cost, cgraph_edge::caller, symtab_node::decl, symtab_node::definition, eni_size_weights, eni_time_weights, cgraph_node::function_symbol(), gcc_checking_assert, cgraph_node::get(), ggc_alloc(), eni_weights::indirect_call_cost, ipa_fn_summaries, ipa_get_indirect_edge_target(), NULL, opt_for_fn, and ipa_fn_summary::time.

Referenced by estimate_edge_size_and_time().

◆ estimate_edge_size_and_time()

static void estimate_edge_size_and_time ( struct cgraph_edge * e,
int * size,
int * min_size,
sreal * time,
ipa_call_arg_values * avals,
ipa_hints * hints )
inlinestatic
Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
handle edge E with probability PROB.  Set HINTS accordingly if edge may be
devirtualized.  AVALS, if non-NULL, describes the context of the call site
as far as values of parameters are concerened.   

References cgraph_edge::callee, estimate_edge_devirt_benefit(), ggc_alloc(), INLINE_HINT_indirect_call, ipa_call_summaries, cgraph_edge::maybe_hot_p(), ipa_fn_summary::size_scale, and cgraph_edge::sreal_frequency().

Referenced by estimate_calls_size_and_time_1(), ipa_merge_fn_summary_after_inlining(), and summarize_calls_size_and_time().

◆ estimate_ipcp_clone_size_and_time()

void estimate_ipcp_clone_size_and_time ( struct cgraph_node * node,
ipa_auto_call_arg_values * avals,
ipa_call_estimates * estimates )
Estimate size and time needed to execute callee of EDGE assuming that
parameters known to be constant at caller of EDGE are propagated.
KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
and types for parameters.   

References ipa_call_context::estimate_size_and_time(), evaluate_conditions_for_known_args(), ggc_alloc(), NULL, and vNULL.

Referenced by estimate_local_effects(), and perform_estimation_of_a_value().

◆ evaluate_conditions_for_known_args()

static void evaluate_conditions_for_known_args ( struct cgraph_node * node,
bool inline_p,
ipa_auto_call_arg_values * avals,
clause_t * ret_clause,
clause_t * ret_nonspec_clause,
ipa_call_summary * es )
static
Compute what conditions may or may not hold given information about
parameters.  RET_CLAUSE returns truths that may hold in a specialized copy,
while RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
copy when called in a given context.  It is a bitmask of conditions. Bit
0 means that condition is known to be false, while bit 1 means that condition
may or may not be true.  These differs - for example NOT_INLINED condition
is always false in the second and also builtin_constant_p tests cannot use
the fact that parameter is indeed a constant.

When INLINE_P is true, assume that we are inlining.  AVAL contains known
information about argument values.  The function does not modify its content
and so AVALs could also be of type ipa_call_arg_values but so far all
callers work with the auto version and so we avoid the conversion for
convenience.

ERROR_MARK value of an argument means compile time invariant.   

References condition::agg_contents, boolean_type_node, condition::by_ref, ipa_predicate::changed, expr_eval_op::code, condition::code, ipa_fn_summary::conds, error_mark_node, ipa_predicate::first_dynamic_condition, fold_binary, fold_binary_to_constant(), range_op_handler::fold_range(), fold_ternary, fold_unary, ggc_alloc(), i, expr_eval_op::index, integer_onep(), integer_zerop(), ipa_find_agg_cst_from_init(), ipa_fn_summaries, ipa_range_set_and_normalize(), ipa_predicate::is_not_constant, ipa_predicate::not_inlined_condition, ipa_predicate::not_sra_candidate, NULL, NULL_TREE, condition::offset, condition::operand_num, condition::param_ops, range_cast(), Value_Range::set_varying(), irange::set_varying(), Value_Range::supports_type_p(), TREE_CODE, TREE_TYPE, expr_eval_op::type, condition::type, Value_Range::type(), TYPE_SIZE, Value_Range::undefined_p(), useless_type_conversion_p(), expr_eval_op::val, condition::val, Value_Range::varying_p(), vec_safe_iterate(), and irange::zero_p().

Referenced by ipa_fn_summary_t::duplicate(), estimate_ipcp_clone_size_and_time(), and evaluate_properties_for_edge().

◆ evaluate_properties_for_edge()

void evaluate_properties_for_edge ( struct cgraph_edge * e,
bool inline_p,
clause_t * clause_ptr,
clause_t * nonspec_clause_ptr,
ipa_auto_call_arg_values * avals,
bool compute_contexts )
Work out what conditions might be true at invocation of E.
Compute costs for inlined edge if INLINE_P is true.

Return in CLAUSE_PTR the evaluated conditions and in NONSPEC_CLAUSE_PTR
(if non-NULL) conditions evaluated for nonspecialized clone called
in a given context.

Vectors in AVALS will be populated with useful known information about
argument values - information not known to have any uses will be omitted -
except for m_known_contexts which will only be calculated if
COMPUTE_CONTEXTS is true.   

References cgraph_edge::call_stmt, cgraph_edge::call_stmt_cannot_inline_p, cgraph_edge::callee, cgraph_edge::caller, ipa_fn_summary::conds, count, error_mark_node, evaluate_conditions_for_known_args(), fre_will_run_p(), gcc_assert, gcc_checking_assert, ggc_alloc(), gimple_call_arg(), gimple_call_num_args(), i, cgraph_node::inlined_to, ipa_call_summaries, ipa_context_from_jfunc(), ipa_edge_args_sum, ipa_fn_summaries, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_param_count(), ipa_get_type(), ipa_is_param_used_by_indirect_call(), ipa_is_param_used_by_ipa_predicates(), ipa_is_param_used_by_polymorphic_call(), ipa_node_params_sum, ipa_push_agg_values_from_jfunc(), ipa_value_from_jfunc(), ipa_value_range_from_jfunc(), is_gimple_min_invariant(), MIN, ipa_predicate::not_inlined_condition, NULL, cgraph_node::thunk, TREE_CODE, cgraph_node::ultimate_alias_target(), Value_Range::undefined_p(), ipa_polymorphic_call_context::useless_p(), Value_Range::varying_p(), void_type_node, and vrp_will_run_p().

Referenced by do_estimate_edge_hints(), do_estimate_edge_size(), do_estimate_edge_time(), and ipa_merge_fn_summary_after_inlining().

◆ find_foldable_builtin_expect()

static gimple * find_foldable_builtin_expect ( basic_block bb)
static
For a typical usage of __builtin_expect (a<b, 1), we
may introduce an extra relation stmt:
With the builtin, we have
  t1 = a <= b;
  t2 = (long int) t1;
  t3 = __builtin_expect (t2, 1);
  if (t3 != 0)
    goto ...
Without the builtin, we have
  if (a<=b)
    goto...
This affects the size/time estimation and may have
an impact on the earlier inlining.
Here find this pattern and fix it up later.   

References CASE_CONVERT, gcc_assert, ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_internal_p(), gimple_call_lhs(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_assign(), NULL, single_imm_use(), SSA_NAME_DEF_STMT, record_modified_bb_info::stmt, and TREE_CODE.

Referenced by analyze_function_body().

◆ fp_expression_p()

static bool fp_expression_p ( gimple * stmt)
static
Return true if STMT compute a floating point expression that may be affected
by -ffast-math and similar flags.   

References FLOAT_TYPE_P, FOR_EACH_SSA_TREE_OPERAND, i, record_modified_bb_info::op, SSA_OP_DEF, SSA_OP_USE, record_modified_bb_info::stmt, and TREE_TYPE.

Referenced by analyze_function_body().

◆ fre_will_run_p()

static bool fre_will_run_p ( struct cgraph_node * node)
static
Similarly about FRE.   

References symtab_node::decl, ggc_alloc(), and opt_for_fn.

Referenced by evaluate_properties_for_edge().

◆ get_minimal_bb()

static basic_block get_minimal_bb ( basic_block init_bb,
basic_block use_bb )
static
Value is initialized in INIT_BB and used in USE_BB.  We want to compute
probability how often it changes between USE_BB.
INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
is in different loop nest, we can do better.
This is all just estimate.  In theory we look for minimal cut separating
INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
anyway.   

References basic_block_def::count, find_common_loop(), ggc_alloc(), loop::header, and basic_block_def::loop_father.

Referenced by param_change_prob(), and record_modified().

◆ inline_analyze_function()

◆ inline_indirect_intraprocedural_analysis()

static void inline_indirect_intraprocedural_analysis ( struct cgraph_node * node)
static
This function performs intraprocedural analysis in NODE that is required to
inline indirect calls.   

References dump_file, dump_flags, ipa_analyze_node(), ipa_print_node_jump_functions(), ipa_print_node_params(), and TDF_DETAILS.

Referenced by inline_analyze_function().

◆ inline_read_section()

static void inline_read_section ( struct lto_file_decl_data * file_data,
const char * data,
size_t len )
static
Stream in inline summaries from the section.   

References condition::agg_contents, bp_unpack_value(), ipa_fn_summary::builtin_constant_p_parms, condition::by_ref, cgraph_node::callees, lto_function_header::cfg_size, expr_eval_op::code, condition::code, ipa_fn_summary::conds, ipa_fn_summary::estimated_stack_size, size_time_entry::exec_predicate, fatal_error(), data_in::file_data, ipa_fn_summary::fp_expressions, gcc_assert, get_gimple_rhs_class(), ggc_alloc(), GIMPLE_BINARY_RHS, GIMPLE_TERNARY_RHS, GIMPLE_UNARY_RHS, i, expr_eval_op::index, cgraph_node::indirect_calls, ipa_fn_summary::inlinable, ipa_fn_summaries, ipa_node_params_sum, ipa_set_param_used_by_ipa_predicates(), ipa_size_summaries, ipa_fn_summary::loop_iterations, ipa_fn_summary::loop_strides, lto_data_in_create(), lto_data_in_delete(), lto_free_section_data(), LTO_section_ipa_fn_summary, lto_stream_offload_p, lto_symtab_encoder_deref(), lto_simple_header::main_size, cgraph_edge::next_callee, size_time_entry::nonconst_predicate, NULL, NULL_TREE, condition::offset, condition::operand_num, condition::param_ops, symtab_node::prevailing_p(), read_ipa_call_summary(), set_hint_predicate(), size_time_entry::size, ipa_fn_summary::size_time_table, sreal::stream_in(), ipa_predicate::stream_in(), stream_read_tree, streamer_read_bitpack(), streamer_read_uhwi(), lto_simple_header_with_strings::string_size, lto_file_decl_data::symtab_node_encoder, ipa_fn_summary::target_info, size_time_entry::time, ipa_fn_summary::time, expr_eval_op::type, condition::type, UNKNOWN_LOCATION, expr_eval_op::val, condition::val, vec_safe_push(), vec_safe_reserve_exact(), and vNULL.

Referenced by ipa_fn_summary_read().

◆ inline_update_callee_summaries()

static void inline_update_callee_summaries ( struct cgraph_node * node,
int depth )
static

◆ ipa_debug_fn_summary()

DEBUG_FUNCTION void ipa_debug_fn_summary ( struct cgraph_node * node)
In ipa-fnsummary.cc   

References ggc_alloc(), and ipa_dump_fn_summary().

◆ ipa_dump_fn_summaries()

void ipa_dump_fn_summaries ( FILE * f)

◆ ipa_dump_fn_summary()

◆ ipa_dump_hints()

◆ ipa_fn_summary_alloc()

◆ ipa_fn_summary_generate()

◆ ipa_fn_summary_read()

static void ipa_fn_summary_read ( void )
static
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.   

References fatal_error(), gcc_assert, ggc_alloc(), inline_read_section(), input_location, ipa_fn_summaries, ipa_fn_summary_alloc(), ipa_prop_read_jump_functions(), ipa_register_cgraph_hooks(), lto_get_file_decl_data(), lto_get_summary_section_data(), and LTO_section_ipa_fn_summary.

◆ ipa_fn_summary_write()

static void ipa_fn_summary_write ( void )
static
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.   

References condition::agg_contents, bitpack_create(), bp_pack_value(), ipa_fn_summary::builtin_constant_p_parms, condition::by_ref, expr_eval_op::code, condition::code, ipa_fn_summary::conds, count, create_output_block(), output_block::decl_state, destroy_output_block(), size_time_entry::exec_predicate, ipa_fn_summary::fp_expressions, ggc_alloc(), i, expr_eval_op::index, ipa_fn_summary::inlinable, ipa_fn_summaries, ipa_prop_write_jump_functions(), ipa_size_summaries, ipa_fn_summary::loop_iterations, ipa_fn_summary::loop_strides, lsei_cgraph_node(), lsei_end_p(), lsei_next_function_in_partition(), lsei_start_function_in_partition(), LTO_section_ipa_fn_summary, lto_stream_offload_p, lto_symtab_encoder_encode(), output_block::main_stream, size_time_entry::nonconst_predicate, NULL, condition::offset, condition::operand_num, condition::param_ops, produce_asm(), size_time_entry::size, ipa_fn_summary::size_time_table, ipa_predicate::stream_out(), sreal::stream_out(), stream_write_tree, streamer_write_bitpack(), streamer_write_char_stream(), streamer_write_hwi(), streamer_write_uhwi(), lto_out_decl_state::symtab_node_encoder, ipa_fn_summary::target_info, size_time_entry::time, ipa_fn_summary::time, expr_eval_op::type, condition::type, expr_eval_op::val, condition::val, vec_safe_iterate(), vec_safe_length(), and write_ipa_call_summary().

◆ ipa_fnsummary_cc_finalize()

void ipa_fnsummary_cc_finalize ( void )
Reset all state within ipa-fnsummary.cc so that we can rerun the compiler
within the same process.  For use by toplev::finalize.   

References ipa_free_fn_summary(), and ipa_free_size_summary().

Referenced by toplev::finalize().

◆ ipa_free_fn_summary()

◆ ipa_free_size_summary()

void ipa_free_size_summary ( void )
Release function summary.   

References ipa_size_summaries, and NULL.

Referenced by ipa_fnsummary_cc_finalize(), and symbol_table::process_new_functions().

◆ ipa_get_stack_frame_offset()

HOST_WIDE_INT ipa_get_stack_frame_offset ( struct cgraph_node * node)
Return stack frame offset where frame of NODE is supposed to start inside
of the function it is inlined to.
Return 0 for functions that are not inlined.   

References cgraph_edge::caller, cgraph_node::callers, ggc_alloc(), cgraph_node::inlined_to, ipa_size_summaries, and offset.

Referenced by caller_growth_limits(), dump_ipa_call_summary(), and ipa_merge_fn_summary_after_inlining().

◆ ipa_merge_fn_summary_after_inlining()

◆ ipa_update_overall_fn_summary()

◆ load_or_store_of_ptr_parameter()

static int load_or_store_of_ptr_parameter ( ipa_func_body_info * fbi,
gimple * stmt )
static
If stmt is simple load or store of value pointed to by a function parmaeter,
return its index.   

References get_base_address(), ggc_alloc(), gimple_assign_lhs(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_store_p(), ipa_get_param_decl_index(), SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, TREE_CODE, and TREE_OPERAND.

Referenced by analyze_function_body().

◆ make_pass_ipa_fn_summary()

ipa_opt_pass_d * make_pass_ipa_fn_summary ( gcc::context * ctxt)

References ggc_alloc().

◆ make_pass_ipa_free_fn_summary()

simple_ipa_opt_pass * make_pass_ipa_free_fn_summary ( gcc::context * ctxt)

References ggc_alloc().

◆ make_pass_local_fn_summary()

gimple_opt_pass * make_pass_local_fn_summary ( gcc::context * ctxt)

References ggc_alloc().

◆ mark_modified()

static bool mark_modified ( ao_ref * ao,
tree vdef,
void * data )
static
Callback of walk_aliased_vdefs.  Flags that it has been invoked to the
boolean variable pointed to by DATA.   

References b.

Referenced by unmodified_parm_1().

◆ param_change_prob()

static int param_change_prob ( ipa_func_body_info * fbi,
gimple * stmt,
int i )
static

◆ phi_result_unknown_predicate()

static bool phi_result_unknown_predicate ( ipa_func_body_info * fbi,
ipa_fn_summary * summary,
class ipa_node_params * params_summary,
basic_block bb,
ipa_predicate * p,
vec< ipa_predicate > nonconstant_names )
static
Find whether a basic block BB is the final block of a (half) diamond CFG
sub-graph and if the predicate the condition depends on is known.  If so,
return true and store the pointer the predicate in *P.   

References FOR_EACH_EDGE, ggc_alloc(), gimple_cond_lhs(), gimple_cond_rhs(), gsi_last_bb(), is_gimple_ip_invariant(), NULL, basic_block_def::preds, single_pred(), single_pred_p(), single_succ_p(), record_modified_bb_info::stmt, and will_be_nonconstant_expr_predicate().

Referenced by analyze_function_body().

◆ points_to_local_or_readonly_memory_p()

bool points_to_local_or_readonly_memory_p ( tree t)
Return true if T is a pointer pointing to memory location that is local
for the function (that means, dead after return) or read-only.   

References cfun, current_function_decl, DECL_BY_REFERENCE, DECL_RESULT, ggc_alloc(), integer_zerop(), ptr_deref_may_alias_global_p(), refs_local_or_readonly_memory_p(), ssa_default_def(), TREE_CODE, and TREE_OPERAND.

Referenced by analyze_function_body(), refs_local_or_readonly_memory_p(), and remap_edge_params().

◆ points_to_possible_sra_candidate_p()

static bool points_to_possible_sra_candidate_p ( tree t)
static
Return true if T is a pointer pointing to memory location that is possible
sra candidate if all functions it is passed to are inlined.   

References auto_var_in_fn_p(), current_function_decl, DECL_P, get_base_address(), ggc_alloc(), TREE_CODE, and TREE_OPERAND.

Referenced by analyze_function_body().

◆ predicate_for_phi_result()

static void predicate_for_phi_result ( class ipa_fn_summary * summary,
gphi * phi,
ipa_predicate * p,
vec< ipa_predicate > nonconstant_names )
static
Given a PHI statement in a function described by inline properties SUMMARY
and *P being the predicate describing whether the selected PHI argument is
known, store a predicate for the result of the PHI statement into
NONCONSTANT_NAMES, if possible.   

References ipa_predicate::dump(), dump_file, dump_flags, gcc_assert, ggc_alloc(), gimple_phi_arg(), gimple_phi_num_args(), gimple_phi_result(), i, is_gimple_min_invariant(), ipa_predicate::or_with(), SSA_NAME_VERSION, TDF_DETAILS, and TREE_CODE.

Referenced by analyze_function_body().

◆ read_ipa_call_summary()

◆ record_modified()

◆ redirect_to_unreachable()

◆ refs_local_or_readonly_memory_p()

bool refs_local_or_readonly_memory_p ( tree t)
Return true if T references memory location that is local
for the function (that means, dead after return) or read-only.   

References auto_var_in_fn_p(), current_function_decl, DECL_P, get_base_address(), ggc_alloc(), points_to_local_or_readonly_memory_p(), TREE_CODE, TREE_OPERAND, and TREE_READONLY.

Referenced by check_op(), and points_to_local_or_readonly_memory_p().

◆ remap_edge_params()

static void remap_edge_params ( struct cgraph_edge * inlined_edge,
struct cgraph_edge * edge )
static
Update change_prob and points_to_local_or_readonly_memory of EDGE after
INLINED_EDGE has been inlined.

When function A is inlined in B and A calls C with parameter that
changes with probability PROB1 and C is known to be passthrough
of argument if B that change with probability PROB2, the probability
of change is now PROB1*PROB2.   

References combine_probabilities(), ggc_alloc(), i, ipa_call_summaries, ipa_edge_args_sum, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_jf_ancestor_formal_id(), ipa_get_jf_constant(), ipa_get_jf_pass_through_formal_id(), IPA_JF_ANCESTOR, IPA_JF_CONST, IPA_JF_PASS_THROUGH, ipa_node_params_sum, and points_to_local_or_readonly_memory_p().

Referenced by remap_edge_summaries().

◆ remap_edge_summaries()

static void remap_edge_summaries ( struct cgraph_edge * inlined_edge,
struct cgraph_node * node,
class ipa_fn_summary * info,
class ipa_node_params * params_summary,
class ipa_fn_summary * callee_info,
const vec< int > & operand_map,
const vec< HOST_WIDE_INT > & offset_map,
clause_t possible_truths,
ipa_predicate * toplev_predicate )
static
Update edge summaries of NODE after INLINED_EDGE has been inlined.

Remap predicates of callees of NODE.  Rest of arguments match
remap_predicate.

Also update change probabilities.   

References cgraph_edge::callee, cgraph_node::callees, edge_set_predicate(), ggc_alloc(), cgraph_node::indirect_calls, cgraph_edge::inline_failed, ipa_call_summaries, cgraph_edge::next_callee, remap_edge_params(), and remap_edge_summaries().

Referenced by ipa_merge_fn_summary_after_inlining(), and remap_edge_summaries().

◆ remap_freqcounting_predicate()

static void remap_freqcounting_predicate ( class ipa_fn_summary * info,
class ipa_node_params * params_summary,
class ipa_fn_summary * callee_info,
vec< ipa_freqcounting_predicate, va_gc > * v,
const vec< int > & operand_map,
const vec< HOST_WIDE_INT > & offset_map,
clause_t possible_truths,
ipa_predicate * toplev_predicate )
static
Run remap_after_inlining on each predicate in V.   

References ggc_alloc(), i, and vec_safe_iterate().

Referenced by ipa_merge_fn_summary_after_inlining().

◆ remap_freqcounting_preds_after_dup()

static vec< ipa_freqcounting_predicate, va_gc > * remap_freqcounting_preds_after_dup ( vec< ipa_freqcounting_predicate, va_gc > * v,
clause_t possible_truths )
static
Duplicate predicates in loop hint vector, allocating memory for them and
remove and deallocate any uninteresting (true or false) ones.  Return the
result.   

References ggc_alloc(), i, NULL, set_hint_predicate(), and vec_safe_length().

Referenced by ipa_fn_summary_t::duplicate().

◆ set_cond_stmt_execution_predicate()

◆ set_hint_predicate()

static void set_hint_predicate ( ipa_predicate ** p,
ipa_predicate new_predicate )
static

◆ set_switch_stmt_execution_predicate()

◆ summarize_calls_size_and_time()

◆ unmodified_parm()

static tree unmodified_parm ( ipa_func_body_info * fbi,
gimple * stmt,
tree op,
poly_int64 * size_p )
static
If OP refers to value of function parameter, return the corresponding
parameter.  Also traverse chains of SSA register assignments.  If non-NULL,
the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
stored to *SIZE_P in that case too.   

References ggc_alloc(), gimple_assign_rhs1(), gimple_assign_single_p(), NULL_TREE, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, TREE_CODE, unmodified_parm(), and unmodified_parm_1().

Referenced by eliminated_by_inlining_prob(), unmodified_parm(), will_be_nonconstant_expr_predicate(), and will_be_nonconstant_predicate().

◆ unmodified_parm_1()

static tree unmodified_parm_1 ( ipa_func_body_info * fbi,
gimple * stmt,
tree op,
poly_int64 * size_p )
static
If OP refers to value of function parameter, return the corresponding
parameter.  If non-NULL, the size of the memory load (or the SSA_NAME of the
PARM_DECL) will be stored to *SIZE_P in that case too.   

References ao_ref_init(), ggc_alloc(), gimple_vuse(), mark_modified(), NULL, NULL_TREE, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, TREE_CODE, tree_to_poly_int64(), TREE_TYPE, TYPE_SIZE, and walk_aliased_vdefs().

Referenced by unmodified_parm(), and unmodified_parm_or_parm_agg_item().

◆ unmodified_parm_or_parm_agg_item()

static bool unmodified_parm_or_parm_agg_item ( struct ipa_func_body_info * fbi,
gimple * stmt,
tree op,
int * index_p,
poly_int64 * size_p,
struct agg_position_info * aggpos )
static
If OP refers to a value of a function parameter or value loaded from an
aggregate passed to a parameter (either by value or reference), return TRUE
and store the number of the parameter to *INDEX_P, the access size into
*SIZE_P, and information whether and how it has been loaded from an
aggregate into *AGGPOS.  INFO describes the function parameters, STMT is the
statement in which OP is used or loaded.   

References gcc_checking_assert, ggc_alloc(), gimple_assign_rhs1(), gimple_assign_single_p(), ipa_get_param_decl_index(), ipa_load_from_parm_agg(), REFERENCE_CLASS_P, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, TREE_CODE, unmodified_parm_1(), and unmodified_parm_or_parm_agg_item().

Referenced by decompose_param_expr(), and unmodified_parm_or_parm_agg_item().

◆ vrp_will_run_p()

static bool vrp_will_run_p ( struct cgraph_node * node)
static
Return true if VRP will be exectued on the function.
We do not want to anticipate optimizations that will not happen.

FIXME: This can be confused with -fdisable and debug counters and thus
it should not be used for correctness (only to make heuristics work).
This means that inliner should do its own optimizations of expressions
that it predicts to be constant so wrong code can not be triggered by
builtin_constant_p.   

References symtab_node::decl, ggc_alloc(), and opt_for_fn.

Referenced by evaluate_properties_for_edge().

◆ will_be_nonconstant_expr_predicate()

◆ will_be_nonconstant_predicate()

◆ write_ipa_call_summary()

static void write_ipa_call_summary ( struct output_block * ob,
struct cgraph_edge * e )
static

Variable Documentation

◆ edge_predicate_pool

◆ ipa_call_summaries

◆ ipa_fn_summaries

◆ ipa_size_summaries