GCC Middle and Back End API Reference
lra-constraints.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "hooks.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "expmed.h"
#include "optabs.h"
#include "regs.h"
#include "ira.h"
#include "recog.h"
#include "output.h"
#include "addresses.h"
#include "expr.h"
#include "cfgrtl.h"
#include "rtl-error.h"
#include "lra.h"
#include "lra-int.h"
#include "print-rtl.h"
#include "function-abi.h"
#include "rtl-iter.h"
Include dependency graph for lra-constraints.cc:

Data Structures

struct  input_reload
class  lra_autoinc_reload_context
struct  lra_invariant
struct  usage_insns
struct  to_inherit


#define EBB_PROBABILITY_CUTOFF    ((REG_BR_PROB_BASE * param_lra_inheritance_ebb_probability_cutoff) / 100)


typedef lra_invariant invariant_t
typedef invariant_tinvariant_ptr_t
typedef const invariant_tconst_invariant_ptr_t


static rtxstrip_subreg (rtx *loc)
static int get_try_hard_regno (int regno)
static int get_hard_regno (rtx x)
static enum reg_class get_reg_class (int regno)
static bool enough_allocatable_hard_regs_p (enum reg_class reg_class, enum machine_mode reg_mode)
static bool in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, bool allow_all_reload_class_changes_p=false)
static bool in_mem_p (int regno)
static bool valid_address_p (machine_mode mode, rtx addr, addr_space_t as)
static bool valid_address_p (rtx op, struct address_info *ad, enum constraint_num constraint)
rtx extract_mem_from_operand (rtx op)
static bool satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
static bool satisfies_address_constraint_p (struct address_info *ad, enum constraint_num constraint)
static bool satisfies_address_constraint_p (rtx op, enum constraint_num constraint)
void lra_init_equiv (void)
static rtx loc_equivalence_callback (rtx, const_rtx, void *)
static void update_equiv (int regno)
static rtx get_equiv (rtx x)
static rtx get_equiv_with_elimination (rtx x, rtx_insn *insn)
static void init_curr_operand_mode (void)
static void init_curr_insn_input_reloads (void)
static rtx canonicalize_reload_addr (rtx addr)
static bool get_reload_reg (enum op_type type, machine_mode mode, rtx original, enum reg_class rclass, HARD_REG_SET *exclude_start_hard_regs, bool in_subreg_p, const char *title, rtx *result_reg)
int lra_constraint_offset (int regno, machine_mode mode)
static bool operands_match_p (rtx x, rtx y, int y_hard_regno)
static void narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
static rtx regno_val_use_in (unsigned int regno, rtx x)
static bool check_conflict_input_operands (int regno, signed char *ins)
static void match_reload (signed char out, signed char *ins, signed char *outs, enum reg_class goal_class, HARD_REG_SET *exclude_start_hard_regs, rtx_insn **before, rtx_insn **after, bool early_clobber_p)
static enum reg_class reg_class_from_constraints (const char *p)
static enum reg_class get_op_class (rtx op)
static rtx_insnemit_spill_move (bool to_p, rtx mem_pseudo, rtx val)
static bool check_and_process_move (bool *change_p, bool *sec_mem_p)
static bool process_addr_reg (rtx *loc, bool check_only_p, rtx_insn **before, rtx_insn **after, enum reg_class cl)
static void insert_move_for_subreg (rtx_insn **before, rtx_insn **after, rtx origreg, rtx newreg)
static bool process_address (int, bool, rtx_insn **, rtx_insn **)
static bool simplify_operand_subreg (int nop, machine_mode reg_mode)
static bool uses_hard_regs_p (rtx x, HARD_REG_SET set)
static bool spilled_pseudo_p (rtx op)
static bool general_constant_p (rtx x)
static bool reg_in_class_p (rtx reg, enum reg_class cl)
static bool prohibited_class_reg_set_mode_p (enum reg_class rclass, HARD_REG_SET &set, machine_mode mode)
static bool update_and_check_small_class_inputs (int nop, int nalt, enum reg_class op_class)
static void print_curr_insn_alt (int alt_number)
static bool process_alt_operands (int only_alternative)
static rtx base_to_reg (struct address_info *ad)
static rtx base_plus_disp_to_reg (struct address_info *ad, rtx disp)
static rtx index_part_to_reg (struct address_info *ad, enum reg_class index_class)
static bool can_add_disp_p (struct address_info *ad)
static bool equiv_address_substitution (struct address_info *ad)
static const charskip_constraint_modifiers (const char *str)
static bool constraint_unique (const char *cstr)
static bool process_address_1 (int nop, bool check_only_p, rtx_insn **before, rtx_insn **after)
static rtx emit_inc (enum reg_class new_rclass, rtx value, poly_int64 inc_amount)
static bool simple_move_p (void)
static void swap_operands (int nop)
static bool curr_insn_transform (bool check_only_p)
bool lra_constrain_insn (rtx_insn *insn)
static bool in_list_p (rtx x, rtx list)
static bool contains_reg_p (rtx x, bool hard_reg_p, bool spilled_p)
static bool loc_equivalence_change_p (rtx *loc)
static bool multi_block_pseudo_p (int regno)
static bool contains_deleted_insn_p (rtx_insn_list *list)
static bool dead_pseudo_p (rtx x, rtx_insn *insn)
static bool insn_rhs_dead_pseudo_p (rtx_insn *insn)
static bool init_insn_rhs_dead_pseudo_p (int regno)
static bool reverse_equiv_p (int regno)
static bool contains_reloaded_insn_p (int regno)
static bool combine_reload_insn (rtx_insn *from, rtx_insn *to)
bool lra_constraints (bool first_p)
static void initiate_invariants (void)
static void finish_invariants (void)
void lra_constraints_init (void)
void lra_constraints_finish (void)
static hashval_t invariant_hash (const void *invariant)
static int invariant_eq_p (const void *invariant1, const void *invariant2)
static invariant_ptr_t insert_invariant (rtx invariant_rtx)
static void clear_invariants (void)
static void setup_next_usage_insn (int regno, rtx insn, int reloads_num, bool after_p)
static void add_next_usage_insn (int regno, rtx_insn *insn, int reloads_num)
static rtx_insnskip_usage_debug_insns (rtx usage_insns)
static bool check_secondary_memory_needed_p (enum reg_class inher_cl, rtx usage_insns)
static bool inherit_reload_reg (bool def_p, int original_regno, enum reg_class cl, rtx_insn *insn, rtx next_usage_insns)
static bool need_for_call_save_p (int regno)
static bool need_for_split_p (HARD_REG_SET potential_reload_hard_regs, int regno)
static enum reg_class choose_split_class (enum reg_class allocno_class, int hard_regno, machine_mode mode)
static void lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno, bool call_save_p)
static bool split_reg (bool before_p, int original_regno, rtx_insn *insn, rtx next_usage_insns, rtx_insn *to)
bool spill_hard_reg_in_range (int regno, enum reg_class rclass, rtx_insn *from, rtx_insn *to)
static bool split_if_necessary (int regno, machine_mode mode, HARD_REG_SET potential_reload_hard_regs, bool before_p, rtx_insn *insn, int max_uid)
static bool invariant_p (const_rtx x)
static bool process_invariant_for_inheritance (rtx dst_reg, rtx invariant_rtx)
static void update_ebb_live_info (rtx_insn *head, rtx_insn *tail)
static void add_to_inherit (int regno, rtx insns)
static rtx_insnget_last_insertion_point (basic_block bb)
static void get_live_on_other_edges (basic_block from, basic_block to, bitmap res)
static bool inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
void lra_inheritance (void)
static void fix_bb_live_info (bitmap live, bitmap removed_pseudos)
static int get_regno (rtx reg)
static void delete_move_and_clobber (rtx_insn *insn, int dregno)
static bool remove_inheritance_pseudos (bitmap remove_pseudos)
static bool undo_optional_reloads (void)
bool lra_undo_inheritance (void)


static int bb_reload_num
static rtx_insncurr_insn
static rtx curr_insn_set
static basic_block curr_bb
static lra_insn_recog_data_t curr_id
static struct lra_static_insn_datacurr_static_id
static machine_mode curr_operand_mode [MAX_RECOG_OPERANDS]
static machine_mode original_subreg_reg_mode [MAX_RECOG_OPERANDS]
static int new_regno_start
static int new_insn_uid_start
static int curr_insn_input_reloads_num
static struct input_reload curr_insn_input_reloads [LRA_MAX_INSN_RELOADS]
static enum reg_class goal_alt [MAX_RECOG_OPERANDS]
static HARD_REG_SET goal_alt_exclude_start_hard_regs [MAX_RECOG_OPERANDS]
static bool goal_alt_match_win [MAX_RECOG_OPERANDS]
static bool goal_alt_win [MAX_RECOG_OPERANDS]
static bool goal_alt_offmemok [MAX_RECOG_OPERANDS]
static int goal_alt_matches [MAX_RECOG_OPERANDS]
static int goal_alt_dont_inherit_ops_num
static int goal_alt_dont_inherit_ops [MAX_RECOG_OPERANDS]
static bool goal_reuse_alt_p
static bool goal_alt_swapped
static int goal_alt_number
static bool goal_alt_out_sp_reload_p
static bool equiv_substition_p [MAX_RECOG_OPERANDS]
static int best_losers
static int best_overall
static int best_reload_nregs
static int best_reload_sum
static bool no_input_reloads_p
static bool no_output_reloads_p
static int curr_swapped
static unsigned int curr_small_class_check = 0
int lra_constraint_iter
bool check_and_force_assignment_correctness_p
static vec< invariant_ptr_tinvariants
static object_allocator< lra_invariant > * invariants_pool
static htab_t invariant_table
static int reloads_num
static int calls_num
static int last_call_for_abi [NUM_ABI_IDS]
static HARD_REG_SET full_and_partial_call_clobbers
static int curr_usage_insns_check
static struct usage_insns * usage_insns
static bitmap_head check_only_regs
static bitmap_head invalid_invariant_regs
static bitmap_head ebb_global_regs
static bitmap_head live_regs
static struct to_inherit to_inherit [LRA_MAX_INSN_RELOADS]
static int to_inherit_num
static bitmap_head temp_bitmap
static const int max_small_class_regs_num = 2
int lra_inheritance_iter
int lra_undo_inheritance_iter

Macro Definition Documentation


X )
((MODE) != VOIDmode \
&& GET_CODE (X) != HIGH \
&& GET_MODE_SIZE (MODE).is_constant () \
&& !targetm.cannot_force_const_mem (MODE, X))
bool is_constant() const
Definition poly-int.h:553
Definition ggc.h:184
ALWAYS_INLINE poly_uint16 GET_MODE_SIZE(machine_mode mode)
Definition machmode.h:647
#define CONSTANT_P(X)
Definition rtl.h:1066
#define GET_CODE(RTX)
Definition rtl.h:725
struct gcc_target targetm
True if X is a constant that can be forced into the constant pool.
MODE is the mode of the operand, or VOIDmode if not known.   

