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

Data Structures

struct  ipcp_value_source
struct  ipcp_value
struct  ipcp_lattice
struct  ipcp_agg_lattice
struct  ipcp_param_lattices
struct  caller_statistics
struct  topo_info

Functions

static struct ipcp_param_latticesipa_get_parm_lattices ()
static struct ipcp_latticeipa_get_scalar_lat ()
static bool ipa_lat_is_single_const ()
static void print_ipcp_constant_value ()
static void print_lattice (FILE *f, struct ipcp_lattice *lat, bool dump_sources, bool dump_benefits)
static void print_all_lattices ()
static void determine_versionability ()
static bool ipcp_versionable_function_p ()
static void init_caller_stats ()
static bool gather_caller_stats ()
static bool ipcp_cloning_candidate_p ()
static void build_toporder_info ()
static void free_toporder_info ()
static void push_node_to_stack ()
static struct cgraph_nodepop_node_from_stack ()
static bool set_lattice_to_bottom ()
static bool set_lattice_contains_variable ()
static bool set_agg_lats_to_bottom ()
static bool set_agg_lats_contain_variable ()
static bool set_all_contains_variable ()
static void initialize_node_lattices ()
static tree ipa_get_jf_pass_through_result ()
static tree ipa_get_jf_ancestor_result ()
tree ipa_value_from_jfunc ()
DEBUG_FUNCTION void ipcp_verify_propagated_values ()
static bool values_equal_for_ipcp_p ()
static void add_value_source (struct ipcp_value *val, struct cgraph_edge *cs, struct ipcp_value *src_val, int src_idx, HOST_WIDE_INT offset)
static bool add_value_to_lattice (struct ipcp_lattice *lat, tree newval, struct cgraph_edge *cs, struct ipcp_value *src_val, int src_idx, HOST_WIDE_INT offset)
static bool add_scalar_value_to_lattice (struct ipcp_lattice *lat, tree newval, struct cgraph_edge *cs, struct ipcp_value *src_val, int src_idx)
static bool propagate_vals_accross_pass_through (struct cgraph_edge *cs, struct ipa_jump_func *jfunc, struct ipcp_lattice *src_lat, struct ipcp_lattice *dest_lat, int src_idx)
static bool propagate_vals_accross_ancestor (struct cgraph_edge *cs, struct ipa_jump_func *jfunc, struct ipcp_lattice *src_lat, struct ipcp_lattice *dest_lat, int src_idx)
static bool propagate_scalar_accross_jump_function (struct cgraph_edge *cs, struct ipa_jump_func *jfunc, struct ipcp_lattice *dest_lat)
static bool set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats, bool new_aggs_by_ref)
static bool merge_agg_lats_step (struct ipcp_param_lattices *dest_plats, HOST_WIDE_INT offset, HOST_WIDE_INT val_size, struct ipcp_agg_lattice ***aglat, bool pre_existing, bool *change)
static bool set_chain_of_aglats_contains_variable ()
static bool merge_aggregate_lattices (struct cgraph_edge *cs, struct ipcp_param_lattices *dest_plats, struct ipcp_param_lattices *src_plats, int src_idx, HOST_WIDE_INT offset_delta)
static bool agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats, struct ipa_jump_func *jfunc)
static bool propagate_aggs_accross_jump_function (struct cgraph_edge *cs, struct ipa_jump_func *jfunc, struct ipcp_param_lattices *dest_plats)
static bool propagate_constants_accross_call ()
static tree ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs, struct ipa_agg_replacement_value *agg_reps)
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, vec< tree > known_vals, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs)
static int devirtualization_time_bonus (struct cgraph_node *node, vec< tree > known_csts, vec< tree > known_binfos, vec< ipa_agg_jump_function_p > known_aggs)
static int hint_time_bonus ()
static bool good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit, int freq_sum, gcov_type count_sum, int size_cost)
static vec< ipa_agg_jf_item_t,
va_gc > * 
context_independent_aggregate_values ()
static bool gather_context_independent_values (struct ipa_node_params *info, vec< tree > *known_csts, vec< tree > *known_binfos, vec< ipa_agg_jump_function_t > *known_aggs, int *removable_params_cost)
static vec
< ipa_agg_jump_function_p
agg_jmp_p_vec_for_t_vec ()
static void estimate_local_effects ()
static void add_val_to_toposort ()
static void add_all_node_vals_to_toposort ()
static void propagate_constants_topo ()
static int safe_add ()
static void propagate_effects ()
static void ipcp_propagate_stage ()
static void ipcp_discover_new_direct_edges (struct cgraph_node *node, vec< tree > known_vals, struct ipa_agg_replacement_value *aggvals)
static void grow_next_edge_clone_vector ()
static void ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, __attribute__((unused)) void *data)
static tree get_clone_agg_value (struct cgraph_node *node, HOST_WIDEST_INT offset, int index)
static bool cgraph_edge_brings_value_p (struct cgraph_edge *cs, struct ipcp_value_source *src)
static struct cgraph_edgeget_next_cgraph_edge_clone ()
static bool get_info_about_necessary_edges (struct ipcp_value *val, int *freq_sum, gcov_type *count_sum, int *caller_count)
static vec< cgraph_edge_pgather_edges_for_value ()
static struct ipa_replace_mapget_replacement_map ()
static void dump_profile_updates (struct cgraph_node *orig_node, struct cgraph_node *new_node)
static void update_profiling_info (struct cgraph_node *orig_node, struct cgraph_node *new_node)
static void update_specialized_profile (struct cgraph_node *new_node, struct cgraph_node *orig_node, gcov_type redirected_sum)
static struct cgraph_nodecreate_specialized_node (struct cgraph_node *node, vec< tree > known_vals, struct ipa_agg_replacement_value *aggvals, vec< cgraph_edge_p > callers)
static void find_more_scalar_values_for_callers_subset (struct cgraph_node *node, vec< tree > known_vals, vec< cgraph_edge_p > callers)
static vec< ipa_agg_jf_item_tcopy_plats_to_inter ()
static void intersect_with_plats (struct ipcp_param_lattices *plats, vec< ipa_agg_jf_item_t > *inter, HOST_WIDE_INT offset)
static vec< ipa_agg_jf_item_tagg_replacements_to_vector (struct cgraph_node *node, int index, HOST_WIDE_INT offset)
static void intersect_with_agg_replacements (struct cgraph_node *node, int index, vec< ipa_agg_jf_item_t > *inter, HOST_WIDE_INT offset)
static vec< ipa_agg_jf_item_tintersect_aggregates_with_edge (struct cgraph_edge *cs, int index, vec< ipa_agg_jf_item_t > inter)
static struct
ipa_agg_replacement_value
find_aggregate_values_for_callers_subset (struct cgraph_node *node, vec< cgraph_edge_p > callers)
static struct
ipa_agg_replacement_value
known_aggs_to_agg_replacement_list ()
static bool cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs, struct cgraph_node *node)
static bool cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, struct cgraph_node *node)
static void perhaps_add_new_callers ()
static void move_binfos_to_values (vec< tree > known_vals, vec< tree > known_binfos)
DEBUG_FUNCTION bool ipcp_val_in_agg_replacements_p (struct ipa_agg_replacement_value *aggvals, int index, HOST_WIDE_INT offset, tree value)
static bool decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, struct ipcp_value *val, vec< tree > known_csts, vec< tree > known_binfos)
static bool decide_whether_version_node ()
static void spread_undeadness ()
static bool has_undead_caller_from_outside_scc_p (struct cgraph_node *node, void *data)
static void identify_dead_nodes ()
static void ipcp_decision_stage ()
static unsigned int ipcp_driver ()
static void ipcp_generate_summary ()
static void ipcp_write_summary ()
static void ipcp_read_summary ()
static bool cgraph_gate_cp ()
ipa_opt_pass_dmake_pass_ipa_cp ()

