GCC Middle and Back End API Reference
|
Data Structures | |
struct | biv_entry |
struct | biv_entry_hasher |
Enumerations | |
enum | iv_grd_result { GRD_INVALID, GRD_INVARIANT, GRD_MAYBE_BIV, GRD_SINGLE_DOM } |
Functions | |
static bool | iv_analyze_op (rtx, rtx, struct rtx_iv *) |
static enum rtx_code | iv_extend_to_rtx_code () |
void | dump_iv_info (FILE *, struct rtx_iv *) |
void | dump_iv_info () |
rtx | lowpart_subreg (enum machine_mode outer_mode, rtx expr, enum machine_mode inner_mode) |
static void | check_iv_ref_table_size () |
static bool | simple_reg_p () |
static void | clear_iv_info () |
void | iv_analysis_loop_init () |
static bool | latch_dominating_def () |
static enum iv_grd_result | iv_get_reaching_def () |
static bool | iv_constant () |
static bool | iv_subreg () |
static bool | iv_extend () |
static bool | iv_neg () |
static bool | iv_add () |
static bool | iv_mult () |
static bool | iv_shift () |
static bool | get_biv_step_1 (df_ref def, rtx reg, rtx *inner_step, enum machine_mode *inner_mode, enum iv_extend_code *extend, enum machine_mode outer_mode, rtx *outer_step) |
static bool | get_biv_step (df_ref last_def, rtx reg, rtx *inner_step, enum machine_mode *inner_mode, enum iv_extend_code *extend, enum machine_mode *outer_mode, rtx *outer_step) |
static void | record_iv () |
static bool | analyzed_for_bivness_p () |
static void | record_biv () |
static bool | iv_analyze_biv () |
bool | iv_analyze_expr () |
static bool | iv_analyze_def () |
static bool | iv_analyze_op () |
bool | iv_analyze () |
bool | iv_analyze_result () |
bool | biv_p () |
rtx | get_iv_value () |
void | iv_analysis_done () |
static unsigned HOST_WIDEST_INT | inverse () |
static int | altered_reg_used () |
static void | mark_altered () |
static bool | simple_rhs_p () |
static int | replace_single_def_regs () |
static bool | suitable_set_for_replacement () |
static void | replace_in_expr () |
static bool | implies_p () |
rtx | canon_condition () |
void | simplify_using_condition () |
static void | eliminate_implied_condition () |
static void | eliminate_implied_conditions () |
static void | simplify_using_initial_values () |
static void | shorten_into_mode (struct rtx_iv *iv, enum machine_mode mode, enum rtx_code cond, bool signed_p, struct niter_desc *desc) |
static bool | canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code cond, struct niter_desc *desc) |
static unsigned HOST_WIDEST_INT | determine_max_iter () |
static void | iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, struct niter_desc *desc) |
static void | check_simple_exit () |
void | find_simple_exit () |
struct niter_desc * | get_simple_loop_desc () |
void | free_simple_loop_desc () |
Variables | |
static bool | clean_slate = true |
static unsigned int | iv_ref_table_size = 0 |
static struct rtx_iv ** | iv_ref_table |
static struct loop * | current_loop |
static hash_table < biv_entry_hasher > | bivs |
enum iv_grd_result |
@verbatim Rtl-level induction variable analysis.
Copyright (C) 2004-2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/.
This is a simple analysis of induction variables of the loop. The major use is for determining the number of iterations of a loop for loop unrolling, doloop optimization and branch prediction. The iv information is computed on demand. Induction variables are analyzed by walking the use-def chains. When a basic induction variable (biv) is found, it is cached in the bivs hash table. When register is proved to be a biv, its description is stored to DF_REF_DATA of the def reference. The analysis works always with one loop -- you must call iv_analysis_loop_init (loop) for it. All the other functions then work with this loop. When you need to work with another loop, just call iv_analysis_loop_init for it. When you no longer need iv analysis, call iv_analysis_done () to clean up the memory. The available functions are: iv_analyze (insn, reg, iv): Stores the description of the induction variable corresponding to the use of register REG in INSN to IV. Returns true if REG is an induction variable in INSN. false otherwise. If use of REG is not found in INSN, following insns are scanned (so that we may call this function on insn returned by get_condition). iv_analyze_result (insn, def, iv): Stores to IV the description of the iv corresponding to DEF, which is a register defined in INSN. iv_analyze_expr (insn, rhs, mode, iv): Stores to IV the description of iv corresponding to expression EXPR evaluated at INSN. All registers used bu EXPR must also be used in INSN.
Possible return values of iv_get_reaching_def.
|
static |
Checks whether register *REG is in set ALT. Callback for for_each_rtx.
Referenced by simplify_using_condition(), and simplify_using_initial_values().
|
static |
If DEF was already analyzed for bivness, store the description of the biv to IV and return true. Otherwise return false.
References hash_table< Descriptor, Allocator >::find_with_hash(), and biv_entry::iv.
Referenced by iv_analyze_biv().
bool biv_p | ( | ) |
Checks whether definition of register REG in INSN is a basic induction variable. IV analysis must have been initialized (via a call to iv_analysis_loop_init) for this function to produce a result.
References df_find_def(), iv_analyze_biv(), latch_dominating_def(), simple_reg_p(), and rtx_iv::step.
rtx canon_condition | ( | ) |
Canonicalizes COND so that (1) Ensure that operands are ordered according to swap_commutative_operands_p. (2) (LE x const) will be replaced with (LT x <const+1>) and similarly for GE, GEU, and LEU.
References const_val, gen_int_mode(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, rtx_iv::mode, swap_commutative_operands_p(), and swap_condition().
Referenced by may_unswitch_on(), simplify_using_condition(), and unswitch_single_loop().
|
static |
Transforms IV0 and IV1 compared by COND so that they are both compared as subregs of the same mode if possible (sometimes it is necessary to add some assumptions to DESC).
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, IV_SIGN_EXTEND, IV_UNKNOWN_EXTEND, IV_ZERO_EXTEND, rtx_iv::mode, niter_desc::mode, rtx_iv::mult, shorten_into_mode(), niter_desc::signed_p, simplify_gen_unary(), rtx_iv::step, and swap_condition().
Referenced by iv_number_of_iterations().
|
static |
References iv_ref_table_size, and memset().
Referenced by clear_iv_info(), iv_analysis_loop_init(), iv_analyze_def(), and record_iv().
|
static |
Checks whether E is a simple exit from LOOP and stores its description into DESC.
References any_condjump_p(), CDI_DOMINATORS, dominated_by_p(), edge_def::flags, get_condition(), niter_desc::in_edge, iv_number_of_iterations(), loop::latch, basic_block_def::loop_father, niter_desc::out_edge, reversed_condition(), niter_desc::simple_p, and edge_def::src.
Referenced by find_simple_exit().
|
static |
Clears the information about ivs stored in df.
References check_iv_ref_table_size(), hash_table< Descriptor, Allocator >::empty(), and free().
Referenced by iv_analysis_done(), and iv_analysis_loop_init().
|
static |
Tries to estimate the maximum number of iterations in LOOP, and return the result. This function is called from iv_number_of_iterations with a number of fields in DESC already filled in. OLD_NITER is the original expression for the number of iterations, before we tried to simplify it.
References const_true_rtx, dump_file, get_mode_bounds(), HOST_WIDEST_INT, HOST_WIDEST_INT_PRINT_DEC, niter_desc::mode, niter_desc::niter_expr, niter_desc::signed_p, simplify_gen_relational(), and simplify_using_initial_values().
Referenced by iv_number_of_iterations().
void dump_iv_info | ( | FILE * | , |
struct rtx_iv * | |||
) |
Dumps information about IV to FILE.
Referenced by iv_analyze_biv(), iv_analyze_def(), and iv_analyze_op().
void dump_iv_info | ( | ) |
|
static |
Use relationship between A and *B to eventually eliminate *B. OP is the operation we consider.
References const_true_rtx, and implies_p().
Referenced by eliminate_implied_conditions().
|
static |
Eliminates the conditions in TAIL that are implied by HEAD. OP is the operation we consider.
References eliminate_implied_condition().
Referenced by simplify_using_initial_values().
void find_simple_exit | ( | ) |
Finds a simple exit of LOOP and stores its description into DESC.
References niter_desc::assumptions, check_simple_exit(), niter_desc::const_iter, edge_def::dest, dump_file, estimated_loop_iterations_int(), flow_bb_inside_loop_p(), free(), get_loop_body(), basic_block_def::index, niter_desc::infinite, max_loop_iterations_int(), niter_desc::niter, niter_desc::niter_expr, niter_desc::noloop_assumptions, loop::num, loop::num_nodes, niter_desc::out_edge, print_rtl(), niter_desc::simple_p, and edge_def::src.
void free_simple_loop_desc | ( | ) |
Releases simple loop description for LOOP.
References ggc_free(), loop::simple_loop_desc, and simple_loop_desc().
|
static |
Gets the operation on register REG inside loop, in shape OUTER_STEP + EXTEND_{OUTER_MODE} (SUBREG_{INNER_MODE} (REG + INNER_STEP)) If the operation cannot be described in this shape, return false. LAST_DEF is the definition of REG that dominates loop latch.
References get_biv_step_1(), and IV_UNKNOWN_EXTEND.
Referenced by iv_analyze_biv().
|
static |
The recursive part of get_biv_step. Gets the value of the single value defined by DEF wrto initial value of REG inside loop, in shape described at get_biv_step.
References find_reg_equal_equiv_note(), GRD_INVALID, GRD_INVARIANT, GRD_MAYBE_BIV, iv_get_reaching_def(), IV_SIGN_EXTEND, IV_UNKNOWN_EXTEND, IV_ZERO_EXTEND, rtx_equal_p(), simple_reg_p(), simplify_gen_binary(), and subreg_lowpart_p().
Referenced by get_biv_step().
rtx get_iv_value | ( | ) |
Calculates value of IV at ITERATION-th iteration.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, iv_extend_to_rtx_code(), IV_UNKNOWN_EXTEND, lowpart_subreg(), rtx_iv::mode, rtx_iv::mult, simplify_gen_binary(), simplify_gen_unary(), and rtx_iv::step.
|
read |
Creates a simple loop description of LOOP if it was not computed already.
References niter_desc::assumptions, find_simple_exit(), niter_desc::infinite, iv_analysis_loop_init(), loop::simple_loop_desc, simple_loop_desc(), niter_desc::simple_p, and warning().
|
static |
Checks whether A implies B.
References const_true_rtx, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, rtx_iv::mode, RTX_COMM_COMPARE, RTX_COMPARE, rtx_equal_p(), simplify_gen_binary(), and simplify_replace_rtx().
Referenced by eliminate_implied_condition(), and simplify_using_condition().
|
static |
Computes inverse to X modulo (1 << MOD).
References HOST_WIDEST_INT.
Referenced by fold_binary_loc(), and iv_number_of_iterations().
|
static |
Evaluates addition or subtraction (according to OP) of IV1 to IV0.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, iv_neg(), IV_UNKNOWN_EXTEND, rtx_iv::mode, simplify_gen_binary(), simplify_gen_unary(), and rtx_iv::step.
Referenced by iv_analyze_expr().
void iv_analysis_done | ( | void | ) |
Free the data for an induction variable analysis.
References clean_slate, clear_iv_info(), df_finish_pass(), hash_table< Descriptor, Allocator >::dispose(), free(), and iv_ref_table_size.
Referenced by doloop_optimize_loops(), unroll_and_peel_loops(), and unswitch_loops().
void iv_analysis_loop_init | ( | ) |
Prepare the data for an induction variable analysis of a LOOP.
References bitmap_set_bit(), check_iv_ref_table_size(), clean_slate, clear_iv_info(), hash_table< Descriptor, Allocator >::create(), df_analyze(), df_chain_add_problem(), DF_DEFER_INSN_RESCAN, df_dump_region(), DF_EQ_NOTES, df_note_add_problem(), df_process_deferred_rescans(), DF_RD_PRUNE_DEAD_DEFS, df_remove_problem(), df_set_blocks(), df_set_flags(), DF_UD_CHAIN, dump_file, free(), get_loop_body_in_dom_order(), and loop::num_nodes.
bool iv_analyze | ( | ) |
Analyzes value VAL at INSN and stores the result to *IV.
References df_find_use(), iv_analyze_op(), and simple_reg_p().
|
static |
Determines whether DEF is a biv and if so, stores its description to *IV.
References analyzed_for_bivness_p(), rtx_iv::base, rtx_iv::delta, dump_file, dump_iv_info(), rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, get_biv_step(), iv_constant(), latch_dominating_def(), rtx_iv::mode, rtx_iv::mult, print_rtl(), record_biv(), simplify_gen_binary(), and rtx_iv::step.
Referenced by biv_p(), and iv_analyze_op().
|
static |
Analyzes iv DEF and stores the result to *IV.
References rtx_iv::base, check_iv_ref_table_size(), dump_file, dump_iv_info(), find_reg_equal_equiv_note(), iv_analyze_expr(), rtx_iv::mode, print_rtl(), print_rtl_single(), record_iv(), and rtx_iv::step.
Referenced by iv_analyze_op(), and iv_analyze_result().
bool iv_analyze_expr | ( | ) |
Analyzes expression RHS used at INSN and stores the result to *IV. The mode of the induction variable is MODE.
References rtx_iv::base, rtx_iv::extend_mode, iv_add(), iv_analyze_expr(), iv_analyze_op(), iv_extend(), iv_mult(), iv_neg(), iv_shift(), IV_SIGN_EXTEND, IV_ZERO_EXTEND, rtx_iv::mode, and rtx_iv::step.
Referenced by iv_analyze(), iv_analyze_expr(), and iv_analyze_op().
|
static |
Analyzes operand OP of INSN and stores the result to *IV.
References dump_file, dump_iv_info(), function_invariant_p(), GRD_INVALID, GRD_INVARIANT, GRD_MAYBE_BIV, iv_analyze_biv(), iv_analyze_def(), iv_analyze_op(), iv_constant(), iv_get_reaching_def(), iv_subreg(), print_rtl(), print_rtl_single(), and subreg_lowpart_p().
bool iv_analyze_result | ( | ) |
Analyzes definition of DEF in INSN and stores the result to IV.
References df_find_def(), and iv_analyze_def().
|
static |
Sets IV to invariant CST in MODE. Always returns true (just for consistency with other iv manipulation functions that may fail).
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, IV_UNKNOWN_EXTEND, rtx_iv::mode, rtx_iv::mult, and rtx_iv::step.
Referenced by iv_analyze_biv(), and iv_analyze_op().
|
static |
Evaluates application of EXTEND to MODE on IV.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, get_iv_value(), iv_extend_to_rtx_code(), IV_UNKNOWN_EXTEND, rtx_iv::mode, rtx_iv::mult, simplify_gen_unary(), and rtx_iv::step.
Referenced by iv_analyze_expr().
|
inlinestatic |
Return the RTX code corresponding to the IV extend code EXTEND.
References IV_SIGN_EXTEND, IV_UNKNOWN_EXTEND, and IV_ZERO_EXTEND.
Referenced by dump_iv_info(), get_iv_value(), and iv_extend().
|
static |
Gets definition of REG reaching its use in INSN and stores it to DEF.
References CDI_DOMINATORS, df_find_use(), DF_REF_READ_WRITE, dominated_by_p(), GRD_INVALID, GRD_INVARIANT, GRD_MAYBE_BIV, GRD_SINGLE_DOM, just_once_each_iteration_p(), and simple_reg_p().
Referenced by get_biv_step_1(), and iv_analyze_op().
|
static |
Evaluates multiplication of IV by constant CST.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, IV_UNKNOWN_EXTEND, rtx_iv::mult, simplify_gen_binary(), and rtx_iv::step.
Referenced by iv_analyze_expr().
|
static |
Evaluates negation of IV.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, IV_UNKNOWN_EXTEND, rtx_iv::mult, simplify_gen_unary(), and rtx_iv::step.
Referenced by iv_add(), and iv_analyze_expr().
|
static |
Computes number of iterations of the CONDITION in INSN in LOOP and stores the result into DESC. Very similar to determine_number_of_iterations (basically its rtl version), complicated by things like subregs.
References alloc_EXPR_LIST(), niter_desc::assumptions, rtx_iv::base, canonicalize_iv_subregs(), niter_desc::const_iter, const_true_rtx, copy_rtx(), rtx_iv::delta, determine_max_iter(), rtx_iv::extend_mode, double_int::from_uhwi(), gen_int_mode(), get_mode_bounds(), HOST_BITS_PER_WIDE_INT, HOST_WIDEST_INT, niter_desc::infinite, inv(), inverse(), iv_analyze(), lowpart_subreg(), rtx_iv::mode, niter_desc::mode, niter_desc::niter, niter_desc::niter_expr, niter_desc::noloop_assumptions, record_niter_bound(), reverse_condition(), rtx_equal_p(), niter_desc::simple_p, simplify_gen_binary(), simplify_gen_relational(), simplify_gen_unary(), simplify_using_initial_values(), rtx_iv::step, and swap_condition().
Referenced by check_simple_exit().
|
static |
Evaluates shift of IV by constant CST.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, IV_UNKNOWN_EXTEND, rtx_iv::mult, simplify_gen_binary(), and rtx_iv::step.
Referenced by iv_analyze_expr().
|
static |
Evaluates application of subreg to MODE on IV.
References rtx_iv::base, rtx_iv::delta, rtx_iv::extend, rtx_iv::extend_mode, rtx_iv::first_special, get_iv_value(), IV_UNKNOWN_EXTEND, lowpart_subreg(), rtx_iv::mode, rtx_iv::mult, simplify_gen_binary(), and rtx_iv::step.
Referenced by iv_analyze_op().
|
static |
Finds the definition of REG that dominates loop latch and stores it to DEF. Returns false if there is not a single definition dominating the latch. If REG has no definition in loop, DEF is set to NULL and true is returned.
References bitmap_bit_p(), df_d::blocks_to_analyze, df, just_once_each_iteration_p(), loop::latch, and df_rd_bb_info::out.
Referenced by biv_p(), and iv_analyze_biv().
Generates a subreg to get the least significant part of EXPR (in mode INNER_MODE) to OUTER_MODE.
References simplify_gen_subreg(), and subreg_lowpart_offset().
Referenced by cselib_lookup_1(), dead_debug_insert_temp(), doloop_optimize(), get_iv_value(), get_reload_reg(), iv_number_of_iterations(), iv_subreg(), lowpart_subreg_maybe_copy(), prepare_call_arguments(), record_jump_cond_subreg(), replace_dead_reg(), simplify_relational_operation_1(), try_apply_stack_adjustment(), try_combine(), and use_narrower_mode().
|
static |
Marks registers altered by EXPR in set ALT.
Referenced by simplify_using_initial_values().
|
static |
References hash_table< Descriptor, Allocator >::find_slot_with_hash(), biv_entry::iv, and biv_entry::regno.
Referenced by iv_analyze_biv().
|
static |
Records information that DEF is induction variable IV.
References check_iv_ref_table_size().
Referenced by iv_analyze_def().
|
static |
Using the data returned by suitable_set_for_replacement, replace DEST with SRC in *EXPR and return the new expression. Also call replace_single_def_regs if the replacement changed something.
References for_each_rtx(), replace_single_def_regs(), and simplify_replace_rtx().
Referenced by simplify_using_initial_values().
|
static |
If REG has a single definition, replace it with its known value in EXPR. Callback for for_each_rtx.
References find_reg_equal_equiv_note(), function_invariant_p(), and simplify_replace_rtx().
Referenced by replace_in_expr(), and simplify_using_initial_values().
|
static |
Transforms invariant IV into MODE. Adds assumptions based on the fact that IV occurs as left operands of comparison COND and its signedness is SIGNED_P to DESC.
References alloc_EXPR_LIST(), rtx_iv::base, rtx_iv::extend, rtx_iv::extend_mode, get_mode_bounds(), niter_desc::infinite, IV_SIGN_EXTEND, IV_ZERO_EXTEND, rtx_iv::mode, niter_desc::noloop_assumptions, and simplify_gen_relational().
Referenced by canonicalize_iv_subregs().
|
static |
Checks whether REG is a well-behaved register.
References subreg_lowpart_p().
Referenced by biv_p(), get_biv_step_1(), iv_analyze(), and iv_get_reaching_def().
|
static |
Checks whether RHS is simple enough to process.
References function_invariant_p().
Referenced by suitable_set_for_replacement().
void simplify_using_condition | ( | ) |
Tries to use the fact that COND holds to simplify EXPR. ALTERED is the set of altered regs.
References altered_reg_used(), canon_condition(), const_true_rtx, exp(), for_each_rtx(), implies_p(), reversed_condition(), rtx_equal_p(), and simplify_replace_rtx().
Referenced by simplify_using_initial_values(), and unswitch_single_loop().
|
static |
Simplifies *EXPR using initial values at the start of the LOOP. If *EXPR is a list, its elements are assumed to be combined using OP.
References alloc_EXPR_LIST(), altered_reg_used(), any_condjump_p(), const_true_rtx, eliminate_implied_conditions(), edge_def::flags, for_each_rtx(), free_EXPR_LIST_list(), free_EXPR_LIST_node(), get_condition(), loop_preheader_edge(), mark_altered(), note_stores(), reg_obstack, replace_in_expr(), replace_single_def_regs(), reversed_condition(), simplify_using_condition(), single_pred(), single_pred_edge(), single_pred_p(), edge_def::src, and suitable_set_for_replacement().
Referenced by determine_max_iter(), and iv_number_of_iterations().
|
static |
A subroutine of simplify_using_initial_values, this function examines INSN to see if it contains a suitable set that we can use to make a replacement. If it is suitable, return true and set DEST and SRC to the lhs and rhs of the set; return false otherwise.
References find_reg_equal_equiv_note(), and simple_rhs_p().
Referenced by simplify_using_initial_values().
|
static |
Bivs of the current loop.
|
static |
Referenced by iv_analysis_done(), and iv_analysis_loop_init().
|
static |
The current loop.
|
static |
Table of rtx_ivs indexed by the df_ref uid field.
|
static |
Referenced by check_iv_ref_table_size(), and iv_analysis_done().