GCC Middle and Back End API Reference
loop-invariant.c File Reference

Data Structures

struct  loop_data
struct  use
struct  def
struct  invariant
struct  invariant_expr_entry
struct  invariant_expr_hasher

Typedefs

typedef struct invariantinvariant_p
typedef hash_table
< invariant_expr_hasher
invariant_htab_type

Functions

static void check_invariant_table_size ()
static bool check_maybe_invariant ()
static struct invariantinvariant_for_use ()
static hashval_t hash_invariant_expr_1 ()
static bool invariant_expr_equal_p ()
static struct invariantfind_or_insert_inv (invariant_htab_type eq, rtx expr, enum machine_mode mode, struct invariant *inv)
static void find_identical_invariants ()
static void merge_identical_invariants ()
static void compute_always_reached (struct loop *loop, basic_block *body, bitmap may_exit, bitmap always_reached)
static void find_exits (struct loop *loop, basic_block *body, bitmap may_exit, bitmap has_exit)
static bool may_assign_reg_p ()
static void find_defs ()
static struct invariantcreate_new_invariant (struct def *def, rtx insn, bitmap depends_on, bool always_executed)
static void record_use ()
static bool check_dependency ()
static bool check_dependencies ()
static void find_invariant_insn ()
static void record_uses ()
static void find_invariants_insn ()
static void find_invariants_bb ()
static void find_invariants_body (struct loop *loop, basic_block *body, bitmap always_reached, bitmap always_executed)
static void find_invariants ()
static void free_use_list ()
static enum reg_class get_pressure_class_and_nregs ()
static void get_inv_cost ()
static int gain_for_invariant (struct invariant *inv, unsigned *regs_needed, unsigned *new_regs, unsigned regs_used, bool speed, bool call_p)
static int best_gain_for_invariant (struct invariant **best, unsigned *regs_needed, unsigned *new_regs, unsigned regs_used, bool speed, bool call_p)
static void set_move_mark ()
static void find_invariants_to_move ()
static int replace_uses ()
static bool move_invariant_reg ()
static void move_invariants ()
static void init_inv_motion_data ()
static void free_inv_motion_data ()
static void move_single_loop_invariants ()
static void free_loop_data ()
static enum reg_class get_regno_pressure_class ()
static void change_pressure ()
static void mark_regno_live ()
static void mark_regno_death ()
static void mark_reg_store (rtx reg, const_rtx setter, void *data)
static void mark_reg_clobber ()
static void mark_reg_death ()
static void mark_ref_regs ()
static void calculate_loop_reg_pressure ()
void move_loop_invariants ()

Variables

static struct loopcurr_loop
static unsigned int invariant_table_size = 0
static struct invariant ** invariant_table
static unsigned actual_stamp
static vec< invariant_pinvariants
static bitmap_head curr_regs_live
static int curr_reg_pressure [N_REG_CLASSES]
static rtx regs_set [(FIRST_PSEUDO_REGISTER > MAX_RECOG_OPERANDS?FIRST_PSEUDO_REGISTER:MAX_RECOG_OPERANDS)*2]
static int n_regs_set

Typedef Documentation

typedef struct invariant* invariant_p

Function Documentation

static int best_gain_for_invariant ( struct invariant **  best,
unsigned *  regs_needed,
unsigned *  new_regs,
unsigned  regs_used,
bool  speed,
bool  call_p 
)
static
Finds invariant with best gain for moving.  Returns the gain, stores
   the invariant in *BEST and number of registers needed for it to
   *REGS_NEEDED.  REGS_USED is the number of registers used in the loop.
   NEW_REGS is the number of new variables already added due to invariant
   motion.   

References invariant::eqto, gain_for_invariant(), inv(), invariant::invno, and invariant::move.

Referenced by find_invariants_to_move().

static void change_pressure ( )
static
Increase (if INCR_P) or decrease current register pressure for
   register REGNO.   

References curr_reg_pressure, get_regno_pressure_class(), and loop_data::max_reg_pressure.

Referenced by calculate_loop_reg_pressure(), mark_regno_death(), and mark_regno_live().

static bool check_dependencies ( )
static
Finds the invariants INSN depends on and store them to the DEPENDS_ON
   bitmap.  Returns true if all dependencies of INSN are known to be
   loop invariants, false otherwise.   

References check_dependency().

