GCC Middle and Back End API Reference
tree-ssa-loop-ivopts.c File Reference

Data Structures

struct  iv
struct  version_info
struct  comp_cost
struct  cost_pair
struct  iv_use
struct  iv_cand
struct  iv_inv_expr_ent
struct  iv_inv_expr_hasher
struct  ivopts_data
struct  iv_ca
struct  iv_ca_delta
struct  ifs_ivopts_data
struct  address_cost_data_s

Typedefs

typedef struct iv_useiv_use_p
typedef struct iv_candiv_cand_p
typedef struct
address_cost_data_s
address_cost_data

Enumerations

enum  use_type { USE_NONLINEAR_EXPR, USE_ADDRESS, USE_COMPARE }
enum  iv_position {
  IP_NORMAL, IP_END, IP_BEFORE_USE, IP_AFTER_USE,
  IP_ORIGINAL
}

Functions

static HOST_WIDE_INT avg_loop_niter ()
static comp_cost force_expr_to_var_cost (tree, bool)
static unsigned n_iv_uses ()
static struct iv_useiv_use ()
static unsigned n_iv_cands ()
static struct iv_candiv_cand ()
edge single_dom_exit ()
void dump_iv (FILE *, struct iv *)
void dump_iv ()
void dump_use (FILE *, struct iv_use *)
void dump_use ()
void dump_uses (FILE *, struct ivopts_data *)
void dump_uses ()
void dump_cand (FILE *, struct iv_cand *)
void dump_cand ()
static struct version_infover_info ()
static struct version_infoname_info ()
static bool stmt_after_ip_normal_pos ()
static bool stmt_after_inc_pos ()
static bool stmt_after_increment ()
static bool abnormal_ssa_name_p ()
static bool idx_contains_abnormal_ssa_name_p (tree base, tree *index, void *data)
bool contains_abnormal_ssa_name_p ()
static struct tree_niter_descniter_for_exit ()
static struct tree_niter_descniter_for_single_dom_exit ()
static void tree_ssa_iv_optimize_init ()
static tree determine_base_object ()
static struct ivalloc_iv ()
static void set_iv ()
static struct ivget_iv ()
static tree determine_biv_step ()
static bool find_bivs ()
static void mark_bivs ()
static bool find_givs_in_stmt_scev ()
static void find_givs_in_stmt ()
static void find_givs_in_bb ()
static void find_givs ()
static bool find_induction_variables ()
static struct iv_userecord_use (struct ivopts_data *data, tree *use_p, struct iv *iv, gimple stmt, enum use_type use_type)
static void record_invariant ()
static struct iv_usefind_interesting_uses_op ()
static bool extract_cond_operands (struct ivopts_data *data, gimple stmt, tree **control_var, tree **bound, struct iv **iv_var, struct iv **iv_bound)
static void find_interesting_uses_cond ()
struct loopoutermost_invariant_loop_for_expr ()
bool expr_invariant_in_loop_p ()
bool stmt_invariant_in_loop_p ()
static bool idx_find_step ()
static bool idx_record_use (tree base, tree *idx, void *vdata)
static bool constant_multiple_of ()
static bool may_be_unaligned_p ()
bool may_be_nonaddressable_p ()
static void find_interesting_uses_address ()
static void find_invariants_stmt ()
static void find_interesting_uses_stmt ()
static void find_interesting_uses_outside ()
static void find_interesting_uses ()
static tree strip_offset_1 (tree expr, bool inside_addr, bool top_compref, unsigned HOST_WIDE_INT *offset)
static tree strip_offset ()
static tree generic_type_for ()
static tree find_depends ()
static struct iv_candadd_candidate_1 (struct ivopts_data *data, tree base, tree step, bool important, enum iv_position pos, struct iv_use *use, gimple incremented_at)
static bool allow_ip_end_pos_p ()
static void add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, bool important, struct iv_use *use)
static void add_candidate (struct ivopts_data *data, tree base, tree step, bool important, struct iv_use *use)
static void add_standard_iv_candidates ()
static void add_old_iv_candidates ()
static void add_old_ivs_candidates ()
static void add_iv_value_candidates (struct ivopts_data *data, struct iv *iv, struct iv_use *use)
static void add_derived_ivs_candidates ()
static void record_important_candidates ()
static void alloc_use_cost_map ()
static comp_cost new_cost ()
static comp_cost add_costs ()
static comp_cost sub_costs ()
static int compare_costs ()
static bool infinite_cost_p ()
static void set_use_iv_cost (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand, comp_cost cost, bitmap depends_on, tree value, enum tree_code comp, int inv_expr_id)
static struct cost_pairget_use_iv_cost (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static unsigned seq_cost ()
static rtx produce_memory_decl_rtl ()
static tree prepare_decl_rtl ()
static unsigned computation_cost ()
static tree var_at_stmt ()
static tree determine_common_wider_type ()
static bool get_computation_aff (struct loop *loop, struct iv_use *use, struct iv_cand *cand, gimple at, struct affine_tree_combination *aff)
static tree get_use_type ()
static tree get_computation_at (struct loop *loop, struct iv_use *use, struct iv_cand *cand, gimple at)
static tree get_computation ()
static unsigned adjust_setup_cost ()
bool multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, enum machine_mode mode, addr_space_t as)
static comp_cost get_address_cost (bool symbol_present, bool var_present, unsigned HOST_WIDE_INT offset, HOST_WIDE_INT ratio, HOST_WIDE_INT cstep, enum machine_mode mem_mode, addr_space_t as, bool speed, bool stmt_after_inc, bool *may_autoinc)
static bool get_shiftadd_cost (tree expr, enum machine_mode mode, comp_cost cost0, comp_cost cost1, tree mult, bool speed, comp_cost *cost)
static comp_cost force_expr_to_var_cost ()
static comp_cost force_var_cost (struct ivopts_data *data, tree expr, bitmap *depends_on)
static comp_cost split_address_cost (struct ivopts_data *data, tree addr, bool *symbol_present, bool *var_present, unsigned HOST_WIDE_INT *offset, bitmap *depends_on)
static comp_cost ptr_difference_cost (struct ivopts_data *data, tree e1, tree e2, bool *symbol_present, bool *var_present, unsigned HOST_WIDE_INT *offset, bitmap *depends_on)
static comp_cost difference_cost (struct ivopts_data *data, tree e1, tree e2, bool *symbol_present, bool *var_present, unsigned HOST_WIDE_INT *offset, bitmap *depends_on)
static bool compare_aff_trees ()
static int get_expr_id ()
static int get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase, tree cbase, HOST_WIDE_INT ratio, bool address_p)
static comp_cost get_computation_cost_at (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand, bool address_p, bitmap *depends_on, gimple at, bool *can_autoinc, int *inv_expr_id)
static comp_cost get_computation_cost (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand, bool address_p, bitmap *depends_on, bool *can_autoinc, int *inv_expr_id)
static bool determine_use_iv_cost_generic (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static bool determine_use_iv_cost_address (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static void cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter, aff_tree *val)
static tree iv_period ()
static enum tree_code iv_elimination_compare ()
static tree strip_wrap_conserving_type_conversions ()
static bool expr_equal_p ()
static bool difference_cannot_overflow_p ()
static bool iv_elimination_compare_lt (struct ivopts_data *data, struct iv_cand *cand, enum tree_code *comp_p, struct tree_niter_desc *niter)
static bool may_eliminate_iv (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand, tree *bound, enum tree_code *comp)
static int parm_decl_cost ()
static bool determine_use_iv_cost_condition (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static bool determine_use_iv_cost (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static bool autoinc_possible_for_pair (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static void set_autoinc_for_original_candidates ()
static void find_iv_candidates ()
static void determine_use_iv_costs ()
static void determine_iv_cost ()
static void determine_iv_costs ()
static unsigned ivopts_global_cost_for_size ()
static void determine_set_costs ()
static bool cheaper_cost_pair ()
static struct cost_pairiv_ca_cand_for_use ()
static void iv_ca_recount_cost ()
static void iv_ca_set_remove_invariants ()
static void iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs, struct iv_use *use)
static void iv_ca_set_add_invariants ()
static void iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs, struct iv_use *use, struct cost_pair *cp)
static void iv_ca_add_use (struct ivopts_data *data, struct iv_ca *ivs, struct iv_use *use, bool important_candidates)
static comp_cost iv_ca_cost ()
static bool iv_ca_has_deps ()
static struct iv_ca_deltaiv_ca_delta_add (struct iv_use *use, struct cost_pair *old_cp, struct cost_pair *new_cp, struct iv_ca_delta *next_change)
static struct iv_ca_deltaiv_ca_delta_join ()
static struct iv_ca_deltaiv_ca_delta_reverse ()
static void iv_ca_delta_commit (struct ivopts_data *data, struct iv_ca *ivs, struct iv_ca_delta *delta, bool forward)
static bool iv_ca_cand_used_p ()
static unsigned iv_ca_n_cands ()
static void iv_ca_delta_free ()
static struct iv_caiv_ca_new ()
static void iv_ca_free ()
static void iv_ca_dump ()
static comp_cost iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs, struct iv_cand *cand, struct iv_ca_delta **delta, unsigned *n_ivs, bool min_ncand)
static comp_cost iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, struct iv_cand *cand, struct iv_ca_delta **delta)
static comp_cost iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs, struct iv_cand *except_cand, struct iv_ca_delta **delta)
static bool try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs, struct iv_use *use, bool originalp)
static struct iv_caget_initial_solution ()
static bool try_improve_iv_set ()
static struct iv_cafind_optimal_iv_set_1 ()
static struct iv_cafind_optimal_iv_set ()
static void create_new_iv ()
static void create_new_ivs ()
static void rewrite_use_nonlinear_expr (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static void adjust_iv_update_pos ()
static void rewrite_use_address (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static void rewrite_use_compare (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
static void rewrite_use ()
static void rewrite_uses ()
static void remove_unused_ivs ()
static bool free_tree_niter_desc (const void *key, void **value, void *data)
static void free_loop_data ()
static void tree_ssa_iv_optimize_finalize ()
static bool loop_body_includes_call ()
static bool tree_ssa_iv_optimize_loop ()
void tree_ssa_iv_optimize ()

Variables

static const comp_cost no_cost = {0, 0}
static const comp_cost infinite_cost = {INFTY, INFTY}
static vec< treedecl_rtl_to_reset
static struct ivopts_datafd_ivopts_data

Typedef Documentation

Returns cost of address in shape symbol + var + OFFSET + RATIO * index.
   If SYMBOL_PRESENT is false, symbol is omitted.  If VAR_PRESENT is false,
   variable is omitted.  Compute the cost for a memory reference that accesses
   a memory location of mode MEM_MODE in address space AS.

   MAY_AUTOINC is set to true if the autoincrement (increasing index by
   size of MEM_MODE / RATIO) is available.  To make this determination, we
   look at the size of the increment to be made, which is given in CSTEP.
   CSTEP may be zero if the step is unknown.
   STMT_AFTER_INC is true iff the statement we're looking at is after the
   increment of the original biv.

   TODO -- there must be some better way.  This all is quite crude.   
typedef struct iv_cand* iv_cand_p
typedef struct iv_use* iv_use_p
The data used by the induction variable optimizations.   

Enumeration Type Documentation

The position where the iv is computed.   
Enumerator:
IP_NORMAL 
IP_END 
IP_BEFORE_USE 
IP_AFTER_USE 
IP_ORIGINAL 
enum use_type
Types of uses.   
Enumerator:
USE_NONLINEAR_EXPR 
USE_ADDRESS 
USE_COMPARE 

Function Documentation

static bool abnormal_ssa_name_p ( )
static
Returns true if EXP is a ssa name that occurs in an abnormal phi node.   

Referenced by idx_contains_abnormal_ssa_name_p().

static void add_autoinc_candidates ( struct ivopts_data data,
tree  base,
tree  step,
bool  important,
struct iv_use use 
)
static
If possible, adds autoincrement candidates BASE + STEP * i based on use USE.
   Important field is set to IMPORTANT.   

References add_candidate_1(), CDI_DOMINATORS, cst_and_fits_in_hwi(), ivopts_data::current_loop, dominated_by_p(), gimple_bb(), HOST_WIDE_INT, int_cst_value(), IP_AFTER_USE, IP_BEFORE_USE, loop::latch, basic_block_def::loop_father, iv_use::op_p, iv_use::stmt, and stmt_could_throw_p().

Referenced by add_candidate().

static void add_candidate ( struct ivopts_data data,
tree  base,
tree  step,
bool  important,
struct iv_use use 
)
static
Adds a candidate BASE + STEP * i.  Important field is set to IMPORTANT and
   position to POS.  If USE is not NULL, the candidate is set as related to
   it.  The candidate computation is scheduled on all available positions.   

References add_autoinc_candidates(), add_candidate_1(), allow_ip_end_pos_p(), ivopts_data::current_loop, IP_END, ip_end_pos(), IP_NORMAL, ip_normal_pos(), iv_use::type, and USE_ADDRESS.

Referenced by add_iv_value_candidates(), add_old_iv_candidates(), and add_standard_iv_candidates().

static struct iv_cand* add_candidate_1 ( struct ivopts_data data,
tree  base,
tree  step,
bool  important,
enum iv_position  pos,
struct iv_use use,
gimple  incremented_at 
)
staticread
Adds a candidate BASE + STEP * i.  Important field is set to IMPORTANT and
   position to POS.  If USE is not NULL, the candidate is set as related to
   it.  If both BASE and STEP are NULL, we add a pseudocandidate for the
   replacement of the final value of the iv by a direct computation.   

References alloc_iv(), bitmap_set_bit(), create_tmp_var_raw(), dump_cand(), dump_file, dump_flags, fd_ivopts_data, find_depends(), generic_type_for(), iv_use::id, iv_cand::id, iv_cand::important, IP_AFTER_USE, IP_BEFORE_USE, IP_ORIGINAL, iv_cand(), ivopts_data::iv_candidates, n_iv_cands(), operand_equal_p(), iv_use::related_cands, and type().

Referenced by add_autoinc_candidates(), add_candidate(), and add_old_iv_candidates().

static void add_derived_ivs_candidates ( )
static
static void add_iv_value_candidates ( struct ivopts_data data,
struct iv iv,
struct iv_use use 
)
static
Adds candidates based on the value of the induction variable IV and USE.   

References add_candidate(), iv::base, build_int_cst(), HOST_WIDE_INT, offset, iv::step, and strip_offset().

Referenced by add_derived_ivs_candidates().

static void add_old_iv_candidates ( )
static
Adds candidates bases on the old induction variable IV.   

References add_candidate(), add_candidate_1(), iv::base, build_int_cst(), ivopts_data::current_loop, IP_ORIGINAL, loop_latch_edge(), iv::ssa_name, and iv::step.

Referenced by add_old_ivs_candidates().

static void add_old_ivs_candidates ( )
static
Adds candidates based on the old induction variables.   

References add_old_iv_candidates(), iv::biv_p, integer_zerop(), version_info::iv, ivopts_data::relevant, iv::step, and ver_info().

Referenced by find_iv_candidates().

static void add_standard_iv_candidates ( )
static
Adds standard iv candidates.   

References add_candidate(), and build_int_cst().

Referenced by find_iv_candidates().

static void adjust_iv_update_pos ( )
static
Performs a peephole optimization to reorder the iv update statement with
   a mem ref to enable instruction combining in later phases. The mem ref uses
   the iv value before the update, so the reordering transformation requires
   adjustment of the offset. CAND is the selected IV_CAND.

   Example:

   t = MEM_REF (base, iv1, 8, 16);  // base, index, stride, offset
   iv2 = iv1 + 1;

   if (t < val)      (1)
     goto L;
   goto Head;


   directly propagating t over to (1) will introduce overlapping live range
   thus increase register pressure. This peephole transform it into:


   iv2 = iv1 + 1;
   t = MEM_REF (base, iv2, 8, 8);
   if (t < val)
     goto L;
   goto Head;

References dump_file, dump_flags, gimple_assign_lhs(), gimple_bb(), gsi_end_p(), gsi_for_stmt(), gsi_last_nondebug_bb(), gsi_move_before(), gsi_prev_nondebug(), gsi_stmt(), IP_BEFORE_USE, IP_NORMAL, print_gimple_stmt(), and iv_use::stmt.

Referenced by rewrite_use_address().

static unsigned adjust_setup_cost ( )
static
Adjust the cost COST for being in loop setup rather than loop body.
   If we're optimizing for space, the loop setup overhead is constant;
   if we're optimizing for speed, amortize it over the per-iteration cost.   

References avg_loop_niter(), ivopts_data::current_loop, and optimize_loop_for_speed_p().

Referenced by determine_iv_cost(), determine_use_iv_cost_condition(), and get_computation_cost_at().

static struct iv* alloc_iv ( )
staticread
Allocates an induction variable with given initial value BASE and step STEP
   for loop LOOP.   

References iv::base, iv::base_object, iv::biv_p, determine_base_object(), iv::have_use_for, iv::ssa_name, iv::step, and iv::use_id.

Referenced by add_candidate_1(), find_interesting_uses_address(), and set_iv().

static void alloc_use_cost_map ( )
static
Allocates the data structure mapping the (use, candidate) pairs to costs.
   If consider_all_candidates is true, we use a two-dimensional array, otherwise
   we allocate a simple list to every use.   

References bitmap_count_bits(), ceil_log2(), ivopts_data::consider_all_candidates, iv_use::cost_map, iv_use(), n_iv_cands(), n_iv_uses(), iv_use::n_map_members, and iv_use::related_cands.

Referenced by determine_use_iv_costs().

static bool allow_ip_end_pos_p ( )
static
Returns true if incrementing the induction variable at the end of the LOOP
   is allowed.

   The purpose is to avoid splitting latch edge with a biv increment, thus
   creating a jump, possibly confusing other optimization passes and leaving
   less freedom to scheduler.  So we allow IP_END_POS only if IP_NORMAL_POS
   is not available (so we do not have a better alternative), or if the latch
   edge is already nonempty.   

References empty_block_p(), ip_end_pos(), and ip_normal_pos().

Referenced by add_candidate().

static bool autoinc_possible_for_pair ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
static
Return true if get_computation_cost indicates that autoincrement is
   a possibility for the pair of USE and CAND, false otherwise.   

References get_computation_cost(), infinite_cost_p(), iv_use::type, and USE_ADDRESS.

Referenced by set_autoinc_for_original_candidates().

static HOST_WIDE_INT avg_loop_niter ( )
inlinestatic
Returns the expected number of loop iterations for LOOP.
   The average trip count is computed from profile data if it
   exists.  

References estimated_stmt_executions_int(), and HOST_WIDE_INT.

Referenced by adjust_setup_cost(), and get_computation_cost_at().

static void cand_value_at ( struct loop loop,
struct iv_cand cand,
gimple  at,
tree  niter,
aff_tree val 
)
static
Computes value of candidate CAND at position AT in iteration NITER, and
   stores it to VAL.   

References aff_combination_add(), aff_combination_convert(), aff_combination_mult(), iv::base, iv::step, stmt_after_increment(), tree_to_aff_combination(), and type().

Referenced by may_eliminate_iv().

static bool cheaper_cost_pair ( )
static
Returns true if A is a cheaper cost pair than B.   

References cost_pair::cand, compare_costs(), and cost_pair::cost.

Referenced by iv_ca_add_use(), iv_ca_extend(), and iv_ca_narrow().

static bool compare_aff_trees ( )
static
static int compare_costs ( )
static
Returns a negative number if COST1 < COST2, a positive number if
   COST1 > COST2, and 0 if COST1 = COST2.   

References comp_cost::complexity, and comp_cost::cost.

Referenced by cheaper_cost_pair(), determine_use_iv_cost_condition(), find_optimal_iv_set(), iv_ca_prune(), try_add_cand_for(), and try_improve_iv_set().

static bool constant_multiple_of ( )
static
If we can prove that TOP = cst * BOT for some constant cst,
   store cst to MUL and return true.  Otherwise return false.
   The returned value is always sign-extended, regardless of the
   signedness of TOP and BOT.   

References double_int::is_zero(), operand_equal_p(), double_int::sdivmod(), double_int::sext(), and tree_to_double_int().

Referenced by get_computation_aff(), and get_computation_cost_at().

bool contains_abnormal_ssa_name_p ( )
Returns true if EXPR contains a ssa name that occurs in an
   abnormal phi node.   

References contains_abnormal_ssa_name_p(), for_each_index(), idx_contains_abnormal_ssa_name_p(), is_gimple_min_invariant(), tcc_binary, tcc_comparison, and tcc_unary.

static void create_new_ivs ( )
static
Creates new induction variables described in SET.   

References create_new_iv(), dump_cand(), dump_file, dump_flags, and iv_cand().

Referenced by tree_ssa_iv_optimize_loop().

static tree determine_base_object ( )
static
Returns a memory object to that EXPR points.  In case we are able to
   determine that it does not point to any such object, NULL is returned.   

References get_base_address().

Referenced by alloc_iv().

static tree determine_biv_step ( )
static
Determines the step of a biv defined in PHI.  Returns NULL if PHI does
   not define a simple affine biv with nonzero step.   

References gimple_bb(), integer_zerop(), basic_block_def::loop_father, simple_iv(), affine_iv::step, and virtual_operand_p().

Referenced by find_bivs().

static tree determine_common_wider_type ( )
static
If A is (TYPE) BA and B is (TYPE) BB, and the types of BA and BB have the
   same precision that is at least as wide as the precision of TYPE, stores
   BA to A and BB to B, and returns the type of BA.  Otherwise, returns the
   type of A and B.   

Referenced by get_computation_aff().

static void determine_iv_cost ( )
static
static void determine_iv_costs ( )
static
Determines costs of computation of the candidates.   

References determine_iv_cost(), dump_file, dump_flags, iv_cand(), and n_iv_cands().

Referenced by tree_ssa_iv_optimize_loop().

static bool determine_use_iv_cost ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
static
Determines cost of basing replacement of USE on CAND.  Returns false
   if USE cannot be based on CAND.   

References determine_use_iv_cost_address(), determine_use_iv_cost_condition(), determine_use_iv_cost_generic(), iv_use::type, USE_ADDRESS, USE_COMPARE, and USE_NONLINEAR_EXPR.

Referenced by determine_use_iv_costs().

static bool determine_use_iv_cost_address ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
static
Determines cost of basing replacement of USE on CAND in an address.   

References comp_cost::cost, get_computation_cost(), infinite_cost, infinite_cost_p(), IP_AFTER_USE, IP_BEFORE_USE, and set_use_iv_cost().

Referenced by determine_use_iv_cost().

static bool determine_use_iv_cost_generic ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
static
Determines cost of basing replacement of USE on CAND in a generic
   expression.   

References get_computation_cost(), infinite_cost_p(), IP_ORIGINAL, set_use_iv_cost(), and iv_use::stmt.

Referenced by determine_use_iv_cost().

static bool difference_cannot_overflow_p ( )
static
Returns true if we can prove that BASE - OFFSET does not overflow.  For now,
   we only detect the situation that BASE = SOMETHING + OFFSET, where the
   calculation is performed in non-wrapping type.

   TODO: More generally, we could test for the situation that
         BASE = SOMETHING + OFFSET' and OFFSET is between OFFSET' and zero.
         This would require knowing the sign of OFFSET.

         Also, we only look for the first addition in the computation of BASE.
         More complex analysis would be better, but introducing it just for
         this optimization seems like an overkill.   

References expand_simple_operations(), expr_equal_p(), get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, and nowrap_type_p().

Referenced by iv_elimination_compare_lt().

static comp_cost difference_cost ( struct ivopts_data data,
tree  e1,
tree  e2,
bool *  symbol_present,
bool *  var_present,
unsigned HOST_WIDE_INT offset,
bitmap depends_on 
)
static
Estimates cost of expressing difference E1 - E2 as
   var + symbol + offset.  The value of offset is added to OFFSET,
   SYMBOL_PRESENT and VAR_PRESENT are set to false if the corresponding
   part is missing.  DEPENDS_ON is a set of the invariants the computation
   depends on.   

References aff_combination_add(), aff_combination_scale(), aff_combination_to_tree(), comp_cost::cost, force_var_cost(), HOST_WIDE_INT, integer_zerop(), mult_by_coeff_cost(), no_cost, operand_equal_p(), ptr_difference_cost(), signed_type_for(), ivopts_data::speed, strip_offset(), tree_to_aff_combination(), and type().

Referenced by get_computation_cost_at().

void dump_cand ( FILE *  ,
struct iv_cand  
)
Dumps information about induction variable candidate CAND to FILE.   

Referenced by add_candidate_1(), and create_new_ivs().

void dump_iv ( FILE *  ,
struct iv  
)
Dumps information about the induction variable IV to FILE.   

Referenced by dump_cand(), dump_use(), and find_induction_variables().

void dump_use ( FILE *  ,
struct iv_use  
)
Dumps information about the USE to FILE.   

Referenced by dump_uses(), and record_use().

void dump_uses ( FILE *  ,
struct ivopts_data  
)
Dumps information about the uses to FILE.   
void dump_uses ( )

References dump_use(), iv_use(), and n_iv_uses().

static bool expr_equal_p ( )
static
bool expr_invariant_in_loop_p ( )
Returns true if expression EXPR is obviously invariant in LOOP,
   i.e. if all its operands are defined outside of the LOOP.  LOOP
   should not be the function body.   

References expr_invariant_in_loop_p(), flow_bb_inside_loop_p(), gimple_bb(), is_gimple_min_invariant(), len, and loop_depth().

static bool extract_cond_operands ( struct ivopts_data data,
gimple  stmt,
tree **  control_var,
tree **  bound,
struct iv **  iv_var,
struct iv **  iv_bound 
)
static
Given a condition in statement STMT, checks whether it is a compare
   of an induction variable and an invariant.  If this is the case,
   CONTROL_VAR is set to location of the iv, BOUND to the location of
   the invariant, IV_VAR and IV_BOUND are set to the corresponding
   induction variable descriptions, and true is returned.  If this is not
   the case, CONTROL_VAR and BOUND are set to the arguments of the
   condition and false is returned.   

References get_iv(), gimple_assign_rhs1_ptr(), gimple_assign_rhs2_ptr(), gimple_cond_lhs_ptr(), gimple_cond_rhs_ptr(), integer_zerop(), and iv::step.

Referenced by determine_use_iv_cost_condition(), find_interesting_uses_cond(), and rewrite_use_compare().

static void find_givs ( )
static
static void find_givs_in_bb ( )
static
Finds general ivs in basic block BB.   

References find_givs_in_stmt(), gsi_end_p(), gsi_next(), gsi_start_bb(), and gsi_stmt().

Referenced by find_givs().

static void find_givs_in_stmt ( )
static
Finds general ivs in statement STMT.   

References affine_iv::base, find_givs_in_stmt_scev(), gimple_assign_lhs(), set_iv(), and affine_iv::step.

Referenced by find_givs_in_bb().

static bool find_givs_in_stmt_scev ( )
static
Checks whether STMT defines a linear induction variable and stores its
   parameters to IV.   

References affine_iv::base, contains_abnormal_ssa_name_p(), ivopts_data::current_loop, expand_simple_operations(), gimple_assign_lhs(), loop_containing_stmt(), simple_iv(), affine_iv::step, and stmt_could_throw_p().

Referenced by find_givs_in_stmt().

static bool find_induction_variables ( )
static
For each ssa name defined in LOOP determines whether it is an induction
   variable and if so, its initial value and step.   

References dump_file, dump_flags, dump_iv(), find_bivs(), find_givs(), integer_zerop(), mark_bivs(), tree_niter_desc::may_be_zero, tree_niter_desc::niter, niter_for_single_dom_exit(), print_generic_expr(), ivopts_data::relevant, and ver_info().

Referenced by tree_ssa_iv_optimize_loop().

static void find_interesting_uses_cond ( )
static
Checks whether the condition in STMT is interesting and if so,
   records it.   

References extract_cond_operands(), find_interesting_uses_op(), record_use(), and USE_COMPARE.

Referenced by find_interesting_uses_stmt().

static void find_interesting_uses_outside ( )
static
Finds interesting uses of induction variables outside of loops
   on loop exit edge EXIT.   

References edge_def::dest, find_interesting_uses_op(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), and virtual_operand_p().

Referenced by find_interesting_uses().

static void find_invariants_stmt ( )
static
Finds and records invariants used in STMT.   

References record_invariant().

Referenced by find_interesting_uses_stmt().

static void find_iv_candidates ( )
static
static struct iv_ca* find_optimal_iv_set_1 ( )
staticread
Attempts to find the optimal set of induction variables.  We do simple
   greedy heuristic -- we try to replace at most one candidate in the selected
   solution and remove the unused ivs while this improves the cost.   

References dump_file, dump_flags, get_initial_solution(), iv_ca_dump(), and try_improve_iv_set().

Referenced by find_optimal_iv_set().

static comp_cost force_expr_to_var_cost ( tree  ,
bool   
)
static
static comp_cost force_var_cost ( struct ivopts_data data,
tree  expr,
bitmap depends_on 
)
static
Estimates cost of forcing EXPR into a variable.  DEPENDS_ON is a set of the
   invariants the computation depends on.   

References fd_ivopts_data, find_depends(), force_expr_to_var_cost(), and ivopts_data::speed.

Referenced by determine_iv_cost(), determine_use_iv_cost_condition(), difference_cost(), get_computation_cost_at(), and ptr_difference_cost().

static bool free_tree_niter_desc ( const void *  key,
void **  value,
void *  data 
)
static
Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
   for pointer_map_traverse.   

References free(), and tree_niter_desc::niter.

Referenced by free_loop_data().

static tree generic_type_for ( )
static
Returns variant of TYPE that can be used as base for different uses.
   We return unsigned type with the same precision, which avoids problems
   with overflows.   

References type(), and unsigned_type_for().

Referenced by add_candidate_1().

static tree get_computation ( )
static
Determines the expression by that USE is expressed from induction variable
   CAND in LOOP.  The computation is unshared.   

References get_computation_at(), and iv_use::stmt.

Referenced by rewrite_use_compare(), and rewrite_use_nonlinear_expr().

static bool get_computation_aff ( struct loop loop,
struct iv_use use,
struct iv_cand cand,
gimple  at,
struct affine_tree_combination aff 
)
static
Determines the expression by that USE is expressed from induction variable
   CAND at statement AT in LOOP.  The expression is stored in a decomposed
   form into AFF.  Returns false if USE cannot be expressed using CAND.   

References aff_combination_add(), aff_combination_convert(), aff_combination_scale(), iv::base, constant_multiple_of(), determine_common_wider_type(), iv_use::iv, iv::step, stmt_after_increment(), tree_to_aff_combination(), unsigned_type_for(), and var_at_stmt().

Referenced by get_computation_at(), and rewrite_use_address().

static tree get_computation_at ( struct loop loop,
struct iv_use use,
struct iv_cand cand,
gimple  at 
)
static
Determines the expression by that USE is expressed from induction variable
   CAND at statement AT in LOOP.  The computation is unshared.   

References aff_combination_to_tree(), get_computation_aff(), get_use_type(), and unshare_aff_combination().

Referenced by get_computation(), get_computation_cost_at(), and remove_unused_ivs().

static comp_cost get_computation_cost ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand,
bool  address_p,
bitmap depends_on,
bool *  can_autoinc,
int *  inv_expr_id 
)
static
Determines the cost of the computation by that USE is expressed
   from induction variable CAND.  If ADDRESS_P is true, we just need
   to create an address from it, otherwise we want to get it into
   register.  A set of invariants we depend on is stored in
   DEPENDS_ON.  If CAN_AUTOINC is nonnull, use it to record whether
   autoinc addressing is likely.   

References get_computation_cost_at(), and iv_use::stmt.

Referenced by autoinc_possible_for_pair(), determine_use_iv_cost_address(), determine_use_iv_cost_condition(), and determine_use_iv_cost_generic().

static comp_cost get_computation_cost_at ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand,
bool  address_p,
bitmap depends_on,
gimple  at,
bool *  can_autoinc,
int *  inv_expr_id 
)
static
Determines the cost of the computation by that USE is expressed
   from induction variable CAND.  If ADDRESS_P is true, we just need
   to create an address from it, otherwise we want to get it into
   register.  A set of invariants we depend on is stored in
   DEPENDS_ON.  AT is the statement at that the value is computed.
   If CAN_AUTOINC is nonnull, use it to record whether autoinc
   addressing is likely.   

References add_cost(), add_costs(), adjust_setup_cost(), aff_combination_add(), aff_combination_to_tree(), avg_loop_niter(), iv::base, iv::base_object, bitmap_clear(), build_int_cst(), comp, comp_cost::complexity, computation_cost(), constant_multiple_of(), comp_cost::cost, cst_and_fits_in_hwi(), ivopts_data::current_loop, difference_cost(), double_int::fits_shwi(), force_var_cost(), get_address_cost(), get_computation_at(), get_loop_invariant_expr_id(), HOST_WIDE_INT, infinite_cost, int_cst_value(), iv_use::iv, mult_by_coeff_cost(), multiplier_allowed_in_address_p(), new_cost(), offset, iv_use::op_p, operand_equal_p(), optimize_bb_for_speed_p(), ivopts_data::speed, iv::step, stmt_after_increment(), double_int::to_shwi(), and tree_to_aff_combination().

Referenced by get_computation_cost().

static struct iv_ca* get_initial_solution ( )
staticread
Finds an initial assignment of candidates to uses.   

References iv_ca_free(), iv_ca_new(), n_iv_uses(), and try_add_cand_for().

Referenced by find_optimal_iv_set_1().

static int get_loop_invariant_expr_id ( struct ivopts_data data,
tree  ubase,
tree  cbase,
HOST_WIDE_INT  ratio,
bool  address_p 
)
static
Returns the pseudo expr id if expression UBASE - RATIO * CBASE
   requires a new compiler generated temporary.  Returns -1 otherwise.
   ADDRESS_P is a flag indicating if the expression is for address
   computation.   

References aff_combination_add(), aff_combination_scale(), aff_combination_to_tree(), compare_aff_trees(), iv_inv_expr_ent::expr, double_int::from_shwi(), get_expr_id(), host_integerp(), is_gimple_min_invariant(), operand_equal_p(), and tree_to_aff_combination().

Referenced by get_computation_cost_at().

static bool get_shiftadd_cost ( tree  expr,
enum machine_mode  mode,
comp_cost  cost0,
comp_cost  cost1,
tree  mult,
bool  speed,
comp_cost cost 
)
static
static struct cost_pair* get_use_iv_cost ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
staticread
static tree get_use_type ( )
static
Return the type of USE.   

References iv::base, build_pointer_type(), iv_use::iv, iv_use::op_p, iv_use::type, type(), and USE_ADDRESS.

Referenced by get_computation_at().

static bool idx_contains_abnormal_ssa_name_p ( tree  base,
tree index,
void *  data 
)
static
Returns false if BASE or INDEX contains a ssa name that occurs in an
   abnormal phi node.  Callback for for_each_index.   

References abnormal_ssa_name_p().

Referenced by contains_abnormal_ssa_name_p().

static bool idx_record_use ( tree  base,
tree idx,
void *  vdata 
)
static
Records use in index IDX.  Callback for for_each_index.  Ivopts data
   object is passed to it in DATA.   

References array_ref_element_size(), array_ref_low_bound(), and find_interesting_uses_op().

Referenced by find_interesting_uses_address().

static void iv_ca_add_use ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_use use,
bool  important_candidates 
)
static
Extend set IVS by expressing USE by some of the candidates in it
   if possible. All important candidates will be considered
   if IMPORTANT_CANDIDATES is true.   