Variables

alloc_pool ipcp_values_pool
alloc_pool ipcp_sources_pool
alloc_pool ipcp_agg_lattice_pool
static gcov_type max_count
static long overall_size
static long max_new_size
static struct ipcp_valuevalues_topo
static vec< cgraph_edge_pnext_edge_clone

Function Documentation

static void add_all_node_vals_to_toposort ( )
static
   Add all values in lattices associated with NODE to the topological sort if
   they are not there yet.  
static bool add_scalar_value_to_lattice ( struct ipcp_lattice lat,
tree  newval,
struct cgraph_edge cs,
struct ipcp_value src_val,
int  src_idx 
)
inlinestatic
   Like above but passes a special value of offset to distinguish that the
   origin is the scalar value of the parameter rather than a part of an
   aggregate.  

References ipcp_lattice::bottom, IPA_JF_CONST, IPA_JF_KNOWN_TYPE, and ipa_jump_func::type.

Referenced by add_value_to_lattice().

static void add_val_to_toposort ( )
static
   Add value CUR_VAL and all yet-unsorted values it is dependent on to the
   topological sort of values.  
static void add_value_source ( struct ipcp_value val,
struct cgraph_edge cs,
struct ipcp_value src_val,
int  src_idx,
HOST_WIDE_INT  offset 
)
static
   Add a new value source to VAL, marking that a value comes from edge CS and
   (if the underlying jump function is a pass-through or an ancestor one) from
   a caller value SRC_VAL of a caller parameter described by SRC_INDEX.  OFFSET
   is negative if the source was the scalar value of the parameter itself or
   the offset within an aggregate.  
