GCC Middle and Back End API Reference
reload.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 "ira.h"
#include "recog.h"
#include "rtl-error.h"
#include "reload.h"
#include "addresses.h"
#include "function-abi.h"
Include dependency graph for reload.cc:

Data Structures

struct  replacement
 
struct  decomposition
 

Macros

#define REG_OK_STRICT
 
#define CONST_POOL_OK_P(MODE, X)
 
#define MATCHES(x, y)
 
#define MERGABLE_RELOADS(when1, when2, op1, op2)
 
#define MERGE_TO_OTHER(when1, when2, op1, op2)
 
#define ADDR_TYPE(type)
 
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX)
 

Functions

static bool small_register_class_p (reg_class_t rclass)
 
static int push_secondary_reload (int, rtx, int, int, enum reg_class, machine_mode, enum reload_type, enum insn_code *, secondary_reload_info *)
 
static enum reg_class find_valid_class (machine_mode, machine_mode, int, unsigned int)
 
static void push_replacement (rtx *, int, machine_mode)
 
static void dup_replacements (rtx *, rtx *)
 
static void combine_reloads (void)
 
static int find_reusable_reload (rtx *, rtx, enum reg_class, enum reload_type, int, int)
 
static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, machine_mode, machine_mode, reg_class_t, int, int)
 
static int hard_reg_set_here_p (unsigned int, unsigned int, rtx)
 
static struct decomposition decompose (rtx)
 
static int immune_p (rtx, rtx, struct decomposition)
 
static bool alternative_allows_const_pool_ref (rtx, const char *, int)
 
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx_insn *, int *)
 
static rtx make_memloc (rtx, int)
 
static bool maybe_memory_address_addr_space_p (machine_mode, rtx, addr_space_t, rtx *)
 
static int find_reloads_address (machine_mode, rtx *, rtx, rtx *, int, enum reload_type, int, rtx_insn *)
 
static rtx subst_reg_equivs (rtx, rtx_insn *)
 
static rtx subst_indexed_address (rtx)
 
static void update_auto_inc_notes (rtx_insn *, int, int)
 
static int find_reloads_address_1 (machine_mode, addr_space_t, rtx, int, enum rtx_code, enum rtx_code, rtx *, int, enum reload_type, int, rtx_insn *)
 
static void find_reloads_address_part (rtx, rtx *, enum reg_class, machine_mode, int, enum reload_type, int)
 
static rtx find_reloads_subreg_address (rtx, int, enum reload_type, int, rtx_insn *, int *)
 
static void copy_replacements_1 (rtx *, rtx *, int)
 
static poly_int64 find_inc_amount (rtx, rtx)
 
static int refers_to_mem_for_reload_p (rtx)
 
static int refers_to_regno_for_reload_p (unsigned int, unsigned int, rtx, rtx *)
 
static void push_reg_equiv_alt_mem (int regno, rtx mem)
 
reg_class_t secondary_reload_class (bool in_p, reg_class_t rclass, machine_mode mode, rtx x)
 
enum reg_class scratch_reload_class (enum insn_code icode)
 
rtx get_secondary_mem (rtx x, machine_mode mode, int opnum, enum reload_type type)
 
void clear_secondary_mem (void)
 
static enum reg_class find_valid_class_1 (machine_mode outer, machine_mode mode, enum reg_class dest_class)
 
static bool complex_word_subreg_p (machine_mode outer_mode, rtx reg)
 
static bool reload_inner_reg_of_subreg (rtx x, machine_mode mode, bool output)
 
static int can_reload_into (rtx in, int regno, machine_mode mode)
 
int push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, enum reg_class rclass, machine_mode inmode, machine_mode outmode, int strict_low, int optional, int opnum, enum reload_type type)
 
void transfer_replacements (int to, int from)
 
int remove_address_replacements (rtx in_rtx)
 
int earlyclobber_operand_p (rtx x)
 
bool strict_memory_address_addr_space_p (machine_mode mode, rtx addr, addr_space_t as, code_helper)
 
int operands_match_p (rtx x, rtx y)
 
int safe_from_earlyclobber (rtx op, rtx clobber)
 
int find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known, short *reload_reg_p)
 
rtx form_sum (machine_mode mode, rtx x, rtx y)
 
void subst_reloads (rtx_insn *insn)
 
void copy_replacements (rtx x, rtx y)
 
void move_replacements (rtx *x, rtx *y)
 
rtx find_replacement (rtx *loc)
 
int reg_overlap_mentioned_for_reload_p (rtx x, rtx in)
 
rtx find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other, short *reload_reg_p, int goalreg, machine_mode mode)
 
static int reg_inc_found_and_valid_p (unsigned int regno, unsigned int endregno, rtx insn)
 
int regno_clobbered_p (unsigned int regno, rtx_insn *insn, machine_mode mode, int sets)
 
rtx reload_adjust_reg_for_mode (rtx reloadreg, machine_mode mode)
 
DEBUG_FUNCTION void debug_reload_to_stream (FILE *f)
 
DEBUG_FUNCTION void debug_reload (void)
 

Variables

int n_reloads
 
struct reload rld [MAX_RELOADS]
 
int n_earlyclobbers
 
rtx reload_earlyclobbers [MAX_RECOG_OPERANDS]
 
int reload_n_operands
 
static int replace_reloads
 
static struct replacement replacements [MAX_RECOG_OPERANDS *((MAX_REGS_PER_ADDRESS *2)+1)]
 
static int n_replacements
 
static rtx secondary_memlocs [NUM_MACHINE_MODES]
 
static rtx secondary_memlocs_elim [NUM_MACHINE_MODES][MAX_RECOG_OPERANDS]
 
static int secondary_memlocs_elim_used = 0
 
static rtx_insnthis_insn
 
static int this_insn_is_asm
 
static int hard_regs_live_known
 
static shortstatic_reload_reg_p
 
static int subst_reg_equivs_changed
 
static int output_reloadnum
 
static const char *const reload_when_needed_name []
 

Macro Definition Documentation

◆ ADDR_TYPE

#define ADDR_TYPE ( type)
Value:
: (type)))
static type_p type(options_p *optsp, bool nested)
Definition gengtype-parse.cc:883
@ RELOAD_FOR_INPADDR_ADDRESS
Definition reload.h:67
@ RELOAD_FOR_OUTADDR_ADDRESS
Definition reload.h:68
@ RELOAD_FOR_OUTPUT_ADDRESS
Definition reload.h:68
@ RELOAD_FOR_INPUT_ADDRESS
Definition reload.h:67
Definition gengtype.h:252

Referenced by find_reloads_address(), and find_reloads_address_1().

◆ CONST_POOL_OK_P

#define CONST_POOL_OK_P ( MODE,
X )
Value:
((MODE) != VOIDmode \
&& CONSTANT_P (X) \
&& GET_CODE (X) != HIGH \
&& !targetm.cannot_force_const_mem (MODE, X))
T * ggc_alloc(ALONE_CXX_MEM_STAT_INFO)
Definition ggc.h:184
#define CONSTANT_P(X)
Definition rtl.h:1066
#define GET_CODE(RTX)
Definition rtl.h:725
struct gcc_target targetm
We do not enable this with CHECKING_P, since it is awfully slow.   
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 find_reloads().

◆ MATCHES

#define MATCHES ( x,
y )
Value:
(x == y || (x != 0 && (REG_P (x) \
? REG_P (y) && REGNO (x) == REGNO (y) \
: rtx_equal_p (x, y) && ! side_effects_p (x))))
bool rtx_equal_p(const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
Definition rtl.cc:422
#define REGNO(RTX)
Definition rtl.h:1914
bool side_effects_p(const_rtx)
Definition rtlanal.cc:3037
#define REG_P(X)
Definition rtl.h:746
const T2 & y
Definition wide-int.h:3870

Referenced by combine_reloads(), find_reloads(), and find_reusable_reload().

◆ MERGABLE_RELOADS

#define MERGABLE_RELOADS ( when1,
when2,
op1,
op2 )
Value:
|| ((when1) == (when2) && (op1) == (op2)) \
@ RELOAD_OTHER
Definition reload.h:70
@ RELOAD_FOR_OPERAND_ADDRESS
Definition reload.h:69
@ RELOAD_FOR_INPUT
Definition reload.h:66
@ RELOAD_FOR_OTHER_ADDRESS
Definition reload.h:70

