GCC Middle and Back End API Reference
ipa-inline-analysis.c File Reference

Data Structures

struct  agg_position_info
struct  record_modified_bb_info
struct  growth_data

Typedefs

typedef struct predicate predicate_t

Enumerations

enum  predicate_conditions { predicate_false_condition = 0, predicate_not_inlined_condition = 1, predicate_first_dynamic_condition = 2 }

Functions

static void inline_node_removal_hook (struct cgraph_node *, void *)
static void inline_node_duplication_hook (struct cgraph_node *, struct cgraph_node *, void *)
static void inline_edge_removal_hook (struct cgraph_edge *, void *)
static void inline_edge_duplication_hook (struct cgraph_edge *, struct cgraph_edge *, void *)
static struct predicate true_predicate ()
static struct predicate single_cond_predicate ()
static struct predicate false_predicate ()
static bool true_predicate_p ()
static bool false_predicate_p ()
static struct predicate not_inlined_predicate ()
static struct predicate add_condition (struct inline_summary *summary, int operand_num, struct agg_position_info *aggpos, enum tree_code code, tree val)
static void add_clause ()
static struct predicate and_predicates (conditions conditions, struct predicate *p, struct predicate *p2)
static bool predicates_equal_p ()
static struct predicate or_predicates (conditions conditions, struct predicate *p, struct predicate *p2)
static bool evaluate_predicate ()
static int predicate_probability (conditions conds, struct predicate *p, clause_t possible_truths, vec< inline_param_summary_t > inline_param_summary)
static void dump_condition ()
static void dump_clause ()
static void dump_predicate ()
void dump_inline_hints ()
static void account_size_time (struct inline_summary *summary, int size, int time, struct predicate *pred)
static void edge_set_predicate ()
static void set_hint_predicate ()
static clause_t evaluate_conditions_for_known_args (struct cgraph_node *node, bool inline_p, vec< tree > known_vals, vec< ipa_agg_jump_function_p > known_aggs)
static void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, clause_t *clause_ptr, vec< tree > *known_vals_ptr, vec< tree > *known_binfos_ptr, vec< ipa_agg_jump_function_p > *known_aggs_ptr)
static void inline_summary_alloc ()
static void reset_inline_edge_summary ()
static void reset_inline_summary ()
static struct predicate remap_predicate_after_duplication (struct predicate *p, clause_t possible_truths, struct inline_summary *info)
static void remap_hint_predicate_after_duplication (struct predicate **p, clause_t possible_truths, struct inline_summary *info)
void initialize_growth_caches ()
void free_growth_caches ()
static void dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node, struct inline_summary *info)
void dump_inline_summary ()
DEBUG_FUNCTION void debug_inline_summary ()
void dump_inline_summaries ()
void initialize_inline_failed ()
static bool mark_modified (ao_ref *ao, tree vdef, void *data)
static tree unmodified_parm_1 ()
static tree unmodified_parm ()
static bool unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, gimple stmt, tree op, int *index_p, struct agg_position_info *aggpos)
static int eliminated_by_inlining_prob ()
static void set_cond_stmt_execution_predicate (struct ipa_node_params *info, struct inline_summary *summary, basic_block bb)
static void set_switch_stmt_execution_predicate (struct ipa_node_params *info, struct inline_summary *summary, basic_block bb)
static void compute_bb_predicates (struct cgraph_node *node, struct ipa_node_params *parms_info, struct inline_summary *summary)
static struct predicate will_be_nonconstant_expr_predicate (struct ipa_node_params *info, struct inline_summary *summary, tree expr, vec< predicate_t > nonconstant_names)
static struct predicate will_be_nonconstant_predicate (struct ipa_node_params *info, struct inline_summary *summary, gimple stmt, vec< predicate_t > nonconstant_names)
static bool record_modified ()
static int param_change_prob ()
static bool phi_result_unknown_predicate (struct ipa_node_params *info, struct inline_summary *summary, basic_block bb, struct predicate *p, vec< predicate_t > nonconstant_names)
static void predicate_for_phi_result (struct inline_summary *summary, gimple phi, struct predicate *p, vec< predicate_t > nonconstant_names)
static struct predicate array_index_predicate (struct inline_summary *info, vec< predicate_t > nonconstant_names, tree op)
static gimple find_foldable_builtin_expect ()
static void estimate_function_body_sizes ()
void compute_inline_parameters ()
static unsigned int compute_inline_parameters_for_current ()
gimple_opt_passmake_pass_inline_parameters ()
static bool estimate_edge_devirt_benefit (struct cgraph_edge *ie, int *size, int *time, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs)
static void estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *time, int prob, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs, inline_hints *hints)
static void estimate_calls_size_and_time (struct cgraph_node *node, int *size, int *time, inline_hints *hints, clause_t possible_truths, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs)
static void estimate_node_size_and_time (struct cgraph_node *node, clause_t possible_truths, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs, int *ret_size, int *ret_time, inline_hints *ret_hints, vec< inline_param_summary_t > inline_param_summary)
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)
static struct predicate remap_predicate (struct inline_summary *info, struct inline_summary *callee_info, struct predicate *p, vec< int > operand_map, vec< int > offset_map, clause_t possible_truths, struct predicate *toplev_predicate)
static void inline_update_callee_summaries ()
static void remap_edge_change_prob (struct cgraph_edge *inlined_edge, struct cgraph_edge *edge)
static void remap_edge_summaries (struct cgraph_edge *inlined_edge, struct cgraph_node *node, struct inline_summary *info, struct inline_summary *callee_info, vec< int > operand_map, vec< int > offset_map, clause_t possible_truths, struct predicate *toplev_predicate)
static void remap_hint_predicate (struct inline_summary *info, struct inline_summary *callee_info, struct predicate **hint, vec< int > operand_map, vec< int > offset_map, clause_t possible_truths, struct predicate *toplev_predicate)
void inline_merge_summary ()
void inline_update_overall_summary ()
int simple_edge_hints ()
int do_estimate_edge_time ()
int do_estimate_edge_size ()
inline_hints do_estimate_edge_hints ()
int estimate_time_after_inlining (struct cgraph_node *node, struct cgraph_edge *edge)
int estimate_size_after_inlining (struct cgraph_node *node, struct cgraph_edge *edge)
static bool do_estimate_growth_1 ()
int do_estimate_growth ()
static void inline_indirect_intraprocedural_analysis ()
static void inline_analyze_function ()
static void add_new_function ()
void inline_generate_summary ()
static struct predicate read_predicate ()
static void read_inline_edge_summary ()
static void inline_read_section (struct lto_file_decl_data *file_data, const char *data, size_t len)
void inline_read_summary ()
static void write_predicate ()
static void write_inline_edge_summary ()
void inline_write_summary ()
void inline_free_summary ()

