GCC Middle and Back End API Reference
value-prof.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "ssa.h"
#include "cgraph.h"
#include "coverage.h"
#include "data-streamer.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "tree-nested.h"
#include "calls.h"
#include "expr.h"
#include "value-prof.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "gimple-pretty-print.h"
#include "dumpfile.h"
#include "builtins.h"
Include dependency graph for value-prof.cc:

Typedefs

typedef int_hash< unsigned int, 0, UINT_MAXprofile_id_hash
 

Functions

static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *)
 
static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *)
 
static bool gimple_mod_subtract_transform (gimple_stmt_iterator *)
 
static bool gimple_stringops_transform (gimple_stmt_iterator *)
 
static void dump_ic_profile (gimple_stmt_iterator *gsi)
 
histogram_value gimple_alloc_histogram_value (struct function *fun, enum hist_type type, gimple *stmt, tree value)
 
static hashval_t histogram_hash (const void *x)
 
static int histogram_eq (const void *x, const void *y)
 
static void set_histogram_value (struct function *fun, gimple *stmt, histogram_value hist)
 
histogram_value gimple_histogram_value (struct function *fun, gimple *stmt)
 
void gimple_add_histogram_value (struct function *fun, gimple *stmt, histogram_value hist)
 
void gimple_remove_histogram_value (struct function *fun, gimple *stmt, histogram_value hist)
 
histogram_value gimple_histogram_value_of_type (struct function *fun, gimple *stmt, enum hist_type type)
 
static void dump_histogram_value (FILE *dump_file, histogram_value hist)
 
void stream_out_histogram_value (struct output_block *ob, histogram_value hist)
 
void stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
 
void dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple *stmt)
 
void gimple_remove_stmt_histograms (struct function *fun, gimple *stmt)
 
void gimple_duplicate_stmt_histograms (struct function *fun, gimple *stmt, struct function *ofun, gimple *ostmt)
 
void gimple_move_stmt_histograms (struct function *fun, gimple *stmt, gimple *ostmt)
 
static int visit_hist (void **slot, void *data)
 
DEBUG_FUNCTION void verify_histograms (void)
 
static int free_hist (void **slot, void *data)
 
void free_histograms (struct function *fn)
 
static bool check_counter (gimple *stmt, const char *name, gcov_type *count, gcov_type *all, profile_count bb_count_d)
 
bool gimple_value_profile_transformations (void)
 
static tree gimple_divmod_fixed_value (gassign *stmt, tree value, profile_probability prob, gcov_type count, gcov_type all)
 
bool get_nth_most_common_value (gimple *stmt, const char *counter_type, histogram_value hist, gcov_type *value, gcov_type *count, gcov_type *all, unsigned n)
 
static tree gimple_mod_pow2 (gassign *stmt, profile_probability prob, gcov_type count, gcov_type all)
 
static tree gimple_mod_subtract (gassign *stmt, profile_probability prob1, profile_probability prob2, int ncounts, gcov_type count1, gcov_type count2, gcov_type all)
 
bool coverage_node_map_initialized_p (void)
 
void init_node_map (bool local)
 
void del_node_map (void)
 
struct cgraph_nodefind_func_by_profile_id (int profile_id)
 
gcallgimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, profile_probability prob)
 
static bool interesting_stringop_to_profile_p (gcall *call, int *size_arg)
 
static void gimple_stringop_fixed_value (gcall *vcall_stmt, tree icall_size, profile_probability prob, gcov_type count, gcov_type all)
 
void stringop_block_profile (gimple *stmt, unsigned int *expected_align, HOST_WIDE_INT *expected_size)
 
static void gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
 
static void gimple_indirect_call_to_profile (gimple *stmt, histogram_values *values)
 
static void gimple_stringops_values_to_profile (gimple *gs, histogram_values *values)
 
static void gimple_values_to_profile (gimple *stmt, histogram_values *values)
 
void gimple_find_values_to_profile (histogram_values *values)
 

Variables

static bool error_found = false
 
static hash_map< profile_id_hash, cgraph_node * > * cgraph_node_map = 0
 

Typedef Documentation

◆ profile_id_hash

Function Documentation

◆ check_counter()

static bool check_counter ( gimple * stmt,
const char * name,
gcov_type * count,
gcov_type * all,
profile_count bb_count_d )
static
The overall number of invocations of the counter should match
execution count of basic block.  Report it as error rather than
internal error as it might mean that user has misused the profile
somehow.   