Referenced by curr_insn_transform(), lra_constraints(), process_alt_operands(), and simplify_operand_subreg().


#define EBB_PROBABILITY_CUTOFF    ((REG_BR_PROB_BASE * param_lra_inheritance_ebb_probability_cutoff) / 100)
This value affects EBB forming.  If probability of edge from EBB to
a BB is not greater than the following value, we don't add the BB
to EBB.   

Referenced by lra_inheritance().


Maximum number of generated reload insns per an insn.  It is for
preventing this pass cycling in a bug case.      

Referenced by lra_constraints().


|| (ira_class_hard_regs_num [(C)] >= 1 \
&& targetm.class_likely_spilled_p (C)))
#define ira_class_hard_regs_num
Definition ira.h:158
True if C is a non-empty register class that has too few registers
to be safely used as a reload target class.      

Referenced by in_class_p(), process_alt_operands(), and update_and_check_small_class_inputs().

Typedef Documentation

◆ const_invariant_ptr_t

◆ invariant_ptr_t

◆ invariant_t

Function Documentation

◆ add_next_usage_insn()

static void add_next_usage_insn ( int regno,
rtx_insn * insn,
int reloads_num )
The function is used to form list REGNO usages which consists of
optional debug insns finished by a non-debug insn using REGNO.
RELOADS_NUM is current number of reload insns processed so far.   

References usage_insns::check, curr_usage_insns_check, DEBUG_INSN_P, gen_rtx_INSN_LIST(), GET_CODE, ggc_alloc(), insns, usage_insns::insns, NONDEBUG_INSN_P, NULL_RTX, reloads_num, setup_next_usage_insn(), and XEXP.

Referenced by inherit_in_ebb().

◆ add_to_inherit()

static void add_to_inherit ( int regno,
rtx insns )
Add inheritance info REGNO and INSNS. Their meaning is described in
structure to_inherit.   

References i, insns, to_inherit::insns, lra_assert, LRA_MAX_INSN_RELOADS, to_inherit::regno, and to_inherit_num.

Referenced by inherit_in_ebb().

◆ base_plus_disp_to_reg()

static rtx base_plus_disp_to_reg ( struct address_info * ad,
rtx disp )
Make reload base reg + DISP from address AD.  Return the new pseudo.   

References base_reg_class(), get_index_code(), GET_MODE, ggc_alloc(), lra_assert, lra_create_new_reg(), lra_emit_add(), NULL, and NULL_RTX.

Referenced by process_address_1().

◆ base_to_reg()

◆ can_add_disp_p()

static bool can_add_disp_p ( struct address_info * ad)
Return true if we can add a displacement to address AD, even if that
makes the address invalid.  The fix-up code requires any new address
to be the sum of the BASE_TERM, INDEX and DISP_TERM fields.   

References ggc_alloc(), and NULL.

Referenced by equiv_address_substitution().

◆ canonicalize_reload_addr()

static rtx canonicalize_reload_addr ( rtx addr)
The canonical form of an rtx inside a MEM is not necessarily the same as the
canonical form of the rtx outside the MEM.  Fix this up in the case that
we're reloading an address (and therefore pulling it outside a MEM).   

References CONST_INT_P, exact_log2(), FOR_EACH_SUBRTX_VAR, GEN_INT, GET_CODE, ggc_alloc(), INTVAL, PUT_CODE, and XEXP.

Referenced by curr_insn_transform().

◆ check_and_process_move()

static bool check_and_process_move ( bool * change_p,
bool * sec_mem_p )
Process a special case insn (register move), return true if we
don't need to process it anymore.  INSN should be a single set
insn.  Set up that RTL was changed through CHANGE_P and that hook
TARGET_SECONDARY_MEMORY_NEEDED says to use secondary memory through

References insn_operand_data::constraint, curr_insn, curr_insn_set, dump_insn_slim(), emit_insn(), end_sequence(), gcc_assert, GET_CODE, get_insns(), GET_MODE, get_reg_class(), ggc_alloc(), insn_data, INSN_UID(), ira_class_hard_regs, lra_assert, lra_create_new_reg_with_unique_value(), lra_dump_file, lra_emit_move(), lra_get_regno_hard_regno(), lra_process_new_insns(), lra_set_insn_deleted(), MEM_P, insn_operand_data::mode, NULL, NULL_RTX, insn_data_d::operand, reg_class_from_constraints(), REG_P, reg_renumber, REGNO, SET_DEST, SET_SRC, start_sequence(), SUBREG_REG, and targetm.

Referenced by curr_insn_transform().

◆ check_conflict_input_operands()

static bool check_conflict_input_operands ( int regno,
signed char * ins )
Return true if all current insn non-output operands except INS (it
has a negaitve end marker) do not use pseudos with the same value
as REGNO.   

References curr_id, curr_static_id, ggc_alloc(), i, lra_operand_data::is_operator, n_operands, lra_static_insn_data::n_operands, NULL_RTX, OP_OUT, lra_static_insn_data::operand, regno_val_use_in(), and lra_operand_data::type.

Referenced by match_reload().

◆ check_secondary_memory_needed_p()

static bool check_secondary_memory_needed_p ( enum reg_class inher_cl,
rtx usage_insns )
Return true if we need secondary memory moves for insn in
USAGE_INSNS after inserting inherited pseudo of class INHER_CL
into the insn.   

References GET_MODE, get_reg_class(), ggc_alloc(), INSN_P, lra_assert, NULL_RTX, REG_P, REGNO, SET_DEST, single_set(), skip_usage_debug_insns(), and targetm.

Referenced by inherit_reload_reg().

◆ choose_split_class()

static enum reg_class choose_split_class ( enum reg_class allocno_class,
int hard_regno,
machine_mode mode )
Return class for the split pseudo created from original pseudo with
ALLOCNO_CLASS and MODE which got a hard register HARD_REGNO.     We
choose subclass of ALLOCNO_CLASS which contains HARD_REGNO and
results in no secondary memory movements.   

References ggc_alloc(), i, ira_class_hard_regs_num, reg_class_contents, reg_class_subclasses, targetm, and TEST_HARD_REG_BIT.

Referenced by split_reg().

◆ clear_invariants()

static void clear_invariants ( void )
Make the invariant table empty.   

References ggc_alloc(), invariant_table, invariants, and invariants_pool.

Referenced by inherit_in_ebb().

◆ combine_reload_insn()

◆ constraint_unique()

static bool constraint_unique ( const char * cstr)
Takes a string of 0 or more comma-separated constraints.  When more
than one constraint is present, evaluate whether they all correspond
to a single, repeated constraint (e.g. "r,r") or whether we have
more than one distinct constraints (e.g. "r,m").   

References ggc_alloc(), and skip_constraint_modifiers().

Referenced by process_address_1().

◆ contains_deleted_insn_p()

static bool contains_deleted_insn_p ( rtx_insn_list * list)
Return true if LIST contains a deleted insn.   

References ggc_alloc(), rtx_insn_list::insn(), rtx_insn_list::next(), NOTE_KIND, NOTE_P, and NULL_RTX.

Referenced by lra_constraints().

◆ contains_reg_p()

static bool contains_reg_p ( rtx x,
bool hard_reg_p,
bool spilled_p )
Return true if X contains an allocatable hard register (if
HARD_REG_P) or a (spilled if SPILLED_P) pseudo.   

References contains_reg_p(), GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, lra_get_regno_hard_regno(), overlaps_hard_reg_set_p(), REG_P, REGNO, XEXP, XVECEXP, and XVECLEN.

Referenced by contains_reg_p(), and lra_constraints().

◆ contains_reloaded_insn_p()

static bool contains_reloaded_insn_p ( int regno)
Return TRUE if REGNO was reloaded in an equivalence init insn.  We
call this function only for non-reverse equivalence.   

References ira_reg_equiv_s::init_insns, rtx_insn_list::insn(), ira_reg_equiv, rtx_insn_list::next(), NULL, NULL_RTX, REG_P, REGNO, SET_DEST, and single_set().

Referenced by lra_constraints().

◆ curr_insn_transform()

static bool curr_insn_transform ( bool check_only_p)
Main entry point of the constraint code: search the body of the
current insn to choose the best alternative.  It is mimicking insn
alternative cost calculation model of former reload pass.  That is
because machine descriptions were written to use this model.  This
model can be changed in future.  Make commutative operand exchange
if it is chosen.

if CHECK_ONLY_P is false, do RTL changes to satisfy the
constraints.  Return true if any change happened during function

If CHECK_ONLY_P is true then don't do any transformation.  Just
check that the insn satisfies all constraints.  If the insn does
not satisfy any constraint, return true.   

References asm_noperands(), base_reg_class(), best_losers, best_overall, best_reload_sum, bitmap_set_bit, bitmap_single_bit_set_p(), CALL_P, canonicalize_reload_addr(), check_and_process_move(), lra_static_insn_data::commutative, CONST_INT_P, CONST_POOL_OK_P, operand_alternative::constraint, copy_rtx(), curr_id, curr_insn, curr_insn_set, curr_operand_mode, curr_static_id, curr_swapped, dump_value_slim(), lra_static_insn_data::dup_num, operand_alternative::earlyclobber, emit_inc(), emit_insn(), emit_move_insn(), emit_spill_move(), end_sequence(), enough_allocatable_hard_regs_p(), equiv_substition_p, error_for_asm(), fatal_insn, find_reg_note(), force_const_mem(), gcc_assert, gcc_unreachable, gen_rtx_SUBREG(), GET_CODE, get_equiv_with_elimination(), get_insn_name(), get_insns(), GET_MODE, GET_MODE_SIZE(), get_reg_class(), get_reload_reg(), GET_RTX_CLASS, get_try_hard_regno(), ggc_alloc(), goal_alt, goal_alt_dont_inherit_ops, goal_alt_dont_inherit_ops_num, goal_alt_exclude_start_hard_regs, goal_alt_match_win, goal_alt_matches, goal_alt_number, goal_alt_offmemok, goal_alt_out_sp_reload_p, goal_alt_swapped, goal_alt_win, goal_reuse_alt_p, i, in_class_p(), INSN_CODE, INSN_UID(), INT_MAX, ira_class_hard_regs, ira_former_scratch_p(), ira_nullify_asm_goto(), ira_reg_class_subset, lra_operand_data::is_operator, JUMP_P, known_le, lra_asm_error_p, lra_asm_insn_error(), lra_assert, lra_change_class(), lra_create_new_reg(), lra_dump_file, lra_emit_move(), lra_get_allocno_class(), lra_get_insn_recog_data(), lra_invalidate_insn_data(), LRA_MAX_INHERITANCE_PASSES, LRA_NON_CLOBBERED_ALT, lra_optional_reload_pseudos, lra_process_new_insns(), lra_reg_info, lra_set_insn_deleted(), lra_set_regno_unique_value(), lra_set_used_insn_alternative(), lra_simple_p, lra_undo_inheritance_iter, LRA_UNKNOWN_ALT, lra_update_dup(), lra_update_insn_regno_info(), lra_update_operator_dups(), match_reload(), max_reg_num(), MEM_ADDR_SPACE, MEM_P, n_alternatives(), lra_static_insn_data::n_alternatives, lra_static_insn_data::n_dups, n_operands, lra_static_insn_data::n_operands, new_regno_start, NEXT_INSN(), no_input_reloads_p, no_output_reloads_p, NULL, NULL_RTX, OP_IN, OP_INOUT, OP_OUT, lra_static_insn_data::operand, lra_static_insn_data::operand_alternative, operands_match_p(), original_subreg_reg_mode, paradoxical_subreg_p(), partial_subreg_p(), PATTERN(), print_curr_insn_alt(), print_dec(), process_address(), process_alt_operands(), prohibited_class_reg_set_mode_p(), PSEUDO_REGNO_MODE, push_to_sequence(), read_modify_subreg_p(), reg_class_contents, REG_P, reg_renumber, REGNO, lra_reg::restore_rtx, rld, RTX_AUTOINC, satisfies_memory_constraint_p(), SET_DEST, SET_SRC, simple_move_p(), simplify_operand_subreg(), simplify_subreg_regno(), single_set(), stack_pointer_rtx, start_sequence(), lra_operand_data::strict_low, SUBREG_BYTE, SUBREG_REG, subst(), swap_operands(), targetm, lra_operand_data::type, WORD_REGISTER_OPERATIONS, and XEXP.