References iv_ca::bad_uses, iv_ca::cands, cheaper_cost_pair(), get_use_iv_cost(), iv_use::id, ivopts_data::important_candidates, iv_ca_set_cp(), iv_cand(), and iv_ca::upto.

Referenced by try_add_cand_for().

static struct cost_pair* iv_ca_cand_for_use ( )
staticread
Returns candidate by that USE is expressed in IVS.   

References iv_ca::cand_for_use, and iv_use::id.

Referenced by find_optimal_iv_set(), iv_ca_delta_commit(), iv_ca_dump(), iv_ca_extend(), iv_ca_narrow(), and try_add_cand_for().

static bool iv_ca_cand_used_p ( )
static
Returns true if CAND is used in IVS.   

References iv_cand::id, and iv_ca::n_cand_uses.

Referenced by try_add_cand_for(), and try_improve_iv_set().

static comp_cost iv_ca_cost ( )
static
static struct iv_ca_delta* iv_ca_delta_add ( struct iv_use use,
struct cost_pair old_cp,
struct cost_pair new_cp,
struct iv_ca_delta next_change 
)
staticread
Creates change of expressing USE by NEW_CP instead of OLD_CP and chains
   it before NEXT_CHANGE.   

References iv_ca_delta::new_cp, iv_ca_delta::next_change, iv_ca_delta::old_cp, and iv_ca_delta::use.