Variables

static struct
cgraph_node_hook_list
function_insertion_hook_holder
static struct
cgraph_node_hook_list
node_removal_hook_holder
static struct
cgraph_2node_hook_list
node_duplication_hook_holder
static struct
cgraph_2edge_hook_list
edge_duplication_hook_holder
static struct
cgraph_edge_hook_list
edge_removal_hook_holder
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
static alloc_pool edge_predicate_pool

Typedef Documentation

typedef struct predicate predicate_t
   We keep info about constantness of SSA names.  

Enumeration Type Documentation

Enumerator:
predicate_false_condition 
predicate_not_inlined_condition 
predicate_first_dynamic_condition 

Function Documentation

static void account_size_time ( struct inline_summary summary,
int  size,
int  time,
struct predicate pred 
)
static
   Record SIZE and TIME under condition PRED into the inline summary.  
     We need to create initial empty unconitional clause, but otherwie
     we don't need to account empty times and sizes.  
     Watch overflow that might result from insane profiles.  
static void add_clause ( )
inlinestatic
   Add clause CLAUSE into the predicate P.  
     True clause.  
     False clause makes the whole predicate false.  Kill the other variants.  
     No one should be sily enough to add false into nontrivial clauses.  
     Look where to insert the clause.  At the same time prune out
     clauses of P that are implied by the new clause and thus
     redundant.  
         If p->clause[i] implies clause, there is nothing to add.  
             We had nothing to add, none of clauses should've become
             redundant.  
         If clause implies p->clause[i], then p->clause[i] becomes redundant.
         Otherwise the p->clause[i] has to stay.  
     Look for clauses that are obviously true.  I.e.
     op0 == 5 || op0 != 5.  
         We have no way to represent !CHANGED and !IS_NOT_CONSTANT
         and thus there is no point for looking for them.  
     We run out of variants.  Be conservative in positive direction.  
     Keep clauses in decreasing order. This makes equivalence testing easy.  