static bool add_value_to_lattice ( struct ipcp_lattice lat,
tree  newval,
struct cgraph_edge cs,
struct ipcp_value src_val,
int  src_idx,
HOST_WIDE_INT  offset 
)
static
   Try to add NEWVAL to LAT, potentially creating a new struct ipcp_value for
   it.  CS, SRC_VAL SRC_INDEX and OFFSET are meant for add_value_source and
   have the same meaning.  
         We can only free sources, not the values themselves, because sources
         of other values in this this SCC might point to them.   

References add_scalar_value_to_lattice(), ipa_edge_within_scc(), ipa_get_jf_pass_through_operation(), ipa_get_jf_pass_through_result(), ipcp_value::next, set_lattice_contains_variable(), ipcp_value::value, and ipcp_lattice::values.

static vec<ipa_agg_jump_function_p> agg_jmp_p_vec_for_t_vec ( )
static
   The current interface in ipa-inline-analysis requires a pointer vector.
   Create it.

   FIXME: That interface should be re-worked, this is slightly silly.  Still,
   I'd like to discuss how to change it first and this demonstrates the
   issue.  

References estimate_move_cost(), ipcp_value::value, and ipcp_param_lattices::virt_call.

static bool agg_pass_through_permissible_p ( struct ipcp_param_lattices src_plats,
struct ipa_jump_func jfunc 
)
static
   Determine whether there is anything to propagate FROM SRC_PLATS through a
   pass-through JFUNC and if so, whether it has conform and conforms to the
   rules about propagating values passed by reference.  

Referenced by copy_plats_to_inter().

static vec<ipa_agg_jf_item_t> agg_replacements_to_vector ( struct cgraph_node node,
int  index,
HOST_WIDE_INT  offset 
)
static
   Copy agggregate replacement values of NODE (which is an IPA-CP clone) to the
   vector result while subtracting OFFSET from the individual value offsets.  
static void build_toporder_info ( )
static
   Allocate the arrays in TOPO and topologically sort the nodes into order.  
static bool cgraph_edge_brings_all_agg_vals_for_node ( struct cgraph_edge cs,
struct cgraph_node node 
)
static
   Determine whether CS also brings all aggregate values that NODE is
   specialized for.  

Referenced by known_aggs_to_agg_replacement_list().

static bool cgraph_edge_brings_all_scalars_for_node ( struct cgraph_edge cs,
struct cgraph_node node 
)
static
   Determine whether CS also brings all scalar values that the NODE is
   specialized for.  

Referenced by known_aggs_to_agg_replacement_list().

static bool cgraph_edge_brings_value_p ( struct cgraph_edge cs,
struct ipcp_value_source src 
)
static
   Return true if edge CS does bring about the value described by SRC.  

Referenced by get_clone_agg_value(), and known_aggs_to_agg_replacement_list().

static bool cgraph_gate_cp ( )
static
   Gate for IPCP optimization.  
     FIXME: We should remove the optimize check after we ensure we never run
     IPA passes when not optimizing.  
static vec<ipa_agg_jf_item_t, va_gc>* context_independent_aggregate_values ( )
static
   Return all context independent values from aggregate lattices in PLATS in a
   vector.  Return NULL if there are none.  
static vec<ipa_agg_jf_item_t> copy_plats_to_inter ( )
static
   Go through PLATS and create a vector of values consisting of values and
   offsets (minus OFFSET) of lattices that contain only a single value.  

References agg_pass_through_permissible_p(), cgraph_edge::caller, ipa_get_ith_jump_func(), ipa_get_jf_pass_through_formal_id(), ipa_get_jf_pass_through_operation(), ipa_get_parm_lattices(), IPA_JF_PASS_THROUGH, ipa_node_params::ipcp_orig_node, and ipa_jump_func::type.

static struct cgraph_node* create_specialized_node ( struct cgraph_node node,
vec< tree known_vals,
struct ipa_agg_replacement_value aggvals,
vec< cgraph_edge_p callers 
)
staticread
   Create a specialized version of NODE with known constants and types of
   parameters in KNOWN_VALS and redirect all edges in CALLERS to it.  