Referenced by iv_ca_extend(), iv_ca_narrow(), and try_add_cand_for().

static void iv_ca_delta_commit ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_ca_delta delta,
bool  forward 
)
static
Commit changes in DELTA to IVS.  If FORWARD is false, the changes are
   reverted instead.   

References iv_ca_cand_for_use(), iv_ca_delta_reverse(), iv_ca_set_cp(), iv_ca_delta::new_cp, iv_ca_delta::next_change, iv_ca_delta::old_cp, and iv_ca_delta::use.

Referenced by iv_ca_extend(), iv_ca_narrow(), iv_ca_prune(), try_add_cand_for(), and try_improve_iv_set().

static void iv_ca_delta_free ( )
static
Free the list of changes DELTA.   

References free(), and iv_ca_delta::next_change.

Referenced by iv_ca_narrow(), iv_ca_prune(), try_add_cand_for(), and try_improve_iv_set().

static struct iv_ca_delta* iv_ca_delta_join ( )
staticread
Joins two lists of changes L1 and L2.  Destructive -- old lists
   are rewritten.   

References last, and iv_ca_delta::next_change.

Referenced by iv_ca_prune(), and try_improve_iv_set().

static struct iv_ca_delta* iv_ca_delta_reverse ( )
staticread
Reverse the list of changes DELTA, forming the inverse to it.   