Referenced by predicates_equal_p().

static struct predicate add_condition ( struct inline_summary summary,
int  operand_num,
struct agg_position_info aggpos,
enum tree_code  code,
tree  val 
)
staticread
   Add condition to condition list CONDS.  AGGPOS describes whether the used
   oprand is loaded from an aggregate and where in the aggregate it is.  It can
   be NULL, which means this not a load from an aggregate.  
     Too many conditions.  Give up and return constant true.  
static void add_new_function ( )
static
   Called when new function is inserted to callgraph late.  
static struct predicate and_predicates ( conditions  conditions,
struct predicate p,
struct predicate p2 
)
staticread
   Return P & P2.  
     Avoid busy work.  
     See how far predicates match.  
     Combine the predicates rest.  

References predicate::clause.

static struct predicate array_index_predicate ( struct inline_summary info,
vec< predicate_t nonconstant_names,
tree  op 
)
staticread
   Return predicate specifying when array index in access OP becomes non-constant.  
static void compute_bb_predicates ( struct cgraph_node node,
struct ipa_node_params parms_info,
struct inline_summary summary 
)
static
   For each BB in NODE attach to its AUX pointer predicate under
   which it is executable.  
     Entry block is always executable.  
     A simple dataflow propagation of predicates forward in the CFG.
     TODO: work in reverse postorder.  
void compute_inline_parameters ( )
   Compute parameters of functions used by inliner.
   EARLY is true when we compute parameters for the early inliner  
     FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
     Once this happen, we will need to more curefully predict call
     statement size.  
     Even is_gimple_min_invariant rely on current_function_decl.  
     Estimate the stack size for the function if we're optimizing.  
     Can this function be inlined at all?  
     Type attributes can use parameter indices to describe them.  
         Otherwise, inlinable functions always can change signature.  
             Functions calling builtin_apply can not change signature.  
     Inlining characteristics are maintained by the cgraph_mark_inline.  

Referenced by cgraph_process_new_functions().

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

References unmodified_parm_1().

inline_hints do_estimate_edge_hints ( )
   Estimate the growth of the caller when inlining EDGE.
   Only to be called via estimate_edge_size.  
     When we do caching, use do_estimate_edge_time to populate the entry.  
     Early inliner runs without caching, go ahead and do the dirty work.  
int do_estimate_edge_size ( )
   Return estimated callee growth after inlining EDGE.
   Only to be called via estimate_edge_size.  
     When we do caching, use do_estimate_edge_time to populate the entry.  
     Early inliner runs without caching, go ahead and do the dirty work.  
int do_estimate_edge_time ( )
   Estimate the time cost for the caller when inlining EDGE.
   Only to be called via estimate_edge_time, that handles the
   caching mechanism.

   When caching, also update the cache entry.  Compute both time and
   size, since we always need both metrics eventually.  
     When caching, update the cache entry.  

References cgraph_edge::caller, cgraph_node::callers, estimate_edge_growth(), cgraph_node::global, growth_data::growth, cgraph_edge::inline_failed, cgraph_global_info::inlined_to, cgraph_edge::next_caller, growth_data::node, and growth_data::self_recursive.

int do_estimate_growth ( )
   Estimate the growth caused by inlining NODE into all callees.  
     For self recursive functions the growth estimation really should be
     infinity.  We don't want to return very large values because the growth
     plays various roles in badness computation fractions.  Be sure to not
     return zero or negative growths. 
         COMDAT functions are very often not shared across multiple units
         since they come from various template instantiations.
         Take this into account.  
static bool do_estimate_growth_1 ( )
static
   Worker for do_estimate_growth.  Collect growth for all callers.  
