GCC Middle and Back End API 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"
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_insn * | this_insn |
static int | this_insn_is_asm |
static int | hard_regs_live_known |
static short * | static_reload_reg_p |
static int | subst_reg_equivs_changed |
static int | output_reloadnum |
static const char *const | reload_when_needed_name [] |
#define ADDR_TYPE | ( | type | ) |
Referenced by find_reloads_address(), and find_reloads_address_1().
#define CONST_POOL_OK_P | ( | MODE, | |
X ) |
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().
#define MATCHES | ( | x, | |
y ) |
Referenced by combine_reloads(), find_reloads(), and find_reusable_reload().
#define MERGABLE_RELOADS | ( | when1, | |
when2, | |||
op1, | |||
op2 ) |
Referenced by find_reusable_reload(), and push_secondary_reload().
#define MERGE_TO_OTHER | ( | when1, | |
when2, | |||
op1, | |||
op2 ) |
Referenced by push_reload(), and push_secondary_reload().
#define REG_OK_FOR_CONTEXT | ( | CONTEXT, | |
REGNO, | |||
MODE, | |||
AS, | |||
OUTER, | |||
INDEX ) |
Referenced by find_reloads_address_1().
#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.
|
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 NULL.
Referenced by find_reloads().
|
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(), make_insn_raw(), MEM_P, r, recog_data, recog_memoized(), REG_P, and test_insn.
Referenced by push_reload().
void clear_secondary_mem | ( | void | ) |
Clear any secondary memory locations we've made.
References secondary_memlocs.
Referenced by reload().
|
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, DF_LR_OUT, earlyclobber_operand_p(), ENTRY_BLOCK_PTR_FOR_FN, fixed_regs, gen_rtx_REG(), 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, 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().
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(), known_le, maybe_gt, and REG_NREGS.
Referenced by push_reload(), and reload_inner_reg_of_subreg().
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().
References copy_replacements_1(), GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, replacement::mode, n_replacements, r, replacements, replacement::what, replacement::where, XEXP, XVECEXP, XVECLEN, and y.
Referenced by copy_replacements(), and copy_replacements_1().
DEBUG_FUNCTION void debug_reload | ( | void | ) |
References 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, 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().
|
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(), 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().
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 i, rtx_def::mode, n_replacements, push_replacement(), r, and replacements.
Referenced by find_reloads().
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().
|
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(), 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().
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, function_abi::clobbers_reg_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, 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().
|
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, i, INTVAL, XEXP, XVECEXP, and XVECLEN.
Referenced by find_inc_amount(), and find_reloads_address_1().
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, constraints, recog_data_d::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, hard_regno_nregs(), hard_regs_live_known, i, immune_p(), INSN_CODE, insn_data, INTVAL, ira_nullify_asm_goto(), ira_reg_class_max_nregs, is_a(), 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, insn_data_d::operand, recog_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().
|
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, 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().
|
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, 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().
|
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, NULL_RTX, push_reload(), targetm, and XEXP.
Referenced by find_reloads_address(), and find_reloads_address_1().
|
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(), 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().
|
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, 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().
If LOC was scheduled to be replaced by something, return the replacement. Otherwise, return *LOC.
References find_replacement(), GET_CODE, GET_MODE, rtx_def::mode, 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().
|
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, 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().
|
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, reg_class_contents, reg_class_size, register_move_cost(), targetm, and TEST_HARD_REG_BIT.
Referenced by push_reload().
|
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, in_hard_reg_set_p(), reg_class_contents, register_move_cost(), and targetm.
Referenced by push_reload().
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, INTVAL, plus_constant(), XEXP, and y.
Referenced by form_sum(), and subst_indexed_address().
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(), 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().
|
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, 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().
|
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 decomposition::base, CONSTANT_P, decompose(), decomposition::end, frame_pointer_rtx, gcc_assert, hard_frame_pointer_rtx, known_ge, MEM_P, refers_to_regno_for_reload_p(), decomposition::reg_flag, rtx_equal_p(), decomposition::safe, stack_pointer_rtx, decomposition::start, poly_int< N, C >::to_constant(), and y.
Referenced by find_reloads(), and safe_from_earlyclobber().
Return a mem ref for the memory equivalent of reg REGNO. This mem ref is not shared with anything.
References adjust_address_nv, copy_rtx(), eliminate_regs(), GET_MODE, NULL_RTX, reg_equiv_memory_loc, replace_equiv_address_nv(), rtx_varies_p(), and XEXP.
Referenced by find_reloads_address(), find_reloads_address_1(), find_reloads_subreg_address(), find_reloads_toplev(), and subst_reg_equivs().
|
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, max_reg_num(), and memory_address_addr_space_p().
Referenced by find_reloads_address().
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().
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, hard_regno_nregs(), i, is_a(), label_ref_label(), MEM_ADDR_SPACE, operands_match_p(), REG_P, REG_WORDS_BIG_ENDIAN, REGNO, RTX_CODE, same_vector_encodings_p(), simplify_subreg_regno(), SUBREG_BYTE, SUBREG_REG, subreg_regno_offset(), XEXP, XINT, XLOC, XSTR, XVECEXP, XVECLEN, XWINT, and y.
Referenced by find_reloads(), and operands_match_p().
|
static |
Add NEW to reg_equiv_alt_mem_list[REGNO] if it's not present in the list yet.
References alloc_EXPR_LIST(), 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().
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(), hard_reg_set_here_p(), hard_regno_nregs(), hard_regs_live_known, i, in_hard_reg_set_p(), is_a(), known_le, LOAD_EXTEND_OP, MAX, maybe_gt, MEM_ADDR_SPACE, MEM_P, MERGE_TO_OTHER, MIN, rtx_def::mode, 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().
|
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 replacement::mode, rtx_def::mode, n_replacements, r, replace_reloads, replacements, and replacement::what.
Referenced by dup_replacements(), and update_auto_inc_notes().
|
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(), secondary_reload_info::icode, insn_data, MERGABLE_RELOADS, MERGE_TO_OTHER, MIN, n_operands, n_reloads, paradoxical_subreg_p(), secondary_reload_info::prev_sri, 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().
|
static |
Return nonzero if anything in X contains a MEM. Look also for pseudo registers.
References GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, 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().
|
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, 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().
|
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, INSN_P, REG_NOTE_KIND, REG_NOTES, REGNO, and XEXP.
Referenced by regno_clobbered_p().
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, 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().
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, 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().
Find the low part, with mode MODE, of a hard regno RELOADREG.
References gen_rtx_REG(), GET_MODE, hard_regno_nregs(), replacement::mode, REG_NREGS, REG_WORDS_BIG_ENDIAN, and REGNO.
Referenced by do_input_reload(), do_output_reload(), emit_output_reload_insns(), find_replacement(), reload_adjust_reg_for_temp(), and subst_reloads().
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, HARD_REGISTER_P, REG_P, SUBREG_REG, subreg_regno(), and targetm.
Referenced by combine_reloads(), and push_reload().
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(), 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().
Similar, but calls decompose.
References decompose(), and immune_p().
Referenced by constrain_operands().
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, insn_data, and n_operands.
Referenced by reload_adjust_reg_for_icode(), and 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 secondary_reload_info::icode, NULL, secondary_reload_info::prev_sri, scratch_reload_class(), and targetm.
Referenced by choose_reload_regs(), emit_output_reload_insns(), memory_move_secondary_cost(), and push_reload().
|
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().
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, 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().
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, reg_equiv_constant, REG_P, reg_renumber, REGNO, subst_indexed_address(), and XEXP.
Referenced by find_reloads_address(), and subst_indexed_address().
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, 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().
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, i, JUMP_P, label_is_jump_target_p(), max_regno, rtx_def::mode, n_replacements, r, reload_adjust_reg_for_mode(), replacements, rld, and XEXP.
Referenced by reload_as_needed().
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().
|
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, push_replacement(), REG_NOTE_KIND, REG_NOTES, REGNO, and XEXP.
Referenced by find_reloads_address_1().
|
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().
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().
int n_reloads |
All reloads of the current insn are recorded here. See reload.h for comments.
Referenced by calculate_needs_all_insns(), choose_reload_regs(), choose_reload_regs_init(), clear_reload_reg_in_use(), combine_reloads(), conflicts_with_override(), copy_reloads(), debug_reload_to_stream(), delete_address_reloads_1(), delete_output_reload(), emit_reload_insns(), find_equiv_reg(), find_reload_regs(), find_reloads(), find_reusable_reload(), forget_marked_reloads(), forget_old_reloads_1(), push_reload(), push_secondary_reload(), reload_as_needed(), reload_reg_free_for_value_p(), reload_reg_reaches_end_p(), reloads_unique_chain_p(), and remove_address_replacements().
|
static |
Number of replacements currently recorded.
Referenced by combine_reloads(), copy_replacements(), copy_replacements_1(), dup_replacements(), find_reloads(), find_replacement(), move_replacements(), push_reload(), push_replacement(), remove_address_replacements(), subst_reloads(), and transfer_replacements().
|
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().
rtx reload_earlyclobbers[MAX_RECOG_OPERANDS] |
Referenced by choose_reload_regs(), earlyclobber_operand_p(), and find_reloads().
int reload_n_operands |
Save the number of operands.
Referenced by choose_reload_regs_init(), emit_reload_insns(), find_reloads(), reload_reg_free_p(), and reload_reg_reaches_end_p().
|
static |
Referenced by debug_reload_to_stream().
|
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().
|
static |
Referenced by combine_reloads(), copy_replacements_1(), delete_trivially_dead_insns(), dup_replacements(), find_reloads(), find_replacement(), is_dead_debug_insn(), move_replacements(), push_reload(), push_replacement(), remove_address_replacements(), replace_dead_reg(), subst_reloads(), and transfer_replacements().
struct reload rld[MAX_RELOADS] |
Referenced by allocate_reload_reg(), choose_reload_regs(), choose_reload_regs_init(), clear_reload_reg_in_use(), combine_reloads(), copy_reloads(), curr_insn_transform(), deallocate_reload_reg(), debug_reload_to_stream(), delete_address_reloads_1(), delete_output_reload(), do_input_reload(), do_output_reload(), emit_input_reload_insns(), emit_output_reload_insns(), emit_reload_insns(), failed_reload(), find_dummy_reload(), find_equiv_reg(), find_reg(), find_reload_regs(), find_reloads(), find_reloads_address_1(), find_replacement(), find_reusable_reload(), gen_reload_chain_without_interm_reg_p(), push_reload(), push_secondary_reload(), reload_as_needed(), reload_reg_class_lower(), reload_reg_free_for_value_p(), reload_reg_reaches_end_p(), reloads_conflict(), reloads_unique_chain_p(), remove_address_replacements(), set_reload_reg(), and subst_reloads().
|
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().
|
static |
Referenced by combine_reloads(), find_reloads(), and get_secondary_mem().
|
static |
Referenced by find_reloads(), and get_secondary_mem().
|
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().
|
static |
Set to 1 in subst_reg_equivs if it changes anything.
Referenced by find_reloads_address(), and subst_reg_equivs().
|
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().
|
static |
Nonzero if this instruction is a user-specified asm with operands.
Referenced by find_reloads(), and push_reload().