References iv_ca_delta::new_cp, iv_ca_delta::next_change, and iv_ca_delta::old_cp.

Referenced by iv_ca_delta_commit().

static comp_cost iv_ca_extend ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_cand cand,
struct iv_ca_delta **  delta,
unsigned *  n_ivs,
bool  min_ncand 
)
static
Try changing candidate in IVS to CAND for each use.  Return cost of the
   new set, and store differences in DELTA.  Number of induction variables
   in the new set is stored to N_IVS. MIN_NCAND is a flag. When it is true
   the function will try to find a solution with mimimal iv candidates.   

References cost_pair::cand, cheaper_cost_pair(), cost_pair::cost, get_use_iv_cost(), iv_ca_cand_for_use(), iv_ca_cost(), iv_ca_delta_add(), iv_ca_delta_commit(), iv_ca_has_deps(), iv_ca_n_cands(), iv_use(), and iv_ca::upto.

Referenced by try_add_cand_for(), and try_improve_iv_set().

static void iv_ca_free ( )
static
Free memory occupied by the set IVS.   

References free().

Referenced by find_optimal_iv_set(), get_initial_solution(), and tree_ssa_iv_optimize_loop().

static bool iv_ca_has_deps ( )
static
Returns true if all dependences of CP are among invariants in IVS.   