Referenced by combine_reload_insn(), lra_constrain_insn(), and lra_constraints().

◆ dead_pseudo_p()

static bool dead_pseudo_p ( rtx x,
rtx_insn * insn )
Return true if X contains a pseudo dying in INSN.   

References dead_pseudo_p(), find_regno_note(), GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, NULL_RTX, REG_P, REGNO, XEXP, XVECEXP, and XVECLEN.

Referenced by dead_pseudo_p(), and insn_rhs_dead_pseudo_p().

◆ delete_move_and_clobber()

static void delete_move_and_clobber ( rtx_insn * insn,
int dregno )
Delete a move INSN with destination reg DREGNO and a previous
clobber insn with the same regno.  The inheritance/split code can
generate moves with preceding clobber and when we delete such moves
we should delete the clobber insn too to keep the correct life

References GET_CODE, get_regno(), ggc_alloc(), lra_assert, lra_set_insn_deleted(), NONDEBUG_INSN_P, NULL, PATTERN(), PREV_INSN(), and XEXP.

Referenced by remove_inheritance_pseudos(), and undo_optional_reloads().

◆ emit_inc()

static rtx emit_inc ( enum reg_class new_rclass,
rtx value,
poly_int64 inc_amount )
Emit insns to reload VALUE into a new register.  VALUE is an
auto-increment or auto-decrement RTX whose operand is a register or
memory location; so reloading involves incrementing that location.

INC_AMOUNT is the number to increment or decrement by (always
positive and ignored for POST_MODIFY/PRE_MODIFY).

Return a pseudo containing the result.   

References address_reload_context::emit_autoinc(), GET_MODE, and ggc_alloc().

Referenced by curr_insn_transform().

◆ emit_spill_move()

static rtx_insn * emit_spill_move ( bool to_p,
rtx mem_pseudo,
rtx val )
Return generated insn mem_pseudo:=val if TO_P or val:=mem_pseudo
otherwise.  If modes of MEM_PSEUDO and VAL are different, use
SUBREG for VAL to make them equal.   

References gen_lowpart_SUBREG(), gen_move_insn(), GET_CODE, GET_MODE, ggc_alloc(), LRA_SUBREG_P, MEM_P, and SUBREG_REG.

Referenced by curr_insn_transform(), and split_reg().

◆ enough_allocatable_hard_regs_p()

static bool enough_allocatable_hard_regs_p ( enum reg_class reg_class,
enum machine_mode reg_mode )
Return true if REG_CLASS has enough allocatable hard regs to keep value of

References ggc_alloc(), hard_reg_set_subset_p(), hard_regno_nregs(), i, ira_class_hard_regs, ira_class_hard_regs_num, lra_no_alloc_regs, reg_class_contents, reg_mode, and TEST_HARD_REG_BIT.

Referenced by curr_insn_transform(), and in_class_p().

◆ equiv_address_substitution()

static bool equiv_address_substitution ( struct address_info * ad)

◆ extract_mem_from_operand()

rtx extract_mem_from_operand ( rtx op)
For special_memory_operand, it could be false for MEM_P (op),
i.e. bcst_mem_operand in i386 backend.
Extract and return real memory operand or op.   


Referenced by asm_operand_ok(), ira_setup_alts(), process_address_1(), record_operand_costs(), record_reg_classes(), satisfies_memory_constraint_p(), and valid_address_p().

◆ finish_invariants()

static void finish_invariants ( void )
Finish the invariant table.   

References ggc_alloc(), invariant_table, invariants, and invariants_pool.

Referenced by lra_constraints_finish().

◆ fix_bb_live_info()

static void fix_bb_live_info ( bitmap live,
bitmap removed_pseudos )
Fix BB live info LIVE after removing pseudos created on pass doing
inheritance/split which are REMOVED_PSEUDOS.      

References bitmap_clear_bit(), bitmap_set_bit, EXECUTE_IF_SET_IN_BITMAP, ggc_alloc(), lra_reg_info, REG_P, and REGNO.

Referenced by remove_inheritance_pseudos().

◆ general_constant_p()

static bool general_constant_p ( rtx x)
Return true if X is a general constant.   

References CONSTANT_P, ggc_alloc(), and LEGITIMATE_PIC_OPERAND_P.

Referenced by process_alt_operands().

◆ get_equiv()

static rtx get_equiv ( rtx x)
If we have decided to substitute X with another value, return that
value, otherwise return X.   

References gcc_unreachable, ggc_alloc(), ira_reg_equiv, lra_get_regno_hard_regno(), NULL_RTX, REG_P, REGNO, and targetm.

Referenced by get_equiv_with_elimination(), loc_equivalence_callback(), and lra_constraints().

◆ get_equiv_with_elimination()

static rtx get_equiv_with_elimination ( rtx x,
rtx_insn * insn )
If we have decided to substitute X with the equivalent value,
return that value after elimination for INSN, otherwise return

References CONSTANT_P, get_equiv(), GET_MODE, and lra_eliminate_regs_1().

Referenced by curr_insn_transform(), equiv_address_substitution(), loc_equivalence_callback(), loc_equivalence_change_p(), and process_addr_reg().

◆ get_hard_regno()

static int get_hard_regno ( rtx x)
Return the hard regno of X after removing its subreg.  If X is not a
register or a subreg of a register, return -1.  If X is a pseudo, use its
assignment.  If X is a hard regno, return the final hard regno which will be
after elimination.   

References GET_MODE, HARD_REGISTER_NUM_P, lra_get_elimination_hard_regno(), lra_get_regno_hard_regno(), REG_P, REGNO, SUBREG_BYTE, SUBREG_P, SUBREG_REG, and subreg_regno_offset().

Referenced by match_reload(), operands_match_p(), process_alt_operands(), and uses_hard_regs_p().

◆ get_last_insertion_point()

static rtx_insn * get_last_insertion_point ( basic_block bb)
Return the last non-debug insn in basic block BB, or the block begin
note if none.   


Referenced by get_live_on_other_edges(), and inherit_in_ebb().

◆ get_live_on_other_edges()

static void get_live_on_other_edges ( basic_block from,
basic_block to,
bitmap res )
Set up RES by registers living on edges FROM except the edge (FROM,
TO) or by registers set up in a jump insn in BB FROM.   

References bitmap_clear(), bitmap_ior_into(), bitmap_set_bit, curr_id, df_get_live_in(), FOR_EACH_EDGE, get_last_insertion_point(), JUMP_P, last, lra_assert, lra_get_insn_recog_data(), lra_insn_reg::next, NULL, OP_IN, lra_insn_reg::regno, basic_block_def::succs, and lra_insn_reg::type.

Referenced by inherit_in_ebb().

◆ get_op_class()

static enum reg_class get_op_class ( rtx op)
If OP is a register, return the class of the register as per
get_reg_class, otherwise return NO_REGS.   

References get_reg_class(), ggc_alloc(), REG_P, and REGNO.

Referenced by simple_move_p().

◆ get_reg_class()

static enum reg_class get_reg_class ( int regno)
If REGNO is a hard register or has been allocated a hard register,
return the class of that register.  If REGNO is a reload pseudo
created by the current constraints pass, return its allocno class.
Return NO_REGS otherwise.   

References ggc_alloc(), HARD_REGISTER_NUM_P, lra_get_allocno_class(), lra_get_elimination_hard_regno(), lra_get_regno_hard_regno(), and new_regno_start.

Referenced by check_and_process_move(), check_secondary_memory_needed_p(), curr_insn_transform(), get_op_class(), in_class_p(), in_mem_p(), inherit_reload_reg(), process_addr_reg(), process_alt_operands(), and reg_in_class_p().

◆ get_regno()

static int get_regno ( rtx reg)
Return regno of the (subreg of) REG. Otherwise, return a negative

References GET_CODE, ggc_alloc(), REG_P, REGNO, and SUBREG_REG.

Referenced by delete_move_and_clobber(), remove_inheritance_pseudos(), and undo_optional_reloads().

◆ get_reload_reg()

static bool get_reload_reg ( enum op_type type,
machine_mode mode,
rtx original,
enum reg_class rclass,
HARD_REG_SET * exclude_start_hard_regs,
bool in_subreg_p,
const char * title,
rtx * result_reg )
reuse an existing reload pseudo.  Don't reuse an existing reload pseudo if
IN_SUBREG_P is true and the reused pseudo should be wrapped up in a SUBREG.
The result pseudo is returned through RESULT_REG.  Return TRUE if we created
a new pseudo, FALSE if we reused an existing reload pseudo.  Use TITLE to
describe new registers for debug purposes.   

References curr_insn, curr_insn_input_reloads, curr_insn_input_reloads_num, dump_value_slim(), GET_CODE, GET_MODE, GET_MODE_SIZE(), ggc_alloc(), i, in_class_p(), input_reload::input, INSN_UID(), lowpart_subreg(), lra_assert, lra_change_class(), lra_create_new_reg(), lra_create_new_reg_with_unique_value(), lra_dump_file, lra_get_allocno_class(), LRA_MAX_INSN_RELOADS, input_reload::match_p, new_insn_uid_start, new_regno_start, NULL, NULL_RTX, OP_OUT, input_reload::reg, REG_P, REGNO, rtx_equal_p(), and side_effects_p().

Referenced by curr_insn_transform(), process_addr_reg(), and simplify_operand_subreg().

◆ get_try_hard_regno()

static int get_try_hard_regno ( int regno)
Return hard regno of REGNO or if it is was not assigned to a hard
register, use a hard register from its allocno class.   