static void dump_clause ( )
static
   Dump clause CLAUSE.  
static void dump_condition ( )
static
   Dump conditional COND.  
static void dump_inline_edge_summary ( FILE *  f,
int  indent,
struct cgraph_node node,
struct inline_summary info 
)
static
   Dump edge summaries associated to NODE and recursively to all clones.
   Indent by INDENT.  
void dump_inline_summaries ( )
void dump_inline_summary ( )
static void dump_predicate ( )
static
   Dump predicate PREDICATE.  

Referenced by dump_inline_hints(), and initialize_growth_caches().

static void edge_set_predicate ( )
static
   Set predicate for edge E.  

Referenced by remap_predicate().

static int eliminated_by_inlining_prob ( )
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.  
         Casts of parameters, loads from parameters passed by reference
         and stores to return value or parameters are often free after
         inlining dua to SRA and further combining.
         Assume that half of statements goes away.  
             Reads of parameter are expected to be free.  
             Match expressions of form &this->field. Those will most likely
             combine with something upstream after inlining.  
             When parameter is not SSA register because its address is taken
             and it is just copied into one, the statement will be completely
             free after inlining (we will copy propagate backward).   
             Reads of parameters passed by reference
             expected to be free (i.e. optimized out after inlining).  
             Copying parameter passed by reference into gimple register is
             probably also going to copy propagate, but we can't be quite
             sure.  
             Writes to parameters, parameters passed by value and return value
             (either dirrectly or passed via invisible reference) are free.  

             TODO: We ought to handle testcase like
             struct a {int a,b;};
             struct a
             retrurnsturct (void)
             {
             struct a a ={1,2};
             return a;
             }

             This translate into:

             retrurnsturct ()
             {
             int a$b;
             int a$a;
             struct a a;
             struct a D.2739;

             <bb 2>:
             D.2739.a = 1;
             D.2739.b = 2;
             return D.2739;

             }
             For that we either need to copy ipa-split logic detecting writes
             to return value.  
static void estimate_calls_size_and_time ( struct cgraph_node node,
int *  size,
int *  time,
inline_hints hints,
clause_t  possible_truths,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs 
)
static
   Increase SIZE and TIME for size and time needed to handle all calls in NODE.
   POSSIBLE_TRUTHS, KNOWN_VALS and KNOWN_BINFOS describe context of the call
   site.  
                 Predicates of calls shall not use NOT_CHANGED codes,
                 sowe do not need to compute probabilities.  

References estimate_node_size_and_time(), evaluate_conditions_for_known_args(), and vNULL.

static bool estimate_edge_devirt_benefit ( struct cgraph_edge ie,
int *  size,
int *  time,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs 
)
static
   Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS and
   KNOWN_BINFOS.  
     Account for difference in cost between indirect and direct calls.  
static void estimate_edge_size_and_time ( struct cgraph_edge e,
int *  size,
int *  time,
int  prob,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs,
inline_hints hints 
)
inlinestatic
   Increase SIZE and TIME for size and time needed to handle edge E.  
static void estimate_function_body_sizes ( )
static
   Compute function body size parameters for NODE.
   When EARLY is true, we compute only simple summaries without
   non-trivial predicates to drive the early inliner.  
     Estimate static overhead for function prologue/epilogue and alignment. 
     Benefits are scaled by probability of elimination that is in range
     <0,2>.  
     When we run into maximal number of entries, we assign everything to the
     constant truth case.  Be sure to have it in list. 
         TODO: Obviously predicates can be propagated down across CFG.  
             This relation stmt should be folded after we remove
             buildin_expect call. Adjust the cost here.  
                 Special case: results of BUILT_IN_CONSTANT_P will be always
                 resolved as constant.  We however don't want to optimize
                 out the cgraph edges.  
             TODO: When conditional jump or swithc is known to be constant, but
             we did not translate it into the predicates, we really can account
             just maximum of the possible paths.  
                 We account everything but the calls.  Calls have their own
                 size/time info attached to cgraph edges.  This is necessary
                 in order to make the cost disappear after inlining.  
                   This is slightly inprecise.  We may want to represent each
                   loop with independent predicate.  
                         This is slightly inprecise.  We may want to represent
                         each loop with independent predicate.  
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_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, prob, and ipa_jump_func::type.