References cost_pair::depends_on, and iv_ca::n_invariant_uses.

Referenced by iv_ca_extend(), and iv_ca_narrow().

static unsigned iv_ca_n_cands ( )
static
Returns number of induction variable candidates in the set IVS.   

References iv_ca::n_cands.

Referenced by iv_ca_extend().

static comp_cost iv_ca_narrow ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_cand cand,
struct iv_ca_delta **  delta 
)
static
static comp_cost iv_ca_prune ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_cand except_cand,
struct iv_ca_delta **  delta 
)
static
Try optimizing the set of candidates IVS by removing candidates different
   from to EXCEPT_CAND from it.  Return cost of the new set, and store
   differences in DELTA.   

References iv_ca::cands, compare_costs(), iv_ca_cost(), iv_ca_delta_commit(), iv_ca_delta_free(), iv_ca_delta_join(), iv_ca_narrow(), and iv_cand().

Referenced by try_improve_iv_set().

static void iv_ca_recount_cost ( )
static
static void iv_ca_set_add_invariants ( )
static
Add invariants in set INVS to set IVS.   

References iv_ca::n_invariant_uses, and iv_ca::n_regs.

Referenced by iv_ca_set_cp().

static void iv_ca_set_remove_invariants ( )
static
Remove invariants in set INVS to set IVS.   