References count, current_function_decl, dump_enabled_p(), dump_printf_loc(), error_at(), dump_user_location_t::from_function_decl(), dump_user_location_t::get_location_t(), ggc_alloc(), MSG_MISSED_OPTIMIZATION, and NULL.

Referenced by get_nth_most_common_value(), gimple_mod_pow2_value_transform(), gimple_mod_subtract_transform(), and gimple_stringops_transform().

◆ coverage_node_map_initialized_p()

bool coverage_node_map_initialized_p ( void )
Returns true if node graph is initialized. This
is used to test if profile_id has been created
for cgraph_nodes.   

References cgraph_node_map.

Referenced by coverage_begin_function(), coverage_end_function(), and get_coverage_counts().

◆ del_node_map()

void del_node_map ( void )
Delete the CGRAPH_NODE_MAP.   

References cgraph_node_map.

Referenced by ipa_profile(), and tree_profiling().

◆ dump_histogram_value()

◆ dump_histograms_for_stmt()

void dump_histograms_for_stmt ( struct function * fun,
FILE * dump_file,
gimple * stmt )
Dump all histograms attached to STMT to DUMP_FILE.   

References dump_file, dump_histogram_value(), ggc_alloc(), and gimple_histogram_value().

Referenced by gimple_dump_bb_buff(), and gimple_value_profile_transformations().

◆ dump_ic_profile()

◆ find_func_by_profile_id()

struct cgraph_node * find_func_by_profile_id ( int profile_id)
Return cgraph node for function with pid  

References cgraph_node_map, cgraph_node::get(), NULL, and cgraph_node::profile_id.

Referenced by speculative_call_summary::dump(), dump_ic_profile(), and ipa_profile().

◆ free_hist()

static int free_hist ( void ** slot,
void * data )
static
Helper function for verify_histograms.  For each histogram reachable via htab
walk verify that it was reached via statement walk.   

References free(), and ggc_alloc().

Referenced by free_histograms().

◆ free_histograms()

void free_histograms ( struct function * fn)

◆ get_nth_most_common_value()

bool get_nth_most_common_value ( gimple * stmt,
const char * counter_type,
histogram_value hist,
gcov_type * value,
gcov_type * count,
gcov_type * all,
unsigned n )
Return the n-th value count of TOPN_VALUE histogram.  If
there's a value, return true and set VALUE and COUNT
arguments.

Counters have the following meaning.

abs (counters[0]) is the number of executions
for i in 0 ... TOPN-1
  counters[2 * i + 2] is target
  counters[2 * i + 3] is corresponding hitrate counter.

Value of counters[0] negative when counter became
full during merging and some values are lost.   

References abs_hwi(), check_counter(), count, dump_file, ggc_alloc(), gimple_bb(), i, PROFILE_REPRODUCIBILITY_MULTITHREADED, and PROFILE_REPRODUCIBILITY_PARALLEL_RUNS.

Referenced by dump_ic_profile(), gimple_divmod_fixed_value_transform(), gimple_stringops_transform(), and ipa_profile_generate_summary().

◆ gimple_add_histogram_value()

◆ gimple_alloc_histogram_value()

◆ gimple_divmod_fixed_value()

static tree gimple_divmod_fixed_value ( gassign * stmt,
tree value,
profile_probability prob,
gcov_type count,
gcov_type all )
static
Generate code for transformation 1 (with parent gimple assignment
STMT and probability of taking the optimal path PROB, which is
equivalent to COUNT/ALL within roundoff error).  This generates the
result into a temp and returns the temp; it does not replace or
alter the original STMT.   

References profile_probability::always(), count, create_tmp_reg(), fold_convert, profile_count::from_gcov_type(), gcc_assert, ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_build_assign(), gimple_build_cond(), gsi_for_stmt(), gsi_insert_before(), GSI_SAME_STMT, profile_probability::invert(), is_gimple_assign(), make_edge(), make_temp_ssa_name(), NULL, NULL_TREE, remove_edge(), split_block(), and TREE_TYPE.

Referenced by gimple_divmod_fixed_value_transform().

◆ gimple_divmod_fixed_value_transform()