References ggc_alloc(), ira_class_hard_regs, lra_get_allocno_class(), and lra_get_regno_hard_regno().

Referenced by curr_insn_transform().

◆ in_class_p()

static bool in_class_p ( rtx reg,
enum reg_class cl,
enum reg_class * new_class,
bool allow_all_reload_class_changes_p = false )
Return true if REG satisfies (or will satisfy) reg class constraint
CL.  Use elimination first if REG is a hard register.  If REG is a
reload pseudo created by this constraints pass, assume that it will
be allocated a hard register from its allocno class, but allow that
class to be narrowed to CL if it is currently a superset of CL and
if either:

- the instruction we're processing is not a reload move.

If NEW_CLASS is nonnull, set *NEW_CLASS to the new allocno class of
REGNO (reg), or NO_REGS if no change in its class was needed.   

References curr_insn, curr_insn_set, enough_allocatable_hard_regs_p(), GET_CODE, GET_MODE, get_reg_class(), ggc_alloc(), hard_reg_set_subset_p(), INSN_UID(), ira_class_subset_p, ira_reg_class_subset, lra_eliminate_reg_if_possible(), lra_no_alloc_regs, MEM_P, new_insn_uid_start, new_regno_start, NULL, reg_class_contents, reg_mode, REG_P, REGNO, SET_SRC, SMALL_REGISTER_CLASS_P, SUBREG_REG, and TEST_HARD_REG_BIT.

Referenced by curr_insn_transform(), get_reload_reg(), narrow_reload_pseudo_class(), process_addr_reg(), process_address_1(), process_alt_operands(), and reg_in_class_p().

◆ in_list_p()

static bool in_list_p ( rtx x,
rtx list )
Return true if X is in LIST.    

References NULL_RTX, and XEXP.

Referenced by lra_constraints().

◆ in_mem_p()

static bool in_mem_p ( int regno)
Return true if REGNO satisfies a memory constraint.    

References get_reg_class(), and ggc_alloc().

Referenced by spilled_pseudo_p().

◆ index_part_to_reg()

static rtx index_part_to_reg ( struct address_info * ad,
enum reg_class index_class )
Make reload of index part of address AD.  Return the new

References expand_mult(), GEN_INT, get_index_scale(), GET_MODE, ggc_alloc(), lra_create_new_reg(), NULL, and NULL_RTX.

Referenced by process_address_1().

◆ inherit_in_ebb()

static bool inherit_in_ebb ( rtx_insn * head,
rtx_insn * tail )
Do inheritance/split transformations in EBB starting with HEAD and
finishing on TAIL.  We process EBB insns in the reverse order.
Return true if we did any inheritance/split transformation in the

We should avoid excessive splitting which results in worse code
because of inaccurate cost calculations for spilling new split
pseudos in such case.  To achieve this we do splitting only if
register pressure is high in given basic block and there are reload
pseudos requiring hard registers.  We could do more register
pressure calculations at any given program point to avoid necessary
splitting even more but it is to expensive and the current approach
works well enough.   

References add_next_usage_insn(), add_to_hard_reg_set(), add_to_inherit(), bb_note(), lra_insn_reg::biggest_mode, bitmap_bit_p, bitmap_clear(), bitmap_set_bit, BLOCK_FOR_INSN(), CALL_P, calls_num, usage_insns::calls_num, usage_insns::check, check_and_force_assignment_correctness_p, check_only_regs, CLEAR_HARD_REG_SET, clear_invariants(), copy_rtx(), curr_bb, curr_id, curr_insn, curr_static_id, curr_usage_insns_check, df_get_live_in(), df_get_live_out(), EDGE_PRED, eliminable_regset, emit_move_insn(), end_sequence(), EXECUTE_IF_SET_IN_BITMAP, find_reg_note(), full_and_partial_call_clobbers, GET_CODE, get_insns(), get_last_insertion_point(), get_live_on_other_edges(), get_max_uid(), GET_MODE, ggc_alloc(), hard_reg_set_subset_p(), hard_regno_nregs(), lra_static_insn_data::hard_regs, i, inherit_reload_reg(), insn_callee_abi(), INSN_P, INSN_UID(), insns, usage_insns::insns, invalid_invariant_regs, ira_class_hard_regs_num, JUMP_P, last_call_for_abi, live_hard_regs, lra_constraint_new_regno_start, lra_dump_file, lra_get_allocno_class(), lra_get_insn_recog_data(), lra_no_alloc_regs, lra_process_new_insns(), max_small_class_regs_num, max_uid, need_for_split_p(), lra_insn_reg::next, NONDEBUG_INSN_P, NULL, NULL_RTX, NUM_ABI_IDS, OP_IN, OP_OUT, ORIGINAL_REGNO, PATTERN(), PREV_INSN(), process_invariant_for_inheritance(), PSEUDO_REGNO_MODE, r, reg_class_contents, REG_P, reg_renumber, to_inherit::regno, lra_insn_reg::regno, REGNO, regno_reg_rtx, reloads_num, remove_from_hard_reg_set(), SET_DEST, SET_HARD_REG_BIT, SET_SRC, setup_next_usage_insn(), SIBLING_CALL_P, single_set(), split_if_necessary(), split_reg(), start_sequence(), lra_insn_reg::subreg_p, temp_bitmap, to_inherit_num, lra_insn_reg::type, XEXP, and XVECEXP.

Referenced by lra_inheritance().

◆ inherit_reload_reg()

static bool inherit_reload_reg ( bool def_p,
int original_regno,
enum reg_class cl,
rtx_insn * insn,
rtx next_usage_insns )
Do inheritance transformations for insn INSN, which defines (if
DEF_P) or uses ORIGINAL_REGNO.  NEXT_USAGE_INSNS specifies which
instruction in the EBB next uses ORIGINAL_REGNO; it has the same
form as the "insns" field of usage_insns.  Return true if we
succeed in such transformation.

The transformations look like:

  p <- ...                i <- ...
  ...             p <- i    (new insn)
  ...        =>
  <- ... p ...    <- ... i ...
  ...             i <- p    (new insn)
  <- ... p ...    <- ... i ...
  ...        =>
  <- ... p ...    <- ... i ...
where p is a spilled original pseudo and i is a new inheritance pseudo.

The inheritance pseudo has the smallest class of two classes CL and
class of ORIGINAL REGNO.   

References bitmap_set_bit, BLOCK_FOR_INSN(), cfun, check_only_regs, check_secondary_memory_needed_p(), DEBUG_INSN_P, dump_insn_slim(), dump_rtl_slim(), end_sequence(), GET_CODE, get_insns(), GET_MODE, get_reg_class(), ggc_alloc(), basic_block_def::index, ira_class_hard_regs_num, ira_class_subset_p, ira_reg_classes_intersect_p, lra_assert, lra_create_new_reg(), lra_dump_file, lra_emit_move(), lra_get_allocno_class(), lra_inheritance_pseudos, lra_process_new_insns(), lra_reg_info, lra_substitute_pseudo(), lra_substitute_pseudo_within_insn(), lra_update_insn_regno_info(), NEXT_INSN(), NONDEBUG_INSN_P, NULL, NULL_RTX, optimize_function_for_size_p(), reg_class_names, REG_P, REGNO, regno_reg_rtx, reloads_num, lra_reg::restore_rtx, SET_DEST, setup_next_usage_insn(), single_set(), skip_usage_debug_insns(), start_sequence(), and XEXP.

Referenced by inherit_in_ebb().

◆ init_curr_insn_input_reloads()

static void init_curr_insn_input_reloads ( void )
Initiate data concerning reuse of input reloads for the current

References curr_insn_input_reloads_num.

Referenced by lra_constraints().

◆ init_curr_operand_mode()

◆ init_insn_rhs_dead_pseudo_p()

static bool init_insn_rhs_dead_pseudo_p ( int regno)
Return true if any init insn of REGNO contains a dying pseudo in
insn right hand side.   

References ira_reg_equiv_s::init_insns, insn_rhs_dead_pseudo_p(), insns, ira_reg_equiv, NULL, and NULL_RTX.

Referenced by lra_constraints().

◆ initiate_invariants()

static void initiate_invariants ( void )
Initiate the invariant table.   

References ggc_alloc(), invariant_eq_p(), invariant_hash(), invariant_table, invariants, invariants_pool, and NULL.

Referenced by lra_constraints_init().

◆ insert_invariant()

static invariant_ptr_t insert_invariant ( rtx invariant_rtx)
Insert INVARIANT_RTX into the table if it is not there yet.  Return
invariant which is in the table.   

References ggc_alloc(), invariant_table, invariants, invariants_pool, and NULL.

Referenced by process_invariant_for_inheritance().

◆ insert_move_for_subreg()

static void insert_move_for_subreg ( rtx_insn ** before,
rtx_insn ** after,
rtx origreg,
rtx newreg )
Insert move insn in simplify_operand_subreg. BEFORE returns
the insn to be inserted before curr insn. AFTER returns the
the insn to be inserted after curr insn.  ORIGREG and NEWREG
are the original reg and new reg for reload.   

References emit_insn(), end_sequence(), get_insns(), ggc_alloc(), lra_emit_move(), push_to_sequence(), and start_sequence().

Referenced by simplify_operand_subreg().

◆ insn_rhs_dead_pseudo_p()

static bool insn_rhs_dead_pseudo_p ( rtx_insn * insn)
Return true if INSN contains a dying pseudo in INSN right hand

References dead_pseudo_p(), gcc_assert, NULL, SET_SRC, and single_set().

Referenced by init_insn_rhs_dead_pseudo_p().

◆ invariant_eq_p()

static int invariant_eq_p ( const void * invariant1,
const void * invariant2 )
Equal function for invariants INVARIANT1 and INVARIANT2.   

References ggc_alloc(), and rtx_equal_p().

Referenced by initiate_invariants().

◆ invariant_hash()

static hashval_t invariant_hash ( const void * invariant)
Hash function for INVARIANT.   

References lra_rtx_hash().

Referenced by initiate_invariants().

◆ invariant_p()

◆ loc_equivalence_callback()

static rtx loc_equivalence_callback ( rtx loc,
const_rtx ,
void * data )
Similar to loc_equivalence_change_p, but for use as
simplify_replace_fn_rtx callback.  DATA is insn for which the
elimination is done.  If it null we don't do the elimination.   

References get_equiv(), get_equiv_with_elimination(), NULL, NULL_RTX, REG_P, and subst().

Referenced by lra_constraints(), and update_equiv().

◆ loc_equivalence_change_p()

static bool loc_equivalence_change_p ( rtx * loc)
Process all regs in location *LOC and change them on equivalent
substitution.  Return true if any change was done.   

References curr_insn, GET_CODE, get_equiv_with_elimination(), GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, loc_equivalence_change_p(), simplify_gen_subreg(), SUBREG_BYTE, SUBREG_REG, subst(), XEXP, XVECEXP, and XVECLEN.