static void estimate_node_size_and_time ( struct cgraph_node node,
clause_t  possible_truths,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs,
int *  ret_size,
int *  ret_time,
inline_hints ret_hints,
vec< inline_param_summary_t inline_param_summary 
)
static
   Estimate size and time needed to execute NODE assuming
   POSSIBLE_TRUTHS clause, and KNOWN_VALS and KNOWN_BINFOS information
   about NODE's arguments. 

Referenced by estimate_calls_size_and_time().

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, 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.  
static clause_t evaluate_conditions_for_known_args ( struct cgraph_node node,
bool  inline_p,
vec< tree known_vals,
vec< ipa_agg_jump_function_p known_aggs 
)
static
   KNOWN_VALS is partial mapping of parameters of NODE to constant values.
   KNOWN_AGGS is a vector of aggreggate jump functions for each parameter.
   Return clause of possible truths. When INLINE_P is true, assume that we are
   inlining.

   ERROR_MARK means compile time invariant.  
         We allow call stmt to have fewer arguments than the callee function
         (especially for K&R style programs).  So bound check here (we assume
         known_aggs vector, if non-NULL, has the same length as
         known_vals).  

Referenced by estimate_calls_size_and_time().

static bool evaluate_predicate ( )
static
   Having partial truth assignment in POSSIBLE_TRUTHS, return false
   if predicate P is known to be false.  
     True remains true.  
     See if we can find clause we can disprove.  

References predicate::clause, i2, condition::operand_num, and predicate_first_dynamic_condition.

static void evaluate_properties_for_edge ( struct cgraph_edge e,
bool  inline_p,
clause_t clause_ptr,
vec< tree > *  known_vals_ptr,
vec< tree > *  known_binfos_ptr,
vec< ipa_agg_jump_function_p > *  known_aggs_ptr 
)
static
   Work out what conditions might be true at invocation of E.  
             TODO: When IPA-CP starts propagating and merging aggregate jump
             functions, use its knowledge of the caller too, just like the
             scalar case above.  

Referenced by remap_edge_change_prob().

static struct predicate false_predicate ( )
staticread
   Return false predicate.  First clause require false condition.  

References predicate::clause, and predicate_false_condition.

Referenced by find_foldable_builtin_expect(), record_modified(), reset_inline_summary(), and set_cond_stmt_execution_predicate().

static bool false_predicate_p ( )
inlinestatic
static gimple find_foldable_builtin_expect ( )
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 basic_block_def::aux, and false_predicate().

void free_growth_caches ( void  )
   Free growth caches.  
void initialize_inline_failed ( )
   Give initial reasons why inlining would fail on EDGE.  This gets either
   nullified or usually overwritten by more precise reasons later.  
       We can't inline if the function is spawing a function.  

References agg_position_info::agg_contents, agg_position_info::by_ref, gimple_assign_single_p(), ipa_get_param_decl_index(), and unmodified_parm_1().

Referenced by cgraph_create_edge_1().

static void inline_analyze_function ( )
static
   Note function body size.  
static void inline_edge_duplication_hook ( struct cgraph_edge src,
struct cgraph_edge dst,
void *  data 
)
static
   Hook that is called by cgraph.c when a node is duplicated.  
static void inline_edge_removal_hook ( struct cgraph_edge edge,
void *  data 
)
static
   Keep edge cache consistent across edge removal.  
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.  
static void inline_indirect_intraprocedural_analysis ( )
static
   This function performs intraprocedural analysis in NODE that is required to
   inline indirect calls.  
void inline_merge_summary ( )
   We inlined EDGE.  Update summary of the function we inlined into.  
             TODO: handle non-NOPs when merging.  
     We do not maintain predicates of inlined edges, free it.  
     Similarly remove param summaries.  