static bool decide_about_value ( struct cgraph_node node,
int  index,
HOST_WIDE_INT  offset,
struct ipcp_value val,
vec< tree known_csts,
vec< tree known_binfos 
)
static
   Decide wheter to create a special version of NODE for value VAL of parameter
   at the given INDEX.  If OFFSET is -1, the value is for the parameter itself,
   otherwise it is stored at the given OFFSET of the parameter.  KNOWN_CSTS,
   KNOWN_BINFOS and KNOWN_AGGS describe the other already known values.  
     TODO: If for some lattice there is only one other known value
     left, make a special node for it too. 

Referenced by move_binfos_to_values().

static bool decide_whether_version_node ( )
static
   Decide whether and what specialized clones of NODE should be created.  
                   If the following is false, the one value is in
                   known_aggs.  
static void determine_versionability ( )
static
   Determine whether it is at all technically possible to create clones of NODE
   and store this information in the ipa_node_params structure associated
   with NODE.  
     There are a number of generic reasons functions cannot be versioned.  We
     also cannot remove parameters if there are type attributes such as fnspec
     present.  
static int devirtualization_time_bonus ( struct cgraph_node node,
vec< tree known_csts,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs 
)
static
   Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
   and KNOWN_BINFOS.  
         Only bare minimum benefit for clearly un-inlineable targets.  
         FIXME: The values below need re-considering and perhaps also
         integrating into the cost metrics, at lest in some very basic way.  
static void dump_profile_updates ( struct cgraph_node orig_node,
struct cgraph_node new_node 
)
static
   Dump new profiling counts 
static void estimate_local_effects ( )
static
   Iterate over known values of parameters of NODE and estimate the local
   effects in terms of time and size they have.  
             The inliner-heuristics based estimates may think that in certain
             contexts some functions do not have any size at all but we want
             all specializations to have at least a tiny cost, not least not to
             divide by zero.  
                 If the following is true, the one value is in known_aggs.  
static struct ipa_agg_replacement_value* find_aggregate_values_for_callers_subset ( struct cgraph_node node,
vec< cgraph_edge_p callers 
)
staticread
   Look at edges in CALLERS and collect all known aggregate values that arrive
   from all of them.  
         Among other things, the following check should deal with all by_ref
         mismatches.  
static void find_more_scalar_values_for_callers_subset ( struct cgraph_node node,
vec< tree known_vals,
vec< cgraph_edge_p callers 
)
static
   Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
   KNOWN_VALS with constants and types that are also known for all of the
   CALLERS.  

References ipa_agg_jf_item::offset, ipa_agg_replacement_value::offset, offset, ipa_agg_jf_item::value, and ipa_agg_replacement_value::value.

static void free_toporder_info ( )
static
   Free information about strongly connected components and the arrays in
   TOPO.  
static bool gather_caller_stats ( )
static
   Worker callback of cgraph_for_node_and_aliases accumulating statistics of
   non-thunk incoming edges to NODE.  

References cgraph_node_name(), and dump_file.

static bool gather_context_independent_values ( struct ipa_node_params info,
vec< tree > *  known_csts,
vec< tree > *  known_binfos,
vec< ipa_agg_jump_function_t > *  known_aggs,
int *  removable_params_cost 
)
static
   Allocate KNOWN_CSTS, KNOWN_BINFOS and, if non-NULL, KNOWN_AGGS and populate
   them with values of parameters that are known independent of the context.
   INFO describes the function.  If REMOVABLE_PARAMS_COST is non-NULL, the
   movement cost of all removable parameters will be stored in it.  
static vec<cgraph_edge_p> gather_edges_for_value ( )
static
   Return a vector of incoming edges that do bring value VAL.  It is assumed
   their number is known and equal to CALLER_COUNT.  
static tree get_clone_agg_value ( struct cgraph_node node,
HOST_WIDEST_INT  offset,
int  index 
)
static
   See if NODE is a clone with a known aggregate value at a given OFFSET of a
   parameter with the given INDEX.  

References cgraph_edge_brings_value_p(), ipcp_value_source::cs, and get_next_cgraph_edge_clone().

Referenced by ipcp_discover_new_direct_edges().

static bool get_info_about_necessary_edges ( struct ipcp_value val,
int *  freq_sum,
gcov_type count_sum,
int *  caller_count 
)
static
   Given VAL, iterate over all its sources and if they still hold, add their
   edge frequency and their number into *FREQUENCY and *CALLER_COUNT
   respectively.  