Referenced by loc_equivalence_change_p(), and lra_constraints().

◆ lra_constrain_insn()

bool lra_constrain_insn ( rtx_insn * insn)
Return true if INSN satisfies all constraints.  In other words, no
reload insns are needed.   

References curr_id, curr_insn, curr_insn_transform(), curr_static_id, get_max_uid(), ggc_alloc(), lra_get_insn_recog_data(), max_reg_num(), new_insn_uid_start, and new_regno_start.

Referenced by do_remat().

◆ lra_constraint_offset()

int lra_constraint_offset ( int regno,
machine_mode mode )
The page contains major code to choose the current insn alternative
and generate reloads for it.      
Return the offset from REGNO of the least significant register
in (reg:MODE REGNO).

This function is used to tell whether two registers satisfy
a matching constraint.  (reg:MODE1 REGNO1) matches (reg:MODE2 REGNO2) if:

      REGNO1 + lra_constraint_offset (REGNO1, MODE1)
      == REGNO2 + lra_constraint_offset (REGNO2, MODE2)   

References GET_MODE_SIZE(), ggc_alloc(), hard_regno_nregs(), and lra_assert.

Referenced by operands_match_p().

◆ lra_constraints()

bool lra_constraints ( bool first_p)
Entry function of LRA constraint pass.  Return true if the
constraint pass did change the code.      

References bb_reload_num, bitmap_bit_p, bitmap_ior_into(), BLOCK_FOR_INSN(), ira_reg_equiv_s::caller_save_p, check_and_force_assignment_correctness_p, combine_reload_insn(), CONST_POOL_OK_P, contains_deleted_insn_p(), contains_reg_p(), contains_reloaded_insn_p(), contains_symbol_ref_p(), copy_rtx(), curr_bb, curr_id, curr_insn, curr_insn_transform(), curr_static_id, DEBUG_INSN_P, ira_reg_equiv_s::defined_p, df_regs_ever_live_p(), df_set_regs_ever_live(), dump_insn_slim(), EXECUTE_IF_SET_IN_BITMAP, GET_CODE, get_equiv(), get_max_uid(), GET_MODE, GET_MODE_SIZE(), ggc_alloc(), hard_regno_nregs(), i, in_list_p(), init_curr_insn_input_reloads(), init_curr_operand_mode(), init_insn_rhs_dead_pseudo_p(), INSN_P, INSN_UID(), internal_error(), ira_reg_equiv, loc_equivalence_callback(), loc_equivalence_change_p(), lra_assert, lra_constraint_iter, lra_constraint_new_regno_start, lra_curr_reload_num, lra_dump_file, lra_dump_insns_if_possible(), lra_eliminate(), lra_get_allocno_class(), lra_get_insn_recog_data(), lra_get_regno_hard_regno(), lra_insn_stack_length(), lra_pop_insn(), lra_push_insn_by_uid(), lra_reg_info, lra_set_insn_deleted(), lra_update_insn_regno_info(), max_reg_num(), MAX_RELOAD_INSNS_NUMBER, maybe_gt, MEM_P, MEM_READONLY_P, multi_block_pseudo_p(), new_insn_uid_start, new_regno_start, NULL, NULL_RTX, PATTERN(), pic_offset_table_rtx, ira_reg_equiv_s::profitable_p, PSEUDO_REGNO_MODE, REG_FREQ_FROM_BB, reg_obstack, REG_P, REGNO, regno_reg_rtx, reverse_equiv_p(), SET_DEST, SET_SRC, simplify_replace_fn_rtx(), single_set(), SUBREG_REG, targetm, and update_equiv().

Referenced by lra().

◆ lra_constraints_finish()

void lra_constraints_finish ( void )
Finalize the LRA constraint pass.  It is done once per

References finish_invariants().

Referenced by lra().

◆ lra_constraints_init()

void lra_constraints_init ( void )
Initiate the LRA constraint pass.  It is done once per

References initiate_invariants().

Referenced by lra().

◆ lra_copy_reg_equiv()

static void lra_copy_reg_equiv ( unsigned int new_regno,
unsigned int original_regno,
bool call_save_p )
Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.  It only
makes sense to call this function if NEW_REGNO is always equal to
ORIGINAL_REGNO.  Set up defined_p flag when caller_save_p flag is set up and
CALL_SAVE_P is true.   

References ira_reg_equiv_s::constant, copy_rtx(), ira_reg_equiv_s::defined_p, ggc_alloc(), ira_reg_equiv_s::invariant, ira_expand_reg_equiv(), ira_reg_equiv, and ira_reg_equiv_s::memory.

Referenced by split_reg().

◆ lra_inheritance()

◆ lra_init_equiv()

void lra_init_equiv ( void )
Initiate equivalences for LRA.  As we keep original equivalences
before any elimination, we need to make copies otherwise any change
in insns might change the equivalences.   

References copy_rtx(), ggc_alloc(), i, ira_expand_reg_equiv(), ira_reg_equiv, max_reg_num(), and NULL_RTX.

Referenced by lra().

◆ lra_undo_inheritance()

◆ match_reload()

static void match_reload ( signed char out,
signed char * ins,
signed char * outs,
enum reg_class goal_class,
HARD_REG_SET * exclude_start_hard_regs,
rtx_insn ** before,
rtx_insn ** after,
bool early_clobber_p )
Generate reloads for matching OUT and INS (array of input operand numbers
with end marker -1) with reg class GOAL_CLASS and EXCLUDE_START_HARD_REGS,
considering output operands OUTS (similar array to INS) needing to be in
different registers.  Add input and output reloads correspondingly to the
lists *BEFORE and *AFTER.  OUT might be negative.  In this case we generate
input reloads for matched input operands INS.  EARLY_CLOBBER_P is a flag
that the output operand is early clobbered for chosen alternative.   

References asm_noperands(), check_conflict_input_operands(), CLEAR_HARD_REG_SET, copy_rtx(), curr_id, curr_insn, curr_insn_input_reloads, curr_insn_input_reloads_num, curr_operand_mode, curr_static_id, emit_clobber(), emit_insn(), end_sequence(), find_reg_note(), find_regno_note(), gen_lowpart_SUBREG(), GET_CODE, get_hard_regno(), get_insns(), GET_MODE, ggc_alloc(), hard_regno_nregs(), i, input_reload::input, known_eq, lra_assert, lra_assign_reg_val(), lra_create_new_reg(), lra_create_new_reg_with_unique_value(), lra_emit_move(), LRA_MAX_INSN_RELOADS, lra_new_regno_start, LRA_SUBREG_P, LRA_TEMP_CLOBBER_P, lra_update_dup(), lra_update_dups(), input_reload::match_p, narrow_reload_pseudo_class(), NULL, NULL_RTX, lra_static_insn_data::operand, partial_subreg_p(), PATTERN(), push_to_sequence(), input_reload::reg, REG_P, REGNO, regno_val_use_in(), SET_HARD_REG_BIT, start_sequence(), lra_operand_data::strict_low, SUBREG_BYTE, SUBREG_P, and SUBREG_REG.

Referenced by curr_insn_transform().

◆ multi_block_pseudo_p()

static bool multi_block_pseudo_p ( int regno)
Return true if REGNO is referenced in more than one block.   

References BLOCK_FOR_INSN(), EXECUTE_IF_SET_IN_BITMAP, ggc_alloc(), lra_reg_info, and NULL.

Referenced by lra_constraints().

◆ narrow_reload_pseudo_class()

static void narrow_reload_pseudo_class ( rtx reg,
enum reg_class cl )
If REG is a reload pseudo, try to make its class satisfying CL.   

References curr_insn, GET_CODE, ggc_alloc(), in_class_p(), INSN_UID(), lra_change_class(), new_insn_uid_start, new_regno_start, REG_P, REGNO, and SUBREG_REG.

Referenced by match_reload().

◆ need_for_call_save_p()

static bool need_for_call_save_p ( int regno)
Return true if we need a caller save/restore for pseudo REGNO which
was assigned to a hard register.   

References call_clobbered_in_region_p(), calls_num, full_and_partial_call_clobbers, gcc_assert, ggc_alloc(), i, last_call_for_abi, lra_assert, NUM_ABI_IDS, PSEUDO_REGNO_MODE, and reg_renumber.

Referenced by need_for_split_p(), and split_reg().

◆ need_for_split_p()

static bool need_for_split_p ( HARD_REG_SET potential_reload_hard_regs,
int regno )
Return true if we need a split for hard register REGNO or pseudo
REGNO which was assigned to a hard register.
POTENTIAL_RELOAD_HARD_REGS contains hard registers which might be
used for reloads since the EBB end.     It is an approximation of the
used hard registers in the split range.  The exact value would
require expensive calculations.  If we were aggressive with
splitting because of the approximation, the split pseudo will save
the same hard register assignment and will be removed in the undo
pass.  We still need the approximation because too aggressive
splitting would result in too inaccurate cost calculation in the
assignment pass because of too many generated moves which will be
probably removed in the undo pass.   

References bitmap_bit_p, ebb_global_regs, eliminable_regset, full_and_partial_call_clobbers, ggc_alloc(), lra_assert, lra_no_alloc_regs, lra_reg_info, need_for_call_save_p(), lra_reg::nrefs, reg_renumber, reloads_num, and TEST_HARD_REG_BIT.

Referenced by inherit_in_ebb(), and split_if_necessary().

◆ operands_match_p()

static bool operands_match_p ( rtx x,
rtx y,
int y_hard_regno )
Like rtx_equal_p except that it allows a REG and a SUBREG to match
if they are the same hard reg, and has special hacks for
auto-increment and auto-decrement.  This is specifically intended for
process_alt_operands to use in determining whether two operands
match.  X is the operand whose number is the lower of the two.

It is supposed that X is the output operand and Y is the input
operand.  Y_HARD_REGNO is the final hard regno of register Y or
register in subreg Y as we know it now.  Otherwise, it is a
negative value.   

References CASE_CONST_UNIQUE, gcc_unreachable, GET_CODE, get_hard_regno(), GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, label_ref_label(), lra_constraint_offset(), operands_match_p(), REG_P, REGNO, RTX_CODE, same_vector_encodings_p(), SUBREG_BYTE, SUBREG_REG, XEXP, XINT, XSTR, XVECEXP, XVECLEN, XWINT, and y.

Referenced by constrain_operands(), curr_insn_transform(), operands_match_p(), and process_alt_operands().

◆ print_curr_insn_alt()

static void print_curr_insn_alt ( int alt_number)

◆ process_addr_reg()

static bool process_addr_reg ( rtx * loc,
bool check_only_p,
rtx_insn ** before,
rtx_insn ** after,
enum reg_class cl )
if CHECK_ONLY_P is false, arrange for address element *LOC to be a
register of class CL.  Add any input reloads to list BEFORE.  AFTER
is nonnull if *LOC is an automodified value; handle that case by
adding the required output reloads to list AFTER.  Return true if
the RTL was changed.