References iv_ca::n_invariant_uses, and iv_ca::n_regs.

Referenced by iv_ca_set_no_cp().

static enum tree_code iv_elimination_compare ( )
static
Returns the comparison operator used when eliminating the iv USE.   

References ivopts_data::current_loop, edge_def::dest, edge_def::flags, flow_bb_inside_loop_p(), gimple_bb(), and iv_use::stmt.

Referenced by may_eliminate_iv().

static bool iv_elimination_compare_lt ( struct ivopts_data data,
struct iv_cand cand,
enum tree_code comp_p,
struct tree_niter_desc niter 
)
static
Tries to replace loop exit by one formulated in terms of a LT_EXPR
   comparison with CAND.  NITER describes the number of iterations of
   the loops.  If successful, the comparison in COMP_P is altered accordingly.

   We aim to handle the following situation:

   sometype *base, *p;
   int a, b, i;

   i = a;
   p = p_0 = base + a;

   do
     {
       bla (*p);
       p++;
       i++;
     }
   while (i < b);

   Here, the number of iterations of the loop is (a + 1 > b) ? 0 : b - a - 1.
   We aim to optimize this to

   p = p_0 = base + a;
   do
     {
       bla (*p);
       p++;
     }
   while (p < p_0 - a + b);

   This preserves the correctness, since the pointer arithmetics does not
   overflow.  More precisely:

   1) if a + 1 <= b, then p_0 - a + b is the final value of p, hence there is no
      overflow in computing it or the values of p.
   2) if a + 1 > b, then we need to verify that the expression p_0 - a does not
      overflow.  To prove this, we use the fact that p_0 = base + a.   