static struct cgraph_edge* get_next_cgraph_edge_clone ( )
staticread
   Get the next clone in the linked list of clones of an edge.  

References cgraph_node::count.

Referenced by get_clone_agg_value().

static struct ipa_replace_map* get_replacement_map ( )
staticread
   Construct a replacement map for a know VALUE for a formal parameter PARAM.
   Return it or NULL if for some reason it cannot be created.  
static bool good_cloning_opportunity_p ( struct cgraph_node node,
int  time_benefit,
int  freq_sum,
gcov_type  count_sum,
int  size_cost 
)
static
   Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
   and SIZE_COST and with the sum of frequencies of incoming edges to the
   potential new clone in FREQUENCIES.  
static void grow_next_edge_clone_vector ( )
inlinestatic
static bool has_undead_caller_from_outside_scc_p ( struct cgraph_node node,
void *  data 
)
static
   Return true if NODE has a caller from outside of its SCC that is not
   dead.  Worker callback for cgraph_for_node_and_aliases.  
static int hint_time_bonus ( )
static
   Return time bonus incurred because of HINTS.  
static void identify_dead_nodes ( )
static
   Identify nodes within the same SCC as NODE which are no longer needed
   because of new clones and will be removed as unreachable.  

References IPA_PASS, ipa_prop_read_all_agg_replacement(), ipa_prop_write_all_agg_replacement(), ipcp_generate_summary(), ipcp_read_summary(), and ipcp_write_summary().

static void init_caller_stats ( )
inlinestatic
   Initialize fields of STAT to zeroes.  

References cgraph_node_name(), and dump_file.

static void initialize_node_lattices ( )
static
   Initialize ipcp_lattices.  
         When cloning is allowed, we can assume that externally visible
         functions are not called.  We will compensate this by cloning
         later.  
static vec<ipa_agg_jf_item_t> intersect_aggregates_with_edge ( struct cgraph_edge cs,
int  index,
vec< ipa_agg_jf_item_t inter 
)
static
   Intersect values in INTER with aggregate values that come along edge CS to
   parameter number INDEX and return it.  If INTER does not actually exist yet,
   copy all incoming values to it.  If we determine we ended up with no values
   whatsoever, return a released vector.  
                 Currently we do not produce clobber aggregate jump
                 functions, adjust when we do.  
             Currently we do not produce clobber aggregate jump
             functions, adjust when we do.  
static void intersect_with_agg_replacements ( struct cgraph_node node,
int  index,
vec< ipa_agg_jf_item_t > *  inter,
HOST_WIDE_INT  offset 
)
static
   Intersect all values in INTER with those that we have already scheduled to
   be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
   (while subtracting OFFSET).  

References ipa_jump_func::agg, ipa_agg_jump_function::items, ipa_agg_jf_item::offset, ipa_agg_jf_item::value, and values_equal_for_ipcp_p().

static void intersect_with_plats ( struct ipcp_param_lattices plats,
vec< ipa_agg_jf_item_t > *  inter,
HOST_WIDE_INT  offset 
)
static
   Intersect all values in INTER with single value lattices in PLATS (while
   subtracting OFFSET).  
tree ipa_get_indirect_edge_target ( struct cgraph_edge ie,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs 
)
   If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
   (which can contain both constants and binfos), KNOWN_BINFOS (which can be
   NULL) or KNOWN_AGGS (which also can be NULL) return the destination.  
static tree ipa_get_indirect_edge_target_1 ( struct cgraph_edge ie,
vec< tree known_vals,
vec< tree known_binfos,
vec< ipa_agg_jump_function_p known_aggs,
struct ipa_agg_replacement_value agg_reps 
)
static
   If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
   (which can contain both constants and binfos), KNOWN_BINFOS, KNOWN_AGGS or
   AGG_REPS return the destination.  The latter three can be NULL.  If AGG_REPS
   is not NULL, KNOWN_AGGS is ignored.  

Referenced by safe_add().

static tree ipa_get_jf_ancestor_result ( )
static
   Return the result of an ancestor jump function JFUNC on the constant value
   INPUT.  Return NULL_TREE if that cannot be determined.  
static tree ipa_get_jf_pass_through_result ( )
static
   Return the result of a (possibly arithmetic) pass through jump function
   JFUNC on the constant value INPUT.  Return NULL_TREE if that cannot be
   determined or be considered an interprocedural invariant.  