Referenced by find_reusable_reload(), and push_secondary_reload().

◆ MERGE_TO_OTHER

#define MERGE_TO_OTHER ( when1,
when2,
op1,
op2 )
Value:
((when1) != (when2) \
|| ! ((op1) == (op2) \

Referenced by push_reload(), and push_secondary_reload().

◆ REG_OK_FOR_CONTEXT

#define REG_OK_FOR_CONTEXT ( CONTEXT,
REGNO,
MODE,
AS,
OUTER,
INDEX )
Value:
((CONTEXT) == 0 \
bool regno_ok_for_base_p(unsigned regno, machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code, rtx_insn *insn=NULL)
Definition addresses.h:101

◆ REG_OK_STRICT

#define REG_OK_STRICT
Search an insn for pseudo regs that must be in hard regs and are not.
   Copyright (C) 1987-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
This file contains subroutines used only from the file reload1.cc.
   It knows how to scan one insn for operands and values
   that need to be copied into registers to make valid code.
   It also finds other operands and values which are valid
   but for which equivalent values in registers exist and
   ought to be used instead.

   Before processing the first insn of the function, call `init_reload'.
   init_reload actually has to be called earlier anyway.

   To scan an insn, call `find_reloads'.  This does two things:
   1. sets up tables describing which values must be reloaded
   for this insn, and what kind of hard regs they must be reloaded into;
   2. optionally record the locations where those values appear in
   the data, so they can be replaced properly later.
   This is done only if the second arg to `find_reloads' is nonzero.

   The third arg to `find_reloads' specifies the number of levels
   of indirect addressing supported by the machine.  If it is zero,
   indirect addressing is not valid.  If it is one, (MEM (REG n))
   is valid even if (REG n) did not get a hard register; if it is two,
   (MEM (MEM (REG n))) is also valid even if (REG n) did not get a
   hard register, and similarly for higher values.

   Then you must choose the hard regs to reload those pseudo regs into,
   and generate appropriate load insns before this insn and perhaps
   also store insns after this insn.  Set up the array `reload_reg_rtx'
   to contain the REG rtx's for the registers you used.  In some
   cases `find_reloads' will return a nonzero value in `reload_reg_rtx'
   for certain reloads.  Then that tells you which register to use,
   so you do not need to allocate one.  But you still do need to add extra
   instructions to copy the value into and out of that register.

   Finally you must call `subst_reloads' to substitute the reload reg rtx's
   into the locations already recorded.

NOTE SIDE EFFECTS:

   find_reloads can alter the operands of the instruction it is called on.

   1. Two operands of any sort may be interchanged, if they are in a
   commutative instruction.
   This happens only if find_reloads thinks the instruction will compile
   better that way.

   2. Pseudo-registers that are equivalent to constants are replaced
   with those constants if they are not in hard registers.

1 happens every time find_reloads is called.
2 happens only when REPLACE is 1, which is only when
actually doing the reloads, not when just counting them.

Using a reload register for several reloads in one insn:

When an insn has reloads, it is considered as having three parts:
the input reloads, the insn itself after reloading, and the output reloads.
Reloads of values used in memory addresses are often needed for only one part.

When this is so, reload_when_needed records which part needs the reload.
Two reloads for different parts of the insn can share the same reload
register.

When a reload is used for addresses in multiple parts, or when it is
an ordinary operand, it is classified as RELOAD_OTHER, and cannot share
a register with any other reload.   

Function Documentation

◆ alternative_allows_const_pool_ref()

static bool alternative_allows_const_pool_ref ( rtx mem,
const char * constraint,
int altnum )
static
Return true if alternative number ALTNUM in constraint-string
CONSTRAINT is guaranteed to accept a reloaded constant-pool reference.
MEM gives the reference if its address hasn't been fully reloaded,
otherwise it is NULL.   

References ggc_alloc(), and NULL.

Referenced by find_reloads().

◆ can_reload_into()

static int can_reload_into ( rtx in,
int regno,
machine_mode mode )
static
Return nonzero if IN can be reloaded into REGNO with mode MODE without
requiring an extra reload register.  The caller has already found that
IN contains some reference to REGNO, so check that we can produce the
new value in a single step.  E.g. if we have
(set (reg r13) (plus (reg r13) (const int 1))), and there is an
instruction that adds one to a register, this should succeed.
However, if we have something like
(set (reg r13) (plus (reg r13) (const int 999))), and the constant 999
needs to be loaded into a register first, we need a separate reload
register.
Such PLUS reloads are generated by find_reload_address_part.
The out-of-range PLUS expressions are usually introduced in the instruction
patterns by register elimination and substituting pseudos without a home
by their function-invariant equivalences.   

References constrain_operands(), extract_insn(), gen_rtx_REG(), get_enabled_alternatives(), ggc_alloc(), make_insn_raw(), MEM_P, r, recog_data, recog_memoized(), REG_P, and test_insn.

Referenced by push_reload().

◆ clear_secondary_mem()

void clear_secondary_mem ( void )
Clear any secondary memory locations we've made.   

References ggc_alloc(), and secondary_memlocs.

Referenced by reload().

◆ combine_reloads()

static void combine_reloads ( void )
static
If there is only one output reload, and it is not for an earlyclobber
operand, try to combine it with a (logically unrelated) input reload
to reduce the number of reload registers needed.

This is safe if the input reload does not appear in
the value being output-reloaded, because this implies
it is not needed any more once the original insn completes.

If that doesn't work, see we can use any of the registers that
die in this insn as a reload register.  We can if it is of the right
class and does not appear in the value being output-reloaded.   

References bitmap_bit_p, cfun, insn_operand_data::constraint, DF_LR_OUT, earlyclobber_operand_p(), ENTRY_BLOCK_PTR_FOR_FN, fixed_regs, gen_rtx_REG(), ggc_alloc(), hard_regno_nregs(), i, INSN_CODE, insn_data, ira_reg_class_max_nregs, known_eq, MATCHES, insn_data_d::n_operands, n_reloads, n_replacements, insn_data_d::operand, ORIGINAL_REGNO, reg_class_contents, reg_class_size, reg_class_subset_p(), REG_NOTE_KIND, REG_NOTES, REG_NREGS, reg_overlap_mentioned_for_reload_p(), REG_P, REGNO, RELOAD_FOR_INPUT, RELOAD_FOR_OUTADDR_ADDRESS, RELOAD_FOR_OUTPUT, RELOAD_FOR_OUTPUT_ADDRESS, reload_inner_reg_of_subreg(), RELOAD_OTHER, replacements, rld, rtx_equal_p(), secondary_memlocs_elim, targetm, TEST_HARD_REG_BIT, this_insn, replacement::what, and XEXP.

Referenced by find_reloads().

◆ complex_word_subreg_p()

static bool complex_word_subreg_p ( machine_mode outer_mode,
rtx reg )
static
Return true if:

(a) (subreg:OUTER_MODE REG ...) represents a word or subword subreg
    of a multiword value; and

(b) the number of *words* in REG does not match the number of *registers*
    in REG.   

References GET_MODE, GET_MODE_SIZE(), ggc_alloc(), known_le, maybe_gt, and REG_NREGS.

Referenced by push_reload(), and reload_inner_reg_of_subreg().

◆ copy_replacements()

void copy_replacements ( rtx x,
rtx y )
Make a copy of any replacements being done into X and move those
copies to locations in Y, a copy of X.   

References copy_replacements_1(), n_replacements, and y.

Referenced by emit_move_change_mode(), and find_reloads_address().

◆ copy_replacements_1()

◆ debug_reload()

DEBUG_FUNCTION void debug_reload ( void )

◆ debug_reload_to_stream()

DEBUG_FUNCTION void debug_reload_to_stream ( FILE * f)
These functions are used to print the variables set by 'find_reloads'  

References GET_MODE_NAME, ggc_alloc(), insn_data, n_reloads, print_dec(), print_inline_rtx(), r, reg_class_names, reload_when_needed_name, rld, and SIGNED.

Referenced by debug_reload(), emit_reload_insns(), and spill_failure().

◆ decompose()

static struct decomposition decompose ( rtx x)
static
Describe the range of registers or memory referenced by X.
If X is a register, set REG_FLAG and put the first register
number into START and the last plus one into END.
If X is a memory reference, put a base address into BASE
and a range of integer offsets into START and END.
If X is pushing on the stack, we can assume it causes no trouble,
so we set the SAFE field.   

References decomposition::base, const0_rtx, CONST_INT_P, CONSTANT_P, decompose(), decomposition::end, end_hard_regno(), gcc_assert, GET_CODE, GET_MODE, GET_MODE_SIZE(), ggc_alloc(), INTVAL, NULL_RTX, offset, decomposition::reg_flag, REG_P, REGNO, decomposition::safe, decomposition::start, subreg_nregs(), SUBREG_REG, true_regnum(), and XEXP.

Referenced by decompose(), find_reloads(), immune_p(), and safe_from_earlyclobber().

◆ dup_replacements()

static void dup_replacements ( rtx * dup_loc,
rtx * orig_loc )
static
Duplicate any replacement we have recorded to apply at
location ORIG_LOC to also be performed at DUP_LOC.
This is used in insn patterns that use match_dup.   

References ggc_alloc(), i, rtx_def::mode, n_replacements, push_replacement(), r, and replacements.

Referenced by find_reloads().

◆ earlyclobber_operand_p()

int earlyclobber_operand_p ( rtx x)
This page contains subroutines used mainly for determining
whether the IN or an OUT of a reload can serve as the
reload register.   
Return 1 if X is an operand of an insn that is being earlyclobbered.   

References i, n_earlyclobbers, and reload_earlyclobbers.

Referenced by combine_reloads(), find_reusable_reload(), push_reload(), refers_to_regno_for_reload_p(), and reload_reg_free_for_value_p().

◆ find_dummy_reload()

static rtx find_dummy_reload ( rtx real_in,
rtx real_out,
rtx * inloc,
rtx * outloc,
machine_mode inmode,
machine_mode outmode,
reg_class_t rclass,
int for_real,
int earlyclobber )
static
Try to find a reload register for an in-out reload (expressions IN and OUT).
See if one of IN and OUT is a register that may be used;
this is desirable since a spill-register won't be needed.
If so, return the register rtx that proves acceptable.

INLOC and OUTLOC are locations where IN and OUT appear in the insn.
RCLASS is the register class required for the reload.

If FOR_REAL is >= 0, it is the number of the reload,
and in some cases when it can be discovered that OUT doesn't need
to be computed, clear out rld[FOR_REAL].out.

If FOR_REAL is -1, this should not be done, because this call
is just to see if a register can be found, not to find and install it.

EARLYCLOBBER is nonzero if OUT is an earlyclobber operand.  This
puts an additional constraint on being able to use IN for OUT since
IN must not appear elsewhere in the insn (it is assumed that IN itself
is safe from the earlyclobber).   

References bitmap_bit_p, cfun, const0_rtx, DF_LR_OUT, ENTRY_BLOCK_PTR_FOR_FN, find_reg_note(), fixed_regs, gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_SIZE(), ggc_alloc(), hard_reg_set_here_p(), hard_regno_nregs(), hard_regs_live_known, i, maybe_gt, ORIGINAL_REGNO, PATTERN(), refers_to_regno_for_reload_p(), reg_class_contents, REG_NREGS, REG_P, REGNO, rld, SUBREG_BYTE, SUBREG_REG, subreg_regno_offset(), targetm, TEST_HARD_REG_BIT, and this_insn.

Referenced by find_reloads(), and push_reload().

◆ find_equiv_reg()

rtx find_equiv_reg ( rtx goal,
rtx_insn * insn,
enum reg_class rclass,
int other,
short * reload_reg_p,
int goalreg,
machine_mode mode )
Check the insns before INSN to see if there is a suitable register
containing the same value as GOAL.
If OTHER is -1, look for a register in class RCLASS.
Otherwise, just see if register number OTHER shares GOAL's value.

Return an rtx for the register found, or zero if none is found.

If RELOAD_REG_P is (short *)1,
we reject any hard reg that appears in reload_reg_rtx
because such a hard reg is also needed coming into this insn.

If RELOAD_REG_P is any other nonzero value,
it is a vector indexed by hard reg number
and we reject any hard reg whose element in the vector is nonnegative
as well as any that appears in reload_reg_rtx.

If GOAL is zero, then GOALREG is a register number; we look
for an equivalent for that register.

MODE is the machine mode of the value we want an equivalence for.
If GOAL is nonzero and not VOIDmode, then it must have mode MODE.

This function is used by jump.cc as well as in the reload pass.

If GOAL is the sum of the stack pointer and a constant, we treat it
as if it were a constant except that sp is required to be unchanging.   

References CALL_INSN_FUNCTION_USAGE, CALL_P, COND_EXEC_CODE, CONST_DOUBLE_AS_FLOAT_P, CONST_INT_P, CONSTANT_ADDRESS_P, CONSTANT_P, DEBUG_INSN_P, end_hard_regno(), END_REGNO(), find_reg_note(), frame_pointer_rtx, GET_CODE, GET_MODE, ggc_alloc(), hard_regno_nregs(), HOST_WIDE_INT_1, i, in_hard_reg_set_p(), insn_callee_abi(), INSN_P, INSN_UID(), LABEL_P, MEM_P, MEM_VOLATILE_P, replacement::mode, n_reloads, NONJUMP_INSN_P, NULL_RTX, operand_subword(), PATTERN(), PREV_INSN(), push_operand(), refers_to_regno_for_reload_p(), reg_class_contents, reg_equiv_memory_loc, REG_NOTE_KIND, REG_NOTES, reg_overlap_mentioned_for_reload_p(), REG_P, REGNO, reload_first_uid, rld, rtx_equal_p(), rtx_renumbered_equal_p(), SCALAR_FLOAT_MODE_P, SET, SET_DEST, SET_SRC, single_set(), stack_pointer_rtx, true_regnum(), volatile_insn_p(), replacement::where, XEXP, XVECEXP, and XVECLEN.

Referenced by choose_reload_regs(), find_reloads(), and push_reload().

◆ find_inc_amount()

static poly_int64 find_inc_amount ( rtx x,
rtx inced )
static
Find a place where INCED appears in an increment or decrement operator
within X, and return the amount INCED is incremented or decremented by.
The value is always positive.   

References CONST_INT_P, find_inc_amount(), GET_CODE, GET_MODE, GET_MODE_SIZE(), GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, INTVAL, XEXP, XVECEXP, and XVECLEN.

Referenced by find_inc_amount(), and find_reloads_address_1().

◆ find_reloads()

int find_reloads ( rtx_insn * insn,
int replace,
int ind_levels,
int live_known,
short * reload_reg_p )
Main entry point of this file: search the body of INSN
for values that need reloading and record them with push_reload.
REPLACE nonzero means record also where the values occur
so that subst_reloads can be used.

IND_LEVELS says how many levels of indirection are supported by this
machine; a value of zero means that a memory reference is not a valid
memory address.

LIVE_KNOWN says we have valid information about which hard
regs are live at each point in the program; this is true when
we are called from global_alloc but false when stupid register
allocation has been done.

RELOAD_REG_P if nonzero is a vector indexed by hard reg number
which is nonnegative if the reg has been commandeered for reloading into.
It is copied into STATIC_RELOAD_REG_P and referenced from there
by various subroutines.

Return TRUE if some operands need to be changed, because of swapping
commutative operands, reg_equiv_address substitution, or whatever.   

References add_reg_note(), ADDR_SPACE_GENERIC, alternative_allows_const_pool_ref(), base_reg_class(), CALL_P, class_only_fixed_regs, combine_reloads(), const0_rtx, CONST_INT_P, CONST_POOL_OK_P, CONSTANT_P, recog_data_d::constraints, constraints, decompose(), recog_data_d::dup_loc, recog_data_d::dup_num, dup_replacements(), elimination_target_reg_p(), emit_insn_after(), emit_insn_before(), end(), error_for_asm(), extract_insn(), fatal_insn, find_dummy_reload(), find_equiv_reg(), find_reg_note(), find_reloads(), find_reloads_address(), find_reloads_toplev(), force_const_mem(), gcc_assert, gen_clobber(), gen_rtx_SUBREG(), get_address_mode(), GET_CODE, get_enabled_alternatives(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_SIZE(), GET_RTX_CLASS, ggc_alloc(), hard_regno_nregs(), hard_regs_live_known, i, immune_p(), INSN_CODE, insn_data, INTVAL, ira_nullify_asm_goto(), ira_reg_class_max_nregs, recog_data_d::is_operator, JUMP_P, known_ge, known_le, label_is_jump_target_p(), LABEL_NUSES, LABEL_P, label_ref_label(), LEGITIMATE_PIC_OPERAND_P, LOAD_EXTEND_OP, MATCHES, MEM_ADDR_SPACE, MEM_P, MIN, mode_dependent_address_p(), n_alternatives(), recog_data_d::n_alternatives, recog_data_d::n_dups, n_earlyclobbers, recog_data_d::n_operands, n_reloads, n_replacements, nr, NULL, NULL_RTX, num_not_at_initial_offset, OBJECT_P, offset, offsettable_memref_p(), offsettable_nonstrict_memref_p(), OP_IN, recog_data_d::operand, insn_data_d::operand, recog_data_d::operand_loc, recog_data_d::operand_mode, recog_data_d::operand_type, operands_match_p(), output_reloadnum, paradoxical_subreg_p(), partial_subreg_p(), PATTERN(), push_reload(), PUT_MODE(), recog_data, reg_alternate_class(), reg_class_contents, reg_class_size, reg_class_subset_p(), reg_class_subunion, reg_equiv_address, reg_equiv_constant, reg_equiv_mem, reg_equiv_memory_loc, reg_fits_class_p(), reg_mentioned_p(), REG_P, reg_preferred_class(), reg_renumber, register_move_cost(), REGNO, reject(), reload_earlyclobbers, RELOAD_FOR_INPADDR_ADDRESS, RELOAD_FOR_INPUT, RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_INSN, RELOAD_FOR_OPADDR_ADDR, RELOAD_FOR_OPERAND_ADDRESS, RELOAD_FOR_OTHER_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS, RELOAD_FOR_OUTPUT, RELOAD_FOR_OUTPUT_ADDRESS, reload_n_operands, RELOAD_OTHER, replace_reloads, replacements, rld, RTX_CODE, rtx_equal_p(), RTX_UNARY, secondary_memlocs_elim, secondary_memlocs_elim_used, SET, SET_DEST, SET_SRC, set_unique_reg_note(), simplify_subreg_regno(), single_set(), skip_alternative(), small_register_class_p(), static_reload_reg_p, insn_operand_data::strict_low, SUBREG_BYTE, SUBREG_REG, subreg_regno_offset(), TARGET_MEM_CONSTRAINT, targetm, TEST_BIT, TEST_HARD_REG_BIT, this_insn, this_insn_is_asm, transfer_replacements(), type(), replacement::what, WORD_REGISTER_OPERATIONS, and XEXP.

Referenced by calculate_needs_all_insns(), find_reloads(), and reload_as_needed().

◆ find_reloads_address()

static int find_reloads_address ( machine_mode mode,
rtx * memrefloc,
rtx ad,
rtx * loc,
int opnum,
enum reload_type type,
int ind_levels,
rtx_insn * insn )
static
Record all reloads needed for handling memory address AD
which appears in *LOC in a memory reference to mode MODE
which itself is found in location  *MEMREFLOC.
Note that we take shortcuts assuming that no multi-reg machine mode
occurs as part of an address.

OPNUM and TYPE specify the purpose of this reload.

IND_LEVELS says how many levels of indirect addressing this machine
supports.

INSN, if nonzero, is the insn in which we do the reload.  It is used
to determine if we may generate output reloads, and where to put USEs
for pseudos that we have to replace with stack slots.

Value is one if this address is reloaded or replaced as a whole; it is
zero if the top level of this address was not reloaded or replaced, and
it is -1 if it may or may not have been reloaded or replaced.

Note that there is no verification that the address will be valid after
this routine does its work.  Instead, we rely on the fact that the address
was valid when reload started.  So we need only undo things that reload
could have broken.  These are wrong register types, pseudos not allocated
to a hard register, and frame pointer elimination.   

References ADDR_SPACE_GENERIC, ADDR_SPACE_GENERIC_P, ADDR_TYPE, arg_pointer_rtx, base_reg_class(), CONST_INT_P, CONSTANT_P, CONSTANT_POOL_ADDRESS_P, copy_replacements(), copy_rtx(), double_reg_address_ok, emit_insn_before(), find_reloads_address(), find_reloads_address_1(), find_reloads_address_part(), frame_pointer_rtx, GET_CODE, GET_MODE, ggc_alloc(), HARD_FRAME_POINTER_IS_FRAME_POINTER, hard_frame_pointer_rtx, index_reg_class(), indirect_symref_ok, INTVAL, make_memloc(), maybe_memory_address_addr_space_p(), MEM_ADDR_SPACE, MEM_P, move_replacements(), NULL_RTX, num_not_at_initial_offset, plus_constant(), push_reg_equiv_alt_mem(), push_reload(), PUT_MODE(), reg_equiv_address, reg_equiv_constant, reg_equiv_mem, reg_equiv_memory_loc, REG_P, REGNO, regno_clobbered_p(), regno_ok_for_base_p(), replace_reloads, rtx_equal_p(), stack_pointer_rtx, strict_memory_address_addr_space_p(), subst_indexed_address(), subst_reg_equivs(), subst_reg_equivs_changed, targetm, this_insn, and XEXP.

Referenced by find_reloads(), find_reloads_address(), find_reloads_address_1(), find_reloads_address_part(), find_reloads_subreg_address(), find_reloads_toplev(), and get_secondary_mem().

◆ find_reloads_address_1()

static int find_reloads_address_1 ( machine_mode mode,
addr_space_t as,
rtx x,
int context,
enum rtx_code outer_code,
enum rtx_code index_code,
rtx * loc,
int opnum,
enum reload_type type,
int ind_levels,
rtx_insn * insn )
static
Record the pseudo registers we must reload into hard registers in a
subexpression of a would-be memory address, X referring to a value
in mode MODE.  (This function is not called if the address we find
is strictly valid.)

CONTEXT = 1 means we are considering regs as index regs,
= 0 means we are considering them as base regs.
OUTER_CODE is the code of the enclosing RTX, typically a MEM, a PLUS,
or an autoinc code.
If CONTEXT == 0 and OUTER_CODE is a PLUS or LO_SUM, then INDEX_CODE
is the code of the index part of the address.  Otherwise, pass SCRATCH
for this argument.
OPNUM and TYPE specify the purpose of any reloads made.

IND_LEVELS says how many levels of indirect addressing are
supported at this point in the address.

INSN, if nonzero, is the insn in which we do the reload.  It is used
to determine if we may generate output reloads.

We return nonzero if X, as a whole, is reloaded or replaced.   
Note that we take shortcuts assuming that no multi-reg machine mode
occurs as part of an address.
Also, this is not fully machine-customizable; it works for machines
such as VAXen and 68000's and 32000's, but other possible machines
could have addressing modes that this does not handle right.
If you add push_reload calls here, you need to make sure gen_reload
handles those cases gracefully.   

References ADDR_TYPE, base_reg_class(), find_inc_amount(), find_reloads_address(), find_reloads_address_1(), find_reloads_address_part(), find_reloads_subreg_address(), gcc_assert, gen_rtx_REG(), GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, index_reg_class(), insn_operand_matches(), ira_reg_class_max_nregs, make_memloc(), MEM_P, memory_operand(), NONJUMP_INSN_P, NULL, NULL_RTX, num_not_at_initial_offset, optab_handler(), PATTERN(), push_reg_equiv_alt_mem(), push_reload(), reg_class_size, reg_equiv_address, reg_equiv_constant, reg_equiv_mem, reg_equiv_memory_loc, REG_OK_FOR_CONTEXT, REG_P, reg_renumber, REGNO, regno_clobbered_p(), regno_ok_for_base_p(), RELOAD_OTHER, rld, RTX_CODE, rtx_equal_p(), SUBREG_BYTE, SUBREG_REG, subreg_regno(), subreg_regno_offset(), this_insn, update_auto_inc_notes(), word_mode, and XEXP.

Referenced by find_reloads_address(), and find_reloads_address_1().

◆ find_reloads_address_part()

static void find_reloads_address_part ( rtx x,
rtx * loc,
enum reg_class rclass,
machine_mode mode,
int opnum,
enum reload_type type,
int ind_levels )
static
X, which is found at *LOC, is a part of an address that needs to be
reloaded into a register of class RCLASS.  If X is a constant, or if
X is a PLUS that contains a constant, check that the constant is a
legitimate operand and that we are supposed to be able to load
it into the register.

If not, force the constant into memory and reload the MEM instead.

MODE is the mode to use, in case X is an integer constant.

OPNUM and TYPE describe the purpose of any reloads made.

IND_LEVELS says how many levels of indirect addressing this machine
supports.   

References CONSTANT_P, find_reloads_address(), force_const_mem(), GET_CODE, GET_MODE, ggc_alloc(), NULL_RTX, push_reload(), targetm, and XEXP.

Referenced by find_reloads_address(), and find_reloads_address_1().

◆ find_reloads_subreg_address()

static rtx find_reloads_subreg_address ( rtx x,
int opnum,
enum reload_type type,
int ind_levels,
rtx_insn * insn,
int * address_reloaded )
static
X, a subreg of a pseudo, is a part of an address that needs to be
reloaded, and the pseusdo is equivalent to a memory location.

Attempt to replace the whole subreg by a (possibly narrower or wider)
memory reference.  If this is possible, return this new memory
reference, and push all required address reloads.  Otherwise,
return NULL.

OPNUM and TYPE identify the purpose of the reload.

IND_LEVELS says how many levels of indirect addressing are
supported at this point in the address.

INSN, if nonzero, is the insn in which we do the reload.  It is used
to determine where to put USEs for pseudos that we have to replace with
stack slots.   

References base_reg_class(), emit_insn_before(), find_reloads_address(), gcc_assert, GET_MODE, GET_MODE_SIZE(), ggc_alloc(), known_eq, make_memloc(), MEM_ADDR_SPACE, MEM_P, NULL, NULL_RTX, offset, recog_data_d::operand, paradoxical_subreg_p(), partial_subreg_p(), push_reg_equiv_alt_mem(), push_reload(), PUT_MODE(), recog_data, reg_equiv_mem, reg_equiv_memory_loc, REGNO, replace_reloads, rtx_equal_p(), simplify_subreg(), strict_memory_address_addr_space_p(), SUBREG_BYTE, SUBREG_REG, WORD_REGISTER_OPERATIONS, and XEXP.

Referenced by find_reloads_address_1(), and find_reloads_toplev().

◆ find_reloads_toplev()

static rtx find_reloads_toplev ( rtx x,
int opnum,
enum reload_type type,
int ind_levels,
int is_set_dest,
rtx_insn * insn,
int * address_reloaded )
static
Scan X for memory references and scan the addresses for reloading.
Also checks for references to "constant" regs that we want to eliminate
and replaces them with the values they stand for.
We may alter X destructively if it contains a reference to such.
If X is just a constant reg, we return the equivalent value
instead of X.

IND_LEVELS says how many levels of indirect addressing this machine
supports.

OPNUM and TYPE identify the purpose of the reload.

IS_SET_DEST is true if X is the destination of a SET, which is not
appropriate to be replaced by a constant.

INSN, if nonzero, is the insn in which we do the reload.  It is used
to determine if we may generate output reloads, and where to put USEs
for pseudos that we have to replace with stack slots.

ADDRESS_RELOADED.  If nonzero, is a pointer to where we put the
result of find_reloads_address.   

References CONSTANT_P, emit_insn_before(), find_reloads_address(), find_reloads_subreg_address(), find_reloads_toplev(), force_const_mem(), gcc_assert, GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, make_memloc(), num_not_at_initial_offset, recog_data_d::operand, push_reg_equiv_alt_mem(), PUT_MODE(), recog_data, reg_equiv_address, reg_equiv_constant, reg_equiv_mem, reg_equiv_memory_loc, REG_P, reg_renumber, REGNO, replace_reloads, RTX_CODE, rtx_equal_p(), shallow_copy_rtx(), simplify_gen_subreg(), SUBREG_BYTE, SUBREG_REG, targetm, and XEXP.

Referenced by find_reloads(), and find_reloads_toplev().

◆ find_replacement()

rtx find_replacement ( rtx * loc)
If LOC was scheduled to be replaced by something, return the replacement.
Otherwise, return *LOC.   

References find_replacement(), GET_CODE, GET_MODE, ggc_alloc(), n_replacements, r, reload_adjust_reg_for_mode(), replacements, rld, simplify_gen_subreg(), SUBREG_BYTE, SUBREG_REG, XEXP, and y.

Referenced by emit_move_multi_word(), find_replacement(), gen_reload(), inc_for_reload(), and replaced_subreg().

◆ find_reusable_reload()

static int find_reusable_reload ( rtx * p_in,
rtx out,
enum reg_class rclass,
enum reload_type type,
int opnum,
int dont_share )
static
Return the number of a previously made reload that can be combined with
a new one, or n_reloads if none of the existing reloads can be used.
OUT, RCLASS, TYPE and OPNUM are the same arguments as passed to
push_reload, they determine the kind of the new reload that we try to
combine.  P_IN points to the corresponding value of IN, which can be
modified by this function.
DONT_SHARE is nonzero if we can't share any input-only reload for IN.   

References earlyclobber_operand_p(), GET_CODE, GET_RTX_CLASS, ggc_alloc(), i, MATCHES, MERGABLE_RELOADS, n_reloads, reg_class_contents, reg_class_subset_p(), REG_P, rld, RTX_AUTOINC, small_register_class_p(), targetm, TEST_HARD_REG_BIT, true_regnum(), and XEXP.

Referenced by push_reload().

◆ find_valid_class()

static enum reg_class find_valid_class ( machine_mode outer,
machine_mode inner,
int n,
unsigned int dest_regno )
static
Find the largest class which has at least one register valid in
mode INNER, and which for every such register, that register number
plus N is also valid in OUTER (if in range) and is cheap to move
into REGNO.  Such a class must exist.   

References gcc_assert, ggc_alloc(), reg_class_contents, reg_class_size, register_move_cost(), targetm, and TEST_HARD_REG_BIT.

Referenced by push_reload().

◆ find_valid_class_1()

static enum reg_class find_valid_class_1 ( machine_mode outer,
machine_mode mode,
enum reg_class dest_class )
static
We are trying to reload a subreg of something that is not a register.
Find the largest class which contains only registers valid in
mode MODE.  OUTER is the mode of the subreg, DEST_CLASS the class in
which we would eventually like to obtain the object.   

References gcc_assert, ggc_alloc(), in_hard_reg_set_p(), reg_class_contents, register_move_cost(), and targetm.

Referenced by push_reload().

◆ form_sum()

rtx form_sum ( machine_mode mode,
rtx x,
rtx y )
Compute the sum of X and Y, making canonicalizations assumed in an
address, namely: sum constant integers, surround the sum of two
constants with a CONST, put the constant as the second operand, and
group the constant on the outermost sum.

This routine assumes both inputs are already in canonical form.   

References CONST_INT_P, CONSTANT_P, form_sum(), gcc_assert, GET_CODE, GET_MODE, ggc_alloc(), INTVAL, plus_constant(), XEXP, and y.

Referenced by form_sum(), and subst_indexed_address().

◆ get_secondary_mem()

rtx get_secondary_mem ( rtx x,
machine_mode mode,
int opnum,
enum reload_type type )
Return a memory location that will be used to copy X in mode MODE.
If we haven't already made a location for this mode in this insn,
call find_reloads_address on the location being returned.   

References assign_stack_local(), copy_rtx(), eliminate_regs(), find_reloads_address(), GET_MODE_SIZE(), ggc_alloc(), MEM_ADDR_SPACE, NULL_RTX, RELOAD_FOR_INPUT, RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_OUTPUT, RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_OTHER, secondary_memlocs, secondary_memlocs_elim, secondary_memlocs_elim_used, strict_memory_address_addr_space_p(), targetm, and XEXP.

Referenced by choose_reload_regs(), gen_reload(), push_reload(), and push_secondary_reload().

◆ hard_reg_set_here_p()

static int hard_reg_set_here_p ( unsigned int beg_regno,
unsigned int end_regno,
rtx x )
static
Return 1 if expression X alters a hard reg in the range
from BEG_REGNO (inclusive) to END_REGNO (exclusive),
either explicitly or in the guise of a pseudo-reg allocated to REGNO.
X should be the body of an instruction.   

References end_hard_regno(), GET_CODE, GET_MODE, ggc_alloc(), hard_reg_set_here_p(), i, r, REG_P, REGNO, SET, SET_DEST, SUBREG_REG, XVECEXP, and XVECLEN.

Referenced by find_dummy_reload(), hard_reg_set_here_p(), and push_reload().

◆ immune_p()

static int immune_p ( rtx x,
rtx y,
struct decomposition ydata )
static
Return 1 if altering Y will not modify the value of X.
Y is also described by YDATA, which should be decompose (Y).   

References CONSTANT_P, decompose(), frame_pointer_rtx, gcc_assert, ggc_alloc(), hard_frame_pointer_rtx, known_ge, MEM_P, refers_to_regno_for_reload_p(), rtx_equal_p(), stack_pointer_rtx, and y.

Referenced by find_reloads(), and safe_from_earlyclobber().

◆ make_memloc()

static rtx make_memloc ( rtx ad,
int regno )
static

◆ maybe_memory_address_addr_space_p()

static bool maybe_memory_address_addr_space_p ( machine_mode mode,
rtx ad,
addr_space_t as,
rtx * part )
static
Returns true if AD could be turned into a valid memory reference
to mode MODE in address space AS by reloading the part pointed to
by PART into a register.   

References gen_rtx_REG(), GET_MODE, ggc_alloc(), max_reg_num(), and memory_address_addr_space_p().

Referenced by find_reloads_address().

◆ move_replacements()

void move_replacements ( rtx * x,
rtx * y )
Change any replacements being done to *X to be done to *Y.   

References i, n_replacements, replacements, replacement::where, and y.

Referenced by find_reloads_address().

◆ operands_match_p()

int operands_match_p ( rtx x,
rtx y )
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
autoincrement and autodecrement.
This is specifically intended for find_reloads to use
in determining whether two operands match.
X is the operand whose number is the lower of the two.

The value is 2 if Y contains a pre-increment that matches
a non-incrementing address in X.   
??? To be completely correct, we should arrange to pass
for X the output operand and for Y the input operand.
For now, we assume that the output operand has the lower number
because that is natural in (SET output (... input ...)).   

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

Referenced by find_reloads(), and operands_match_p().

◆ push_reg_equiv_alt_mem()

static void push_reg_equiv_alt_mem ( int regno,
rtx mem )
static
Add NEW to reg_equiv_alt_mem_list[REGNO] if it's not present in the
list yet.   

References alloc_EXPR_LIST(), ggc_alloc(), reg_equiv_alt_mem_list, rtx_equal_p(), and XEXP.

Referenced by find_reloads_address(), find_reloads_address_1(), find_reloads_subreg_address(), and find_reloads_toplev().

◆ push_reload()

int push_reload ( rtx in,
rtx out,
rtx * inloc,
rtx * outloc,
enum reg_class rclass,
machine_mode inmode,
machine_mode outmode,
int strict_low,
int optional,
int opnum,
enum reload_type type )
Record one reload that needs to be performed.
IN is an rtx saying where the data are to be found before this instruction.
OUT says where they must be stored after the instruction.
(IN is zero for data not read, and OUT is zero for data not written.)
INLOC and OUTLOC point to the places in the instructions where
IN and OUT were found.
If IN and OUT are both nonzero, it means the same register must be used
to reload both IN and OUT.

RCLASS is a register class required for the reloaded data.
INMODE is the machine mode that the instruction requires
for the reg that replaces IN and OUTMODE is likewise for OUT.

If IN is zero, then OUT's location and mode should be passed as
INLOC and INMODE.

STRICT_LOW is the 1 if there is a containing STRICT_LOW_PART rtx.

OPTIONAL nonzero means this reload does not need to be performed:
it can be discarded if that is more convenient.

OPNUM and TYPE say what the purpose of this reload is.

The return value is the reload-number for this reload.

If both IN and OUT are nonzero, in some rare cases we might
want to make two separate reloads.  (Actually we never do this now.)
Therefore, the reload-number for OUT is stored in
output_reloadnum when we return; the return value applies to IN.
Usually (presently always), when IN and OUT are nonzero,
the two reload-numbers are equal, but the caller should be careful to
distinguish them.   

References bitmap_bit_p, can_reload_into(), cfun, complex_word_subreg_p(), const0_rtx, CONSTANT_P, contains_allocatable_reg_of_mode, DF_LR_OUT, earlyclobber_operand_p(), end_hard_regno(), ENTRY_BLOCK_PTR_FOR_FN, error_for_asm(), find_dummy_reload(), find_equiv_reg(), find_reg_fusage(), find_reusable_reload(), find_valid_class(), find_valid_class_1(), fixed_regs, gcc_assert, gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_SIZE(), get_secondary_mem(), ggc_alloc(), hard_reg_set_here_p(), hard_regno_nregs(), hard_regs_live_known, i, in_hard_reg_set_p(), known_le, LOAD_EXTEND_OP, MAX, maybe_gt, MEM_ADDR_SPACE, MEM_P, MERGE_TO_OTHER, MIN, mode_dependent_address_p(), n_reloads, n_replacements, NULL, NULL_RTX, ORIGINAL_REGNO, output_reloadnum, paradoxical_subreg_p(), partial_subreg_p(), PATTERN(), push_reload(), push_secondary_reload(), r, refers_to_regno_for_reload_p(), REG_CAN_CHANGE_MODE_P, reg_class_contents, reg_class_subset_p(), reg_equiv_constant, reg_equiv_mem, reg_mentioned_p(), REG_NOTE_KIND, REG_NOTES, REG_NREGS, reg_or_subregno(), reg_overlap_mentioned_for_reload_p(), REG_P, reg_renumber, REGNO, RELOAD_FOR_OUTPUT, reload_inner_reg_of_subreg(), RELOAD_OTHER, remove_address_replacements(), replace_equiv_address_nv(), replace_reloads, replacements, rld, rtx_equal_p(), secondary_reload_class(), static_reload_reg_p, SUBREG_BYTE, subreg_lowpart_p(), SUBREG_REG, subreg_regno(), subreg_regno_offset(), targetm, TEST_HARD_REG_BIT, this_insn, this_insn_is_asm, type(), replacement::what, word_mode, WORD_REGISTER_OPERATIONS, and XEXP.

Referenced by find_reloads(), find_reloads_address(), find_reloads_address_1(), find_reloads_address_part(), find_reloads_subreg_address(), and push_reload().

◆ push_replacement()

static void push_replacement ( rtx * loc,
int reloadnum,
machine_mode mode )
static
Record an additional place we must replace a value
for which we have already recorded a reload.
RELOADNUM is the value returned by push_reload
when the reload was recorded.
This is used in insn patterns that use match_dup.   

References ggc_alloc(), replacement::mode, rtx_def::mode, n_replacements, r, replace_reloads, replacements, and replacement::what.

Referenced by dup_replacements(), and update_auto_inc_notes().

◆ push_secondary_reload()

static int push_secondary_reload ( int in_p,
rtx x,
int opnum,
int optional,
enum reg_class reload_class,
machine_mode reload_mode,
enum reload_type type,
enum insn_code * picode,
secondary_reload_info * prev_sri )
static
Determine if any secondary reloads are needed for loading (if IN_P is
nonzero) or storing (if IN_P is zero) X to or from a reload register of
register class RELOAD_CLASS in mode RELOAD_MODE.  If secondary reloads
are needed, push them.

Return the reload number of the secondary reload we made, or -1 if
we didn't need one.  *PICODE is set to the insn_code to use if we do
need a secondary reload.   

References gcc_assert, GET_MODE, get_secondary_mem(), ggc_alloc(), insn_data, MERGABLE_RELOADS, MERGE_TO_OTHER, MIN, n_operands, n_reloads, paradoxical_subreg_p(), push_secondary_reload(), reg_class_subset_p(), reg_equiv_mem, REG_P, REGNO, RELOAD_FOR_INPADDR_ADDRESS, RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS, RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_OTHER, rld, small_register_class_p(), SUBREG_REG, targetm, and type().

Referenced by push_reload(), and push_secondary_reload().

◆ refers_to_mem_for_reload_p()

static int refers_to_mem_for_reload_p ( rtx x)
static
Return nonzero if anything in X contains a MEM.  Look also for pseudo
registers.   

References GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, MEM_P, refers_to_mem_for_reload_p(), reg_equiv_memory_loc, REG_P, REGNO, and XEXP.

Referenced by refers_to_mem_for_reload_p(), and reg_overlap_mentioned_for_reload_p().

◆ refers_to_regno_for_reload_p()

static int refers_to_regno_for_reload_p ( unsigned int regno,
unsigned int endregno,
rtx x,
rtx * loc )
static
Return nonzero if register in range [REGNO, ENDREGNO)
appears either explicitly or implicitly in X
other than being stored into (except for earlyclobber operands).

References contained within the substructure at LOC do not count.
LOC may be zero, meaning don't ignore anything.

This is similar to refers_to_regno_p in rtlanal.cc except that we
look at equivalences for pseudos that didn't get hard registers.   

References earlyclobber_operand_p(), END_REGNO(), gcc_assert, GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, r, refers_to_regno_for_reload_p(), reg_equiv_constant, reg_equiv_invariant, reg_equiv_memory_loc, REG_P, REGNO, RTX_CODE, SET, SET_DEST, SET_SRC, subreg_nregs(), SUBREG_REG, subreg_regno(), XEXP, XVECEXP, and XVECLEN.

Referenced by find_dummy_reload(), find_equiv_reg(), immune_p(), push_reload(), refers_to_regno_for_reload_p(), and reg_overlap_mentioned_for_reload_p().

◆ reg_inc_found_and_valid_p()

static int reg_inc_found_and_valid_p ( unsigned int regno,
unsigned int endregno,
rtx insn )
static
Return 1 if registers from REGNO to ENDREGNO are the subjects of a
REG_INC note in insn INSN.  REGNO must refer to a hard register.   

References AUTO_INC_DEC, gcc_assert, ggc_alloc(), INSN_P, REG_NOTE_KIND, REG_NOTES, REGNO, and XEXP.

Referenced by regno_clobbered_p().

◆ reg_overlap_mentioned_for_reload_p()

int reg_overlap_mentioned_for_reload_p ( rtx x,
rtx in )
Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
we check if any register number in X conflicts with the relevant register
numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
contains a MEM (we don't bother checking for memory addresses that can't
conflict because we expect this to be a rare case.

This function is similar to reg_overlap_mentioned_p in rtlanal.cc except
that we look at equivalences for pseudos that didn't get hard registers.   

References CONSTANT_P, END_REGNO(), gcc_assert, GET_CODE, GET_MODE, GET_RTX_CLASS, ggc_alloc(), MEM_P, refers_to_mem_for_reload_p(), refers_to_regno_for_reload_p(), reg_equiv_constant, reg_equiv_memory_loc, reg_mentioned_p(), reg_overlap_mentioned_for_reload_p(), REG_P, REGNO, RTX_AUTOINC, rtx_equal_p(), SUBREG_BYTE, subreg_nregs(), SUBREG_REG, subreg_regno_offset(), and XEXP.

Referenced by choose_reload_regs(), combine_reloads(), find_equiv_reg(), push_reload(), and reg_overlap_mentioned_for_reload_p().

◆ regno_clobbered_p()

int regno_clobbered_p ( unsigned int regno,
rtx_insn * insn,
machine_mode mode,
int sets )
Return 1 if register REGNO is the subject of a clobber in insn INSN.
If SETS is 1, also consider SETs.  If SETS is 2, enable checking
REG_INC.  REGNO must refer to a hard register.   

References end_hard_regno(), gcc_assert, GET_CODE, ggc_alloc(), i, replacement::mode, PATTERN(), reg_inc_found_and_valid_p(), REG_P, REGNO, SET, XEXP, XVECEXP, and XVECLEN.

Referenced by choose_reload_regs(), emit_output_reload_insns(), find_reloads_address(), and find_reloads_address_1().

◆ reload_adjust_reg_for_mode()

rtx reload_adjust_reg_for_mode ( rtx reloadreg,
machine_mode mode )

◆ reload_inner_reg_of_subreg()

static bool reload_inner_reg_of_subreg ( rtx x,
machine_mode mode,
bool output )
static
Return true if X is a SUBREG that will need reloading of its SUBREG_REG
expression.  MODE is the mode that X will be used in.  OUTPUT is true if
the function is invoked for the output part of an enclosing reload.   

References complex_word_subreg_p(), CONSTANT_P, GET_CODE, ggc_alloc(), HARD_REGISTER_P, REG_P, SUBREG_REG, subreg_regno(), and targetm.

Referenced by combine_reloads(), and push_reload().

◆ remove_address_replacements()

int remove_address_replacements ( rtx in_rtx)
IN_RTX is the value loaded by a reload that we now decided to inherit,
or a subpart of it.  If we have any replacements registered for IN_RTX,
cancel the reloads that were supposed to load them.
Return nonzero if we canceled any reloads.   

References deallocate_reload_reg(), ggc_alloc(), i, loc_mentioned_in_p(), MAX_RELOADS, n_reloads, n_replacements, remove_address_replacements(), replacements, rld, replacement::what, and replacement::where.

Referenced by choose_reload_regs(), push_reload(), and remove_address_replacements().

◆ safe_from_earlyclobber()

int safe_from_earlyclobber ( rtx op,
rtx clobber )
Similar, but calls decompose.   

References decompose(), ggc_alloc(), and immune_p().

Referenced by constrain_operands().

◆ scratch_reload_class()

enum reg_class scratch_reload_class ( enum insn_code icode)
ICODE is the insn_code of a reload pattern.  Check that it has exactly
three operands, verify that operand 2 is an output operand, and return
its register class.
??? We'd like to be able to handle any pattern with at least 2 operands,
for zero or more scratch registers, but that needs more infrastructure.   

References gcc_assert, ggc_alloc(), insn_data, and n_operands.

Referenced by reload_adjust_reg_for_icode(), and secondary_reload_class().

◆ secondary_reload_class()

reg_class_t secondary_reload_class ( bool in_p,
reg_class_t rclass,
machine_mode mode,
rtx x )
If a secondary reload is needed, return its class.  If both an intermediate
register and a scratch register is needed, we return the class of the
intermediate register.   

References ggc_alloc(), NULL, scratch_reload_class(), and targetm.

Referenced by choose_reload_regs(), emit_output_reload_insns(), memory_move_secondary_cost(), and push_reload().

◆ small_register_class_p()

static bool small_register_class_p ( reg_class_t rclass)
inlinestatic
True if C is a non-empty register class that has too few registers
to be safely used as a reload target class.   

References reg_class_size, and targetm.

Referenced by find_reloads(), find_reusable_reload(), and push_secondary_reload().

◆ strict_memory_address_addr_space_p()

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

References ADDR_SPACE_GENERIC_P, gcc_assert, ggc_alloc(), replacement::mode, and targetm.

Referenced by find_reloads_address(), find_reloads_subreg_address(), get_secondary_mem(), offsettable_address_addr_space_p(), operand_subword(), and reload().

◆ subst_indexed_address()

static rtx subst_indexed_address ( rtx addr)
static
If ADDR is a sum containing a pseudo register that should be
replaced with a constant (from reg_equiv_constant),
return the result of doing so, and also apply the associative
law so that the result is more likely to be a valid address.
(But it is not guaranteed to be one.)

Note that at most one register is replaced, even if more are
replaceable.  Also, we try to put the result into a canonical form
so it is more likely to be a valid address.

In all other cases, return ADDR.   

References form_sum(), GET_CODE, GET_MODE, ggc_alloc(), reg_equiv_constant, REG_P, reg_renumber, REGNO, subst_indexed_address(), and XEXP.

Referenced by find_reloads_address(), and subst_indexed_address().

◆ subst_reg_equivs()

static rtx subst_reg_equivs ( rtx ad,
rtx_insn * insn )
static
Find all pseudo regs appearing in AD
that are eliminable in favor of equivalent values
and do not have hard regs; replace them by their equivalents.
INSN, if nonzero, is the insn in which we do the reload.  We put USEs in
front of it for pseudos that we have to replace with stack slots.   

References CASE_CONST_ANY, CONST_INT_P, emit_insn_before(), frame_pointer_rtx, GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, ggc_alloc(), i, make_memloc(), num_not_at_initial_offset, PUT_MODE(), reg_equiv_constant, reg_equiv_mem, reg_equiv_memory_loc, REGNO, RTX_CODE, rtx_equal_p(), subst_reg_equivs(), subst_reg_equivs_changed, and XEXP.

Referenced by find_reloads_address(), and subst_reg_equivs().

◆ subst_reloads()

void subst_reloads ( rtx_insn * insn)
Substitute into the current INSN the registers into which we have reloaded
the things that need reloading.  The array `replacements'
contains the locations of all pointers that must be changed
and says what to replace them with.

Return the rtx that X translates into; usually X, but modified.   

References find_reg_note(), gcc_assert, GET_CODE, GET_MODE, ggc_alloc(), i, JUMP_P, label_is_jump_target_p(), max_regno, n_replacements, r, reload_adjust_reg_for_mode(), replacements, rld, and XEXP.

Referenced by reload_as_needed().

◆ transfer_replacements()

void transfer_replacements ( int to,
int from )
Transfer all replacements that used to be in reload FROM to be in
reload TO.   

References i, n_replacements, replacements, and replacement::what.

Referenced by find_reloads().

◆ update_auto_inc_notes()

static void update_auto_inc_notes ( rtx_insn * insn,
int regno,
int reloadnum )
static
Update the REG_INC notes for an insn.  It updates all REG_INC
notes for the instruction which refer to REGNO the to refer
to the reload number.

INSN is the insn for which any REG_INC notes need updating.

REGNO is the register number which has been reloaded.

RELOADNUM is the reload number.   

References AUTO_INC_DEC, ggc_alloc(), push_replacement(), REG_NOTE_KIND, REG_NOTES, REGNO, and XEXP.

Referenced by find_reloads_address_1().

Variable Documentation

◆ hard_regs_live_known

int hard_regs_live_known
static
If hard_regs_live_known is nonzero,
we can tell which hard regs are currently live,
at least enough to succeed in choosing dummy reloads.   

Referenced by find_dummy_reload(), find_reloads(), and push_reload().

◆ n_earlyclobbers

int n_earlyclobbers
All the "earlyclobber" operands of the current insn
are recorded here.   

Referenced by choose_reload_regs(), earlyclobber_operand_p(), and find_reloads().

◆ n_reloads

◆ n_replacements

◆ output_reloadnum

int output_reloadnum
static
On return from push_reload, holds the reload-number for the OUT
operand, which can be different for that from the input operand.   

Referenced by find_reloads(), and push_reload().

◆ reload_earlyclobbers

◆ reload_n_operands

int reload_n_operands

◆ reload_when_needed_name

const char* const reload_when_needed_name[]
static
Initial value:
=
{
"RELOAD_FOR_INPUT",
"RELOAD_FOR_OUTPUT",
"RELOAD_FOR_INSN",
"RELOAD_FOR_INPUT_ADDRESS",
"RELOAD_FOR_INPADDR_ADDRESS",
"RELOAD_FOR_OUTPUT_ADDRESS",
"RELOAD_FOR_OUTADDR_ADDRESS",
"RELOAD_FOR_OPERAND_ADDRESS",
"RELOAD_FOR_OPADDR_ADDR",
"RELOAD_OTHER",
"RELOAD_FOR_OTHER_ADDRESS"
}

Referenced by debug_reload_to_stream().

◆ replace_reloads

int replace_reloads
static
Replacing reloads.

If `replace_reloads' is nonzero, then as each reload is recorded
an entry is made for it in the table `replacements'.
Then later `subst_reloads' can look through that table and
perform all the replacements needed.   
Nonzero means record the places to replace.   

Referenced by find_reloads(), find_reloads_address(), find_reloads_subreg_address(), find_reloads_toplev(), push_reload(), and push_replacement().

◆ replacements

◆ rld

◆ secondary_memlocs

rtx secondary_memlocs[NUM_MACHINE_MODES]
static
Save MEMs needed to copy from one class of registers to another.  One MEM
is used per mode, but normally only one or two modes are ever used.

We keep two versions, before and after register elimination.  The one
after register elimination is record separately for each operand.  This
is done in case the address is not valid to be sure that we separately
reload each.   

Referenced by clear_secondary_mem(), and get_secondary_mem().

◆ secondary_memlocs_elim

rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS]
static

◆ secondary_memlocs_elim_used

int secondary_memlocs_elim_used = 0
static

Referenced by find_reloads(), and get_secondary_mem().

◆ static_reload_reg_p

short* static_reload_reg_p
static
Indexed by hard reg number,
element is nonnegative if hard reg has been spilled.
This vector is passed to `find_reloads' as an argument
and is not changed here.   

Referenced by find_reloads(), and push_reload().

◆ subst_reg_equivs_changed

int subst_reg_equivs_changed
static
Set to 1 in subst_reg_equivs if it changes anything.   

Referenced by find_reloads_address(), and subst_reg_equivs().

◆ this_insn

rtx_insn* this_insn
static
The instruction we are doing reloads for;
so we can test whether a register dies in it.   

Referenced by combine_reloads(), find_dummy_reload(), find_reloads(), find_reloads_address(), find_reloads_address_1(), and push_reload().

◆ this_insn_is_asm

int this_insn_is_asm
static
Nonzero if this instruction is a user-specified asm with operands.   

Referenced by find_reloads(), and push_reload().