GCC Middle and Back End API Reference
ipa-inline.h File Reference
#include "ipa-prop.h"
Include dependency graph for ipa-inline.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  condition
struct  predicate
struct  size_time_entry
struct  inline_summary
struct  inline_param_summary
struct  inline_edge_summary
struct  edge_growth_cache_entry

Macros

#define MAX_CLAUSES   8
#define INLINE_SIZE_SCALE   2
#define INLINE_TIME_SCALE   (CGRAPH_FREQ_BASE * 2)

Typedefs

typedef struct condition condition
typedef int inline_hints
typedef vec< condition, va_gc > * conditions
typedef unsigned int clause_t
typedef struct size_time_entry size_time_entry
typedef struct inline_summary inline_summary_t
typedef struct inline_param_summary inline_param_summary_t
typedef struct inline_edge_summary inline_edge_summary_t
typedef struct
edge_growth_cache_entry 
edge_growth_cache_entry

Enumerations

enum  inline_hints_vals {
  INLINE_HINT_indirect_call = 1, INLINE_HINT_loop_iterations = 2, INLINE_HINT_loop_stride = 4, INLINE_HINT_same_scc = 8,
  INLINE_HINT_in_scc = 16, INLINE_HINT_declared_inline = 32, INLINE_HINT_cross_module = 64, INLINE_HINT_array_index = 128
}

Functions

void debug_inline_summary (struct cgraph_node *)
void dump_inline_summaries (FILE *f)
void dump_inline_summary (FILE *f, struct cgraph_node *node)
void dump_inline_hints (FILE *f, inline_hints)
void inline_generate_summary (void)
void inline_read_summary (void)
void inline_write_summary (void)
void inline_free_summary (void)
void initialize_inline_failed (struct cgraph_edge *)
int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *)
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *)
void estimate_ipcp_clone_size_and_time (struct cgraph_node *, vec< tree >, vec< tree >, vec< ipa_agg_jump_function_p >, int *, int *, inline_hints *)
int do_estimate_growth (struct cgraph_node *)
void inline_merge_summary (struct cgraph_edge *edge)
void inline_update_overall_summary (struct cgraph_node *node)
int do_estimate_edge_size (struct cgraph_edge *edge)
int do_estimate_edge_time (struct cgraph_edge *edge)
inline_hints do_estimate_edge_hints (struct cgraph_edge *edge)
void initialize_growth_caches (void)
void free_growth_caches (void)
void compute_inline_parameters (struct cgraph_node *, bool)
bool speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
bool inline_call (struct cgraph_edge *, bool, vec< cgraph_edge_p > *, int *, bool)
unsigned int inline_transform (struct cgraph_node *)
void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *)
static struct inline_summaryinline_summary ()
static struct inline_edge_summaryinline_edge_summary ()
static int estimate_growth ()
static int estimate_edge_size ()
static int estimate_edge_growth ()
static int estimate_edge_time ()
static inline_hints estimate_edge_hints ()
static void reset_node_growth_cache ()
static void reset_edge_growth_cache ()

Variables

vec< inline_summary_t, va_gc > * inline_summary_vec
vec< inline_edge_summary_tinline_edge_summary_vec
vec< int > node_growth_cache
vec< edge_growth_cache_entryedge_growth_cache
int ncalls_inlined
int nfunctions_inlined

Macro Definition Documentation

#define INLINE_SIZE_SCALE   2

Represnetation of function body size and time depending on the inline context. We keep simple array of record, every containing of predicate and time/size to account.

We keep values scaled up, so fractional sizes and times can be accounted.

Referenced by dump_inline_hints().

#define INLINE_TIME_SCALE   (CGRAPH_FREQ_BASE * 2)

Referenced by dump_inline_hints().

#define MAX_CLAUSES   8

Representation of predicates i.e. formulas using conditions defined above. Predicates are simple logical formulas in conjunctive-disjunctive form.

Predicate is array of clauses terminated by 0. Every clause must be true in order to make predicate true. Clauses are represented as bitmaps of conditions. One of conditions must be true in order for clause to be true.

Referenced by and_predicates(), estimate_size_after_inlining(), evaluate_predicate(), and predicates_equal_p().


Typedef Documentation

