GCC Middle and Back End API Reference
loop-iv.c File 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_descget_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 loopcurrent_loop
static hash_table
< biv_entry_hasher
bivs

Enumeration Type Documentation

@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.   
Enumerator:
GRD_INVALID 
GRD_INVARIANT 
GRD_MAYBE_BIV 
GRD_SINGLE_DOM 

Function Documentation

static int altered_reg_used ( )
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 bool analyzed_for_bivness_p ( )
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 bool canonicalize_iv_subregs ( struct rtx_iv iv0,
struct rtx_iv iv1,
enum rtx_code  cond,
struct niter_desc desc 
)
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 void check_iv_ref_table_size ( )
static
static void check_simple_exit ( )
static
static void clear_iv_info ( )
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 unsigned HOST_WIDEST_INT determine_max_iter ( )
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().

static void eliminate_implied_condition ( )
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 void 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 free_simple_loop_desc ( )
Releases simple loop description for LOOP.   

References ggc_free(), loop::simple_loop_desc, and simple_loop_desc().

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
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 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
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().

struct niter_desc* get_simple_loop_desc ( )
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 unsigned HOST_WIDEST_INT inverse ( )
static
Computes inverse to X modulo (1 << MOD).   

References HOST_WIDEST_INT.

Referenced by fold_binary_loc(), and iv_number_of_iterations().

static bool iv_add ( )
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  )
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 bool iv_analyze_def ( )
static
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.

static bool iv_analyze_op ( rtx  ,
rtx  ,
struct rtx_iv  
)
static
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 bool iv_constant ( )
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 enum rtx_code iv_extend_to_rtx_code ( )
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 enum iv_grd_result iv_get_reaching_def ( )
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 bool iv_mult ( )
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 bool iv_neg ( )
static
static bool iv_shift ( )
static
static bool iv_subreg ( )
static
static bool latch_dominating_def ( )
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().

rtx lowpart_subreg ( enum machine_mode  outer_mode,
rtx  expr,
enum machine_mode  inner_mode 
)
static void mark_altered ( )
static
Marks registers altered by EXPR in set ALT.   

Referenced by simplify_using_initial_values().

static void record_biv ( )
static
static void record_iv ( )
static
Records information that DEF is induction variable IV.   

References check_iv_ref_table_size().

Referenced by iv_analyze_def().

static void replace_in_expr ( )
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 int replace_single_def_regs ( )
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 void shorten_into_mode ( struct rtx_iv iv,
enum machine_mode  mode,
enum rtx_code  cond,
bool  signed_p,
struct niter_desc desc 
)
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 bool simple_reg_p ( )
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 bool simple_rhs_p ( )
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 bool suitable_set_for_replacement ( )
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().


Variable Documentation

Bivs of the current loop.   
bool clean_slate = true
static
struct loop* current_loop
static
The current loop.   
struct rtx_iv** iv_ref_table
static
Table of rtx_ivs indexed by the df_ref uid field.   
unsigned int iv_ref_table_size = 0
static