if CHECK_ONLY_P is true, check that the *LOC is a correct address
register.  Return false if the address register is correct.   

References copy_rtx(), curr_insn, dump_value_slim(), emit_insn(), end_sequence(), GET_CODE, get_equiv_with_elimination(), get_insns(), GET_MODE, GET_MODE_SIZE(), get_reg_class(), get_reload_reg(), ggc_alloc(), in_class_p(), INSN_UID(), known_le, lra_change_class(), lra_create_new_reg_with_unique_value(), lra_dump_file, lra_emit_move(), NULL, OP_IN, OP_INOUT, ptr_mode, push_to_sequence(), REG_P, REGNO, start_sequence(), and SUBREG_REG.

Referenced by process_address_1().

◆ process_address()

static bool process_address ( int nop,
bool check_only_p,
rtx_insn ** before,
rtx_insn ** after )
If CHECK_ONLY_P is false, do address reloads until it is necessary.
Use process_address_1 as a helper function.  Return true for any
RTL changes.

If CHECK_ONLY_P is true, just check address correctness.  Return
false if the address correct.   

References ggc_alloc(), and process_address_1().

Referenced by curr_insn_transform(), and simplify_operand_subreg().

◆ process_address_1()

static bool process_address_1 ( int nop,
bool check_only_p,
rtx_insn ** before,
rtx_insn ** after )
Major function to make reloads for an address in operand NOP or
check its correctness (If CHECK_ONLY_P is true). The supported
cases are:

1) an address that existed before LRA started, at which point it
must have been valid.  These addresses are subject to elimination
and may have become invalid due to the elimination offset being out
of range.

2) an address created by forcing a constant to memory
(force_const_to_mem).  The initial form of these addresses might
not be valid, and it is this function's job to make them valid.

3) a frame address formed from a register and a (possibly zero)
constant offset.  As above, these addresses might not be valid and
this function must make them so.

Add reloads to the lists *BEFORE and *AFTER.  We might need to add
reloads to *AFTER because of inc/dec, {pre, post} modify in the
address.  Return true for any RTL change.

The function is a helper function which does not produce all
transformations (when CHECK_ONLY_P is false) which can be
necessary.  It does just basic steps.  To do all necessary
transformations use function process_address.   

References base_plus_disp_to_reg(), base_reg_class(), base_to_reg(), CONSTANT_P, lra_operand_data::constraint, constraint_unique(), copy_rtx(), curr_id, curr_insn, curr_static_id, decompose_lea_address(), decompose_mem_address(), delete_insns_since(), emit_insn(), end(), end_sequence(), equiv_address_substitution(), extract_mem_from_operand(), find_regno_note(), gcc_assert, GET_CODE, get_index_code(), get_index_scale(), get_insns(), get_last_insn(), GET_MODE, ggc_alloc(), in_class_p(), IN_RANGE, index_part_to_reg(), index_reg_class(), INSN_CODE, insns, ira_class_hard_regs_num, lra_operand_data::is_address, last, lra_assert, lra_change_class(), lra_create_new_reg(), lra_emit_move(), lra_get_allocno_class(), MEM_P, NEXT_INSN(), NULL, NULL_RTX, lra_static_insn_data::operand, poly_int_rtx_p(), PREV_INSN(), process_addr_reg(), push_to_sequence(), recog_memoized(), REG_P, REGNO, satisfies_address_constraint_p(), SET_SRC, simplify_gen_binary(), single_set(), skip_constraint_modifiers(), start_sequence(), SUBREG_REG, targetm, valid_address_p(), and XEXP.

Referenced by process_address().

◆ process_alt_operands()

static bool process_alt_operands ( int only_alternative)
Major function to choose the current insn alternative and what
operands should be reloaded and how.     If ONLY_ALTERNATIVE is not
negative we should consider only this alternative.  Return false if
we cannot choose the alternative or find how to reload the

References add_to_hard_reg_set(), ADDR_SPACE_GENERIC, ALTERNATIVE_BIT, operand_alternative::anything_ok, base_reg_class(), bb_reload_num, best_losers, best_overall, best_reload_nregs, best_reload_sum, CLEAR_HARD_REG_SET, CONST_INT_P, CONST_POOL_OK_P, CONSTANT_P, operand_alternative::constraint, curr_id, curr_insn, curr_insn_set, curr_operand_mode, curr_small_class_check, curr_static_id, curr_swapped, DECL_HARD_REGISTER, lra_operand_data::early_clobber_alts, end(), equiv_substition_p, fatal_insn, find_reg_note(), find_regno_note(), general_constant_p(), GET_CODE, get_hard_regno(), GET_MODE, GET_MODE_SIZE(), get_reg_class(), ggc_alloc(), goal_alt, goal_alt_dont_inherit_ops, goal_alt_dont_inherit_ops_num, goal_alt_exclude_start_hard_regs, goal_alt_match_win, goal_alt_matches, goal_alt_number, goal_alt_offmemok, goal_alt_out_sp_reload_p, goal_alt_swapped, goal_alt_win, goal_reuse_alt_p, hard_reg_set_empty_p(), hard_reg_set_subset_p(), HARD_REGISTER_P, i, in_class_p(), in_hard_reg_set_p(), INSN_CODE, INSN_UID(), INTVAL, ira_class_hard_regs, ira_class_hard_regs_num, ira_class_subset_p, ira_exclude_class_mode_regs, ira_former_scratch_p(), ira_prohibited_class_mode_regs, ira_reg_class_max_nregs, lra_operand_data::is_address, lra_operand_data::is_operator, lra_reg::last_reload, lra_assert, lra_constraint_iter, lra_dump_file, lra_get_elimination_hard_regno(), LRA_LOSER_COST_FACTOR, LRA_MAX_REJECT, lra_no_alloc_regs, lra_reg_info, MEM_P, n_alternatives(), lra_static_insn_data::n_alternatives, n_operands, lra_static_insn_data::n_operands, no_input_reloads_p, no_output_reloads_p, NULL, NULL_RTX, OP_IN, OP_INOUT, OP_OUT, lra_static_insn_data::operand, lra_static_insn_data::operand_alternative, operands_match_p(), ORIGINAL_REGNO, print_curr_insn_alt(), prohibited_class_reg_set_mode_p(), REG_ATTRS, reg_class_contents, reg_class_subunion, REG_EXPR, reg_in_class_p(), REG_P, REG_USERVAR_P, REGNO, regno_reg_rtx, operand_alternative::reject, reject(), satisfies_address_constraint_p(), satisfies_memory_constraint_p(), SET_SRC, SMALL_REGISTER_CLASS_P, spilled_pseudo_p(), stack_pointer_rtx, lra_operand_data::strict_low, SUBREG_P, SUBREG_REG, targetm, TEST_BIT, TEST_HARD_REG_BIT, lra_operand_data::type, update_and_check_small_class_inputs(), uses_hard_regs_p(), VAR_P, VECTOR_MODE_P, and wider_subreg_mode().

Referenced by curr_insn_transform().

◆ process_invariant_for_inheritance()

static bool process_invariant_for_inheritance ( rtx dst_reg,
rtx invariant_rtx )

◆ prohibited_class_reg_set_mode_p()

static bool prohibited_class_reg_set_mode_p ( enum reg_class rclass,
machine_mode mode )
Return true if SET of RCLASS contains no hard regs which can be
used in MODE.   

References ggc_alloc(), hard_reg_set_subset_p(), ira_prohibited_class_mode_regs, lra_assert, and reg_class_contents.

Referenced by curr_insn_transform(), and process_alt_operands().

◆ reg_class_from_constraints()

static enum reg_class reg_class_from_constraints ( const char * p)
Return register class which is union of all reg classes in insn
constraint alternative string starting with P.   

References ADDR_SPACE_GENERIC, base_reg_class(), ggc_alloc(), and reg_class_subunion.

Referenced by check_and_process_move().

◆ reg_in_class_p()

static bool reg_in_class_p ( rtx reg,
enum reg_class cl )

◆ regno_val_use_in()

static rtx regno_val_use_in ( unsigned int regno,
rtx x )
Searches X for any reference to a reg with the same value as REGNO,
returning the rtx of the reference found if any.  Otherwise,
returns NULL_RTX.   

References GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, lra_reg_info, NULL_RTX, REG_P, REGNO, regno_val_use_in(), XEXP, XVECEXP, and XVECLEN.

Referenced by check_conflict_input_operands(), match_reload(), and regno_val_use_in().

◆ remove_inheritance_pseudos()

static bool remove_inheritance_pseudos ( bitmap remove_pseudos)
Remove inheritance/split pseudos which are in REMOVE_PSEUDOS and
return true if we did any change.  The undo transformations for
inheritance looks like
   i <- i2
   p <- i         =>   p <- i2
or removing
   p <- i, i <- p, and i <- i3
where p is original pseudo from which inheritance pseudo i was
created, i and i3 are removed inheritance pseudos, i2 is another
not removed inheritance pseudo.  All split pseudos or other
occurrences of removed inheritance pseudos are changed on the
corresponding original pseudos.

The function also schedules insns changed and created during
inheritance/split pass for processing by the subsequent constraint

References bitmap_bit_p, bitmap_empty_p(), BLOCK_FOR_INSN(), cfun, curr_id, curr_insn, delete_move_and_clobber(), df_get_live_in(), df_get_live_out(), dump_insn_slim(), emit_insn(), end_sequence(), fix_bb_live_info(), FOR_BB_INSNS_REVERSE, FOR_EACH_BB_FN, GET_CODE, get_insns(), GET_MODE, get_regno(), ggc_alloc(), INSN_P, INSN_UID(), lra_assert, lra_dump_file, lra_get_insn_recog_data(), lra_inheritance_pseudos, lra_process_new_insns(), lra_push_insn_and_update_insn_regno_info(), lra_reg_info, lra_set_used_insn_alternative_by_uid(), lra_split_regs, lra_substitute_pseudo_within_insn(), LRA_UNKNOWN_ALT, lra_update_insn_regno_info(), lra_insn_reg::next, NONDEBUG_INSN_P, NULL, NULL_RTX, PREV_INSN(), REG_P, lra_insn_reg::regno, REGNO, regno_reg_rtx, remove_pseudos(), lra_reg::restore_rtx, SET_DEST, SET_SRC, single_set(), start_sequence(), and SUBREG_REG.

Referenced by lra_undo_inheritance().

◆ reverse_equiv_p()

static bool reverse_equiv_p ( int regno)
Return TRUE if REGNO has a reverse equivalence.  The equivalence is
reverse only if we have one init insn with given REGNO as a

References ira_reg_equiv_s::init_insns, INSN_P, insns, ira_reg_equiv, NULL, NULL_RTX, REG_P, REGNO, SET_SRC, and single_set().

Referenced by lra_constraints().

◆ satisfies_address_constraint_p() [1/2]

static bool satisfies_address_constraint_p ( rtx op,
enum constraint_num constraint )
Return true if the eliminated form of address OP satisfies extra
address constraint CONSTRAINT.   

