GCC Middle and Back End API Reference
|
Data Structures | |
struct | input_reload |
struct | usage_insns |
struct | to_inherit |
Functions | |
static rtx * | strip_subreg () |
static int | get_try_hard_regno () |
static int | get_final_hard_regno () |
static int | get_hard_regno () |
static enum reg_class | get_reg_class () |
static bool | in_class_p () |
static bool | in_mem_p () |
static rtx | get_equiv_substitution () |
static void | init_curr_operand_mode () |
static void | init_curr_insn_input_reloads () |
static void | change_class (int regno, enum reg_class new_class, const char *title, bool nl_p) |
static bool | get_reload_reg (enum op_type type, enum machine_mode mode, rtx original, enum reg_class rclass, const char *title, rtx *result_reg) |
static bool | ok_for_index_p_nonstrict () |
static bool | ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code) |
int | lra_constraint_offset () |
static bool | operands_match_p () |
static void | narrow_reload_pseudo_class () |
static void | match_reload (signed char out, signed char *ins, enum reg_class goal_class, rtx *before, rtx *after) |
static enum reg_class | reg_class_from_constraints () |
static enum reg_class | get_op_class () |
static rtx | emit_spill_move () |
static bool | check_and_process_move () |
static bool | process_addr_reg () |
static bool | simplify_operand_subreg () |
static bool | uses_hard_regs_p () |
static bool | spilled_pseudo_p () |
static bool | general_constant_p () |
static bool | reg_in_class_p () |
static bool | process_alt_operands () |
static int | valid_address_p (enum machine_mode mode, rtx addr, addr_space_t as) |
static bool | valid_address_p () |
static rtx | base_plus_disp_to_reg () |
static bool | can_add_disp_p () |
static bool | equiv_address_substitution () |
static bool | process_address () |
static rtx | emit_inc () |
static bool | simple_move_p () |
static void | swap_operands () |
static bool | curr_insn_transform () |
static bool | in_list_p () |
static bool | contains_reg_p () |
static bool | loc_equivalence_change_p () |
static rtx | loc_equivalence_callback () |
static bool | multi_block_pseudo_p () |
static bool | contains_deleted_insn_p () |
static bool | dead_pseudo_p () |
static bool | insn_rhs_dead_pseudo_p () |
static bool | init_insn_rhs_dead_pseudo_p () |
static bool | reverse_equiv_p () |
static bool | contains_reloaded_insn_p () |
bool | lra_constraints () |
void | lra_constraints_init () |
void | lra_constraints_finish () |
static void | setup_next_usage_insn () |
static void | add_next_usage_insn () |
static bool | substitute_pseudo () |
static rtx | skip_usage_debug_insns () |
static bool | check_secondary_memory_needed_p (enum reg_class inher_cl, rtx usage_insns) |
static bool | inherit_reload_reg (bool def_p, int original_regno, enum reg_class cl, rtx insn, rtx next_usage_insns) |
static bool | need_for_call_save_p () |
static bool | need_for_split_p () |
static enum reg_class | choose_split_class (enum reg_class allocno_class, int hard_regno, enum machine_mode mode) |
static bool | split_reg () |
static bool | split_if_necessary (int regno, enum machine_mode mode, HARD_REG_SET potential_reload_hard_regs, bool before_p, rtx insn, int max_uid) |
static void | update_ebb_live_info () |
static void | add_to_inherit () |
static rtx | get_last_insertion_point () |
static void | get_live_on_other_edges () |
static bool | inherit_in_ebb () |
void | lra_inheritance () |
static void | fix_bb_live_info () |
static int | get_regno () |
static bool | remove_inheritance_pseudos () |
static bool | undo_optional_reloads () |
bool | lra_undo_inheritance () |
|
static |
The function is used to form list REGNO usages which consists of optional debug insns finished by a non-debug insn using REGNO. RELOADS_NUM is current number of reload insns processed so far.
References usage_insns::check, curr_usage_insns_check, usage_insns::insns, and setup_next_usage_insn().
Referenced by inherit_in_ebb().
|
static |
Add inheritance info REGNO and INSNS. Their meaning is described in structure to_inherit.
References to_inherit::insns, to_inherit::regno, and to_inherit_num.
Referenced by inherit_in_ebb().
|
static |
Make reload base reg + disp from address AD. Return the new pseudo.
References address_info::as, address_info::base, address_info::base_outer_code, base_reg_class(), address_info::base_term, address_info::disp, address_info::disp_term, get_index_code(), lra_create_new_reg(), lra_emit_add(), and address_info::mode.
Referenced by process_address().
|
static |
Return true if we can add a displacement to address AD, even if that makes the address invalid. The fix-up code requires any new address to be the sum of the BASE_TERM, INDEX and DISP_TERM fields.
References address_info::autoinc_p, address_info::base, address_info::base_term, address_info::disp, address_info::disp_term, and address_info::segment.
Referenced by equiv_address_substitution().
|
static |
Change class of pseudo REGNO to NEW_CLASS. Print info about it using TITLE. Output a new line if NL_P.
References lra_dump_file, reg_class_names, and setup_reg_classes().
Referenced by curr_insn_transform(), get_reload_reg(), narrow_reload_pseudo_class(), process_addr_reg(), and process_address().
|
static |
Process a special case insn (register move), return true if we don't need to process it anymore. INSN should be a single set insn. Set up that RTL was changed through CHANGE_P and macro SECONDARY_MEMORY_NEEDED says to use secondary memory through SEC_MEM_P.
References insn_operand_data::constraint, copy_rtx(), curr_insn, curr_insn_set, dump_insn_slim(), emit_insn(), end_sequence(), secondary_reload_info::extra_cost, get_insns(), get_reg_class(), secondary_reload_info::icode, insn_data, lra_create_new_reg_with_unique_value(), lra_dump_file, lra_emit_move(), lra_get_regno_hard_regno(), lra_process_new_insns(), lra_set_insn_deleted(), insn_data_d::operand, secondary_reload_info::prev_sri, reg_class_from_constraints(), reg_renumber, start_sequence(), and targetm.
Referenced by curr_insn_transform().
|
static |
Return true if we need secondary memory moves for insn in USAGE_INSNS after inserting inherited pseudo of class INHER_CL into the insn.
References get_reg_class(), and skip_usage_debug_insns().
Referenced by inherit_reload_reg().
|
static |
Return class for the split pseudo created from original pseudo with ALLOCNO_CLASS and MODE which got a hard register HARD_REGNO. We choose subclass of ALLOCNO_CLASS which contains HARD_REGNO and results in no secondary memory movements.
Referenced by split_reg().
|
static |
Return true if LIST contains a deleted insn.
Referenced by lra_constraints().
|
static |
Return true if X contains an allocatable hard register (if HARD_REG_P) or a (spilled if SPILLED_P) pseudo.
References lra_get_regno_hard_regno(), lra_no_alloc_regs, and overlaps_hard_reg_set_p().
Referenced by lra_constraints().
|
static |
Return TRUE if REGNO was reloaded in an equivalence init insn. We call this function only for non-reverse equivalence.
References ira_reg_equiv::init_insns.
Referenced by lra_constraints().
|
static |
Main entry point of the constraint code: search the body of the current insn to choose the best alternative. It is mimicking insn alternative cost calculation model of former reload pass. That is because machine descriptions were written to use this model. This model can be changed in future. Make commutative operand exchange if it is chosen. Return true if some RTL changes happened during function call.
References base_reg_class(), best_losers, best_overall, best_reload_sum, bitmap_set_bit(), cc0_rtx, change_class(), check_and_process_move(), lra_static_insn_data::commutative, operand_alternative::constraint, copy_rtx(), curr_insn, curr_insn_set, curr_operand_mode, curr_swapped, dump_value_slim(), emit_inc(), emit_insn(), emit_spill_move(), end_sequence(), error_for_asm(), find_reg_note(), force_const_mem(), gen_rtx_SUBREG(), get_equiv_substitution(), get_insn_name(), get_insns(), get_reg_class(), get_reload_reg(), get_try_hard_regno(), goal_alt, goal_alt_dont_inherit_ops, goal_alt_dont_inherit_ops_num, goal_alt_match_win, goal_alt_matches, goal_alt_number, goal_alt_offmemok, goal_alt_swapped, goal_alt_win, in_class_p(), lra_operand_data::is_operator, lra_create_new_reg(), lra_dump_file, lra_emit_move(), lra_former_scratch_operand_p(), lra_get_regno_hard_regno(), lra_invalidate_insn_data(), lra_optional_reload_pseudos, lra_process_new_insns(), lra_reg_info, lra_set_insn_deleted(), lra_set_regno_unique_value(), lra_set_used_insn_alternative(), lra_simple_p, lra_undo_inheritance_iter, lra_update_dup(), lra_update_insn_regno_info(), lra_update_operator_dups(), match_reload(), max_reg_num(), address_info::mode, n_alternatives(), lra_static_insn_data::n_alternatives, n_operands, lra_static_insn_data::n_operands, new_regno_start, no_input_reloads_p, no_output_reloads_p, OP_IN, OP_INOUT, OP_OUT, lra_static_insn_data::operand, lra_static_insn_data::operand_alternative, lra_insn_recog_data::operand_loc, process_address(), process_alt_operands(), push_to_sequence(), reg_referenced_p(), reg_renumber, reg_set_p(), lra_reg::restore_regno, rld, RTX_AUTOINC, simple_move_p(), simplify_operand_subreg(), simplify_subreg_regno(), start_sequence(), lra_operand_data::strict_low, subst(), swap_operands(), targetm, and lra_insn_recog_data::used_insn_alternative.
Referenced by lra_constraints().
|
static |
Return true if X contains a pseudo dying in INSN.
References find_regno_note().
Referenced by insn_rhs_dead_pseudo_p().
|
static |
Emit insns to reload VALUE into a new register. VALUE is an auto-increment or auto-decrement RTX whose operand is a register or memory location; so reloading involves incrementing that location. IN is either identical to VALUE, or some cheaper place to reload value being incremented/decremented from. INC_AMOUNT is the number to increment or decrement by (always positive and ignored for POST_MODIFY/PRE_MODIFY). Return pseudo containing the result.
References add_insn(), delete_insns_since(), emit_insn(), gen_add2_insn(), gen_move_insn(), gen_sub2_insn(), get_last_insn(), last, lra_create_new_reg(), recog_memoized(), and rtx_equal_p().
Referenced by curr_insn_transform().
|
static |
Return generated insn mem_pseudo:=val if TO_P or val:=mem_pseudo otherwise. If modes of MEM_PSEUDO and VAL are different, use SUBREG for VAL to make them equal.
References gen_lowpart_SUBREG(), gen_move_insn(), and gen_rtx_SUBREG().
Referenced by curr_insn_transform(), and split_reg().
|
static |
Make equiv substitution in address AD. Return true if a substitution was made.
References address_info::base_term, address_info::base_term2, can_add_disp_p(), curr_insn, address_info::disp, dump_value_slim(), get_equiv_substitution(), get_index_scale(), HOST_WIDE_INT, address_info::index_term, address_info::inner, lra_dump_file, address_info::outer, plus_constant(), strip_subreg(), and update_address().
Referenced by process_address().
|
static |
Fix BB live info LIVE after removing pseudos created on pass doing inheritance/split which are REMOVED_PSEUDOS.
References bitmap_clear_bit(), bitmap_set_bit(), lra_reg_info, and lra_insn_reg::regno.
Referenced by remove_inheritance_pseudos().
|
inlinestatic |
Return true if X is a general constant.
Referenced by process_alt_operands().
|
static |
If we have decided to substitute X with another value, return that value, otherwise return X.
References lra_get_regno_hard_regno().
Referenced by curr_insn_transform(), equiv_address_substitution(), loc_equivalence_callback(), loc_equivalence_change_p(), lra_constraints(), and process_addr_reg().
|
static |
Return final hard regno (plus offset) which will be after elimination. We do this for matching constraints because the final hard regno could have a different class.
References lra_get_elimination_hard_regno(), and offset.
Referenced by get_hard_regno(), and get_reg_class().
|
static |
Return hard regno of X after removing subreg and making elimination. If X is not a register or subreg of register, return -1. For pseudo use its assignment.
References get_final_hard_regno(), lra_get_regno_hard_regno(), offset, and subreg_regno_offset().
Referenced by operands_match_p(), process_alt_operands(), and uses_hard_regs_p().
|
static |
Return the last non-debug insn in basic block BB, or the block begin note if none.
Referenced by get_live_on_other_edges(), and inherit_in_ebb().
|
static |
Set up RES by registers living on edges FROM except the edge (FROM, TO) or by registers set up in a jump insn in BB FROM.
References bitmap_clear(), bitmap_ior_into(), bitmap_set_bit(), edge_def::dest, df_get_live_in(), get_last_insertion_point(), last, lra_get_insn_recog_data(), lra_insn_reg::next, OP_IN, lra_insn_reg::regno, lra_insn_recog_data::regs, and basic_block_def::succs.
Referenced by inherit_in_ebb().
|
inlinestatic |
If OP is a register, return the class of the register as per get_reg_class, otherwise return NO_REGS.
References get_reg_class().
Referenced by simple_move_p().
|
static |
If REGNO is a hard register or has been allocated a hard register, return the class of that register. If REGNO is a reload pseudo created by the current constraints pass, return its allocno class. Return NO_REGS otherwise.
References get_final_hard_regno(), lra_get_allocno_class(), lra_get_regno_hard_regno(), and new_regno_start.
Referenced by check_and_process_move(), check_secondary_memory_needed_p(), curr_insn_transform(), get_op_class(), in_class_p(), in_mem_p(), inherit_reload_reg(), process_addr_reg(), process_alt_operands(), and reg_in_class_p().
|
static |
Return regno of the (subreg of) REG. Otherwise, return a negative number.
Referenced by remove_inheritance_pseudos().
|
static |
Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already created input reload pseudo (only if TYPE is not OP_OUT). The result pseudo is returned through RESULT_REG. Return TRUE if we created a new pseudo, FALSE if we reused the already created input reload pseudo. Use TITLE to describe new registers for debug purposes.
References change_class(), curr_insn_input_reloads, curr_insn_input_reloads_num, dump_value_slim(), in_class_p(), input_reload::input, lowpart_subreg(), lra_create_new_reg(), lra_create_new_reg_with_unique_value(), lra_dump_file, lra_get_allocno_class(), OP_OUT, input_reload::reg, rtx_equal_p(), and side_effects_p().
Referenced by curr_insn_transform(), process_addr_reg(), and simplify_operand_subreg().
|
static |
Return hard regno of REGNO or if it is was not assigned to a hard register, use a hard register from its allocno class.
References lra_get_allocno_class(), and lra_get_regno_hard_regno().
Referenced by curr_insn_transform().
|
static |
Return true if REG satisfies (or will satisfy) reg class constraint CL. Use elimination first if REG is a hard register. If REG is a reload pseudo created by this constraints pass, assume that it will be allocated a hard register from its allocno class, but allow that class to be narrowed to CL if it is currently a superset of CL. If NEW_CLASS is nonnull, set *NEW_CLASS to the new allocno class of REGNO (reg), or NO_REGS if no change in its class was needed.
References curr_insn, get_reg_class(), hard_reg_set_subset_p(), lra_eliminate_reg_if_possible(), lra_no_alloc_regs, new_insn_uid_start, new_regno_start, and reg_mode.
Referenced by curr_insn_transform(), get_reload_reg(), narrow_reload_pseudo_class(), process_addr_reg(), process_alt_operands(), and reg_in_class_p().
|
static |
Return true if X is in LIST.
Referenced by lra_constraints().
|
static |
Return true if REGNO satisfies a memory constraint.
References get_reg_class().
Referenced by spilled_pseudo_p().
|
static |
Do inheritance/split transformations in EBB starting with HEAD and finishing on TAIL. We process EBB insns in the reverse order. Return true if we did any inheritance/split transformation in the EBB. We should avoid excessive splitting which results in worse code because of inaccurate cost calculations for spilling new split pseudos in such case. To achieve this we do splitting only if register pressure is high in given basic block and there are reload pseudos requiring hard registers. We could do more register pressure calculations at any given program point to avoid necessary splitting even more but it is to expensive and the current approach works well enough.
References add_next_usage_insn(), add_to_hard_reg_set(), add_to_inherit(), bb_note(), bitmap_clear(), bitmap_set_bit(), calls_num, usage_insns::calls_num, usage_insns::check, copy_rtx(), curr_bb, curr_insn, curr_usage_insns_check, df_get_live_in(), df_get_live_out(), eliminable_regset, emit_move_insn(), end_sequence(), find_reg_note(), get_insns(), get_last_insertion_point(), get_live_on_other_edges(), get_max_uid(), hard_reg_set_subset_p(), lra_static_insn_data::hard_regs, inherit_reload_reg(), lra_insn_recog_data::insn_static_data, usage_insns::insns, live_hard_regs, lra_constraint_new_regno_start, lra_dump_file, lra_get_allocno_class(), lra_get_insn_recog_data(), lra_no_alloc_regs, lra_process_new_insns(), lra_risky_transformations_p, max_uid, need_for_split_p(), lra_insn_reg::next, OP_IN, OP_OUT, reg_renumber, lra_insn_reg::regno, to_inherit::regno, lra_insn_recog_data::regs, reloads_num, setup_next_usage_insn(), split_if_necessary(), split_reg(), start_sequence(), lra_insn_reg::subreg_p, temp_bitmap, and to_inherit_num.
Referenced by lra_inheritance().
|
static |
Do inheritance transformations for insn INSN, which defines (if DEF_P) or uses ORIGINAL_REGNO. NEXT_USAGE_INSNS specifies which instruction in the EBB next uses ORIGINAL_REGNO; it has the same form as the "insns" field of usage_insns. Return true if we succeed in such transformation. The transformations look like: p <- ... i <- ... ... p <- i (new insn) ... => <- ... p ... <- ... i ... or ... i <- p (new insn) <- ... p ... <- ... i ... ... => <- ... p ... <- ... i ... where p is a spilled original pseudo and i is a new inheritance pseudo. The inheritance pseudo has the smallest class of two classes CL and class of ORIGINAL REGNO.
References usage_insns::after_p, bitmap_set_bit(), check_secondary_memory_needed_p(), dump_insn_slim(), dump_rtl_slim(), emit_move_insn(), end_sequence(), get_insns(), get_reg_class(), lra_create_new_reg(), lra_dump_file, lra_get_allocno_class(), lra_inheritance_pseudos, lra_process_new_insns(), lra_reg_info, lra_update_insn_regno_info(), reg_class_names, regno_reg_rtx, reloads_num, lra_reg::restore_regno, setup_next_usage_insn(), skip_usage_debug_insns(), start_sequence(), and substitute_pseudo().
Referenced by inherit_in_ebb().
|
static |
Initiate data concerning reuse of input reloads for the current insn.
References curr_insn_input_reloads_num.
Referenced by lra_constraints().
|
static |
Set up curr_operand_mode.
References curr_operand_mode, lra_insn_recog_data::icode, lra_operand_data::is_address, lra_static_insn_data::n_operands, lra_static_insn_data::operand, and lra_insn_recog_data::operand_loc.
Referenced by lra_constraints().
|
static |
Return true if any init insn of REGNO contains a dying pseudo in insn right hand side.
References ira_reg_equiv::init_insns, and insn_rhs_dead_pseudo_p().
Referenced by lra_constraints().
|
static |
Return true if INSN contains a dying pseudo in INSN right hand side.
References dead_pseudo_p().
Referenced by init_insn_rhs_dead_pseudo_p().
|
static |
Similar to loc_equivalence_change_p, but for use as simplify_replace_fn_rtx callback.
References get_equiv_substitution(), and subst().
Referenced by lra_constraints().
|
static |
Process all regs in location *LOC and change them on equivalent substitution. Return true if any change was done.
References get_equiv_substitution(), simplify_gen_subreg(), and subst().
Referenced by lra_constraints().
int lra_constraint_offset | ( | ) |
The page contains major code to choose the current insn alternative and generate reloads for it.
Return the offset from REGNO of the least significant register in (reg:MODE REGNO). This function is used to tell whether two registers satisfy a matching constraint. (reg:MODE1 REGNO1) matches (reg:MODE2 REGNO2) if: REGNO1 + lra_constraint_offset (REGNO1, MODE1) == REGNO2 + lra_constraint_offset (REGNO2, MODE2)
Referenced by operands_match_p().
bool lra_constraints | ( | ) |
Entry function of LRA constraint pass. Return true if the constraint pass did change the code.
References bb_reload_num, lra_reg::biggest_mode, bitmap_bit_p(), bitmap_clear(), bitmap_ior_into(), contains_deleted_insn_p(), contains_reg_p(), contains_reloaded_insn_p(), curr_bb, curr_insn, curr_insn_transform(), ira_reg_equiv::defined_p, df_regs_ever_live_p(), df_set_regs_ever_live(), dump_insn_slim(), frequency, get_equiv_substitution(), get_max_uid(), in_list_p(), init_curr_insn_input_reloads(), init_curr_operand_mode(), init_insn_rhs_dead_pseudo_p(), lra_insn_recog_data::insn_static_data, internal_error(), last_bb, loc_equivalence_callback(), loc_equivalence_change_p(), lra_constraint_iter, lra_constraint_iter_after_spill, lra_constraint_new_regno_start, lra_curr_reload_num, lra_dump_file, lra_eliminate(), lra_get_insn_recog_data(), lra_get_regno_hard_regno(), lra_insn_stack_length(), lra_pop_insn(), lra_push_insn_by_uid(), lra_reg_info, lra_risky_transformations_p, lra_set_insn_deleted(), lra_update_insn_regno_info(), max_reg_num(), multi_block_pseudo_p(), new_insn_uid_start, new_regno_start, lra_insn_recog_data::operand_loc, ira_reg_equiv::profitable_p, reg_obstack, regno_reg_rtx, reverse_equiv_p(), and simplify_replace_fn_rtx().
Referenced by lra().
void lra_constraints_finish | ( | void | ) |
Finalize the LRA constraint pass. It is done once per function.
Referenced by lra().
void lra_constraints_init | ( | void | ) |
Initiate the LRA constraint pass. It is done once per function.
Referenced by lra().
void lra_inheritance | ( | void | ) |
Entry function for inheritance/split pass.
References bitmap_clear(), bitmap_ior_into(), curr_usage_insns_check, df_get_live_in(), df_get_live_out(), find_fallthru_edge(), free(), basic_block_def::index, inherit_in_ebb(), lra_constraint_new_regno_start, lra_dump_file, lra_inheritance_iter, basic_block_def::next_bb, edge_def::probability, reg_obstack, basic_block_def::succs, timevar_pop(), timevar_push(), and update_ebb_live_info().
Referenced by lra().
bool lra_undo_inheritance | ( | void | ) |
Entry function for undoing inheritance/split transformation. Return true if we did any RTL change in this pass.
References bitmap_clear(), bitmap_set_bit(), lra_dump_file, lra_inheritance_pseudos, lra_reg_info, lra_split_regs, lra_undo_inheritance_iter, reg_obstack, reg_renumber, lra_insn_reg::regno, remove_inheritance_pseudos(), remove_pseudos(), lra_reg::restore_regno, and undo_optional_reloads().
Referenced by lra().
|
static |
Generate reloads for matching OUT and INS (array of input operand numbers with end marker -1) with reg class GOAL_CLASS. Add input and output reloads correspondingly to the lists *BEFORE and *AFTER. OUT might be negative. In this case we generate input reloads for matched input operands INS.
References copy_rtx(), curr_insn, curr_operand_mode, emit_clobber(), emit_insn(), end_sequence(), find_reg_note(), find_regno_note(), gen_lowpart_SUBREG(), gen_rtx_SUBREG(), get_insns(), lra_assign_reg_val(), lra_create_new_reg_with_unique_value(), lra_emit_move(), lra_new_regno_start, lra_update_dup(), lra_update_dups(), narrow_reload_pseudo_class(), lra_insn_recog_data::operand_loc, push_to_sequence(), input_reload::reg, and start_sequence().
Referenced by curr_insn_transform().
|
static |
Return true if REGNO is referenced in more than one block.
References lra_reg_info.
Referenced by lra_constraints().
|
static |
If REG is a reload pseudo, try to make its class satisfying CL.
References change_class(), curr_insn, in_class_p(), new_insn_uid_start, and new_regno_start.
Referenced by match_reload().
|
inlinestatic |
Return true if we need a caller save/restore for pseudo REGNO which was assigned to a hard register.
References calls_num, overlaps_hard_reg_set_p(), and reg_renumber.
Referenced by need_for_split_p(), and split_reg().
|
inlinestatic |
Return true if we need a split for hard register REGNO or pseudo REGNO which was assigned to a hard register. POTENTIAL_RELOAD_HARD_REGS contains hard registers which might be used for reloads since the EBB end. It is an approximation of the used hard registers in the split range. The exact value would require expensive calculations. If we were aggressive with splitting because of the approximation, the split pseudo will save the same hard register assignment and will be removed in the undo pass. We still need the approximation because too aggressive splitting would result in too inaccurate cost calculation in the assignment pass because of too many generated moves which will be probably removed in the undo pass.
References bitmap_bit_p(), calls_num, eliminable_regset, lra_no_alloc_regs, lra_reg_info, need_for_call_save_p(), reg_renumber, and reloads_num.
Referenced by inherit_in_ebb(), and split_if_necessary().
|
inlinestatic |
A version of regno_ok_for_base_p for use here, when all pseudos should count as OK. Arguments as for regno_ok_for_base_p.
References ok_for_base_p_1().
|
inlinestatic |
The page contains code to extract memory address parts.
Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudos.
|
static |
Like rtx_equal_p except that it allows a REG and a SUBREG to match if they are the same hard reg, and has special hacks for auto-increment and auto-decrement. This is specifically intended for process_alt_operands to use in determining whether two operands match. X is the operand whose number is the lower of the two. It is supposed that X is the output operand and Y is the input operand. Y_HARD_REGNO is the final hard regno of register Y or register in subreg Y as we know it now. Otherwise, it is a negative value.
References get_hard_regno(), and lra_constraint_offset().
Referenced by check_asm_stack_operands(), constrain_operands(), find_reloads(), operands_match_p(), process_alt_operands(), regmove_backward_pass(), and subst_asm_stack_regs().
|
static |
Arrange for address element *LOC to be a register of class CL. Add any input reloads to list BEFORE. AFTER is nonnull if *LOC is an automodified value; handle that case by adding the required output reloads to list AFTER. Return true if the RTL was changed.
References change_class(), copy_rtx(), curr_insn, dump_value_slim(), emit_insn(), end_sequence(), get_equiv_substitution(), get_insns(), get_reg_class(), get_reload_reg(), in_class_p(), lra_create_new_reg_with_unique_value(), lra_dump_file, lra_emit_move(), OP_IN, OP_INOUT, push_to_sequence(), input_reload::reg, start_sequence(), and strip_subreg().
Referenced by process_address().
|
static |
Major function to make reloads for an address in operand NOP. The supported cases are: 1) an address that existed before LRA started, at which point it must have been valid. These addresses are subject to elimination and may have become invalid due to the elimination offset being out of range. 2) an address created by forcing a constant to memory (force_const_to_mem). The initial form of these addresses might not be valid, and it is this function's job to make them valid. 3) a frame address formed from a register and a (possibly zero) constant offset. As above, these addresses might not be valid and this function must make them so. Add reloads to the lists *BEFORE and *AFTER. We might need to add reloads to *AFTER because of inc/dec, {pre, post} modify in the address. Return true for any RTL change.
References address_info::as, address_info::autoinc_p, address_info::base, address_info::base_outer_code, base_plus_disp_to_reg(), base_reg_class(), address_info::base_term, address_info::base_term2, change_class(), lra_operand_data::constraint, copy_rtx(), curr_insn, decompose_lea_address(), decompose_mem_address(), delete_insns_since(), address_info::disp, address_info::disp_term, emit_insn(), end_sequence(), equiv_address_substitution(), find_regno_note(), get_index_code(), get_insns(), get_last_insn(), address_info::index, address_info::index_term, address_info::inner, last, lra_create_new_reg(), lra_emit_move(), lra_get_allocno_class(), address_info::mode, lra_static_insn_data::operand, lra_insn_recog_data::operand_loc, address_info::outer, process_addr_reg(), push_to_sequence(), recog_memoized(), simplify_gen_binary(), start_sequence(), and valid_address_p().
Referenced by curr_insn_transform().
|
static |
Major function to choose the current insn alternative and what operands should be reloaded and how. If ONLY_ALTERNATIVE is not negative we should consider only this alternative. Return false if we can not choose the alternative or find how to reload the operands.
References add_to_hard_reg_set(), lra_insn_recog_data::alternative_enabled_p, operand_alternative::anything_ok, base_reg_class(), bb_reload_num, best_losers, best_overall, best_reload_nregs, best_reload_sum, operand_alternative::constraint, curr_insn, curr_insn_set, curr_operand_mode, curr_swapped, lra_operand_data::early_clobber, find_reg_note(), find_regno_note(), general_constant_p(), get_hard_regno(), get_reg_class(), goal_alt, goal_alt_dont_inherit_ops, goal_alt_dont_inherit_ops_num, goal_alt_match_win, goal_alt_matches, goal_alt_number, goal_alt_offmemok, goal_alt_swapped, goal_alt_win, hard_reg_set_subset_p(), in_class_p(), in_hard_reg_set_p(), lra_operand_data::is_operator, lra_reg::last_reload, len, lra_dump_file, lra_former_scratch_p(), lra_no_alloc_regs, lra_reg_info, address_info::mode, n_alternatives(), lra_static_insn_data::n_alternatives, n_operands, lra_static_insn_data::n_operands, no_input_reloads_p, no_output_reloads_p, offsettable_nonstrict_memref_p(), OP_IN, OP_OUT, lra_static_insn_data::operand, lra_static_insn_data::operand_alternative, lra_insn_recog_data::operand_loc, operands_match_p(), reg_in_class_p(), operand_alternative::reject, reject(), spilled_pseudo_p(), lra_operand_data::strict_low, targetm, and uses_hard_regs_p().
Referenced by curr_insn_transform().
|
static |
Return register class which is union of all reg classes in insn constraint alternative string starting with P.
References base_reg_class(), and len.
Referenced by check_and_process_move().
|
static |
References get_reg_class(), and in_class_p().
Referenced by process_alt_operands().
|
static |
Remove inheritance/split pseudos which are in REMOVE_PSEUDOS and return true if we did any change. The undo transformations for inheritance looks like i <- i2 p <- i => p <- i2 or removing p <- i, i <- p, and i <- i3 where p is original pseudo from which inheritance pseudo i was created, i and i3 are removed inheritance pseudos, i2 is another not removed inheritance pseudo. All split pseudos or other occurrences of removed inheritance pseudos are changed on the corresponding original pseudos. The function also schedules insns changed and created during inheritance/split pass for processing by the subsequent constraint pass.
References bitmap_bit_p(), bitmap_empty_p(), curr_insn, df_get_live_in(), df_get_live_out(), dump_insn_slim(), fix_bb_live_info(), get_regno(), lra_dump_file, lra_get_insn_recog_data(), lra_inheritance_pseudos, lra_push_insn_and_update_insn_regno_info(), lra_reg_info, lra_set_insn_deleted(), lra_set_used_insn_alternative_by_uid(), lra_split_regs, lra_update_insn_regno_info(), lra_insn_reg::next, lra_insn_reg::regno, regno_reg_rtx, lra_insn_recog_data::regs, lra_reg::restore_regno, and substitute_pseudo().
Referenced by lra_undo_inheritance().
|
static |
Return TRUE if REGNO has a reverse equivalence. The equivalence is reverse only if we have one init insn with given REGNO as a source.
Referenced by lra_constraints().
|
static |
References usage_insns::after_p, calls_num, usage_insns::calls_num, usage_insns::check, curr_usage_insns_check, usage_insns::insns, reloads_num, and usage_insns::reloads_num.
Referenced by add_next_usage_insn(), inherit_in_ebb(), and inherit_reload_reg().
|
static |
Return true if the current move insn does not need processing as we already know that it satisfies its constraints.
References curr_insn_set, get_op_class(), and targetm.
Referenced by curr_insn_transform().
|
static |
Make reloads for subreg in operand NOP with internal subreg mode REG_MODE, add new reloads for further processing. Return true if any reload was generated.
References alter_subreg(), bitmap_set_bit(), curr_insn, emit_insn(), end_sequence(), force_const_mem(), get_insns(), get_reload_reg(), lra_emit_move(), lra_get_regno_hard_regno(), lra_process_new_insns(), lra_subreg_reload_pseudos, OP_IN, OP_OUT, lra_static_insn_data::operand, lra_insn_recog_data::operand_loc, push_to_sequence(), input_reload::reg, simplify_subreg_regno(), start_sequence(), and targetm.
Referenced by curr_insn_transform().
|
static |
Return first non-debug insn in list USAGE_INSNS.
Referenced by check_secondary_memory_needed_p(), and inherit_reload_reg().
|
inlinestatic |
|
static |
Recognize that we need a split transformation for insn INSN, which defines or uses REGNO in its insn biggest MODE (we use it only if REGNO is a hard register). POTENTIAL_RELOAD_HARD_REGS contains hard registers which might be used for reloads since the EBB end. Put the save before INSN if BEFORE_P is true. MAX_UID is maximla uid before starting INSN processing. Return true if we succeed in such transformation.
References usage_insns::check, curr_usage_insns_check, usage_insns::insns, need_for_split_p(), and split_reg().
Referenced by inherit_in_ebb().
|
static |
Do split transformations for insn INSN, which defines or uses ORIGINAL_REGNO. NEXT_USAGE_INSNS specifies which instruction in the EBB next uses ORIGINAL_REGNO; it has the same form as the "insns" field of usage_insns. The transformations look like: p <- ... p <- ... ... s <- p (new insn -- save) ... => ... p <- s (new insn -- restore) <- ... p ... <- ... p ... or <- ... p ... <- ... p ... ... s <- p (new insn -- save) ... => ... p <- s (new insn -- restore) <- ... p ... <- ... p ... where p is an original pseudo got a hard register or a hard register and s is a new split pseudo. The save is put before INSN if BEFORE_P is true. Return true if we succeed in such transformation.
References usage_insns::after_p, bitmap_set_bit(), choose_split_class(), dump_insn_slim(), dump_rtl_slim(), emit_spill_move(), lra_create_new_reg(), lra_dump_file, lra_get_allocno_class(), lra_process_new_insns(), lra_reg_info, lra_risky_transformations_p, lra_split_regs, lra_update_insn_regno_info(), need_for_call_save_p(), reg_class_names, reg_renumber, regno_reg_rtx, lra_reg::restore_regno, and substitute_pseudo().
Referenced by inherit_in_ebb(), and split_if_necessary().
|
inlinestatic |
If LOC is nonnull, strip any outer subreg from it.
Referenced by equiv_address_substitution(), process_addr_reg(), and valid_address_p().
|
static |
Replace all references to register OLD_REGNO in *LOC with pseudo register NEW_REG. Return true if any change was made.
References gen_lowpart_SUBREG(), and gen_rtx_SUBREG().
Referenced by inherit_reload_reg(), remove_inheritance_pseudos(), split_reg(), and undo_optional_reloads().
|
inlinestatic |
Swap operands NOP and NOP + 1.
References curr_operand_mode, lra_update_dup(), address_info::mode, and lra_insn_recog_data::operand_loc.
Referenced by curr_insn_transform().
|
static |
If optional reload pseudos failed to get a hard register or was not inherited, it is better to remove optional reloads. We do this transformation after undoing inheritance to figure out necessity to remove optional reloads easier. Return true if we do any change.
References bitmap_clear(), bitmap_clear_bit(), bitmap_copy(), bitmap_empty_p(), dump_insn_slim(), lra_insn_recog_data::insn, lra_dump_file, lra_optional_reload_pseudos, lra_reg_info, lra_set_insn_deleted(), lra_update_insn_regno_info(), reg_obstack, reg_renumber, lra_insn_reg::regno, regno_reg_rtx, lra_reg::restore_regno, and substitute_pseudo().
Referenced by lra_undo_inheritance().
|
static |
Update live info in EBB given by its HEAD and TAIL insns after inheritance/split transformation. The function removes dead moves too.
References bitmap_and(), bitmap_bit_p(), bitmap_clear_bit(), bitmap_set_bit(), curr_bb, curr_insn, edge_def::dest, df_get_live_in(), df_get_live_out(), dump_insn_slim(), last_bb, lra_dump_file, lra_get_insn_recog_data(), lra_set_insn_deleted(), lra_insn_reg::next, OP_OUT, lra_insn_reg::regno, lra_insn_recog_data::regs, lra_insn_reg::subreg_p, and basic_block_def::succs.
Referenced by lra_inheritance().
|
static |
Return TRUE if X refers for a hard register from SET.
References address_info::base_term, decompose_mem_address(), get_hard_regno(), address_info::index_term, and overlaps_hard_reg_set_p().
Referenced by process_alt_operands().
|
static |
Return 1 if ADDR is a valid memory address for mode MODE in address space AS, and check that each pseudo has the proper kind of hard reg.
References address_info::mode, and targetm.
Referenced by process_address(), and valid_address_p().
|
static |
Return whether address AD is valid.
References address_info::as, address_info::base_term, address_info::base_term2, address_info::index_term, lra_eliminate_reg_if_possible(), address_info::mode, address_info::outer, strip_subreg(), and valid_address_p().
|
static |
Code for RTL transformations to satisfy insn constraints. Copyright (C) 2010-2013 Free Software Foundation, Inc. Contributed by Vladimir Makarov <vmakarov@redhat.com>. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later 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 code for 3 passes: constraint pass, inheritance/split pass, and pass for undoing failed inheritance and split. The major goal of constraint pass is to transform RTL to satisfy insn and address constraints by: o choosing insn alternatives; o generating *reload insns* (or reloads in brief) and *reload pseudos* which will get necessary hard registers later; o substituting pseudos with equivalent values and removing the instructions that initialized those pseudos. The constraint pass has biggest and most complicated code in LRA. There are a lot of important details like: o reuse of input reload pseudos to simplify reload pseudo allocations; o some heuristics to choose insn alternative to improve the inheritance; o early clobbers etc. The pass is mimicking former reload pass in alternative choosing because the reload pass is oriented to current machine description model. It might be changed if the machine description model is changed. There is special code for preventing all LRA and this pass cycling in case of bugs. On the first iteration of the pass we process every instruction and choose an alternative for each one. On subsequent iterations we try to avoid reprocessing instructions if we can be sure that the old choice is still valid. The inheritance/spilt pass is to transform code to achieve ineheritance and live range splitting. It is done on backward traversal of EBBs. The inheritance optimization goal is to reuse values in hard registers. There is analogous optimization in old reload pass. The inheritance is achieved by following transformation: reload_p1 <- p reload_p1 <- p ... new_p <- reload_p1 ... => ... reload_p2 <- p reload_p2 <- new_p where p is spilled and not changed between the insns. Reload_p1 is also called *original pseudo* and new_p is called *inheritance pseudo*. The subsequent assignment pass will try to assign the same (or another if it is not possible) hard register to new_p as to reload_p1 or reload_p2. If the assignment pass fails to assign a hard register to new_p, this file will undo the inheritance and restore the original code. This is because implementing the above sequence with a spilled new_p would make the code much worse. The inheritance is done in EBB scope. The above is just a simplified example to get an idea of the inheritance as the inheritance is also done for non-reload insns. Splitting (transformation) is also done in EBB scope on the same pass as the inheritance: r <- ... or ... <- r r <- ... or ... <- r ... s <- r (new insn -- save) ... => ... r <- s (new insn -- restore) ... <- r ... <- r The *split pseudo* s is assigned to the hard register of the original pseudo or hard register r. Splitting is done: o In EBBs with high register pressure for global pseudos (living in at least 2 BBs) and assigned to hard registers when there are more one reloads needing the hard registers; o for pseudos needing save/restore code around calls. If the split pseudo still has the same hard register as the original pseudo after the subsequent assignment pass or the original pseudo was split, the opposite transformation is done on the same pass for undoing inheritance.
Value of LRA_CURR_RELOAD_NUM at the beginning of BB of the current insn. Remember that LRA_CURR_RELOAD_NUM is the number of emitted reload insns.
Referenced by lra_constraints(), and process_alt_operands().
|
static |
The following five variables are used to choose the best insn alternative. They reflect final characteristics of the best alternative.
Number of necessary reloads and overall cost reflecting the previous value and other unpleasantness of the best alternative.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Overall number hard registers used for reloads. For example, on some targets we need 2 general registers to reload DFmode and only one floating point register.
Referenced by process_alt_operands().
|
static |
Overall number reflecting distances of previous reloading the same value. The distances are counted from the current BB start. It is used to improve inheritance chances.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Number of calls passed so far in current EBB.
Referenced by inherit_in_ebb(), need_for_call_save_p(), need_for_split_p(), and setup_next_usage_insn().
|
static |
Registers involved in inheritance/split in the current EBB (inheritance/split pseudos and original registers).
|
static |
Referenced by inherit_in_ebb(), lra_constraints(), and update_ebb_live_info().
|
static |
|
static |
The current insn being processed and corresponding its single set (NULL otherwise), its data (basic block, the insn data, the insn static data, and the mode of each operand).
Referenced by check_and_process_move(), curr_insn_transform(), equiv_address_substitution(), find_and_remove_re(), in_class_p(), inherit_in_ebb(), lra_constraints(), match_reload(), narrow_reload_pseudo_class(), process_addr_reg(), process_address(), process_alt_operands(), process_insn_equiv_class(), remove_inheritance_pseudos(), set_insn_equiv_classes(), simplify_operand_subreg(), and update_ebb_live_info().
|
static |
Array containing info about input reloads. It is used to find the same input reload and reuse the reload pseudo in this case.
Referenced by get_reload_reg().
|
static |
The number of elements in the following array.
Referenced by get_reload_reg(), and init_curr_insn_input_reloads().
|
static |
Referenced by check_and_process_move(), curr_insn_transform(), process_alt_operands(), and simple_move_p().
|
static |
Referenced by curr_insn_transform(), init_curr_operand_mode(), match_reload(), process_alt_operands(), and swap_operands().
|
static |
|
static |
True if we swapped the commutative operands in the current insn.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Current reload pseudo check for validity of elements in USAGE_INSNS.
Referenced by add_next_usage_insn(), inherit_in_ebb(), lra_inheritance(), setup_next_usage_insn(), and split_if_necessary().
|
static |
Global registers occurring in the current EBB.
|
static |
The following data describe the result of process_alt_operands. The data are used in curr_insn_transform to generate reloads.
The chosen reg classes which should be used for the corresponding operands.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Numbers of operands whose reload pseudos should not be inherited.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
The number of elements in the following array.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
True if the operand should be the same as another operand and that other operand does not need a reload.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
The number of an operand to which given operand can be matched to.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
The chosen insn alternative.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
True if the operand can be offsetable memory.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
True if the insn commutative operands should be swapped.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
True if the operand does not need a reload.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Check only registers living at the current program point in the current EBB.
int lra_constraint_iter |
The current iteration number of this LRA pass.
Referenced by lra(), and lra_constraints().
int lra_constraint_iter_after_spill |
The current iteration number of this LRA pass after the last spill pass.
Referenced by lra(), and lra_constraints().
int lra_inheritance_iter |
Current number of inheritance/split iteration.
Referenced by improve_inheritance(), lra(), and lra_inheritance().
bool lra_risky_transformations_p |
True if we substituted equiv which needs checking register allocation correctness because the equivalent value contains allocatable hard registers or when we restore multi-register pseudo.
Referenced by inherit_in_ebb(), lra_constraints(), setup_live_pseudos_and_spill_after_risky_transforms(), and split_reg().
int lra_undo_inheritance_iter |
This page contains code to undo failed inheritance/split transformations.
Current number of iteration undoing inheritance/split.
Referenced by curr_insn_transform(), lra(), and lra_undo_inheritance().
|
static |
Referenced by in_class_p(), lra_constraints(), and narrow_reload_pseudo_class().
|
static |
Start numbers for new registers and insns at the current constraints pass start.
Referenced by curr_insn_transform(), get_reg_class(), in_class_p(), lra_constraints(), and narrow_reload_pseudo_class().
|
static |
True if the current insn should have no correspondingly input or output reloads.
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
Referenced by curr_insn_transform(), and process_alt_operands().
|
static |
This page contains code to do inheritance/split transformations.
Number of reloads passed so far in current EBB.
Referenced by inherit_in_ebb(), inherit_reload_reg(), need_for_split_p(), and setup_next_usage_insn().
|
static |
Used as a temporary results of some bitmap calculations.
Referenced by compute_earliest(), compute_farthest(), and inherit_in_ebb().
|
static |
Array containing all info for doing inheritance from the current insn.
|
static |
Number elements in the previous array.
Referenced by add_to_inherit(), and inherit_in_ebb().
|
static |
Map: regno -> corresponding pseudo usage insns.