Referenced by find_invariant_insn().

static bool check_dependency ( )
static
Finds the invariants USE depends on and store them to the DEPENDS_ON
   bitmap.  Returns true if all dependencies of USE are known to be
   loop invariants, false otherwise.   

References bitmap_set_bit(), CDI_DOMINATORS, check_invariant_table_size(), invariant::def, defs, DF_HARD_REG_LIVE, DF_REF_READ_WRITE, dominated_by_p(), inv(), def::invno, df_link::next, df_link::ref, and targetm.

Referenced by check_dependencies().

static void check_invariant_table_size ( )
static
Check the size of the invariant table and realloc if necessary.   

References invariant_table_size, and memset().

Referenced by check_dependency(), find_defs(), find_invariant_insn(), free_inv_motion_data(), and invariant_for_use().

static bool check_maybe_invariant ( )
static
Test for possibility of invariantness of X.   

Referenced by find_invariant_insn(), and move_invariant_reg().

static void compute_always_reached ( struct loop loop,
basic_block body,
bitmap  may_exit,
bitmap  always_reached 
)
static
Determines the basic blocks inside LOOP that are always executed and
   stores their bitmap to ALWAYS_REACHED.  MAY_EXIT is a bitmap of
   basic blocks that may either exit the loop, or contain the call that
   does not have to return.  BODY is body of the loop obtained by
   get_loop_body_in_dom_order.   

References bitmap_bit_p(), bitmap_set_bit(), CDI_DOMINATORS, dominated_by_p(), loop::latch, and loop::num_nodes.

Referenced by find_invariants().

static struct invariant* create_new_invariant ( struct def def,
rtx  insn,
bitmap  depends_on,
bool  always_executed 
)
staticread
Creates a new invariant for definition DEF in INSN, depending on invariants
   in DEPENDS_ON.  ALWAYS_EXECUTED is true if the insn is always executed,
   unless the program ends due to a function call.  The newly created invariant
   is returned.   

References address_cost(), invariant::always_executed, invariant::cheap_address, invariant::cost, invariant::def, invariant::depends_on, dump_bitmap(), dump_file, invariant::eqto, invariant::insn, inv(), def::invno, invariant::invno, invariant::move, optimize_bb_for_speed_p(), invariant::orig_regno, invariant::reg, set_rtx_cost(), set_src_cost(), invariant::stamp, and word_mode.

Referenced by find_invariant_insn().

static void find_defs ( )
static
static void find_exits ( struct loop loop,
basic_block body,
bitmap  may_exit,
bitmap  has_exit 
)
static
Finds exits out of the LOOP with body BODY.  Marks blocks in that we may
   exit the loop by cfg edge to HAS_EXIT and MAY_EXIT.  In MAY_EXIT
   additionally mark blocks that may exit due to a call.   

References loop::aux, bitmap_set_bit(), edge_def::dest, find_common_loop(), flow_bb_inside_loop_p(), flow_loop_nested_p(), basic_block_def::loop_father, loop::num_nodes, and reg_obstack.

Referenced by find_invariants().

static void find_identical_invariants ( )
static
Finds invariants identical to INV and records the equivalence.  EQ is the
   hash table of the invariants.   

References invariant::depends_on, dump_file, invariant::eqto, find_or_insert_inv(), invariant::insn, and invariant::invno.

Referenced by merge_identical_invariants().

static void find_invariant_insn ( )
static
Finds invariant in INSN.  ALWAYS_REACHED is true if the insn is always
   executed.  ALWAYS_EXECUTED is true if the insn is always executed,
   unless the program ends due to a function call.   

References can_throw_internal(), check_dependencies(), check_invariant_table_size(), check_maybe_invariant(), create_new_invariant(), df_find_def(), inv(), may_assign_reg_p(), may_trap_or_fault_p(), and sets_cc0_p().

Referenced by find_invariants_insn().

static void find_invariants_bb ( )
static
Finds invariants in basic block BB.  ALWAYS_REACHED is true if the
   basic block is always executed.  ALWAYS_EXECUTED is true if the basic
   block is always executed, unless the program ends due to a function
   call.   

References find_invariants_insn(), and invariant::insn.

Referenced by find_invariants_body().