static bool gimple_divmod_fixed_value_transform ( gimple_stmt_iterator * si)
static
Transformations based on profile information for values.
   Copyright (C) 2003-2024 Free Software Foundation, Inc.

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/>.   
In this file value profile based optimizations are placed.  Currently the
  following optimizations are implemented (for more detailed descriptions
  see comments at value_profile_transformations):

  1) Division/modulo specialization.  Provided that we can determine that the
     operands of the division have some special properties, we may use it to
     produce more effective code.

  2) Indirect/virtual call specialization. If we can determine most
     common function callee in indirect/virtual call. We can use this
     information to improve code effectiveness (especially info for
     the inliner).

  3) Speculative prefetching.  If we are able to determine that the difference
     between addresses accessed by a memory reference is usually constant, we
     may add the prefetch instructions.
     FIXME: This transformation was removed together with RTL based value
     profiling.


  Value profiling internals
  ==========================

  Every value profiling transformation starts with defining what values
  to profile.  There are different histogram types (see HIST_TYPE_* in
  value-prof.h) and each transformation can request one or more histogram
  types per GIMPLE statement.  The function gimple_find_values_to_profile()
  collects the values to profile in a vec, and adds the number of counters
  required for the different histogram types.

  For a -fprofile-generate run, the statements for which values should be
  recorded, are instrumented in instrument_values().  The instrumentation
  is done by helper functions that can be found in tree-profile.cc, where
  new types of histograms can be added if necessary.

  After a -fprofile-use, the value profiling data is read back in by
  compute_value_histograms() that translates the collected data to
  histograms and attaches them to the profiled statements via
  gimple_add_histogram_value().  Histograms are stored in a hash table
  that is attached to every intrumented function, see VALUE_HISTOGRAMS
  in function.h.
  
  The value-profile transformations driver is the function
  gimple_value_profile_transformations().  It traverses all statements in
  the to-be-transformed function, and looks for statements with one or
  more histograms attached to it.  If a statement has histograms, the
  transformation functions are called on the statement.

  Limitations / FIXME / TODO:
  * Only one histogram of each type can be associated with a statement.
  * Some value profile transformations are done in builtins.cc (?!)
  * Updating of histograms needs some TLC.
  * The value profiling code could be used to record analysis results
    from non-profiling (e.g. VRP).
  * Adding new profilers should be simplified, starting with a cleanup
    of what-happens-where and with making gimple_find_values_to_profile
    and gimple_value_profile_transformations table-driven, perhaps...
Do transform 1) on INSN if applicable.   

References a, build_int_cst(), cfun, count, dump_enabled_p(), dump_printf_loc(), wide_int_storage::from_array(), get_gcov_type(), get_nth_most_common_value(), ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_bb(), gimple_divmod_fixed_value(), gimple_histogram_value_of_type(), gimple_remove_histogram_value(), gsi_stmt(), HIST_TYPE_TOPN_VALUES, histogram, HOST_BITS_PER_WIDE_INT, INTEGRAL_TYPE_P, MSG_OPTIMIZED_LOCATIONS, profile_probability::never(), optimize_bb_for_size_p(), profile_probability::probability_in_gcov_type(), si, simple_cst_equal(), TREE_TYPE, TYPE_PRECISION, update_stmt(), and wide_int_to_tree().

Referenced by gimple_value_profile_transformations().

◆ gimple_divmod_values_to_profile()

static void gimple_divmod_values_to_profile ( gimple * stmt,
histogram_values * values )
static

◆ gimple_duplicate_stmt_histograms()

◆ gimple_find_values_to_profile()

◆ gimple_histogram_value()

◆ gimple_histogram_value_of_type()

◆ gimple_ic()

◆ gimple_indirect_call_to_profile()

static void gimple_indirect_call_to_profile ( gimple * stmt,
histogram_values * values )
static
Find calls inside STMT for that we want to measure histograms for
indirect/virtual call optimization.  

References cfun, ggc_alloc(), gimple_alloc_histogram_value(), gimple_call_fn(), gimple_call_fndecl(), gimple_call_internal_p(), HIST_TYPE_INDIR_CALL, and NULL_TREE.

Referenced by gimple_values_to_profile().

◆ gimple_mod_pow2()

static tree gimple_mod_pow2 ( gassign * stmt,
profile_probability prob,
gcov_type count,
gcov_type all )
static
Generate code for transformation 2 (with parent gimple assign STMT and
probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
within roundoff error).  This generates the result into a temp and returns
the temp; it does not replace or alter the original STMT.   