References aff_combination_add(), aff_combination_scale(), comp, cst_and_fits_in_hwi(), difference_cannot_overflow_p(), HOST_WIDE_INT, int_cst_value(), integer_onep(), invert_tree_comparison(), IP_ORIGINAL, ivopts_data::loop_single_exit_p, tree_niter_desc::may_be_zero, affine_tree_combination::n, tree_niter_desc::niter, nowrap_type_p(), affine_tree_combination::offset, offset, and tree_to_aff_combination().

Referenced by may_eliminate_iv().

static tree iv_period ( )
static
Returns period of induction variable iv.   

References build_low_bits_mask(), num_ending_zeros(), iv::step, tree_low_cst(), type(), and unsigned_type_for().

Referenced by may_eliminate_iv().

static unsigned ivopts_global_cost_for_size ( )
static
Calculates cost for having SIZE induction variables.   

References ivopts_data::body_includes_call, estimate_reg_pressure_cost(), ivopts_data::regs_used, and ivopts_data::speed.

Referenced by determine_set_costs(), and iv_ca_recount_cost().

static bool loop_body_includes_call ( )
static
Returns true if the loop body BODY includes any function calls.   

References gimple_call_fndecl(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_call(), and is_inexpensive_builtin().

Referenced by tree_ssa_iv_optimize_loop().

bool may_be_nonaddressable_p ( )
Return true if EXPR may be non-addressable.    

References is_gimple_addressable(), is_gimple_reg(), and may_be_nonaddressable_p().

static bool may_be_unaligned_p ( )
static
Returns true if memory reference REF with step STEP may be unaligned.   

References get_inner_reference(), get_object_alignment(), highest_pow2_factor(), and HOST_WIDE_INT.

Referenced by find_interesting_uses_address().

static bool may_eliminate_iv ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand,
tree bound,
enum tree_code comp 
)
static
bool multiplier_allowed_in_address_p ( HOST_WIDE_INT  ratio,
enum machine_mode  mode,
addr_space_t  as 
)
Returns true if multiplying by RATIO is allowed in an address.  Test the
   validity for a memory reference accessing memory of mode MODE in
   address space AS.   

References bitmap_bit_p(), bitmap_clear(), bitmap_set_bit(), dump_file, dump_flags, gen_int_mode(), gen_raw_REG(), HOST_WIDE_INT, memory_address_addr_space_p(), sbitmap_alloc(), and targetm.

Referenced by get_address_cost(), get_computation_cost_at(), and most_expensive_mult_to_index().

static struct version_info* name_info ( )
staticread
Returns the info for ssa name NAME.   

References ver_info().

Referenced by create_new_iv(), find_depends(), get_iv(), record_invariant(), rewrite_use_nonlinear_expr(), and set_iv().

static comp_cost new_cost ( )
static
Returns description of computation cost of expression whose runtime
   cost is RUNTIME and complexity corresponds to COMPLEXITY.   

References comp_cost::complexity, and comp_cost::cost.

Referenced by attempt_change(), combine_validate_cost(), force_expr_to_var_cost(), get_address_cost(), get_computation_cost_at(), get_shiftadd_cost(), split_address_cost(), and try_replace_in_use().

static struct tree_niter_desc* niter_for_exit ( )
staticread
Returns the structure describing number of iterations determined from
    EXIT of DATA->current_loop, or NULL if something goes wrong.   

References contains_abnormal_ssa_name_p(), ivopts_data::current_loop, tree_niter_desc::niter, ivopts_data::niters, number_of_iterations_exit(), pointer_map_contains(), pointer_map_create(), and pointer_map_insert().

Referenced by may_eliminate_iv(), and niter_for_single_dom_exit().

static struct tree_niter_desc* niter_for_single_dom_exit ( )
staticread
Returns the structure describing number of iterations determined from
   single dominating exit of DATA->current_loop, or NULL if something
   goes wrong.   

References ivopts_data::current_loop, niter_for_exit(), and single_dom_exit().

Referenced by find_induction_variables().

struct loop* outermost_invariant_loop_for_expr ( )
read
Returns the outermost loop EXPR is obviously invariant in
   relative to the loop LOOP, i.e. if all its operands are defined
   outside of the returned loop.  Returns NULL if EXPR is not
   even obviously invariant in LOOP.   

References flow_bb_inside_loop_p(), gimple_bb(), is_gimple_min_invariant(), len, loop_depth(), basic_block_def::loop_father, outermost_invariant_loop_for_expr(), and superloop_at_depth().

static int parm_decl_cost ( )
static
static tree prepare_decl_rtl ( )
static
Prepares decl_rtl for variables referred in *EXPR_P.  Callback for
   walk_tree.  DATA contains the actual fake register number.   

References decl_rtl_to_reset, gen_raw_REG(), handled_component_p(), and produce_memory_decl_rtl().

Referenced by computation_cost().

static rtx produce_memory_decl_rtl ( )
static
Produce DECL_RTL for object obj so it looks like it is stored in memory.   

References gen_raw_REG(), gen_rtx_MEM(), set_mem_addr_space(), and targetm.

Referenced by force_expr_to_var_cost(), and prepare_decl_rtl().

static comp_cost ptr_difference_cost ( struct ivopts_data data,
tree  e1,
tree  e2,
bool *  symbol_present,
bool *  var_present,
unsigned HOST_WIDE_INT offset,
bitmap depends_on 
)
static
Estimates cost of expressing difference of addresses E1 - E2 as
   var + symbol + offset.  The value of offset is added to OFFSET,
   SYMBOL_PRESENT and VAR_PRESENT are set to false if the corresponding
   part is missing.  DEPENDS_ON is a set of the invariants the computation
   depends on.   

References aff_combination_add(), aff_combination_scale(), aff_combination_to_tree(), force_var_cost(), HOST_WIDE_INT, integer_zerop(), no_cost, ptr_difference_const(), signed_type_for(), split_address_cost(), tree_to_aff_combination(), and type().

Referenced by difference_cost().

static void record_important_candidates ( )
static
static void record_invariant ( )
static
Checks whether OP is a loop-level invariant and if so, records it.
   NONLINEAR_USE is true if the invariant is used in a way we do not
   handle specially.   

References bitmap_set_bit(), ivopts_data::current_loop, flow_bb_inside_loop_p(), gimple_bb(), version_info::has_nonlin_use, version_info::inv_id, ivopts_data::max_inv_id, version_info::name, name_info(), ivopts_data::relevant, and virtual_operand_p().

Referenced by find_interesting_uses_op(), and find_invariants_stmt().

static struct iv_use* record_use ( struct ivopts_data data,
tree use_p,
struct iv iv,
gimple  stmt,
enum use_type  use_type 
)
staticread
static void rewrite_use ( )
static
static void rewrite_use_address ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand 
)
static
static void rewrite_uses ( )
static
Rewrite the uses using the selected induction variables.   