Referenced by add_value_to_lattice().

static struct ipcp_param_lattices* ipa_get_parm_lattices ( )
staticread
   Return the param lattices structure corresponding to the Ith formal
   parameter of the function described by INFO.  

References print_generic_expr().

Referenced by copy_plats_to_inter(), propagate_aggs_accross_jump_function(), set_agg_lats_contain_variable(), and set_chain_of_aglats_contains_variable().

static struct ipcp_lattice* ipa_get_scalar_lat ( )
staticread
   Return the lattice corresponding to the scalar value of the Ith formal
   parameter of the function described by INFO.  

References ipcp_lattice::bottom.

Referenced by update_specialized_profile().

static bool ipa_lat_is_single_const ( )
inlinestatic
   Return whether LAT is a lattice with a single constant and without an
   undefined value.  

Referenced by move_binfos_to_values().

tree ipa_value_from_jfunc ( )
   Determine whether JFUNC evaluates to a known value (that is either a
   constant or a binfo) and if so, return it.  Otherwise return NULL. INFO
   describes the caller node so that pass-through jump functions can be
   evaluated.  

References dump_file, and print_all_lattices().

Referenced by ipa_find_agg_cst_for_param(), and update_specialized_profile().

static bool ipcp_cloning_candidate_p ( )
static
   Return true if this NODE is viable candidate for cloning.  
     When profile is available and function is hot, propagate into it even if
     calls seems cold; constant propagation can improve function's speed
     significantly.  
static void ipcp_decision_stage ( )
static
   The decision stage.  Iterate over the topological order of call graph nodes
   TOPO and make specialized clones if deemed beneficial.  
static void ipcp_discover_new_direct_edges ( struct cgraph_node node,
vec< tree known_vals,
struct ipa_agg_replacement_value aggvals 
)
static
   Discover newly direct outgoing edges from NODE which is a new clone with
   known KNOWN_VALS and make them direct.  
     Turning calls to direct calls will improve overall summary.  

References cgraph_edge::caller, get_clone_agg_value(), ipcp_value_source::index, ipa_node_params::known_vals, ipcp_value_source::offset, ipcp_value_source::val, ipcp_value::value, and values_equal_for_ipcp_p().

static unsigned int ipcp_driver ( )
static
   The IPCP driver.  
     Topological sort.  
     Do the interprocedural propagation.  
     Decide what constant propagation and cloning should be performed.  
     Free all IPCP structures.  
static void ipcp_edge_duplication_hook ( struct cgraph_edge src,
struct cgraph_edge dst,
__attribute__((unused)) void *  data 
)
static
   Edge duplication hook to grow the appropriate linked list in
   next_edge_clone. 
static void ipcp_generate_summary ( )
static
   Initialization and computation of IPCP data structures.  This is the initial
   intraprocedural analysis of functions, which gathers information to be
   propagated later on.  

Referenced by identify_dead_nodes().

static void ipcp_propagate_stage ( )
static
   Propagate constants, binfos and their effects from the summaries
   interprocedurally.  

References cgraph_edge_max_uid.

static void ipcp_read_summary ( )
static
   Read ipcp summary.  

Referenced by identify_dead_nodes().

DEBUG_FUNCTION bool ipcp_val_in_agg_replacements_p ( struct ipa_agg_replacement_value aggvals,
int  index,
HOST_WIDE_INT  offset,
tree  value 
)
   Return true if there is a replacement equivalent to VALUE, INDEX and OFFSET
   among those in the AGGVALS list.  
DEBUG_FUNCTION void ipcp_verify_propagated_values ( void  )
   If checking is enabled, verify that no lattice is in the TOP state, i.e. not
   bottom, not containing a variable component and without any known value at
   the same time.  
static bool ipcp_versionable_function_p ( )
static
   Return true if it is at all technically possible to create clones of a
   NODE.  

References cgraph_function_with_gimple_body_p().

static void ipcp_write_summary ( )
static
   Write ipcp summary for nodes in SET.  

Referenced by identify_dead_nodes().

ipa_opt_pass_d* make_pass_ipa_cp ( )
static bool merge_agg_lats_step ( struct ipcp_param_lattices dest_plats,
HOST_WIDE_INT  offset,
HOST_WIDE_INT  val_size,
struct ipcp_agg_lattice ***  aglat,
bool  pre_existing,
bool *  change 
)
static
   Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
   already existing lattice for the given OFFSET and SIZE, marking all skipped
   lattices as containing variable and checking for overlaps.  If there is no
   already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
   it with offset, size and contains_variable to PRE_EXISTING, and return true,
   unless there are too many already.  If there are two many, return false.  If
   there are overlaps turn whole DEST_PLATS to bottom and return false.  If any
   skipped lattices were newly marked as containing variable, set *CHANGE to
   true.  