References decompose_lea_address(), ggc_alloc(), and satisfies_address_constraint_p().

◆ satisfies_address_constraint_p() [2/2]

static bool satisfies_address_constraint_p ( struct address_info * ad,
enum constraint_num constraint )
Return true if the eliminated form of address AD satisfies extra
address constraint CONSTRAINT.   

References ggc_alloc().

Referenced by process_address_1(), process_alt_operands(), and satisfies_address_constraint_p().

◆ satisfies_memory_constraint_p()

static bool satisfies_memory_constraint_p ( rtx op,
enum constraint_num constraint )
Return true if the eliminated form of memory reference OP satisfies
extra (special) memory constraint CONSTRAINT.   

References decompose_mem_address(), extract_mem_from_operand(), ggc_alloc(), and MEM_P.

Referenced by curr_insn_transform(), and process_alt_operands().

◆ setup_next_usage_insn()

◆ simple_move_p()

static bool simple_move_p ( void )
Return true if the current move insn does not need processing as we
already know that it satisfies its constraints.   

References curr_insn, curr_insn_set, GET_MODE, get_op_class(), ggc_alloc(), lra_assert, multiple_sets(), NULL_RTX, SET_DEST, SET_SRC, and targetm.

Referenced by curr_insn_transform().

◆ simplify_operand_subreg()

◆ skip_constraint_modifiers()

static const char * skip_constraint_modifiers ( const char * str)
Skip all modifiers and whitespaces in constraint STR and return the

Referenced by constraint_unique(), and process_address_1().

◆ skip_usage_debug_insns()

static rtx_insn * skip_usage_debug_insns ( rtx usage_insns)
Return first non-debug insn in list USAGE_INSNS.   

References GET_CODE, ggc_alloc(), NULL_RTX, and XEXP.

Referenced by check_secondary_memory_needed_p(), and inherit_reload_reg().

◆ spill_hard_reg_in_range()

bool spill_hard_reg_in_range ( int regno,
enum reg_class rclass,
rtx_insn * from,
rtx_insn * to )
Split a hard reg for reload pseudo REGNO having RCLASS and living
in the range [FROM, TO].  Return true if did a split.  Otherwise,
return false.   

References bitmap_bit_p, EXECUTE_IF_SET_IN_BITMAP, ggc_alloc(), i, INSN_P, INSN_UID(), ira_class_hard_regs, ira_class_hard_regs_num, lra_assert, lra_get_insn_recog_data(), lra_no_alloc_regs, lra_reg_info, lra_insn_reg::next, NEXT_INSN(), NULL, lra_insn_reg::regno, SET_HARD_REG_BIT, split_reg(), and TEST_HARD_REG_BIT.

Referenced by lra_split_hard_reg_for().

◆ spilled_pseudo_p()

static bool spilled_pseudo_p ( rtx op)
Return true if OP is a spilled pseudo.  

References ggc_alloc(), in_mem_p(), REG_P, and REGNO.

Referenced by process_alt_operands().

◆ split_if_necessary()

static bool split_if_necessary ( int regno,
machine_mode mode,
HARD_REG_SET potential_reload_hard_regs,
bool before_p,
rtx_insn * insn,
int max_uid )
Recognize that we need a split transformation for insn INSN, which
defines or uses REGNO in its insn biggest MODE (we use it only if
REGNO is a hard register).  POTENTIAL_RELOAD_HARD_REGS contains
hard registers which might be used for reloads since the EBB end.
Put the save before INSN if BEFORE_P is true.  MAX_UID is maximla
uid before starting INSN processing.  Return true if we succeed in
such transformation.   

References curr_usage_insns_check, GET_CODE, ggc_alloc(), hard_regno_nregs(), i, INSN_UID(), insns, max_uid, need_for_split_p(), NULL, NULL_RTX, split_reg(), and XEXP.

Referenced by inherit_in_ebb().

◆ split_reg()

static bool split_reg ( bool before_p,
int original_regno,
rtx_insn * insn,
rtx next_usage_insns,
rtx_insn * to )
Do split transformations for insn INSN, which defines or uses
ORIGINAL_REGNO.  NEXT_USAGE_INSNS specifies which instruction in
the EBB next uses ORIGINAL_REGNO; it has the same form as the
"insns" field of usage_insns.  If TO is not NULL, we don't use
usage_insns, we put restore insns after TO insn.  It is a case when
we call it from lra_split_hard_reg_for, outside the inheritance

The transformations look like:

  p <- ...                p <- ...
  ...             s <- p    (new insn -- save)
  ...        =>
  ...             p <- s    (new insn -- restore)
  <- ... p ...    <- ... p ...
  <- ... p ...    <- ... p ...
  ...             s <- p    (new insn -- save)
  ...        =>
  ...             p <- s    (new insn -- restore)
  <- ... p ...    <- ... p ...

where p is an original pseudo got a hard register or a hard
register and s is a new split pseudo.  The save is put before INSN
if BEFORE_P is true.     Return true if we succeed in such

References usage_insns::after_p, lra_reg::biggest_mode, bitmap_set_bit, check_and_force_assignment_correctness_p, check_only_regs, choose_split_class(), DEBUG_INSN_P, dump_insn_slim(), dump_rtl_slim(), emit_spill_move(), gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_NAME, GET_MODE_PRECISION(), ggc_alloc(), HARD_REGISTER_NUM_P, HARD_REGNO_CALLER_SAVE_MODE, hard_regno_nregs(), ira_allocno_class_translate, lra_assert, lra_copy_reg_equiv(), lra_create_new_reg(), lra_dump_file, lra_get_allocno_class(), lra_process_new_insns(), lra_reg_info, lra_split_regs, lra_substitute_pseudo(), lra_update_insn_regno_info(), maybe_gt, need_for_call_save_p(), NEXT_INSN(), NONDEBUG_INSN_P, NOTE_P, NULL, NULL_RTX, paradoxical_subreg_p(), PSEUDO_REGNO_MODE, reg_class_names, reg_renumber, REGNO, regno_reg_rtx, lra_reg::restore_rtx, targetm, and XEXP.

Referenced by inherit_in_ebb(), spill_hard_reg_in_range(), and split_if_necessary().

◆ strip_subreg()

static rtx * strip_subreg ( rtx * loc)
If LOC is nonnull, strip any outer subreg from it.   

References GET_CODE, ggc_alloc(), and SUBREG_REG.

Referenced by equiv_address_substitution().

◆ swap_operands()

static void swap_operands ( int nop)

◆ undo_optional_reloads()

static bool undo_optional_reloads ( void )
If optional reload pseudos failed to get a hard register or was not
inherited, it is better to remove optional reloads.  We do this
transformation after undoing inheritance to figure out necessity to
remove optional reloads easier.  Return true if we do any

References bitmap_bit_p, bitmap_clear_bit(), bitmap_copy(), bitmap_empty_p(), delete_move_and_clobber(), dump_insn_slim(), EXECUTE_IF_SET_IN_BITMAP, gcc_unreachable, GET_CODE, get_regno(), ggc_alloc(), lra_insn_recog_data::insn, INSN_UID(), lra_dump_file, lra_inheritance_pseudos, lra_optional_reload_pseudos, lra_reg_info, lra_substitute_pseudo_within_insn(), lra_update_insn_regno_info(), new_regno_start, NULL, NULL_RTX, PATTERN(), reg_obstack, REG_P, reg_renumber, REGNO, lra_reg::restore_rtx, SET_DEST, SET_SRC, single_set(), and SUBREG_P.

Referenced by lra_undo_inheritance().

◆ update_and_check_small_class_inputs()

static bool update_and_check_small_class_inputs ( int nop,
int nalt,
enum reg_class op_class )
Update number of used inputs of class OP_CLASS for operand NOP
of alternative NALT.  Return true if we have more such class operands
than the number of available regs.   

References curr_small_class_check, curr_static_id, lra_operand_data::early_clobber_alts, ggc_alloc(), hard_reg_set_intersect_p(), ira_class_hard_regs_num, ira_no_alloc_regs, OP_OUT, lra_static_insn_data::operand, reg_class_contents, SMALL_REGISTER_CLASS_P, TEST_BIT, and lra_operand_data::type.

Referenced by process_alt_operands().

◆ update_ebb_live_info()

◆ update_equiv()

static void update_equiv ( int regno)
Update equivalence for REGNO.  We need to this as the equivalence
might contain other pseudos which are changed by their

References ira_reg_equiv_s::invariant, ira_reg_equiv, loc_equivalence_callback(), ira_reg_equiv_s::memory, NULL_RTX, and simplify_replace_fn_rtx().

Referenced by lra_constraints().

◆ uses_hard_regs_p()