References iv_use(), n_iv_uses(), rewrite_use(), and iv_use::selected.

Referenced by tree_ssa_iv_optimize_loop().

static unsigned seq_cost ( )
static
Returns estimate on cost of computing SEQ.   

References cost_pair::cost, and set_src_cost().

Referenced by computation_cost(), and get_address_cost().

static void set_autoinc_for_original_candidates ( )
static
Examine IP_ORIGINAL candidates to see if they are incremented next to a
   use that allows autoincrement, and set their AINC_USE if possible.   

References autoinc_possible_for_pair(), gimple_uid(), IP_ORIGINAL, iv_cand(), iv_use(), n_iv_cands(), n_iv_uses(), and iv_use::stmt.

Referenced by find_iv_candidates().

static void set_iv ( )
static
Sets STEP and BASE for induction variable IV.   

References alloc_iv(), bitmap_set_bit(), version_info::iv, name_info(), ivopts_data::relevant, and iv::ssa_name.

Referenced by find_bivs(), find_givs_in_stmt(), and get_iv().

static void set_use_iv_cost ( struct ivopts_data data,
struct iv_use use,
struct iv_cand cand,
comp_cost  cost,
bitmap  depends_on,
tree  value,
enum tree_code  comp,
int  inv_expr_id 
)
static
Sets cost of (USE, CANDIDATE) pair to COST and record that it depends
   on invariants DEPENDS_ON and that the value used in expressing it
   is VALUE, and in case of iv elimination the comparison operator is COMP.   

References cost_pair::cand, cost_pair::comp, comp, ivopts_data::consider_all_candidates, cost_pair::cost, iv_use::cost_map, cost_pair::depends_on, iv_cand::id, infinite_cost_p(), cost_pair::inv_expr_id, iv_use::n_map_members, and cost_pair::value.

Referenced by determine_use_iv_cost_address(), determine_use_iv_cost_condition(), and determine_use_iv_cost_generic().

edge single_dom_exit ( )
The single loop exit if it dominates the latch, NULL otherwise.   

References just_once_each_iteration_p(), single_exit(), and edge_def::src.

static comp_cost split_address_cost ( struct ivopts_data data,
tree  addr,
bool *  symbol_present,
bool *  var_present,
unsigned HOST_WIDE_INT offset,
bitmap depends_on 
)
static
Estimates cost of expressing address ADDR  as var + symbol + offset.  The
   value of offset is added to OFFSET, SYMBOL_PRESENT and VAR_PRESENT are set
   to false if the corresponding part is missing.  DEPENDS_ON is a set of the
   invariants the computation depends on.   

References fd_ivopts_data, find_depends(), get_inner_reference(), HOST_WIDE_INT, new_cost(), no_cost, and ivopts_data::speed.

Referenced by ptr_difference_cost().

static bool stmt_after_inc_pos ( )
static
Returns true if STMT if after the place where the original induction
   variable CAND is incremented.  If TRUE_IF_EQUAL is set, we return true
   if the positions are identical.   

References CDI_DOMINATORS, dominated_by_p(), gimple_bb(), and gimple_uid().

Referenced by stmt_after_increment().

static bool stmt_after_increment ( )
static
Returns true if STMT if after the place where the induction variable
   CAND is incremented in LOOP.   

References IP_AFTER_USE, IP_BEFORE_USE, IP_END, IP_NORMAL, IP_ORIGINAL, stmt_after_inc_pos(), and stmt_after_ip_normal_pos().

Referenced by cand_value_at(), get_computation_aff(), get_computation_cost_at(), may_eliminate_iv(), and var_at_stmt().

static bool stmt_after_ip_normal_pos ( )
static
Returns true if STMT is after the place where the IP_NORMAL ivs will be
   emitted in LOOP.   

References gimple_bb(), ip_normal_pos(), last_stmt(), and loop::latch.

Referenced by stmt_after_increment().

bool stmt_invariant_in_loop_p ( )
Returns true if statement STMT is obviously invariant in LOOP,
   i.e. if all its operands on the RHS are defined outside of the LOOP.
   LOOP should not be the function body.   

References expr_invariant_in_loop_p(), gimple_get_lhs(), gimple_num_ops(), gimple_op(), and loop_depth().

static tree strip_offset ( )
static
Strips constant offsets from EXPR and stores them to OFFSET.   

References strip_offset_1().

Referenced by add_iv_value_candidates(), and difference_cost().

static tree strip_offset_1 ( tree  expr,
bool  inside_addr,
bool  top_compref,
unsigned HOST_WIDE_INT offset 
)
static
Strips constant offsets from EXPR and stores them to OFFSET.  If INSIDE_ADDR
   is true, assume we are inside an address.  If TOP_COMPREF is true, assume
   we are at the top-level of the processed address.   

References array_ref_element_size(), build_int_cst(), component_ref_field_offset(), copy_node(), cst_and_fits_in_hwi(), HOST_WIDE_INT, int_cst_value(), integer_zerop(), and type().

Referenced by strip_offset().

static tree strip_wrap_conserving_type_conversions ( )
static
static comp_cost sub_costs ( )
static
Subtracts costs COST1 and COST2.   

References comp_cost::complexity, and comp_cost::cost.

Referenced by iv_ca_set_no_cp().

void tree_ssa_iv_optimize ( void  )
static void tree_ssa_iv_optimize_finalize ( )
static
static bool try_add_cand_for ( struct ivopts_data data,
struct iv_ca ivs,
struct iv_use use,
bool  originalp 
)
static
Tries to extend the sets IVS in the best possible way in order
   to express the USE.  If ORIGINALP is true, prefer candidates from
   the original set of IVs, otherwise favor important candidates not
   based on any memory object.   

References iv_ca::bad_uses, cost_pair::cand, compare_costs(), iv_use::cost_map, get_use_iv_cost(), iv_cand::important, ivopts_data::important_candidates, infinite_cost_p(), IP_ORIGINAL, iv_ca_add_use(), iv_ca_cand_for_use(), iv_ca_cand_used_p(), iv_ca_cost(), iv_ca_delta_add(), iv_ca_delta_commit(), iv_ca_delta_free(), iv_ca_extend(), iv_ca_set_cp(), iv_ca_set_no_cp(), iv_cand(), iv_use::n_map_members, and iv_ca::upto.

Referenced by get_initial_solution().

static bool try_improve_iv_set ( )
static
static tree var_at_stmt ( )
static
Returns variable containing the value of candidate CAND at statement AT.   

References stmt_after_increment().

Referenced by get_computation_aff(), rewrite_use_address(), and rewrite_use_compare().

static struct version_info* ver_info ( )
staticread

Variable Documentation

vec<tree> decl_rtl_to_reset
static
The list of trees for that the decl_rtl field must be reset is stored
   here.   

Referenced by free_loop_data(), prepare_decl_rtl(), tree_ssa_iv_optimize_finalize(), and tree_ssa_iv_optimize_init().

struct ivopts_data* fd_ivopts_data
static
Records invariants in *EXPR_P.  Callback for walk_tree.  DATA contains
   the bitmap to that we should store it.   

Referenced by add_candidate_1(), determine_use_iv_cost_condition(), find_depends(), force_var_cost(), and split_address_cost().