static void inline_node_duplication_hook ( struct cgraph_node src,
struct cgraph_node dst,
void *  data 
)
static
   Hook that is called by cgraph.c when a node is duplicated.  
     TODO: as an optimization, we may avoid copying conditions
     that are known to be false or true.  
     When there are any replacements in the function body, see if we can figure
     out that something was optimized out.  
         Use SRC parm info since it may not be copied yet.  
         Remap size_time vectors.
         Simplify the predicate by prunning out alternatives that are known
         to be false.
         TODO: as on optimization, we can also eliminate conditions known
         to be true.  
         Remap edge predicates with the same simplification as above.
         Also copy constantness arrays.   
         Remap indirect edge predicates with the same simplificaiton as above. 
         Also copy constantness arrays.   
         If inliner or someone after inliner will ever start producing
         non-trivial clones, we will get trouble with lack of information
         about updating self sizes, because size vectors already contains
         sizes of the calees.  
static void inline_node_removal_hook ( struct cgraph_node node,
void *  data 
)
static
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.  
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.  
static void inline_summary_alloc ( )
static
   Allocate the inline summary vector or resize it to cover all cgraph nodes. 

References inline_summary::loop_iterations, and pool_free().

Referenced by inline_node_removal_hook().

static void inline_update_callee_summaries ( )
static
   Update summary information of inline clones after inlining.
   Compute peak stack usage.  
void inline_update_overall_summary ( )
   For performance reasons inline_merge_summary is not updating overall size
   and time.  Recompute it.  

References estimate_edge_time(), false_predicate_p(), inline_edge_summary(), inline_summary(), inline_edge_summary::predicate, and inline_summary::time.

Referenced by add_new_edges_to_heap().

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.  
gimple_opt_pass* make_pass_inline_parameters ( )
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.  
static struct predicate not_inlined_predicate ( )
staticread
   Return predicate that is set true when function is not inlined.  
static struct predicate or_predicates ( conditions  conditions,
struct predicate p,
struct predicate p2 
)
staticread
   Return P | P2.  
     Avoid busy work.  
     OK, combine the predicates.  
static int param_change_prob ( )
static
   Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
   will change since last invocation of STMT. 

   Value 0 is reserved for compile time invariants.
   For common parameters it is REG_BR_PROB_BASE.  For loop invariants it
   ought to be REG_BR_PROB_BASE / estimated_iters.  
     Global invariants neve change.  
     We would have to do non-trivial analysis to really work out what
     is the probability of value to change (i.e. when init statement
     is in a sibling loop of the call). 

     We do an conservative estimate: when call is executed N times more often
     than the statement defining value, we take the frequency 1/N.  
         Assume that every memory is initialized at entry.
         TODO: Can we easilly determine if value is always defined
         and thus we may skip entry block?  

References edge_def::src.