static bool merge_aggregate_lattices ( struct cgraph_edge cs,
struct ipcp_param_lattices dest_plats,
struct ipcp_param_lattices src_plats,
int  src_idx,
HOST_WIDE_INT  offset_delta 
)
static
   Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
   DELTA_OFFSET.  CS is the call graph edge and SRC_IDX the index of the source
   parameter used for lattice value sources.  Return true if DEST_PLATS changed
   in any way.  

References ipa_jump_func::agg, and ipa_agg_jump_function::items.

static void move_binfos_to_values ( vec< tree known_vals,
vec< tree known_binfos 
)
static
static void perhaps_add_new_callers ( )
static
   Given an original NODE and a VAL for which we have already created a
   specialized clone, look whether there are incoming edges that still lead
   into the old node but now also bring the requested value and also conform to
   all other criteria such that they can be redirected the the special node.
   This function can therefore redirect the final edge in a SCC.  
static struct cgraph_node* pop_node_from_stack ( )
staticread
   Pop a node from the stack in TOPO and return it or return NULL if the stack
   is empty.  

References ipcp_param_lattices::aggs_contain_variable, ipcp_lattice::contains_variable, and ipcp_param_lattices::itself.

static void print_ipcp_constant_value ( )
static
   Print V which is extracted from a value in a lattice to F.  

Referenced by update_specialized_profile().

static void print_lattice ( FILE *  f,
struct ipcp_lattice lat,
bool  dump_sources,
bool  dump_benefits 
)
static
   Print a lattice LAT to F.  
static bool propagate_aggs_accross_jump_function ( struct cgraph_edge cs,
struct ipa_jump_func jfunc,
struct ipcp_param_lattices dest_plats 
)
static
   Propagate scalar values across jump function JFUNC that is associated with
   edge CS and put the values into DEST_LAT.  
             Currently we do not produce clobber aggregate jump
             functions, replace with merging when we do.  
             Currently we do not produce clobber aggregate jump
             functions, replace with merging when we do.  

References symtab_node_base::alias, AVAIL_OVERWRITABLE, cgraph_edge::callee, cgraph_alias_target(), cgraph_function_node(), cgraph_function_with_gimple_body_p(), symtab_node_base::definition, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_param_count(), ipa_get_parm_lattices(), ipcp_param_lattices::itself, propagate_scalar_accross_jump_function(), set_all_contains_variable(), cgraph_node::thunk, and cgraph_thunk_info::thunk_p.

static bool propagate_constants_accross_call ( )
static
   Propagate constants from the caller to the callee of CS.  INFO describes the
   caller.  
     If this call goes through a thunk we must not propagate to the first (0th)
     parameter.  However, we might need to uncover a thunk from below a series
     of aliases first.  

References ipa_agg_replacement_value::value.

static void propagate_constants_topo ( )
static
   One pass of constants propagation along the call graph edges, from callers
   to callees (requires topological ordering in TOPO), iterate over strongly
   connected components.  
         First, iteratively propagate within the strongly connected component
         until all lattices stabilize.  
         Afterwards, propagate along edges leading out of the SCC, calculates
         the local effects of the discovered constants and all valid values to
         their topological sort.  
static void propagate_effects ( )
static
   Propagate the estimated effects of individual values along the topological
   from the dependent values to those they depend on.  

References cgraph_edge::callee, dump_file, dump_flags, ipa_find_reference(), ipa_get_controlled_uses(), ipa_remove_reference(), and ipa_set_controlled_uses().

static bool propagate_scalar_accross_jump_function ( struct cgraph_edge cs,
struct ipa_jump_func jfunc,
struct ipcp_lattice dest_lat 
)
static
   Propagate scalar values across jump function JFUNC that is associated with
   edge CS and put the values into DEST_LAT.  
         If we would need to clone the caller and cannot, do not propagate.  
     TODO: We currently do not handle member method pointers in IPA-CP (we only
     use it for indirect inlining), we should propagate them too.  

Referenced by propagate_aggs_accross_jump_function().

static bool propagate_vals_accross_ancestor ( struct cgraph_edge cs,
struct ipa_jump_func jfunc,
struct ipcp_lattice src_lat,
struct ipcp_lattice dest_lat,
int  src_idx 
)
static
   Propagate values through an ancestor jump function JFUNC associated with
   edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
   is the index of the source parameter.  
