GCC Middle and Back End API Reference
ipa-cp.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
#include "target.h"
#include "ipa-prop.h"
#include "bitmap.h"
#include "tree-pass.h"
#include "flags.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
#include "tree-inline.h"
#include "params.h"
#include "ipa-inline.h"
#include "ipa-utils.h"
Include dependency graph for ipa-cp.c:

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(), NULL_TREE, TREE_CODE, TREE_TYPE, 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.

References FOR_EACH_VEC_ELT.

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_EDGE_REF, 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_REF, 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 gcc_checking_assert, 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(), ipcp_write_summary(), NULL, OPTGROUP_NONE, TODO_dump_symtab, and TODO_remove_functions.

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, gcc_checking_assert, 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 DECL_INITIAL, print_generic_expr(), and TREE_OPERAND.

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, NULL_TREE, 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(), and gcc_checking_assert.

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, gcc_assert, 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, gcc_checking_assert, IPA_EDGE_REF, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_param_count(), ipa_get_parm_lattices(), IPA_NODE_REF, 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_NODE_REF, ipa_remove_reference(), ipa_set_controlled_uses(), IPA_UNDESCRIBED_USE, and NULL.

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 gcc_checking_assert, 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 gcc_checking_assert, ipa_get_jf_pass_through_operation(), ipa_get_jf_pass_through_type_preserved(), and TREE_CODE.

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, IPA_NODE_REF, 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, ipa_is_param_used(), and TREE_CODE.

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, FOR_EACH_VEC_ELT, ipa_dump_param(), IPA_EDGE_REF, ipa_get_cs_argument_count(), ipa_get_ith_jump_func(), ipa_get_param_count(), ipa_get_scalar_lat(), IPA_NODE_REF, ipa_value_from_jfunc(), NULL_TREE, 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.