GCC Middle and Back End API Reference
ree.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cfgrtl.h"
#include "expr.h"
#include "tree-pass.h"
Include dependency graph for ree.cc:

Data Structures

struct  ext_cand
 
struct  ext_modified
 
class  ext_state
 

Enumerations

enum  ext_modified_kind { EXT_MODIFIED_NONE , EXT_MODIFIED_ZEXT , EXT_MODIFIED_SEXT }
 

Functions

static bool update_reg_equal_equiv_notes (rtx_insn *insn, machine_mode new_mode, machine_mode old_mode, enum rtx_code code)
 
static bool combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set)
 
static bool transform_ifelse (ext_cand *cand, rtx_insn *def_insn)
 
static struct df_linkget_defs (rtx_insn *insn, rtx reg, vec< rtx_insn * > *dest)
 
static struct df_linkget_uses (rtx_insn *insn, rtx reg)
 
static bool is_cond_copy_insn (rtx_insn *insn, rtx *reg1, rtx *reg2)
 
static bool make_defs_and_copies_lists (rtx_insn *extend_insn, const_rtx set_pat, ext_state *state)
 
static rtxget_sub_rtx (rtx_insn *def_insn)
 
static bool merge_def_and_ext (ext_cand *cand, rtx_insn *def_insn, ext_state *state)
 
static rtx get_extended_src_reg (rtx src)
 
static bool combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
 
static void add_removable_extension (const_rtx expr, rtx_insn *insn, vec< ext_cand > *insn_list, unsigned *def_map, bitmap init_regs)
 
static vec< ext_candfind_removable_extensions (void)
 
static void find_and_remove_re (void)
 
static unsigned int rest_of_handle_ree (void)
 
rtl_opt_passmake_pass_ree (gcc::context *ctxt)
 

Variables

static int max_insn_uid
 

Enumeration Type Documentation

◆ ext_modified_kind

Enumerator
EXT_MODIFIED_NONE 
EXT_MODIFIED_ZEXT 
EXT_MODIFIED_SEXT 

Function Documentation

◆ add_removable_extension()

static void add_removable_extension ( const_rtx expr,
rtx_insn * insn,
vec< ext_cand > * insn_list,
unsigned * def_map,
bitmap init_regs )
static

◆ combine_reaching_defs()

static bool combine_reaching_defs ( ext_cand * cand,
const_rtx set_pat,
ext_state * state )
static
This function goes through all reaching defs of the source
of the candidate for elimination (CAND) and tries to combine
the extension with the definition instruction.  The changes
are made as a group so that even if one definition cannot be
merged, all reaching definitions end up not being merged.
When a conditional copy is encountered, merging is attempted
transitively on its definitions.  It returns true upon success
and false upon failure.   

References apply_change_group(), BITS_PER_WORD, BLOCK_FOR_INSN(), cancel_changes(), constrain_operands(), DEBUG_INSN_P, defs, DF_INSN_LUID, DF_REF_INSN, DF_REF_LOC, ext_modified::do_not_reextend, dump_file, emit_move_insn(), end_sequence(), EXT_MODIFIED_NONE, EXT_MODIFIED_SEXT, EXT_MODIFIED_ZEXT, extract_insn(), FOR_EACH_VEC_ELT, gcc_assert, gen_rtx_REG(), get_defs(), get_extended_src_reg(), get_insns(), GET_MODE, GET_MODE_PRECISION(), GET_MODE_UNIT_SIZE, get_preferred_alternatives(), get_sub_rtx(), get_uses(), ggc_alloc(), hard_regno_nregs(), i, cand::insn, INSN_UID(), ext_modified::kind, known_lt, make_defs_and_copies_lists(), merge_def_and_ext(), insn_def::next, use::next, NEXT_INSN(), NULL, NULL_RTX, paradoxical_subreg_p(), print_rtl_single(), recog_memoized(), REG_NREGS, reg_overlap_mentioned_p(), REG_P, reg_set_between_p(), reg_used_between_p(), REGNO, SET_DEST, SET_SRC, single_set(), start_sequence(), targetm, transform_ifelse(), and WORD_REGISTER_OPERATIONS.

Referenced by find_and_remove_re().

◆ combine_set_extension()

static bool combine_set_extension ( ext_cand * cand,
rtx_insn * curr_insn,
rtx * orig_set )
static
Given a insn (CURR_INSN), an extension candidate for removal (CAND)
and a pointer to the SET rtx (ORIG_SET) that needs to be modified,
this code modifies the SET rtx to a new SET rtx that extends the
right hand expression into a register on the left hand side.  Note
that multiple assumptions are made about the nature of the set that
needs to be true for this to work and is called from merge_def_and_ext.

Original :
(set (reg a) (expression))

Transform :
(set (reg a) (any_extend (expression)))

Special Cases :
If the expression is a constant or another extension, then directly
assign it to the register.   

References curr_insn, dump_file, gen_int_mode(), gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_MASK, ggc_alloc(), HWI_COMPUTABLE_MODE_P(), cand::insn, INTVAL, print_rtl_single(), REGNO, SET_DEST, SET_SRC, simplify_rtx(), single_set(), update_reg_equal_equiv_notes(), validate_change(), and XEXP.

Referenced by merge_def_and_ext().

◆ find_and_remove_re()

◆ find_removable_extensions()

static vec< ext_cand > find_removable_extensions ( void )
static

◆ get_defs()

static struct df_link * get_defs ( rtx_insn * insn,
rtx reg,
vec< rtx_insn * > * dest )
static
Get all the reaching definitions of an instruction.  The definitions are
desired for REG used in INSN.  Return the definition list or NULL if a
definition is missing.  If DEST is non-NULL, additionally push the INSN
of the definitions onto DEST.   

