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 "output.h"
#include "rtl-error.h"
#include "lra-int.h"
Data Structures | |
class | lra_elim_table |
struct | elim_table_1 |
Macros | |
#define | NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1) |
Variables | |
static class lra_elim_table * | reg_eliminate = 0 |
static const struct elim_table_1 | reg_eliminate_1 [] |
static class lra_elim_table * | elimination_map [FIRST_PSEUDO_REGISTER] |
static class lra_elim_table | self_elim_table |
static poly_int64 | self_elim_offsets [FIRST_PSEUDO_REGISTER] |
static rtx | eliminable_reg_rtx [FIRST_PSEUDO_REGISTER] |
static bool | elimination_fp2sp_occured_p = false |
static poly_int64 | curr_sp_change |
#define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1) |
Referenced by check_eliminable_occurrences(), eliminate_regs_1(), eliminate_regs_in_insn(), eliminate_regs_in_insn(), elimination_costs_in_insn(), elimination_effects(), elimination_target_reg_p(), init_elim_table(), init_elim_table(), init_eliminable_invariants(), init_elimination(), lra_eliminate(), lra_update_fp2sp_elimination(), mark_not_eliminable(), mark_not_eliminable(), print_elim_table(), reload(), set_initial_elim_offsets(), set_label_offsets(), set_offsets_for_label(), setup_elimination_map(), update_eliminable_offsets(), update_eliminables(), update_reg_eliminate(), and verify_initial_elim_offsets().
void eliminate_regs_in_insn | ( | rtx_insn * | insn, |
bool | replace_p, | ||
bool | first_p, | ||
poly_int64 | update_sp_offset ) |
Scan INSN and eliminate all eliminable hard registers in it. If REPLACE_P is true, do the replacement destructively. Also delete the insn as dead it if it is setting an eliminable register. If REPLACE_P is false, just update the offsets while keeping the base register the same. If FIRST_P, use the sp offset for elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If UPDATE_SP_OFFSET is non-zero, don't use difference of the offset and the previous offset. Attach the note about used elimination for insns setting frame pointer to update elimination easy (without parsing already generated elimination insns to find offset previously used) in future.
References asm_noperands(), lra_elim_table::can_eliminate, DEBUG_INSN_P, lra_static_insn_data::dup_num, lra_elim_table::from_rtx, gen_lowpart, GET_CODE, get_elimination(), GET_MODE, have_addptr3_insn(), i, insn_data, ira_reg_equiv, ira_reg_equiv_len, known_eq, lra_assert, lra_eliminate_regs_1(), lra_get_insn_recog_data(), lra_pmode_pseudo, lra_update_insn_recog_data(), lra_static_insn_data::n_dups, lra_static_insn_data::n_operands, NULL, NULL_RTX, NUM_ELIMINABLE_REGS, lra_elim_table::offset, OP_IN, lra_static_insn_data::operand, PATTERN(), plus_constant(), poly_int_rtx_p(), lra_elim_table::previous_offset, recog_memoized(), reg_eliminate, REG_P, REGNO, SET_DEST, SET_SRC, single_set(), stack_pointer_rtx, subreg_lowpart_p(), SUBREG_REG, lra_elim_table::to_rtx, trunc_int_for_mode(), lra_operand_data::type, validate_change(), and XEXP.
Referenced by change_sp_offset(), lra_process_new_insns(), and process_insn_for_elimination().
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 CONSTANT_P, form_sum(), GET_CODE, GET_MODE, lra_elim_table::offset, plus_constant(), poly_int_rtx_p(), XEXP, and y.
Referenced by eliminate_regs_1(), form_sum(), form_sum(), and lra_eliminate_regs_1().
|
static |
Return elimination which will be used for hard reg REG, NULL otherwise.
References eliminable_reg_rtx, elimination_map, lra_elim_table::from_rtx, known_eq, lra_assert, NULL, lra_elim_table::offset, REG_P, REGNO, self_elim_offsets, and self_elim_table.
Referenced by eliminate_regs_in_insn(), lra_eliminate_reg_if_possible(), and lra_eliminate_regs_1().
|
static |
Initialize the table of hard registers to eliminate. Pre-condition: global flag frame_pointer_needed has been set before calling this function.
References eliminable_reg_rtx, frame_pointer_needed, elim_table_1::from, lra_elim_table::from, lra_elim_table::from_rtx, gen_rtx_REG(), lra_in_progress, NUM_ELIMINABLE_REGS, lra_elim_table::offset, lra_elim_table::previous_offset, reg_eliminate, reg_eliminate_1, self_elim_offsets, self_elim_table, setup_can_eliminate(), stack_realign_fp, SUPPORTS_STACK_ALIGNMENT, targetm, elim_table_1::to, lra_elim_table::to, and lra_elim_table::to_rtx.
Referenced by init_elimination().
|
static |
Function for initialization of elimination once per function. It sets up sp offset for each insn.
References cfun, curr_sp_change, find_reg_note(), FOR_BB_INSNS, FOR_EACH_BB_FN, frame_pointer_needed, init_elim_table(), INSN_P, lra_get_insn_recog_data(), mark_not_eliminable(), NONDEBUG_INSN_P, NULL_RTX, NUM_ELIMINABLE_REGS, PATTERN(), reg_eliminate, setup_can_eliminate(), setup_elimination_map(), basic_block_def::succs, and lra_elim_table::to.
Referenced by lra_eliminate().
void lra_debug_elim_table | ( | void | ) |
Print info about elimination table to stderr.
References print_elim_table().
Entry function to do final elimination if FINAL_P or to update elimination register offsets (FIRST_P if we are doing it the first time).
References bitmap_clear(), bitmap_empty_p(), bitmap_initialize(), bitmap_ior_into(), elimination_fp2sp_occured_p, elimination_map, EXECUTE_IF_SET_IN_BITMAP, lra_elim_table::from, gcc_assert, init_elimination(), lra_dump_file, lra_reg_info, NULL, NUM_ELIMINABLE_REGS, print_elim_table(), process_insn_for_elimination(), reg_eliminate, reg_obstack, timevar_pop(), timevar_push(), and update_reg_eliminate().
Referenced by lra(), and lra_constraints().
void lra_eliminate_reg_if_possible | ( | rtx * | loc | ) |
Eliminate hard reg given by its location LOC.
References get_elimination(), lra_assert, lra_no_alloc_regs, NULL, REG_P, REGNO, TEST_HARD_REG_BIT, and lra_elim_table::to_rtx.
Referenced by in_class_p().
This function is used externally in subsequent passes of GCC. It always does a full elimination of X.
References lra_eliminate_regs_1(), and NULL.
Referenced by based_loc_descr(), compute_frame_pointer_to_fb_displacement(), reg_loc_descriptor(), and vt_initialize().
rtx lra_eliminate_regs_1 | ( | rtx_insn * | insn, |
rtx | x, | ||
machine_mode | mem_mode, | ||
bool | subst_p, | ||
bool | update_p, | ||
poly_int64 | update_sp_offset, | ||
bool | full_p ) |
Scan X and replace any eliminable registers (such as fp) with a replacement (such as sp) if SUBST_P, plus an offset. The offset is a change in the offset between the eliminable register and its substitution if UPDATE_P, or the full offset if FULL_P, or otherwise zero. If FULL_P, we also use the SP offsets for elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating offsets of register elimnable to SP. If UPDATE_SP_OFFSET is non-zero, don't use difference of the offset and the previous offset. MEM_MODE is the mode of an enclosing MEM. We need this to know how much to adjust a register for, e.g., PRE_DEC. Also, if we are inside a MEM, we are allowed to replace a sum of a hard register and the constant zero with the hard register, which we cannot do outside a MEM. In addition, we need to record the fact that a hard register is referenced outside a MEM. If we make full substitution to SP for non-null INSN, add the insn sp offset.
References alloc_reg_note(), alter_subreg(), CASE_CONST_ANY, CONST_INT_P, CONSTANT_P, current_function_decl, DEBUG_INSN_P, elimination_fp2sp_occured_p, form_sum(), lra_elim_table::from, lra_elim_table::from_rtx, gcc_assert, gcc_unreachable, gen_rtvec_v(), GET_CODE, get_elimination(), GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, INTVAL, known_eq, lra_assert, lra_eliminate_regs_1(), lra_get_insn_recog_data(), MEM_P, move_plus_up(), NULL, NULL_RTX, lra_elim_table::offset, paradoxical_subreg_p(), plus_constant(), poly_int_rtx_p(), lra_elim_table::previous_offset, REG_NOTE_KIND, REG_P, replace_equiv_address_nv(), SET, shallow_copy_rtx(), simplify_gen_binary(), simplify_gen_subreg(), stack_pointer_rtx, SUBREG_BYTE, SUBREG_REG, lra_elim_table::to, lra_elim_table::to_rtx, XEXP, XVEC, XVECEXP, and XVECLEN.
Referenced by eliminate_regs_in_insn(), get_equiv_with_elimination(), lra_eliminate_regs(), lra_eliminate_regs_1(), and remove_pseudos().
bool lra_fp_pseudo_p | ( | void | ) |
Return true if we have a pseudo assigned to hard frame pointer.
References add_to_hard_reg_set(), CLEAR_HARD_REG_SET, frame_pointer_needed, HARD_FRAME_POINTER_REGNUM, i, lra_reg_info, max_reg_num(), overlaps_hard_reg_set_p(), PSEUDO_REGNO_MODE, and reg_renumber.
Referenced by lra().
int lra_get_elimination_hard_regno | ( | int | hard_regno | ) |
Return the current substitution hard register of the elimination of HARD_REGNO. If HARD_REGNO is not eliminable, return itself.
References elimination_map, NULL, and lra_elim_table::to.
Referenced by get_hard_regno(), get_reg_class(), and process_alt_operands().
int lra_update_fp2sp_elimination | ( | int * | spilled_pseudos | ) |
Update frame pointer to stack pointer elimination if we started with permitted frame pointer elimination and now target reports that we can not do this elimination anymore. Record spilled pseudos in SPILLED_PSEUDOS unless it is null, and return the recorded pseudos number.
References add_to_hard_reg_set(), CLEAR_HARD_REG_SET, elimination_fp2sp_occured_p, frame_pointer_needed, lra_elim_table::from, gcc_assert, HARD_FRAME_POINTER_REGNUM, lra_dump_file, NULL, NUM_ELIMINABLE_REGS, reg_eliminate, setup_can_eliminate(), spill_pseudos(), spilled_pseudos, targetm, and lra_elim_table::to.
Referenced by lra_spill().
poly_int64 lra_update_sp_offset | ( | rtx | x, |
poly_int64 | offset ) |
Update and return stack pointer OFFSET after processing X.
References curr_sp_change, mark_not_eliminable(), and lra_elim_table::offset.
Referenced by setup_sp_offset().
|
static |
Scan rtx X for references to elimination source or target registers in contexts that would prevent the elimination from happening. Update the table of eliminables to reflect the changed state. MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM.
References curr_sp_change, lra_elim_table::from_rtx, GET_CODE, GET_MODE, GET_MODE_SIZE(), GET_RTX_FORMAT, GET_RTX_LENGTH, hard_frame_pointer_rtx, i, mark_not_eliminable(), NUM_ELIMINABLE_REGS, lra_elim_table::offset, poly_int_rtx_p(), reg_eliminate, REG_P, REGNO, SET, SET_DEST, SET_SRC, setup_can_eliminate(), stack_pointer_rtx, lra_elim_table::to_rtx, XEXP, XVECEXP, and XVECLEN.
Referenced by init_elimination(), lra_update_sp_offset(), mark_not_eliminable(), and reload().
Transform (subreg (plus reg const)) to (plus (subreg reg) const) when it is possible. Return X or the transformation result if the transformation is done.
References CONSTANT_P, GET_CODE, GET_MODE, GET_MODE_CLASS, lowpart_subreg(), paradoxical_subreg_p(), simplify_subreg(), subreg_lowpart_offset(), subreg_lowpart_p(), SUBREG_REG, and XEXP.
Referenced by lra_eliminate_regs_1().
|
static |
Print info about elimination table to file F.
References lra_elim_table::can_eliminate, lra_elim_table::from, NUM_ELIMINABLE_REGS, lra_elim_table::offset, lra_elim_table::previous_offset, print_dec(), reg_eliminate, and lra_elim_table::to.
Referenced by lra_debug_elim_table(), and lra_eliminate().
Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add the insn for subsequent processing in the constraint pass, update the insn info.
References check_and_force_assignment_correctness_p, eliminate_regs_in_insn(), INSN_CODE, lra_push_insn(), lra_set_used_insn_alternative(), LRA_UNKNOWN_ALT, lra_update_insn_recog_data(), lra_update_insn_regno_info(), PATTERN(), and recog().
Referenced by lra_eliminate().
|
static |
Setup possibility of elimination in elimination table element EP to VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame pointer to stack pointer is not possible anymore.
References lra_elim_table::can_eliminate, frame_pointer_needed, lra_elim_table::from, HARD_FRAME_POINTER_REGNUM, lra_elim_table::prev_can_eliminate, REGNO_POINTER_ALIGN, and lra_elim_table::to.
Referenced by init_elim_table(), init_elimination(), lra_update_fp2sp_elimination(), mark_not_eliminable(), and update_reg_eliminate().
|
static |
Set up ELIMINATION_MAP of the currently used eliminations.
References lra_elim_table::can_eliminate, elimination_map, lra_elim_table::from, i, NULL, NUM_ELIMINABLE_REGS, and reg_eliminate.
Referenced by init_elimination(), and update_reg_eliminate().
|
static |
Spill pseudos which are assigned to hard registers in SET, record them in SPILLED_PSEUDOS unless it is null, and return the recorded pseudos number. Add affected insns for processing in the subsequent constraint pass.
References bitmap_bit_p, bitmap_clear(), bitmap_initialize(), bitmap_ior_into(), get_insns(), hard_reg_set_empty_p(), i, INSN_UID(), lra_dump_file, lra_no_alloc_regs, lra_push_insn(), lra_reg_info, lra_set_used_insn_alternative(), LRA_UNKNOWN_ALT, max_reg_num(), NEXT_INSN(), NULL, NULL_RTX, overlaps_hard_reg_set_p(), PSEUDO_REGNO_MODE, reg_obstack, reg_renumber, spilled_pseudos, and TEST_HARD_REG_BIT.
Update all offsets and possibility for elimination on eliminable registers. Spill pseudos assigned to registers which are uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard registers whose offsets should be changed. Return true if any elimination offset changed.
References add_to_hard_reg_set(), bitmap_ior_into(), lra_elim_table::can_eliminate, CLEAR_HARD_REG_SET, eliminable_regset, elimination_fp2sp_occured_p, elimination_map, fixed_regs, lra_elim_table::from, gcc_assert, known_eq, lra_assert, lra_dump_file, lra_no_alloc_regs, lra_reg_info, lra_update_reg_val_offset(), NULL, NUM_ELIMINABLE_REGS, lra_elim_table::offset, lra_elim_table::prev_can_eliminate, lra_elim_table::previous_offset, reg_eliminate, self_elim_offsets, setup_can_eliminate(), setup_elimination_map(), spill_pseudos(), stack_pointer_rtx, targetm, lra_elim_table::to, and lra_elim_table::to_rtx.
Referenced by lra_eliminate().
|
static |
Stack pointer offset before the current insn relative to one at the func start. RTL insns can change SP explicitly. We keep the changes from one insn to another through this variable.
Referenced by init_elimination(), lra_update_sp_offset(), and mark_not_eliminable().
|
static |
Map: hard regno -> RTL presentation. RTL presentations of all potentially eliminable hard registers are stored in the map.
Referenced by get_elimination(), and init_elim_table().
Flag that we already did frame pointer to stack pointer elimination.
Referenced by lra_eliminate(), lra_eliminate_regs_1(), lra_update_fp2sp_elimination(), and update_reg_eliminate().
|
static |
Map: eliminable "from" register -> its current elimination, or NULL if none. The elimination table may contain more than one elimination for the same hard register, but this map specifies the one that we are currently using.
Referenced by get_elimination(), lra_eliminate(), lra_get_elimination_hard_regno(), setup_elimination_map(), and update_reg_eliminate().
|
static |
The elimination table. Each array entry describes one possible way of eliminating a register in favor of another. If there is more than one way of eliminating a particular register, the most preferred should be specified first.
Referenced by check_eliminable_occurrences(), eliminate_regs(), eliminate_regs_1(), eliminate_regs_in_insn(), eliminate_regs_in_insn(), elimination_costs_in_insn(), elimination_effects(), elimination_target_reg_p(), init_elim_table(), init_elim_table(), init_elimination(), lra_eliminate(), lra_update_fp2sp_elimination(), mark_not_eliminable(), mark_not_eliminable(), print_elim_table(), reload(), set_initial_elim_offsets(), set_label_offsets(), set_offsets_for_label(), setup_elimination_map(), update_eliminable_offsets(), update_eliminables(), update_reg_eliminate(), and verify_initial_elim_offsets().
|
static |
Referenced by init_elim_table(), and init_elim_table().
|
static |
Offsets should be used to restore original offsets for eliminable hard register which just became not eliminable. Zero, otherwise.
Referenced by get_elimination(), init_elim_table(), and update_reg_eliminate().
|
static |
When an eliminable hard register becomes not eliminable, we use the following special structure to restore original offsets for the register.
Referenced by get_elimination(), and init_elim_table().