static void find_invariants_body ( struct loop loop,
basic_block body,
bitmap  always_reached,
bitmap  always_executed 
)
static
Finds invariants in LOOP with body BODY.  ALWAYS_REACHED is the bitmap of
   basic blocks in BODY that are always executed.  ALWAYS_EXECUTED is the
   bitmap of basic blocks in BODY that are always executed unless the program
   ends due to a function call.   

References bitmap_bit_p(), find_invariants_bb(), and loop::num_nodes.

Referenced by find_invariants().

static void find_invariants_insn ( )
static
Finds invariants in INSN.  ALWAYS_REACHED is true if the insn is always
   executed.  ALWAYS_EXECUTED is true if the insn is always executed,
   unless the program ends due to a function call.   

References find_invariant_insn(), and record_uses().

Referenced by find_invariants_bb().

static void find_invariants_to_move ( )
static
Determines which invariants to move.   

References best_gain_for_invariant(), df, inv(), invariant::invno, and set_move_mark().

Referenced by move_single_loop_invariants().

static struct invariant* find_or_insert_inv ( invariant_htab_type  eq,
rtx  expr,
enum machine_mode  mode,
struct invariant inv 
)
staticread
Checks whether invariant with value EXPR in machine mode MODE is
   recorded in EQ.  If this is the case, return the invariant.  Otherwise
   insert INV to the table for this expression and return INV.   

References invariant_expr_entry::expr, hash_table< Descriptor, Allocator >::find_slot_with_hash(), invariant_expr_entry::hash, hash_invariant_expr_1(), invariant::insn, inv(), invariant_expr_entry::inv, and invariant_expr_entry::mode.

Referenced by find_identical_invariants().

static void free_inv_motion_data ( )
static
Frees the data allocated by invariant motion.   

References check_invariant_table_size(), invariant::def, invariant::depends_on, free(), free_use_list(), inv(), and def::uses.

Referenced by move_single_loop_invariants().

static void free_loop_data ( )
static
Releases the auxiliary data for LOOP.   

References loop::aux, bitmap_clear(), free(), loop_data::regs_live, and loop_data::regs_ref.

Referenced by move_loop_invariants().

static void free_use_list ( )
static
Frees a list of uses USE.   

References free(), and use::next.

Referenced by free_inv_motion_data().

static int gain_for_invariant ( struct invariant inv,
unsigned *  regs_needed,
unsigned *  new_regs,
unsigned  regs_used,
bool  speed,
bool  call_p 
)
static
Calculates gain for eliminating invariant INV.  REGS_USED is the number
   of registers used in the loop, NEW_REGS is the number of new variables
   already added due to the invariant motion.  The number of registers needed
   for it is stored in *REGS_NEEDED.  SPEED and CALL_P are flags passed
   through to estimate_reg_pressure_cost.  

References actual_stamp, estimate_reg_pressure_cost(), and get_inv_cost().

Referenced by best_gain_for_invariant().

static void get_inv_cost ( )
static
static enum reg_class get_pressure_class_and_nregs ( )
static
Return pressure class and number of hard registers (through *NREGS)
   for destination of INSN.  

References reg_allocno_class().

Referenced by get_inv_cost().

static enum reg_class get_regno_pressure_class ( )
static
Return pressure class and number of needed hard registers (through
   *NREGS) of register REGNO.   

References eliminable_regset, and reg_allocno_class().

Referenced by calculate_loop_reg_pressure(), and change_pressure().

static hashval_t hash_invariant_expr_1 ( )
static
Computes hash value for invariant expression X in INSN.   

References df_find_use(), invariant::eqto, hash_rtx(), inv(), and invariant_for_use().

Referenced by find_or_insert_inv().

static void init_inv_motion_data ( )
static
Initializes invariant motion data.   

References actual_stamp.

Referenced by move_single_loop_invariants().

static bool invariant_expr_equal_p ( )
static
Returns true if the invariant expressions E1 and E2 used in insns INSN1
   and INSN2 have always the same value.   

References df_find_use(), invariant::eqto, invariant_for_use(), and rtx_equal_p().

Referenced by invariant_expr_hasher::equal().

static struct invariant* invariant_for_use ( )
staticread
Returns the invariant definition for USE, or NULL if USE is not
   invariant.   

References CDI_DOMINATORS, check_invariant_table_size(), defs, DF_REF_READ_WRITE, dominated_by_p(), df_link::next, and df_link::ref.