static bool uses_hard_regs_p ( rtx x,

◆ valid_address_p() [1/2]

static bool valid_address_p ( machine_mode mode,
rtx addr,
addr_space_t as )
Return true if ADDR is a valid memory address for mode MODE in address
space AS, and check that each pseudo has the proper kind of hard

References ADDR_SPACE_GENERIC_P, ggc_alloc(), lra_assert, and targetm.

Referenced by base_to_reg(), process_address_1(), simplify_operand_subreg(), and valid_address_p().

◆ valid_address_p() [2/2]

static bool valid_address_p ( rtx op,
struct address_info * ad,
enum constraint_num constraint )
Return true if the eliminated form of AD is a legitimate target address.
If OP is a MEM, AD is the address within OP, otherwise OP should be
ignored.  CONSTRAINT is one constraint that the operand may need
to meet.   

References extract_mem_from_operand(), ggc_alloc(), MEM_P, and valid_address_p().

Variable Documentation

◆ bb_reload_num

int bb_reload_num
Code for RTL transformations to satisfy insn constraints.
Copyright (C) 2010-2024 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.

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

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
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
This file contains code for 3 passes: constraint pass,
inheritance/split pass, and pass for undoing failed inheritance and

The major goal of constraint pass is to transform RTL to satisfy
insn and address constraints by:
  o choosing insn alternatives;
  o generating *reload insns* (or reloads in brief) and *reload
    pseudos* which will get necessary hard registers later;
  o substituting pseudos with equivalent values and removing the
    instructions that initialized those pseudos.

The constraint pass has biggest and most complicated code in LRA.
There are a lot of important details like:
  o reuse of input reload pseudos to simplify reload pseudo
  o some heuristics to choose insn alternative to improve the
  o early clobbers etc.

The pass is mimicking former reload pass in alternative choosing
because the reload pass is oriented to current machine description
model.  It might be changed if the machine description model is

There is special code for preventing all LRA and this pass cycling
in case of bugs.

On the first iteration of the pass we process every instruction and
choose an alternative for each one.  On subsequent iterations we try
to avoid reprocessing instructions if we can be sure that the old
choice is still valid.

The inheritance/spilt pass is to transform code to achieve
ineheritance and live range splitting.  It is done on backward
traversal of EBBs.

The inheritance optimization goal is to reuse values in hard
registers. There is analogous optimization in old reload pass.  The
inheritance is achieved by following transformation:

    reload_p1 <- p           reload_p1 <- p
    ...              new_p <- reload_p1
    ...         =>   ...
    reload_p2 <- p           reload_p2 <- new_p

where p is spilled and not changed between the insns.  Reload_p1 is
also called *original pseudo* and new_p is called *inheritance

The subsequent assignment pass will try to assign the same (or
another if it is not possible) hard register to new_p as to
reload_p1 or reload_p2.

If the assignment pass fails to assign a hard register to new_p,
this file will undo the inheritance and restore the original code.
This is because implementing the above sequence with a spilled
new_p would make the code much worse.  The inheritance is done in
EBB scope.  The above is just a simplified example to get an idea
of the inheritance as the inheritance is also done for non-reload

Splitting (transformation) is also done in EBB scope on the same
pass as the inheritance:

    r <- ... or ... <- r                 r <- ... or ... <- r
    ...                          s <- r (new insn -- save)
    ...                   =>
    ...                          r <- s (new insn -- restore)
    ... <- r                             ... <- r

 The *split pseudo* s is assigned to the hard register of the
 original pseudo or hard register r.

 Splitting is done:
   o In EBBs with high register pressure for global pseudos (living
     in at least 2 BBs) and assigned to hard registers when there
     are more one reloads needing the hard registers;
   o for pseudos needing save/restore code around calls.

 If the split pseudo still has the same hard register as the
 original pseudo after the subsequent assignment pass or the
 original pseudo was split, the opposite transformation is done on
 the same pass for undoing inheritance.   
Value of LRA_CURR_RELOAD_NUM at the beginning of BB of the current
insn.  Remember that LRA_CURR_RELOAD_NUM is the number of emitted
reload insns.   

Referenced by lra_constraints(), and process_alt_operands().

◆ best_losers

int best_losers
The following five variables are used to choose the best insn
alternative.     They reflect final characteristics of the best
Number of necessary reloads and overall cost reflecting the
previous value and other unpleasantness of the best alternative.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ best_overall

int best_overall

◆ best_reload_nregs

int best_reload_nregs
Overall number hard registers used for reloads.  For example, on
some targets we need 2 general registers to reload DFmode and only
one floating point register.      

Referenced by process_alt_operands().

◆ best_reload_sum

int best_reload_sum
Overall number reflecting distances of previous reloading the same
value.  The distances are counted from the current BB start.  It is
used to improve inheritance chances.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ calls_num

int calls_num
Number of calls passed so far in current EBB.   

Referenced by inherit_in_ebb(), need_for_call_save_p(), and setup_next_usage_insn().

◆ check_and_force_assignment_correctness_p

bool check_and_force_assignment_correctness_p
True if we should during assignment sub-pass check assignment
correctness for all pseudos and spill some of them to correct
conflicts.  It can be necessary when we substitute equiv which
needs checking register allocation correctness because the
equivalent value contains allocatable hard registers, or when we
restore multi-register pseudo, or when we change the insn code and
its operand became INOUT operand when it was IN one before.   

Referenced by inherit_in_ebb(), lra_assign(), lra_constraints(), process_insn_for_elimination(), setup_live_pseudos_and_spill_after_risky_transforms(), and split_reg().

◆ check_only_regs

bitmap_head check_only_regs
Registers involved in inheritance/split in the current EBB
(inheritance/split pseudos and original registers).      

Referenced by inherit_in_ebb(), inherit_reload_reg(), lra_inheritance(), process_invariant_for_inheritance(), split_reg(), and update_ebb_live_info().

◆ curr_bb

basic_block curr_bb

◆ curr_id

◆ curr_insn

◆ curr_insn_input_reloads

struct input_reload curr_insn_input_reloads[LRA_MAX_INSN_RELOADS]
Array containing info about input reloads.  It is used to find the
same input reload and reuse the reload pseudo in this case.      

Referenced by get_reload_reg(), and match_reload().

◆ curr_insn_input_reloads_num

int curr_insn_input_reloads_num
The number of elements in the following array.   

Referenced by get_reload_reg(), init_curr_insn_input_reloads(), and match_reload().

◆ curr_insn_set

◆ curr_operand_mode

◆ curr_small_class_check

unsigned int curr_small_class_check = 0
Used to check validity info about small class input operands.  It
should be incremented at start of processing an insn

Referenced by process_alt_operands(), and update_and_check_small_class_inputs().

◆ curr_static_id

◆ curr_swapped

int curr_swapped
True if we swapped the commutative operands in the current

Referenced by curr_insn_transform(), ira_setup_alts(), and process_alt_operands().

◆ curr_usage_insns_check

int curr_usage_insns_check
Current reload pseudo check for validity of elements in

Referenced by add_next_usage_insn(), inherit_in_ebb(), lra_inheritance(), setup_next_usage_insn(), and split_if_necessary().

◆ ebb_global_regs

bitmap_head ebb_global_regs
Global registers occurring in the current EBB.   

Referenced by lra_inheritance(), and need_for_split_p().

◆ equiv_substition_p

bool equiv_substition_p[MAX_RECOG_OPERANDS]
True if the corresponding operand is the result of an equivalence

Referenced by curr_insn_transform(), process_alt_operands(), and swap_operands().

◆ full_and_partial_call_clobbers

HARD_REG_SET full_and_partial_call_clobbers
Which registers have been fully or partially clobbered by a call
since they were last used.   

Referenced by inherit_in_ebb(), need_for_call_save_p(), need_for_split_p(), and setup_next_usage_insn().

◆ goal_alt

enum reg_class goal_alt[MAX_RECOG_OPERANDS]
The following data describe the result of process_alt_operands.
The data are used in curr_insn_transform to generate reloads.   
The chosen reg classes which should be used for the corresponding

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_dont_inherit_ops

int goal_alt_dont_inherit_ops[MAX_RECOG_OPERANDS]
Numbers of operands whose reload pseudos should not be inherited.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_dont_inherit_ops_num

int goal_alt_dont_inherit_ops_num
The number of elements in the following array.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_exclude_start_hard_regs

HARD_REG_SET goal_alt_exclude_start_hard_regs[MAX_RECOG_OPERANDS]
Hard registers which cannot be a start hard register for the corresponding

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_match_win

bool goal_alt_match_win[MAX_RECOG_OPERANDS]
True if the operand should be the same as another operand and that
other operand does not need a reload.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_matches

int goal_alt_matches[MAX_RECOG_OPERANDS]
The number of an operand to which given operand can be matched to.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_number

int goal_alt_number
The chosen insn alternative.    

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_offmemok

bool goal_alt_offmemok[MAX_RECOG_OPERANDS]
True if the operand can be offsetable memory.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_out_sp_reload_p

bool goal_alt_out_sp_reload_p
True if output reload of the stack pointer should be generated.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_swapped

bool goal_alt_swapped
True if the insn commutative operands should be swapped.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_alt_win

bool goal_alt_win[MAX_RECOG_OPERANDS]
True if the operand does not need a reload.    

Referenced by curr_insn_transform(), and process_alt_operands().

◆ goal_reuse_alt_p

bool goal_reuse_alt_p
True if we should try only this alternative for the next constraint sub-pass
to speed up the sub-pass.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ invalid_invariant_regs

bitmap_head invalid_invariant_regs
Reload pseudos cannot be involded in invariant inheritance in the
current EBB.   

Referenced by inherit_in_ebb(), invariant_p(), and lra_inheritance().

◆ invariant_table

htab_t invariant_table
Hash table for the invariants.   

◆ invariants

vec<invariant_ptr_t> invariants
Pointer to the inheritance invariants.   

◆ invariants_pool

object_allocator<lra_invariant>* invariants_pool
Allocation pool for the invariants.   

Referenced by clear_invariants(), finish_invariants(), initiate_invariants(), and insert_invariant().

◆ last_call_for_abi

int last_call_for_abi[NUM_ABI_IDS]
Index ID is the CALLS_NUM associated the last call we saw with
ABI identifier ID.   

Referenced by inherit_in_ebb(), and need_for_call_save_p().

◆ live_regs

bitmap_head live_regs
Check only registers living at the current program point in the
current EBB.      

Referenced by lra_inheritance(), and update_ebb_live_info().

◆ lra_constraint_iter

int lra_constraint_iter
The current iteration number of this LRA pass.   

Referenced by lra(), lra_constraints(), and process_alt_operands().

◆ lra_inheritance_iter

int lra_inheritance_iter
Current number of inheritance/split iteration.   

Referenced by improve_inheritance(), lra(), and lra_inheritance().

◆ lra_undo_inheritance_iter

int lra_undo_inheritance_iter
This page contains code to undo failed inheritance/split
Current number of iteration undoing inheritance/split.   

Referenced by curr_insn_transform(), lra(), and lra_undo_inheritance().

◆ max_small_class_regs_num

const int max_small_class_regs_num = 2
We split for reloads of small class of hard regs.  The following
defines how many hard regs the class should have to be qualified as
small.  The code is mostly oriented to x86/x86-64 architecture
where some insns need to use only specific register or pair of
registers and these register can live in RTL explicitly, e.g. for
parameter passing.   

Referenced by inherit_in_ebb().

◆ new_insn_uid_start

◆ new_regno_start

int new_regno_start
Start numbers for new registers and insns at the current constraints
pass start.      

Referenced by curr_insn_transform(), get_reg_class(), get_reload_reg(), in_class_p(), lra_constrain_insn(), lra_constraints(), narrow_reload_pseudo_class(), and undo_optional_reloads().

◆ no_input_reloads_p

bool no_input_reloads_p
True if the current insn should have no correspondingly input or
output reloads.   

Referenced by curr_insn_transform(), and process_alt_operands().

◆ no_output_reloads_p

bool no_output_reloads_p

◆ original_subreg_reg_mode

machine_mode original_subreg_reg_mode[MAX_RECOG_OPERANDS]
Mode of the register substituted by its equivalence with VOIDmode
(e.g. constant) and whose subreg is given operand of the current
insn.  VOIDmode in all other cases.   

Referenced by curr_insn_transform(), simplify_operand_subreg(), and swap_operands().

◆ reloads_num

int reloads_num
This page contains code to do inheritance/split
Number of reloads passed so far in current EBB.   

Referenced by add_next_usage_insn(), inherit_in_ebb(), inherit_reload_reg(), need_for_split_p(), and setup_next_usage_insn().

◆ temp_bitmap

bitmap_head temp_bitmap
Used as a temporary results of some bitmap calculations.   

Referenced by compute_earliest(), compute_farthest(), inherit_in_ebb(), and lra_inheritance().

◆ to_inherit

struct to_inherit to_inherit[LRA_MAX_INSN_RELOADS]
Array containing all info for doing inheritance from the current

◆ to_inherit_num

int to_inherit_num
Number elements in the previous array.   

Referenced by add_to_inherit(), and inherit_in_ebb().

◆ usage_insns

struct usage_insns* usage_insns
Map: regno -> corresponding pseudo usage insns.