static bool propagate_vals_accross_pass_through ( struct cgraph_edge cs,
struct ipa_jump_func jfunc,
struct ipcp_lattice src_lat,
struct ipcp_lattice dest_lat,
int  src_idx 
)
static
   Propagate values through a pass-through jump function JFUNC associated with
   edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
   is the index of the source parameter.  
     Do not create new values when propagating within an SCC because if there
     are arithmetic functions with circular dependencies, there is infinite
     number of them and we would just make lattices bottom.  

References ipa_binfo_from_known_type_jfunc(), and set_lattice_contains_variable().

static void push_node_to_stack ( )
inlinestatic
   Add NODE to the stack in TOPO, unless it is already there.  
static int safe_add ( )
static
static bool set_agg_lats_contain_variable ( )
inlinestatic
   Mark all aggegate lattices in PLATS as containing an unknown value and
   return true if they were not previously marked as such.  

References cgraph_edge::indirect_info, ipa_get_parm_lattices(), cgraph_indirect_call_info::param_index, and ipcp_param_lattices::virt_call.

static bool set_agg_lats_to_bottom ( )
inlinestatic
   Set all aggegate lattices in PLATS to bottom and return true if they were
   not previously set as such.  
static bool set_all_contains_variable ( )
inlinestatic
   Mark bot aggregate and scalar lattices as containing an unknown variable,
   return true is any of them has not been marked as such so far.  

References ipa_get_jf_pass_through_operation(), and ipa_get_jf_pass_through_type_preserved().

Referenced by propagate_aggs_accross_jump_function().

static bool set_chain_of_aglats_contains_variable ( )
static
   Set all AGLAT and all other aggregate lattices reachable by next pointers as
   containing an unknown value.  

References ipcp_param_lattices::aggs_bottom, cgraph_edge::caller, ipa_get_jf_pass_through_formal_id(), ipa_get_jf_pass_through_operation(), ipa_get_parm_lattices(), IPA_JF_PASS_THROUGH, and ipa_jump_func::type.

static bool set_check_aggs_by_ref ( struct ipcp_param_lattices dest_plats,
bool  new_aggs_by_ref 
)
static
   If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
   NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
   other cases, return false).  If there are no aggregate items, set
   aggs_by_ref to NEW_AGGS_BY_REF.  

References ipcp_agg_lattice::next, and set_lattice_contains_variable().

static bool set_lattice_contains_variable ( )
inlinestatic
   Mark lattice as containing an unknown value and return true if it previously
   was not marked as such.  

Referenced by add_value_to_lattice(), propagate_vals_accross_pass_through(), and set_check_aggs_by_ref().

static bool set_lattice_to_bottom ( )
inlinestatic
   Set lattice LAT to bottom and return true if it previously was not set as
   such.  
static void spread_undeadness ( )
static
static void update_profiling_info ( struct cgraph_node orig_node,
struct cgraph_node new_node 
)
static
   After a specialized NEW_NODE version of ORIG_NODE has been created, update
   their profile information to reflect this.  

References bitmap_set_bit(), and ipa_is_param_used().

static void update_specialized_profile ( struct cgraph_node new_node,
struct cgraph_node orig_node,
gcov_type  redirected_sum 
)
static
   Update the respective profile of specialized NEW_NODE and the original
   ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
   have been redirected to the specialized version.  

References cgraph_edge::caller, count, dump_file, dump_flags, ipa_dump_param(), ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_param_count(), ipa_get_scalar_lat(), ipa_value_from_jfunc(), print_ipcp_constant_value(), and values_equal_for_ipcp_p().

static bool values_equal_for_ipcp_p ( )
static
   Return true iff X and Y should be considered equal values by IPA-CP.  

Referenced by intersect_with_agg_replacements(), ipcp_discover_new_direct_edges(), and update_specialized_profile().


Variable Documentation

alloc_pool ipcp_agg_lattice_pool
alloc_pool ipcp_sources_pool
alloc_pool ipcp_values_pool
   Allocation pools for values and their sources in ipa-cp.  
gcov_type max_count
static
   Maximal count found in program.  
long max_new_size
static
vec<cgraph_edge_p> next_edge_clone
static
   Vector of pointers which for linked lists of clones of an original crgaph
   edge. 
long overall_size
static
   Original overall size of the program.  

Referenced by dump_histogram().

struct ipcp_value* values_topo
static
   Head of the linked list of topologically sorted values.