References DF_REF_CHAIN, DF_REF_INSN, DF_REF_INSN_INFO, DF_REF_REG, FOR_EACH_INSN_USE, gcc_assert, GET_CODE, ggc_alloc(), global_regs, NULL, REGNO, and set_of().

Referenced by add_removable_extension(), combine_reaching_defs(), and make_defs_and_copies_lists().

◆ get_extended_src_reg()

static rtx get_extended_src_reg ( rtx src)
inlinestatic
Given SRC, which should be one or more extensions of a REG, strip
away the extensions and return the REG.   

References gcc_assert, GET_CODE, ggc_alloc(), REG_P, and XEXP.

Referenced by combine_reaching_defs().

◆ get_sub_rtx()

static rtx * get_sub_rtx ( rtx_insn * def_insn)
static
If DEF_INSN has single SET expression with a register
destination, possibly buried inside a PARALLEL, return
the address of the SET expression, else return NULL.
This is similar to single_set, except that single_set
allows multiple SETs when all but one is dead.   

References GET_CODE, ggc_alloc(), i, NULL, PATTERN(), REG_P, SET, SET_DEST, XVECEXP, and XVECLEN.

Referenced by combine_reaching_defs(), find_and_remove_re(), and merge_def_and_ext().

◆ get_uses()

static struct df_link * get_uses ( rtx_insn * insn,
rtx reg )
static
Get all the reaching uses of an instruction.  The uses are desired for REG
set in INSN.  Return use list or NULL if a use is missing or irregular.   

References DF_REF_CHAIN, DF_REF_CLASS, DF_REF_REG, DF_REF_REGULAR, FOR_EACH_INSN_DEF, gcc_assert, ggc_alloc(), NULL, and REGNO.

Referenced by combine_reaching_defs().

◆ is_cond_copy_insn()

static bool is_cond_copy_insn ( rtx_insn * insn,
rtx * reg1,
rtx * reg2 )
static
Return true if INSN is
  (SET (reg REGNO (def_reg)) (if_then_else (cond) (REG x1) (REG x2)))
and store x1 and x2 in REG_1 and REG_2.   

References GET_CODE, ggc_alloc(), NULL_RTX, SET, SET_DEST, SET_SRC, single_set(), and XEXP.

Referenced by make_defs_and_copies_lists().

◆ make_defs_and_copies_lists()

static bool make_defs_and_copies_lists ( rtx_insn * extend_insn,
const_rtx set_pat,
ext_state * state )
static
Reaching Definitions of the extended register could be conditional copies
or regular definitions.  This function separates the two types into two
lists, STATE->DEFS_LIST and STATE->COPIES_LIST.  This is necessary because,
if a reaching definition is a conditional copy, merging the extension with
this definition is wrong.  Conditional copies are merged by transitively
merging their definitions.  The defs_list is populated with all the reaching
definitions of the extension instruction (EXTEND_INSN) which must be merged
with an extension.  The copies_list contains all the conditional moves that
will later be extended into a wider mode conditional move if all the merges
are successful.  The function returns false upon failure, true upon
success.   

References gcc_assert, get_defs(), ggc_alloc(), INSN_UID(), is_cond_copy_insn(), max_insn_uid, SET_SRC, and XEXP.

Referenced by combine_reaching_defs().

◆ make_pass_ree()

rtl_opt_pass * make_pass_ree ( gcc::context * ctxt)

References ggc_alloc().

◆ merge_def_and_ext()

static bool merge_def_and_ext ( ext_cand * cand,
rtx_insn * def_insn,
ext_state * state )
static
Merge the DEF_INSN with an extension.  Calls combine_set_extension
on the SET pattern.   

References combine_set_extension(), EXT_MODIFIED_NONE, EXT_MODIFIED_SEXT, EXT_MODIFIED_ZEXT, GET_MODE, GET_MODE_UNIT_SIZE, get_sub_rtx(), ggc_alloc(), INSN_UID(), ext_modified::kind, NULL, SET_DEST, SET_SRC, and XEXP.

Referenced by combine_reaching_defs().

◆ rest_of_handle_ree()

static unsigned int rest_of_handle_ree ( void )
static
Find and remove redundant extensions.   

References find_and_remove_re().

◆ transform_ifelse()

static bool transform_ifelse ( ext_cand * cand,
rtx_insn * def_insn )
static
Treat if_then_else insns, where the operands of both branches
are registers, as copies.  For instance,
Original :
(set (reg:SI a) (if_then_else (cond) (reg:SI b) (reg:SI c)))
Transformed :
(set (reg:DI a) (if_then_else (cond) (reg:DI b) (reg:DI c)))
DEF_INSN is the if_then_else insn.   

References dump_file, gcc_assert, gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_UNIT_SIZE, ggc_alloc(), PATTERN(), print_rtl_single(), REGNO, SET, SET_DEST, SET_SRC, update_reg_equal_equiv_notes(), validate_change(), and XEXP.

Referenced by combine_reaching_defs().

◆ update_reg_equal_equiv_notes()

static bool update_reg_equal_equiv_notes ( rtx_insn * insn,
machine_mode new_mode,
machine_mode old_mode,
enum rtx_code code )
static
Update or remove REG_EQUAL or REG_EQUIV notes for INSN.   

References gen_int_mode(), GET_CODE, GET_MODE_MASK, ggc_alloc(), HWI_COMPUTABLE_MODE_P(), INTVAL, new_mode(), REG_NOTE_KIND, REG_NOTES, validate_change(), and XEXP.

Referenced by combine_set_extension(), and transform_ifelse().

Variable Documentation

◆ max_insn_uid