References profile_probability::always(), build_int_cst(), count, create_tmp_reg(), profile_count::from_gcov_type(), gcc_assert, ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_build_assign(), gimple_build_cond(), gsi_for_stmt(), gsi_insert_before(), GSI_SAME_STMT, profile_probability::invert(), is_gimple_assign(), make_edge(), make_temp_ssa_name(), NULL, NULL_TREE, remove_edge(), split_block(), and TREE_TYPE.

Referenced by gimple_mod_pow2_value_transform().

◆ gimple_mod_pow2_value_transform()

◆ gimple_mod_subtract()

static tree gimple_mod_subtract ( gassign * stmt,
profile_probability prob1,
profile_probability prob2,
int ncounts,
gcov_type count1,
gcov_type count2,
gcov_type all )
static
Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
NCOUNTS the number of cases to support.  Currently only NCOUNTS==0 or 1 is
supported and this is built into this interface.  The probabilities of taking
the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
COUNT2/ALL respectively within roundoff error).  This generates the
result into a temp and returns the temp; it does not replace or alter
the original STMT.   
FIXME: Generalize the interface to handle NCOUNTS > 1.   

References profile_probability::always(), create_tmp_reg(), profile_count::from_gcov_type(), gcc_assert, ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_build_assign(), gimple_build_cond(), gsi_for_stmt(), gsi_insert_before(), GSI_SAME_STMT, is_gimple_assign(), make_edge(), make_temp_ssa_name(), NULL, NULL_TREE, split_block(), and TREE_TYPE.

Referenced by gimple_mod_subtract_transform().

◆ gimple_mod_subtract_transform()

◆ gimple_move_stmt_histograms()

void gimple_move_stmt_histograms ( struct function * fun,
gimple * stmt,
gimple * ostmt )

◆ gimple_remove_histogram_value()

◆ gimple_remove_stmt_histograms()

void gimple_remove_stmt_histograms ( struct function * fun,
gimple * stmt )
Remove all histograms associated with STMT.   

References gimple_histogram_value(), gimple_remove_histogram_value(), and NULL.

Referenced by gsi_remove(), gsi_replace(), and move_block_to_fn().

◆ gimple_stringop_fixed_value()

◆ gimple_stringops_transform()

◆ gimple_stringops_values_to_profile()

static void gimple_stringops_values_to_profile ( gimple * gs,
histogram_values * values )
static

◆ gimple_value_profile_transformations()

◆ gimple_values_to_profile()

static void gimple_values_to_profile ( gimple * stmt,
histogram_values * values )
static
Find values inside STMT for that we want to measure histograms and adds
them to list VALUES.   

References gimple_divmod_values_to_profile(), gimple_indirect_call_to_profile(), and gimple_stringops_values_to_profile().

Referenced by gimple_find_values_to_profile().

◆ histogram_eq()

static int histogram_eq ( const void * x,
const void * y )
static
Return nonzero if statement for histogram_value X is Y.   

References y.

Referenced by set_histogram_value().

◆ histogram_hash()

static hashval_t histogram_hash ( const void * x)
static
Hash value for histogram.   

References ggc_alloc().

◆ init_node_map()

void init_node_map ( bool local)

◆ interesting_stringop_to_profile_p()

static bool interesting_stringop_to_profile_p ( gcall * call,
int * size_arg )
static
Return true if the stringop CALL shall be profiled.  SIZE_ARG be
set to the argument index for the size of the string operation.   

References DECL_FUNCTION_CODE(), ggc_alloc(), gimple_call_fndecl(), and validate_gimple_arglist().

Referenced by gimple_stringop_fixed_value(), gimple_stringops_transform(), and gimple_stringops_values_to_profile().

◆ set_histogram_value()

static void set_histogram_value ( struct function * fun,
gimple * stmt,
histogram_value hist )
static

◆ stream_in_histogram_value()

◆ stream_out_histogram_value()

◆ stringop_block_profile()

◆ verify_histograms()

◆ visit_hist()

static int visit_hist ( void ** slot,
void * data )
static
Helper function for verify_histograms.  For each histogram reachable via htab
walk verify that it was reached via statement walk.   

References debug_gimple_stmt(), dump_histogram_value(), error(), error_found, ggc_alloc(), HIST_TYPE_TIME_PROFILE, and visited.

Referenced by verify_histograms().

Variable Documentation

◆ cgraph_node_map

◆ error_found