typedef unsigned int clause_t
typedef struct condition condition

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/. Representation of inline parameters that do depend on context function is inlined into (i.e. known constant values of function parameters.

Conditions that are interesting for function body are collected into CONDS vector. They are of simple for function_param OP VAL, where VAL is IPA invariant. The conditions are then referred by predicates.

typedef int inline_hints

Enumeration Type Documentation

Inline hints are reasons why inline heuristics should preffer inlining given function. They are represtented as bitmap of the following values.

Enumerator:
INLINE_HINT_indirect_call 

When inlining turns indirect call into a direct call, it is good idea to do so.

INLINE_HINT_loop_iterations 

Inlining may make loop iterations or loop stride known. It is good idea to do so because it enables loop optimizatoins.

INLINE_HINT_loop_stride 
INLINE_HINT_same_scc 

Inlining within same strongly connected component of callgraph is often a loss due to increased stack frame usage and prologue setup costs.

INLINE_HINT_in_scc 

Inlining functions in strongly connected component is not such a great win.

INLINE_HINT_declared_inline 

If function is declared inline by user, it may be good idea to inline it.

INLINE_HINT_cross_module 

Programs are usually still organized for non-LTO compilation and thus if functions are in different modules, inlining may not be so important.

INLINE_HINT_array_index 

If array indexes of loads/stores become known there may be room for further optimization.


Function Documentation

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.

     We may eliminate the need for out-of-line copy to be output.
     In that case just go ahead and re-use it.  This is not just an
     memory optimization.  Making offline copy of fuction disappear
     from the program will improve future decisions on inlining.   
         Recursive inlining never wants the master clone to
         be overwritten.   
         TODO: When callee is in a comdat group, we could remove all of it,
         including all inline clones inlined into it.  That would however
         need small function inlining to register edge removal hook to
         maintain the priority queue.

         For now we keep the ohter functions in the group in program until
         cgraph_remove_unreachable_functions gets rid of them.   
 Recursively clone all bodies.   

References cgraph_edge::callee, cgraph_node::callers, can_remove_node_now_p(), cgraph_clone_node(), cgraph_redirect_edge_callee(), cgraph_edge::count, symtab_node_base::decl, DECL_EXTERNAL, symtab_node_base::definition, symtab_node_base::externally_visible, cgraph_edge::frequency, gcc_assert, cgraph_node::global, inline_summary(), cgraph_global_info::inlined_to, cgraph_edge::next_caller, nfunctions_inlined, inline_summary::size, symtab_dissolve_same_comdat_group_list(), update_noncloned_frequencies(), and vNULL.

void compute_inline_parameters ( struct cgraph_node ,
bool   
)
void debug_inline_summary ( struct cgraph_node )
inline_hints do_estimate_edge_hints ( struct cgraph_edge edge)
int do_estimate_edge_size ( struct cgraph_edge edge)
int do_estimate_edge_time ( struct cgraph_edge edge)
int do_estimate_growth ( struct cgraph_node )
void dump_inline_hints ( FILE *  f,
inline_hints   
)
void dump_inline_summaries ( FILE *  f)
void dump_inline_summary ( FILE *  f,
struct cgraph_node node 
)
static int estimate_edge_growth ( )
inlinestatic

Return estimated callee growth after inlining EDGE.

Referenced by do_estimate_edge_time(), and simple_edge_hints().

static inline_hints estimate_edge_hints ( )
inlinestatic

Return estimated callee runtime increase after inlning EDGE.

static int estimate_edge_size ( )
inlinestatic

Return estimated size of the inline sequence of EDGE.

static int estimate_edge_time ( )
inlinestatic

Return estimated callee runtime increase after inlning EDGE.

Referenced by inline_update_overall_summary().

static int estimate_growth ( )
inlinestatic

Return estimated unit growth after inlning all calls to NODE. Quick accesors to the inline growth caches. For convenience we keep zero 0 as unknown. Because growth can be both positive and negative, we simply increase positive growths by 1.

void estimate_ipcp_clone_size_and_time ( struct cgraph_node node,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs,
int *  ret_size,
int *  ret_time,
inline_hints hints 
)

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_BINFOS are vectors of assumed known constant values and types for parameters.

References combine_probabilities(), inline_edge_summary(), IPA_EDGE_REF, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_jf_pass_through_formal_id(), IPA_JF_PASS_THROUGH, ipa_node_params_vector, inline_edge_summary::param, and ipa_jump_func::type.

int estimate_size_after_inlining ( struct cgraph_node node,
struct cgraph_edge edge 
)

Estimate the size of NODE after inlining EDGE which should be an edge to either NODE or a call inlined into NODE.

References predicate::clause, gcc_assert, MAX_CLAUSES, and streamer_read_uhwi().

int estimate_time_after_inlining ( struct cgraph_node node,
struct cgraph_edge edge 
)

Estimate self time of the function NODE after inlining EDGE.

void free_growth_caches ( void  )

Free growth caches.

void initialize_inline_failed ( struct cgraph_edge )
bool inline_call ( struct cgraph_edge e,
bool  update_original,
vec< cgraph_edge_p > *  new_edges,
int *  overall_size,
bool  update_overall_summary 
)

In ipa-inline-transform.c

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 inline_update_overall_summary.

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

 Don't inline inlined edges.   
 Don't even think of inlining inline clone.   
 If aliases are involved, redirect edge to the actual destination and
 possibly remove the aliases.   
 Account the change of overall unit size; external functions will be
 removed and are thus not accounted.   
 This must happen after inline_merge_summary that rely on jump
 functions of callee to not be updated.   

Referenced by flatten_function().

void inline_free_summary ( void  )

Release inline summary.

void inline_generate_summary ( void  )

Note function body size.

When not optimizing, do not bother to analyze. Inlining is still done because edge redirection needs to happen there.

void inline_merge_summary ( struct cgraph_edge edge)
void inline_read_summary ( void  )

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.

Fatal error here. We do not want to support compiling ltrans units with different version of compiler or different flags than the WPA unit, so this should never happen.

unsigned int inline_transform ( struct cgraph_node )
void inline_update_overall_summary ( struct cgraph_node node)
void inline_write_summary ( void  )

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.

static void reset_edge_growth_cache ( )
inlinestatic

Reset cached value for EDGE.

Referenced by lookup_recursive_calls(), and recursive_inlining().

static void reset_node_growth_cache ( )
inlinestatic

Reset cached value for NODE.

bool speculation_useful_p ( struct cgraph_edge e,
bool  anticipate_inlining 
)

Variable Documentation

vec<edge_growth_cache_entry> edge_growth_cache
vec<inline_edge_summary_t> inline_edge_summary_vec
vec<inline_summary_t, va_gc>* inline_summary_vec

VECtor holding inline summaries. In GGC memory because conditions might point to constant trees.

Referenced by cgraph_process_new_functions().

int ncalls_inlined

Callgraph transformations to handle inlining 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/. 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.

int nfunctions_inlined

Referenced by clone_inlined_nodes().

vec<int> node_growth_cache

Cached node/edge growths.