Referenced by hash_invariant_expr_1(), invariant_expr_equal_p(), and record_uses().

static void mark_ref_regs ( )
static
Mark occurrence of registers in X for the current loop.   

References bitmap_set_bit(), and loop_outer().

Referenced by calculate_loop_reg_pressure().

static void mark_reg_clobber ( )
static
Mark clobbering register REG.   

References mark_reg_store().

Referenced by calculate_loop_reg_pressure().

static void mark_reg_death ( )
static
Mark register REG death.   

References last, and mark_regno_death().

Referenced by calculate_loop_reg_pressure().

static void mark_reg_store ( rtx  reg,
const_rtx  setter,
void *  data 
)
static
Mark setting register REG.   

References last, mark_regno_live(), n_regs_set, and regs_set.

Referenced by calculate_loop_reg_pressure(), and mark_reg_clobber().

static void mark_regno_death ( )
static
Mark REGNO death.   

References bitmap_clear_bit(), and change_pressure().

Referenced by mark_reg_death().

static void mark_regno_live ( )
static
Mark REGNO birth.   

References bitmap_set_bit(), change_pressure(), and loop_outer().

Referenced by mark_reg_store().

static bool may_assign_reg_p ( )
static
Check whether we may assign a value to X from a register.   

References can_copy_p().

Referenced by find_invariant_insn().

static void merge_identical_invariants ( )
static
Find invariants with the same value and record the equivalences.   

References hash_table< Descriptor, Allocator >::create(), hash_table< Descriptor, Allocator >::dispose(), find_identical_invariants(), and inv().

Referenced by find_invariants().

static void move_invariants ( )
static
Move selected invariant out of the LOOP.  Newly created regs are marked
   in TEMPORARY_REGS.   

References inv(), move_invariant_reg(), invariant::orig_regno, invariant::reg, reg_allocno_class(), reg_alternate_class(), reg_preferred_class(), resize_reg_info(), and setup_reg_classes().

Referenced by move_single_loop_invariants().

static void move_single_loop_invariants ( )
static
static void record_use ( )
static
static void record_uses ( )
static
Record registers used in INSN that have a unique invariant definition.   

References invariant::def, inv(), invariant_for_use(), and record_use().

Referenced by find_invariants_insn().

static int replace_uses ( )
static
Replace the uses, reached by the definition of invariant INV, by REG.

   IN_GROUP is nonzero if this is part of a group of changes that must be
   performed as a group.  In that case, the changes will be stored.  The
   function `apply_change_group' will validate and apply the changes.   

References apply_change_group(), invariant::def, use::insn, use::next, use::pos, def::uses, and validate_change().

Referenced by move_invariant_reg().

static void set_move_mark ( )
static
Marks invariant INVNO and all its dependencies for moving.   

References invariant::depends_on, dump_file, invariant::eqto, inv(), invariant::invno, and invariant::move.

Referenced by find_invariants_to_move().


Variable Documentation

unsigned actual_stamp
static
The actual stamp for marking already visited invariants during determining
   costs of movements.   

Referenced by gain_for_invariant(), get_inv_cost(), and init_inv_motion_data().

struct loop* curr_loop
static
Currently processed loop.   
int curr_reg_pressure[N_REG_CLASSES]
static
Current reg pressure for each pressure class.   

Referenced by calculate_loop_reg_pressure(), and change_pressure().

bitmap_head curr_regs_live
static
Registers currently living.   

Referenced by calculate_bb_reg_pressure().

struct invariant** invariant_table
static
unsigned int invariant_table_size = 0
static
Table of invariants indexed by the df_ref uid field.   

Referenced by check_invariant_table_size(), and move_loop_invariants().

vec<invariant_p> invariants
static
The invariants.   
int n_regs_set
static
Number of regs stored in the previous array.   

Referenced by calculate_loop_reg_pressure(), and mark_reg_store().

rtx regs_set[(FIRST_PSEUDO_REGISTER > MAX_RECOG_OPERANDS?FIRST_PSEUDO_REGISTER:MAX_RECOG_OPERANDS)*2]
static
Record all regs that are set in any one insn.  Communication from
   mark_reg_{store,clobber} and global_conflicts.  Asm can refer to
   all hard-registers.   

Referenced by calculate_loop_reg_pressure(), look_for_hardregs(), mark_reg_store(), and replace_read().