GCC Middle and Back End API Reference
|
Data Structures | |
struct | replacement |
struct | decomposition |
Functions | |
static bool | small_register_class_p () |
static int | push_secondary_reload (int, rtx, int, int, enum reg_class, enum machine_mode, enum reload_type, enum insn_code *, secondary_reload_info *) |
static enum reg_class | find_valid_class (enum machine_mode, enum machine_mode, int, unsigned int) |
static void | push_replacement (rtx *, int, enum 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 *, enum machine_mode, enum 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, int *) |
static rtx | make_memloc (rtx, int) |
static int | maybe_memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t, rtx *) |
static int | find_reloads_address (enum machine_mode, rtx *, rtx, rtx *, int, enum reload_type, int, rtx) |
static rtx | subst_reg_equivs (rtx, rtx) |
static rtx | subst_indexed_address (rtx) |
static void | update_auto_inc_notes (rtx, int, int) |
static int | find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int, enum rtx_code, enum rtx_code, rtx *, int, enum reload_type, int, rtx) |
static void | find_reloads_address_part (rtx, rtx *, enum reg_class, enum machine_mode, int, enum reload_type, int) |
static rtx | find_reloads_subreg_address (rtx, int, enum reload_type, int, rtx, int *) |
static void | copy_replacements_1 (rtx *, rtx *, int) |
static int | 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 () |
reg_class_t | secondary_reload_class (bool in_p, reg_class_t rclass, enum machine_mode mode, rtx x) |
enum reg_class | scratch_reload_class () |
rtx | get_secondary_mem (rtx x, enum machine_mode mode, int opnum, enum reload_type type) |
void | clear_secondary_mem () |
static enum reg_class | find_valid_class_1 (enum machine_mode outer, enum machine_mode mode, enum reg_class dest_class) |
static bool | reload_inner_reg_of_subreg () |
static int | can_reload_into () |
int | push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, enum reg_class rclass, enum machine_mode inmode, enum machine_mode outmode, int strict_low, int optional, int opnum, enum reload_type type) |
static void | push_replacement () |
static void | dup_replacements () |
void | transfer_replacements () |
int | remove_address_replacements () |
int | earlyclobber_operand_p () |
static int | hard_reg_set_here_p () |
int | strict_memory_address_addr_space_p (enum machine_mode mode, rtx addr, addr_space_t as) |
int | operands_match_p () |
static struct decomposition | decompose () |
static int | immune_p () |
int | safe_from_earlyclobber () |
int | find_reloads (rtx insn, int replace, int ind_levels, int live_known, short *reload_reg_p) |
static rtx | make_memloc () |
static rtx | subst_reg_equivs () |
rtx | form_sum () |
static rtx | subst_indexed_address () |
void | subst_reloads () |
void | copy_replacements () |
static void | copy_replacements_1 () |
void | move_replacements () |
rtx | find_replacement () |
int | reg_overlap_mentioned_for_reload_p () |
static int | refers_to_mem_for_reload_p () |
rtx | find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other, short *reload_reg_p, int goalreg, enum machine_mode mode) |
static int | find_inc_amount () |
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, enum machine_mode mode, int sets) |
rtx | reload_adjust_reg_for_mode () |
DEBUG_FUNCTION void | debug_reload_to_stream () |
DEBUG_FUNCTION void | debug_reload () |
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 | 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 [] |
|
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 it didn't need any reloads, otherwise it is 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(), make_insn_raw(), recog_data, recog_memoized(), and test_insn.
Referenced by push_reload().
void clear_secondary_mem | ( | void | ) |
Clear any secondary memory locations we've made.
References memset(), and 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(), insn_operand_data::constraint, earlyclobber_operand_p(), gen_rtx_REG(), insn_data, insn_data_d::n_operands, n_reloads, n_replacements, insn_data_d::operand, reload::opnum, reload::out, reload::out_reg, reload::outmode, reload::rclass, reg_class_subset_p(), reg_overlap_mentioned_for_reload_p(), 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, reload::secondary_out_icode, reload::secondary_out_reload, targetm, this_insn, replacement::what, and reload::when_needed.
Referenced by find_reloads().
void copy_replacements | ( | ) |
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(), and n_replacements.
Referenced by emit_move_change_mode(), and find_reloads_address().
Referenced by copy_replacements(), and copy_replacements_1().
|
static |
References copy_replacements_1(), replacement::mode, n_replacements, replacements, replacement::what, and replacement::where.
DEBUG_FUNCTION void debug_reload | ( | void | ) |
References debug_reload_to_stream().
DEBUG_FUNCTION void debug_reload_to_stream | ( | ) |
These functions are used to print the variables set by 'find_reloads'
References insn_data, n_reloads, print_inline_rtx(), reg_class_names, reload_when_needed_name, and rld.
Referenced by debug_reload(), emit_reload_insns(), and spill_failure().
|
staticread |
Referenced by decompose(), find_reloads(), immune_p(), and safe_from_earlyclobber().
|
staticread |
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, decompose(), decomposition::end, end_hard_regno(), memset(), offset, decomposition::reg_flag, decomposition::safe, decomposition::start, subreg_nregs(), and true_regnum().
Referenced by find_reloads().
|
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 replacement::mode, n_replacements, push_replacement(), replacements, replacement::what, and replacement::where.
int earlyclobber_operand_p | ( | ) |
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 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(), find_reg_note(), gen_rtx_REG(), hard_reg_set_here_p(), hard_regs_live_known, reload::out, refers_to_regno_for_reload_p(), rld, subreg_regno_offset(), targetm, and this_insn.
Referenced by find_reloads(), and push_reload().
rtx find_equiv_reg | ( | rtx | goal, |
rtx | insn, | ||
enum reg_class | rclass, | ||
int | other, | ||
short * | reload_reg_p, | ||
int | goalreg, | ||
enum 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.c 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 end_hard_regno(), find_reg_note(), HOST_WIDE_INT, in_hard_reg_set_p(), replacement::mode, n_reloads, operand_subword(), push_operand(), refers_to_regno_for_reload_p(), reg_overlap_mentioned_for_reload_p(), reload_first_uid, rld, rtx_equal_p(), rtx_renumbered_equal_p(), SET, true_regnum(), volatile_insn_p(), and replacement::where.
Referenced by choose_reload_regs(), find_reloads(), and push_reload().
Referenced by find_inc_amount(), find_reloads_address_1(), 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 find_inc_amount().
int find_reloads | ( | rtx | 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(), alternative_allows_const_pool_ref(), recog_data_d::alternative_enabled_p, base_reg_class(), cc0_rtx, combine_reloads(), 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(), decomposition::end, error_for_asm(), extract_insn(), find_dummy_reload(), find_equiv_reg(), find_reg_note(), find_reloads(), find_reloads_address(), find_reloads_toplev(), force_const_mem(), gen_clobber(), gen_rtx_SUBREG(), get_address_mode(), hard_regs_live_known, immune_p(), reload::in, reload::in_reg, reload::inc, reload::inmode, insn_code_number, insn_data, recog_data_d::is_operator, label_is_jump_target_p(), len, memcpy(), memset(), reload::mode, n_alternatives(), recog_data_d::n_alternatives, recog_data_d::n_dups, n_earlyclobbers, recog_data_d::n_operands, n_reloads, n_replacements, nr, reload::nregs, num_not_at_initial_offset, offset, offsettable_memref_p(), offsettable_nonstrict_memref_p(), recog_data_d::operand, insn_data_d::operand, recog_data_d::operand_loc, recog_data_d::operand_mode, operands_match_p(), reload::opnum, reload::outmode, output_reloadnum, push_reload(), reload::rclass, recog_data, reg_alternate_class(), reg_class_subset_p(), reg_fits_class_p(), reg_mentioned_p(), reg_preferred_class(), reg_referenced_p(), reg_renumber, reload::reg_rtx, reg_set_p(), register_move_cost(), 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_equal_p(), RTX_UNARY, secondary_memlocs_elim, secondary_memlocs_elim_used, SET, set_unique_reg_note(), simplify_subreg_regno(), skip_alternative(), small_register_class_p(), static_reload_reg_p, insn_operand_data::strict_low, subreg_regno_offset(), targetm, this_insn, this_insn_is_asm, transfer_replacements(), type(), replacement::what, and reload::when_needed.
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 base_reg_class(), copy_replacements(), copy_rtx(), emit_insn_before(), find_reloads_address_1(), find_reloads_address_part(), make_memloc(), maybe_memory_address_addr_space_p(), move_replacements(), num_not_at_initial_offset, plus_constant(), push_reg_equiv_alt_mem(), push_reload(), regno_clobbered_p(), regno_ok_for_base_p(), replace_reloads, rtx_equal_p(), strict_memory_address_addr_space_p(), subst_indexed_address(), subst_reg_equivs(), subst_reg_equivs_changed, targetm, and this_insn.
Referenced by find_reloads(), 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 base_reg_class(), find_inc_amount(), find_reloads_address(), find_reloads_address_part(), find_reloads_subreg_address(), gen_rtx_REG(), reload::inc, insn_operand_matches(), make_memloc(), memory_operand(), num_not_at_initial_offset, optab_handler(), push_reg_equiv_alt_mem(), push_reload(), reg_renumber, regno_clobbered_p(), regno_ok_for_base_p(), RELOAD_OTHER, rld, rtx_equal_p(), sets_cc0_p(), subreg_regno(), subreg_regno_offset(), this_insn, update_auto_inc_notes(), and word_mode.
Referenced by find_reloads_address().
|
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 find_reloads_address(), force_const_mem(), push_reload(), and targetm.
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(), make_memloc(), offset, recog_data_d::operand, paradoxical_subreg_p(), push_reg_equiv_alt_mem(), push_reload(), recog_data, replace_reloads, rtx_equal_p(), simplify_subreg(), and strict_memory_address_addr_space_p().
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 emit_insn_before(), find_reloads_address(), find_reloads_subreg_address(), force_const_mem(), make_memloc(), num_not_at_initial_offset, recog_data_d::operand, push_reg_equiv_alt_mem(), recog_data, reg_renumber, replace_reloads, rtx_equal_p(), simplify_gen_subreg(), and targetm.
Referenced by find_reloads().
rtx find_replacement | ( | ) |
If LOC was scheduled to be replaced by something, return the replacement. Otherwise, return *LOC.
References replacement::mode, n_replacements, reload::reg_rtx, reload_adjust_reg_for_mode(), replacements, rld, simplify_gen_subreg(), replacement::what, and replacement::where.
Referenced by emit_move_multi_word(), 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(), n_reloads, reload::out, reg_class_subset_p(), rld, RTX_AUTOINC, small_register_class_p(), targetm, and true_regnum().
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 register_move_cost().
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 in_hard_reg_set_p(), and register_move_cost().
Referenced by push_reload().
rtx form_sum | ( | ) |
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 form_sum(), and plus_constant().
rtx get_secondary_mem | ( | rtx | x, |
enum 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(), mode_for_size(), 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, and strict_memory_address_addr_space_p().
Referenced by choose_reload_regs(), gen_reload(), push_reload(), and push_secondary_reload().
|
static |
Referenced by find_dummy_reload(), hard_reg_set_here_p(), and push_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(), hard_reg_set_here_p(), and SET.
|
static |
Referenced by find_reloads(), and safe_from_earlyclobber().
|
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, decompose(), decomposition::end, refers_to_regno_for_reload_p(), decomposition::reg_flag, rtx_equal_p(), decomposition::safe, and decomposition::start.
|
static |
Return a mem ref for the memory equivalent of reg REGNO. This mem ref is not shared with anything.
References copy_rtx(), eliminate_regs(), replace_equiv_address_nv(), and rtx_varies_p().
|
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(), max_reg_num(), and memory_address_addr_space_p().
Referenced by find_reloads_address().
void move_replacements | ( | ) |
Change any replacements being done to *X to be done to *Y.
References n_replacements, replacements, and replacement::where.
Referenced by find_reloads_address().
int operands_match_p | ( | ) |
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 operands_match_p(), and subreg_regno_offset().
|
static |
Add NEW to reg_equiv_alt_mem_list[REGNO] if it's not present in the list yet.
References alloc_EXPR_LIST(), and rtx_equal_p().
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, | ||
enum machine_mode | inmode, | ||
enum 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(), earlyclobber_operand_p(), end_hard_regno(), error_for_asm(), find_dummy_reload(), find_equiv_reg(), find_inc_amount(), find_reusable_reload(), find_valid_class(), find_valid_class_1(), gen_rtx_REG(), get_secondary_mem(), hard_reg_set_here_p(), hard_regs_live_known, reload::in, in_hard_reg_set_p(), reload::in_reg, reload::inc, reload::inmode, replacement::mode, n_reloads, n_replacements, reload::nocombine, reload::opnum, reload::optional, reload::out, reload::out_reg, reload::outmode, output_reloadnum, push_reload(), push_secondary_reload(), reload::rclass, refers_to_regno_for_reload_p(), reg_class_subset_p(), reg_mentioned_p(), reg_or_subregno(), reg_overlap_mentioned_for_reload_p(), reg_renumber, reload::reg_rtx, RELOAD_FOR_OUTPUT, reload_inner_reg_of_subreg(), RELOAD_OTHER, remove_address_replacements(), replace_equiv_address_nv(), replace_reloads, replacements, rld, rtx_equal_p(), reload::secondary_in_icode, reload::secondary_in_reload, reload::secondary_out_icode, reload::secondary_out_reload, reload::secondary_p, secondary_reload_class(), sets_cc0_p(), static_reload_reg_p, subreg_lowpart_p(), subreg_regno(), subreg_regno_offset(), targetm, this_insn, this_insn_is_asm, type(), replacement::what, reload::when_needed, replacement::where, and word_mode.
Referenced by find_reloads(), find_reloads_address(), find_reloads_address_1(), find_reloads_address_part(), find_reloads_subreg_address(), and push_reload().
|
static |
Referenced by dup_replacements(), and update_auto_inc_notes().
|
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, n_replacements, replace_reloads, replacements, replacement::what, and replacement::where.
|
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 get_secondary_mem(), secondary_reload_info::icode, reload::in, reload::in_reg, reload::inc, reload::inmode, insn_data, n_operands, n_reloads, reload::nocombine, reload::opnum, reload::optional, reload::out, reload::out_reg, reload::outmode, paradoxical_subreg_p(), secondary_reload_info::prev_sri, reload::rclass, reg_class_subset_p(), reload::reg_rtx, RELOAD_FOR_INPADDR_ADDRESS, RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS, RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_OTHER, rld, reload::secondary_in_icode, reload::secondary_in_reload, reload::secondary_out_icode, reload::secondary_out_reload, reload::secondary_p, small_register_class_p(), targetm, type(), and reload::when_needed.
Referenced by push_reload().
|
static |
Referenced by refers_to_mem_for_reload_p(), and reg_overlap_mentioned_for_reload_p().
|
static |
Return nonzero if anything in X contains a MEM. Look also for pseudo registers.
References refers_to_mem_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.c except that we look at equivalences for pseudos that didn't get hard registers.
References earlyclobber_operand_p(), SET, subreg_nregs(), and subreg_regno().
Referenced by find_dummy_reload(), find_equiv_reg(), immune_p(), push_reload(), 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.
Referenced by regno_clobbered_p().
int reg_overlap_mentioned_for_reload_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.c except that we look at equivalences for pseudos that didn't get hard registers.
References refers_to_mem_for_reload_p(), refers_to_regno_for_reload_p(), reg_mentioned_p(), RTX_AUTOINC, rtx_equal_p(), subreg_nregs(), and subreg_regno_offset().
Referenced by choose_reload_regs(), combine_reloads(), find_equiv_reg(), and push_reload().
int regno_clobbered_p | ( | unsigned int | regno, |
rtx | insn, | ||
enum 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 replacement::mode, reg_inc_found_and_valid_p(), and SET.
Referenced by choose_reload_regs(), emit_output_reload_insns(), find_reloads_address(), and find_reloads_address_1().
rtx reload_adjust_reg_for_mode | ( | ) |
Find the low part, with mode MODE, of a hard regno RELOADREG.
References gen_rtx_REG().
Referenced by do_input_reload(), do_output_reload(), emit_output_reload_insns(), find_replacement(), reload_adjust_reg_for_temp(), and subst_reloads().
|
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 subreg_regno().
Referenced by combine_reloads(), and push_reload().
int remove_address_replacements | ( | ) |
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(), reload::in, loc_mentioned_in_p(), memset(), n_reloads, n_replacements, replacements, rld, replacement::what, and replacement::where.
Referenced by choose_reload_regs(), and push_reload().
int safe_from_earlyclobber | ( | ) |
Similar, but calls decompose.
References decompose(), and immune_p().
Referenced by constrain_operands().
enum reg_class scratch_reload_class | ( | ) |
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 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, | ||
enum 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, 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 targetm.
Referenced by find_reloads(), find_reusable_reload(), and push_secondary_reload().
int strict_memory_address_addr_space_p | ( | enum machine_mode | mode, |
rtx | addr, | ||
addr_space_t | as | ||
) |
Return 1 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 replacement::mode, and targetm.
Referenced by constrain_operands(), find_reloads_address(), find_reloads_subreg_address(), get_secondary_mem(), offsettable_address_addr_space_p(), operand_subword(), and reload().
Referenced by find_reloads_address(), and subst_indexed_address().
|
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(), reg_renumber, and subst_indexed_address().
Referenced by find_reloads_address(), and subst_reg_equivs().
|
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 emit_insn_before(), make_memloc(), num_not_at_initial_offset, rtx_equal_p(), subst_reg_equivs(), and subst_reg_equivs_changed.
void subst_reloads | ( | ) |
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(), label_is_jump_target_p(), max_regno, replacement::mode, n_replacements, reload::optional, reload::reg_rtx, reload_adjust_reg_for_mode(), replacements, rld, replacement::what, and replacement::where.
Referenced by reload_as_needed().
void transfer_replacements | ( | ) |
Transfer all replacements that used to be in reload FROM to be in reload TO.
References 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 push_replacement().
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 |
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().