static bool phi_result_unknown_predicate ( struct ipa_node_params info,
struct inline_summary summary,
basic_block  bb,
struct predicate p,
vec< predicate_t 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 gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_lhs(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_assign(), and single_imm_use().

static void predicate_for_phi_result ( struct inline_summary summary,
gimple  phi,
struct predicate p,
vec< predicate_t 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 inline_summary::conds, symtab_node_base::decl, inline_summary::entry, inline_summary(), order, true_predicate(), and vNULL.

static int predicate_probability ( conditions  conds,
struct predicate p,
clause_t  possible_truths,
vec< inline_param_summary_t inline_param_summary 
)
static
   Return the probability in range 0...REG_BR_PROB_BASE that the predicated
   instruction will be recomputed per invocation of the inlined call.  
     True remains true.  
     See if we can find clause we can disprove.  
static bool predicates_equal_p ( )
inlinestatic
   Return true if predicates are obviously equal.  

References add_clause(), and predicate::clause.

Referenced by dump_inline_hints().

static struct predicate read_predicate ( )
staticread
   Read predicate from IB.  
     Zero-initialize the remaining clauses in OUT.  
static bool record_modified ( )
static
   Callback of walk_aliased_vdefs.  Records basic blocks where the value may be
   set except for info->stmt.  

References false_predicate().

static void remap_edge_change_prob ( struct cgraph_edge inlined_edge,
struct cgraph_edge edge 
)
static
   Update change_prob of EDGE after INLINED_EDGE has been inlined.
   When functoin A is inlined in B and A calls C with parameter that
   changes with probability PROB1 and C is known to be passthroug
   of argument if B that change with probability PROB2, the probability
   of change is now PROB1*PROB2.  

References count, evaluate_properties_for_edge(), HOST_WIDE_INT, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_jf_ancestor_agg_preserved(), ipa_get_jf_ancestor_formal_id(), ipa_get_jf_ancestor_offset(), ipa_get_jf_pass_through_agg_preserved(), ipa_get_jf_pass_through_formal_id(), ipa_get_jf_pass_through_operation(), ipa_get_param_count(), IPA_JF_ANCESTOR, IPA_JF_PASS_THROUGH, map, offset, and ipa_jump_func::type.

Referenced by remap_predicate().

static void remap_edge_summaries ( struct cgraph_edge inlined_edge,
struct cgraph_node node,
struct inline_summary info,
struct inline_summary callee_info,
vec< int >  operand_map,
vec< int >  offset_map,
clause_t  possible_truths,
struct 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.  
                 TODO: We should remove the edge for code that will be
                 optimized out, but we need to keep verifiers and tree-inline
                 happy.  Make it cold for now.  
             TODO: We should remove the edge for code that will be optimized
             out, but we need to keep verifiers and tree-inline happy.
             Make it cold for now.  

Referenced by remap_predicate().

static void remap_hint_predicate ( struct inline_summary info,
struct inline_summary callee_info,
struct predicate **  hint,
vec< int >  operand_map,
vec< int >  offset_map,
clause_t  possible_truths,
struct predicate toplev_predicate 
)
static
static void remap_hint_predicate_after_duplication ( struct predicate **  p,
clause_t  possible_truths,
struct inline_summary info 
)
static
   Same as remap_predicate_after_duplication but handle hint predicate *P.
   Additionally care about allocating new memory slot for updated predicate
   and set it to NULL when it becomes true or false (and thus uninteresting).
     We do not want to free previous predicate; it is used by node origin.  
static struct predicate remap_predicate ( struct inline_summary info,
struct inline_summary callee_info,
struct predicate p,
vec< int >  operand_map,
vec< int >  offset_map,
clause_t  possible_truths,
struct predicate toplev_predicate 
)
staticread
   Translate all conditions from callee representation into caller
   representation and symbolically evaluate predicate P into new predicate.

   INFO is inline_summary of function we are adding predicate into, CALLEE_INFO
   is summary of function predicate P is from. OPERAND_MAP is array giving
   callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clausule of all
   callee conditions that may be true in caller context.  TOPLEV_PREDICATE is
   predicate under which callee is executed.  OFFSET_MAP is an array of of
   offsets that need to be added to conditions, negative offset means that
   conditions relying on values passed by reference have to be discarded
   because they might not be preserved (and should be considered offset zero
   for other purposes).  
     True predicate is easy.  
           Do we have condition we can't disprove?   
               Work out if the condition can translate to predicate in the
               inlined function.  
                   See if we can remap condition operand to caller's operand.
                   Otherwise give up.  
                       TODO: For non-aggregate conditions, adding an offset is
                       basically an arithmetic jump function processing which
                       we should support in future.  
               Fixed conditions remains same, construct single
               condition predicate.  

References cgraph_edge::callee, cgraph_node::callees, cgraph_edge::count, edge_set_predicate(), false_predicate_p(), cgraph_edge::frequency, cgraph_node::indirect_calls, inline_edge_summary(), cgraph_edge::inline_failed, cgraph_edge::next_callee, inline_edge_summary::predicate, remap_edge_change_prob(), and remap_edge_summaries().

static struct predicate remap_predicate_after_duplication ( struct predicate p,
clause_t  possible_truths,
struct inline_summary info 
)
staticread
   Remap predicate P of former function to be predicate of duplicated functoin.
   POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
   INFO is inline summary of the duplicated node.  
static void reset_inline_edge_summary ( )
static
   We are called multiple time for given function; clear
   data from previous run so they are not cumulated.  
static void reset_inline_summary ( )
static
   We are called multiple time for given function; clear
   data from previous run so they are not cumulated.  

References false_predicate().

static void set_cond_stmt_execution_predicate ( struct ipa_node_params info,
struct inline_summary summary,
basic_block  bb 
)
static
   If BB ends by a conditional we can turn into predicates, attach corresponding
   predicates to the CFG edges.   
     TODO: handle conditionals like
     var = op0 < 4;
     if (var != 0).  
     Special case
     if (builtin_constant_p (op))
     constant_code
     else
     nonconstant_code.
     Here we can predicate nonconstant_code.  We can't
     really handle constant_code since we have no predicate
     for this and also the constant code is not known to be
     optimized away when inliner doen't see operand is constant.
     Other optimizers might think otherwise.  

References false_predicate(), and pool_alloc().

static void set_hint_predicate ( )
static
static void set_switch_stmt_execution_predicate ( struct ipa_node_params info,
struct inline_summary summary,
basic_block  bb 
)
static
   If BB ends by a switch we can turn into predicates, attach corresponding
   predicates to the CFG edges.   
         For default we might want to construct predicate that none
         of cases is met, but it is bit hard to do not having negations
         of conditionals handy.  
int simple_edge_hints ( )
static struct predicate single_cond_predicate ( )
staticread
   Return predicate testing single condition number COND.  

References predicate_false_condition.

Referenced by false_predicate_p().

static struct predicate true_predicate ( )
staticread
   Return true predicate (tautology).
   We represent it by empty list of clauses.  

References predicate::clause.

Referenced by predicate_for_phi_result().

static bool true_predicate_p ( )
inlinestatic
   Return true if P is (false).  

Referenced by will_be_nonconstant_expr_predicate().

static tree unmodified_parm ( )
static
   If OP refers to value of function parameter, return the corresponding
   parameter.  Also traverse chains of SSA register assignments.  

References get_base_address(), gimple_assign_lhs(), and gimple_assign_rhs1().

Referenced by unmodified_parm_or_parm_agg_item(), and will_be_nonconstant_expr_predicate().

static tree unmodified_parm_1 ( )
static
   If OP refers to value of function parameter, return the corresponding
   parameter.  
     SSA_NAME referring to parm default def?  
     Non-SSA parm reference?  

References gimple_assign_rhs_code(), and gimple_num_ops().

Referenced by debug_inline_summary(), and initialize_inline_failed().

static bool unmodified_parm_or_parm_agg_item ( struct ipa_node_params info,
gimple  stmt,
tree  op,
int *  index_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 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 get_base_address(), and unmodified_parm().

static struct predicate will_be_nonconstant_expr_predicate ( struct ipa_node_params info,
struct inline_summary summary,
tree  expr,
vec< predicate_t nonconstant_names 
)
staticread
   Return predicate specifying when the STMT might have result that is not
   a compile time constant.  

References ipa_get_param_decl_index(), true_predicate_p(), and unmodified_parm().

static struct predicate will_be_nonconstant_predicate ( struct ipa_node_params info,
struct inline_summary summary,
gimple  stmt,
vec< predicate_t nonconstant_names 
)
staticread
   Return predicate specifying when the STMT might have result that is not
   a compile time constant.  
     What statments might be optimized away
     when their arguments are constant
     TODO: also trivial builtins.
     builtin_constant_p is already handled later.  
     Stores will stay anyway.  
     Loads can be optimized when the value is known.  
     See if we understand all operands before we start
     adding conditionals.  
         For arguments we can build a condition.  
         If we know when operand is constant,
         we still can say something useful.  
static void write_inline_edge_summary ( )
static
   Write inline summary for edge E to OB.  
static void write_predicate ( )
static
   Write predicate P to OB.  

Variable Documentation

struct cgraph_2edge_hook_list* edge_duplication_hook_holder
static
vec<edge_growth_cache_entry> edge_growth_cache
alloc_pool edge_predicate_pool
static
   Edge predicates goes here.  
struct cgraph_edge_hook_list* edge_removal_hook_holder
static
struct cgraph_node_hook_list* function_insertion_hook_holder
static
   Holders of ipa cgraph hooks: 
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().

struct cgraph_2node_hook_list* node_duplication_hook_holder
static
vec<int> node_growth_cache
   Cached node/edge growths.  
struct cgraph_node_hook_list* node_removal_hook_holder
static