GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "expmed.h"
#include "insn-config.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cfgrtl.h"
#include "cfgbuild.h"
#include "dce.h"
#include "expr.h"
#include "explow.h"
#include "tree-pass.h"
#include "lower-subreg.h"
#include "rtl-iter.h"
#include "target.h"
Data Structures | |
struct | cost_rtxes |
Macros | |
#define | LOG_COSTS 0 |
#define | FORCE_LOWERING 0 |
#define | twice_word_mode this_target_lower_subreg->x_twice_word_mode |
#define | choices this_target_lower_subreg->x_choices |
Enumerations | |
enum | classify_move_insn { NOT_SIMPLE_MOVE , DECOMPOSABLE_SIMPLE_MOVE , SIMPLE_MOVE } |
Functions | |
static bool | interesting_mode_p (machine_mode mode, unsigned int *bytes, unsigned int *words) |
static int | shift_cost (bool speed_p, struct cost_rtxes *rtxes, enum rtx_code code, machine_mode mode, int op1) |
static void | compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes, bool *splitting, enum rtx_code code, int word_move_zero_cost, int word_move_cost) |
static void | compute_costs (bool speed_p, struct cost_rtxes *rtxes) |
void | init_lower_subreg (void) |
static bool | simple_move_operand (rtx x) |
static rtx | operand_for_swap_move_operator (rtx x) |
static rtx | simple_move (rtx_insn *insn, bool speed_p) |
static bool | find_pseudo_copy (rtx set) |
static void | propagate_pseudo_copies (void) |
static void | find_decomposable_subregs (rtx *loc, enum classify_move_insn *pcmi) |
static void | decompose_register (unsigned int regno) |
static rtx | simplify_subreg_concatn (machine_mode outermode, rtx op, poly_uint64 orig_byte) |
static rtx | simplify_gen_subreg_concatn (machine_mode outermode, rtx op, machine_mode innermode, unsigned int byte) |
static bool | resolve_reg_p (rtx x) |
static bool | resolve_subreg_p (rtx x) |
static bool | resolve_subreg_use (rtx *loc, rtx insn) |
static void | resolve_reg_notes (rtx_insn *insn) |
static bool | can_decompose_p (rtx x) |
static rtx | resolve_operand_for_swap_move_operator (rtx opnd) |
static rtx_insn * | resolve_simple_move (rtx set, rtx_insn *insn) |
static bool | resolve_clobber (rtx pat, rtx_insn *insn) |
static bool | resolve_use (rtx pat, rtx_insn *insn) |
static void | resolve_debug (rtx_insn *insn) |
static bool | find_decomposable_shift_zext (rtx_insn *insn, bool speed_p) |
static rtx_insn * | resolve_shift_zext (rtx_insn *insn, bool speed_p) |
static void | dump_shift_choices (enum rtx_code code, bool *splitting) |
static void | dump_choices (bool speed_p, const char *description) |
static void | decompose_multiword_subregs (bool decompose_copies) |
rtl_opt_pass * | make_pass_lower_subreg (gcc::context *ctxt) |
rtl_opt_pass * | make_pass_lower_subreg2 (gcc::context *ctxt) |
rtl_opt_pass * | make_pass_lower_subreg3 (gcc::context *ctxt) |
Variables | |
static bitmap | decomposable_context |
static bitmap | non_decomposable_context |
static bitmap | subreg_context |
static vec< bitmap > | reg_copy_graph |
struct target_lower_subreg | default_target_lower_subreg |
#define choices this_target_lower_subreg->x_choices |
#define FORCE_LOWERING 0 |
Referenced by compute_costs(), and compute_splitting_shift().
#define LOG_COSTS 0 |
Decompose multiword subregs. Copyright (C) 2007-2024 Free Software Foundation, Inc. Contributed by Richard Henderson <rth@redhat.com> Ian Lance Taylor <iant@google.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/>.
Decompose multi-word pseudo-registers into individual pseudo-registers when possible and profitable. This is possible when all the uses of a multi-word register are via SUBREG, or are copies of the register to another location. Breaking apart the register permits more CSE and permits better register allocation. This is profitable if the machine does not have move instructions to do this. This pass only splits moves with modes that are wider than word_mode and ASHIFTs, LSHIFTRTs, ASHIFTRTs and ZERO_EXTENDs with integer modes that are twice the width of word_mode. The latter could be generalized if there was a need to do this, but the trend in architectures is to not need this. There are two useful preprocessor defines for use by maintainers: #define LOG_COSTS 1 if you wish to see the actual cost estimates that are being used for each mode wider than word mode and the cost estimates for zero extension and the shifts. This can be useful when port maintainers are tuning insn rtx costs. #define FORCE_LOWERING 1 if you wish to test the pass with all the transformation forced on. This can be useful for finding bugs in the transformations.
Referenced by compute_costs(), compute_splitting_shift(), and init_lower_subreg().
#define twice_word_mode this_target_lower_subreg->x_twice_word_mode |
enum classify_move_insn |
Return whether X can be decomposed into subwords.
References bitmap_bit_p, GET_MODE, HARD_REGISTER_NUM_P, interesting_mode_p(), REG_P, REGNO, simplify_subreg_regno(), subreg_context, and word_mode.
Referenced by resolve_simple_move().
|
static |
Compute what we should do when optimizing for speed or size; SPEED_P selects which. Use RTXES for computing costs.
References choices, compute_splitting_shift(), CONST0_RTX, FORCE_LOWERING, GET_MODE_NAME, GET_RTX_NAME, i, interesting_mode_p(), LOG_COSTS, PUT_MODE(), cost_rtxes::set, set_rtx_cost(), SET_SRC, set_src_cost(), cost_rtxes::source, cost_rtxes::target, twice_word_mode, word_mode, and cost_rtxes::zext.
Referenced by init_lower_subreg().
|
static |
For each X in the range [0, BITS_PER_WORD), set SPLITTING[X] to true if it is profitable to split a double-word CODE shift of X + BITS_PER_WORD bits. SPEED_P says whether we are testing for speed or size profitability. Use the rtxes in RTXES to calculate costs. WORD_MOVE_ZERO_COST is the cost of moving zero into a word-mode register. WORD_MOVE_COST is the cost of moving between word registers.
References BITS_PER_WORD, FORCE_LOWERING, GET_MODE_NAME, GET_RTX_NAME, i, LOG_COSTS, shift_cost(), twice_word_mode, and word_mode.
Referenced by compute_costs().
|
static |
Look for registers which are always accessed via word-sized SUBREGs or -if DECOMPOSE_COPIES is true- via copies. Decompose these registers into several word-sized pseudo-registers.
References apply_change_group(), b, BASIC_BLOCK_FOR_FN, BB_END, BB_HEAD, BITMAP_ALLOC, bitmap_and_compl_into(), bitmap_clear(), bitmap_empty_p(), BITMAP_FREE, bitmap_set_bit, can_throw_internal(), cfun, choices, control_flow_insn_p(), DEBUG_INSN_P, decomposable_context, DECOMPOSABLE_SIMPLE_MOVE, decompose_register(), df, DF_DEFER_INSN_RESCAN, df_set_flags(), dump_choices(), dump_file, recog_data_d::dup_loc, recog_data_d::dup_num, end(), EXECUTE_IF_SET_IN_BITMAP, extract_insn(), find_decomposable_shift_zext(), find_decomposable_subregs(), find_pseudo_copy(), FOR_BB_INSNS, FOR_EACH_BB_FN, gcc_assert, GET_CODE, GET_MODE, i, basic_block_def::index, INSN_P, last_basic_block_for_fn, max_reg_num(), recog_data_d::n_dups, recog_data_d::n_operands, NEXT_INSN(), non_decomposable_context, NOT_SIMPLE_MOVE, NULL, NULL_RTX, num_validated_changes(), recog_data_d::operand, recog_data_d::operand_loc, optimize_function_for_speed_p(), PATTERN(), propagate_pseudo_copies(), recog_data, recog_memoized(), reg_copy_graph, regno_reg_rtx, resolve_clobber(), resolve_debug(), resolve_reg_notes(), resolve_shift_zext(), resolve_simple_move(), resolve_subreg_use(), resolve_use(), rtl_make_eh_edge(), run_word_dce(), SET_SRC, SIMPLE_MOVE, simple_move(), split_block(), subreg_context, and validate_unshare_change().
|
static |
Decompose REGNO into word-sized components. We smash the REG node in place. This ensures that (1) something goes wrong quickly if we fail to make some replacement, and (2) the debug information inside the symbol table is automatically kept up to date.
References dump_file, fputc(), gcc_unreachable, gen_reg_rtx_offset(), GET_MODE, i, interesting_mode_p(), NULL_RTX, PUT_CODE, REGNO, regno_reg_rtx, rtvec_alloc(), RTVEC_ELT, word_mode, XVEC, and XVECEXP.
Referenced by decompose_multiword_subregs().
|
static |
Print to dump_file a description of what we're doing when optimizing for speed or size; SPEED_P says which. DESCRIPTION is a description of the SPEED_P choice.
References choices, dump_file, dump_shift_choices(), GET_MODE_NAME, i, interesting_mode_p(), and twice_word_mode.
Referenced by decompose_multiword_subregs().
Print to dump_file a description of what we're doing with shift code CODE. SPLITTING[X] is true if we are splitting shifts by X + BITS_PER_WORD.
References BITS_PER_WORD, dump_file, GET_MODE_NAME, GET_RTX_NAME, i, and twice_word_mode.
Referenced by dump_choices().
Check if INSN is a decomposable multiword-shift or zero-extend and set the decomposable_context bitmap accordingly. SPEED_P is true if we are optimizing INSN for speed rather than size. Return true if INSN is decomposable.
References bitmap_set_bit, BITS_PER_WORD, choices, CONST_INT_P, decomposable_context, GET_CODE, GET_MODE, HARD_REGISTER_NUM_P, IN_RANGE, INTVAL, REG_P, REGNO, SET_DEST, SET_SRC, single_set(), twice_word_mode, word_mode, and XEXP.
Referenced by decompose_multiword_subregs().
|
static |
If we find a SUBREG in *LOC which we could use to decompose a pseudo-register, set a bit in DECOMPOSABLE_CONTEXT. If we find an unadorned register which is not a simple pseudo-register copy, DATA will point at the type of move, and we set a bit in DECOMPOSABLE_CONTEXT or NON_DECOMPOSABLE_CONTEXT as appropriate.
References bitmap_set_bit, decomposable_context, DECOMPOSABLE_SIMPLE_MOVE, find_decomposable_subregs(), FLOAT_MODE_P, FOR_EACH_SUBRTX_VAR, gcc_unreachable, GET_CODE, GET_MODE, HARD_REGISTER_NUM_P, interesting_mode_p(), MEM_P, non_decomposable_context, NOT_SIMPLE_MOVE, REG_P, REGNO, SIMPLE_MOVE, subreg_context, SUBREG_REG, targetm, word_mode, and XEXP.
Referenced by decompose_multiword_subregs(), and find_decomposable_subregs().
If SET is a copy from one multi-word pseudo-register to another, record that in reg_copy_graph. Return whether it is such a copy.
References b, BITMAP_ALLOC, bitmap_set_bit, HARD_REGISTER_NUM_P, NULL, NULL_RTX, operand_for_swap_move_operator(), reg_copy_graph, REG_P, REGNO, SET_DEST, and SET_SRC.
Referenced by decompose_multiword_subregs().
void init_lower_subreg | ( | void | ) |
Do one-per-target initialisation. This involves determining which operations on the machine are profitable. If none are found, then the pass just returns when called.
References compute_costs(), const0_rtx, gen_rtx_REG(), GET_MODE_2XWIDER_MODE(), LAST_VIRTUAL_REGISTER, LOG_COSTS, cost_rtxes::set, cost_rtxes::shift, cost_rtxes::source, cost_rtxes::target, this_target_lower_subreg, twice_word_mode, word_mode, and cost_rtxes::zext.
Referenced by backend_init_target().
|
inlinestatic |
Return true if MODE is a mode we know how to lower. When returning true, store its byte size in *BYTES and its word size in *WORDS.
References CEIL, and GET_MODE_SIZE().
Referenced by can_decompose_p(), compute_costs(), decompose_register(), dump_choices(), find_decomposable_subregs(), resolve_clobber(), resolve_simple_move(), and simplify_subreg_concatn().
rtl_opt_pass * make_pass_lower_subreg | ( | gcc::context * | ctxt | ) |
rtl_opt_pass * make_pass_lower_subreg2 | ( | gcc::context * | ctxt | ) |
rtl_opt_pass * make_pass_lower_subreg3 | ( | gcc::context * | ctxt | ) |
If X is an operator that can be treated as a simple move that we can split, then return the operand that is operated on.
References BITS_PER_WORD, CONST_INT_P, GET_CODE, GET_MODE, INTVAL, NULL_RTX, simple_move_operand(), twice_word_mode, and XEXP.
Referenced by find_pseudo_copy(), resolve_simple_move(), and simple_move().
|
static |
Look through the registers in DECOMPOSABLE_CONTEXT. For each case where they are copied to another register, add the register to which they are copied to DECOMPOSABLE_CONTEXT. Use NON_DECOMPOSABLE_CONTEXT to limit this--we don't bother to track copies of registers which are in NON_DECOMPOSABLE_CONTEXT.
References b, bitmap_and_compl(), bitmap_clear(), bitmap_copy(), bitmap_empty_p(), bitmap_ior_and_compl_into(), bitmap_ior_into(), decomposable_context, EXECUTE_IF_SET_IN_BITMAP, i, non_decomposable_context, propagate(), queue, and reg_copy_graph.
Referenced by decompose_multiword_subregs().
Change a CLOBBER of a decomposed register into a CLOBBER of the component registers. Return whether we changed something.
References df_insn_rescan(), emit_insn_after(), gcc_assert, gcc_unreachable, GET_MODE, i, interesting_mode_p(), NULL_RTX, paradoxical_subreg_p(), resolve_reg_notes(), resolve_reg_p(), resolve_subreg_p(), simplify_gen_subreg_concatn(), SUBREG_REG, validate_change(), word_mode, and XEXP.
Referenced by decompose_multiword_subregs().
|
static |
A VAR_LOCATION can be simplified.
References copy_rtx(), df_insn_rescan(), FOR_EACH_SUBRTX_PTR, GET_MODE, PATTERN(), resolve_reg_notes(), resolve_reg_p(), resolve_subreg_p(), simplify_subreg_concatn(), SUBREG_BYTE, and SUBREG_REG.
Referenced by decompose_multiword_subregs().
OPND is a concatn operand this is used with a simple move operator. Return a new rtx with the concatn's operands swapped.
References copy_rtx(), gcc_assert, GET_CODE, and XVECEXP.
Referenced by resolve_simple_move().
|
static |
Resolve any decomposed registers which appear in register notes on INSN.
References df_notes_rescan(), find_reg_equal_equiv_note(), NULL_RTX, num_validated_changes(), REG_NOTE_KIND, REG_NOTES, remove_note(), resolve_reg_p(), resolve_subreg_use(), and XEXP.
Referenced by decompose_multiword_subregs(), resolve_clobber(), resolve_debug(), and resolve_use().
Return whether we should resolve X into the registers into which it was decomposed.
References GET_CODE.
Referenced by resolve_clobber(), resolve_debug(), resolve_reg_notes(), resolve_shift_zext(), resolve_simple_move(), resolve_subreg_p(), resolve_subreg_use(), and resolve_use().
Decompose a more than word wide shift (in INSN) of a multiword pseudo or a multiword zero-extend of a wordmode pseudo into a move and 'set to zero' insn. SPEED_P says whether we are optimizing for speed or size, when checking if a ZERO_EXTEND is preferable. Return a pointer to the new insn when a replacement was done.
References BITS_PER_WORD, choices, CONST0_RTX, copy_rtx(), delete_insn(), dump_file, emit_insn_before(), emit_move_insn(), end_sequence(), expand_shift(), force_reg(), GET_CODE, get_insns(), GET_MODE, GET_MODE_SIZE(), INSN_UID(), insns, INTVAL, is_a(), NEXT_INSN(), NULL, NULL_RTX, REG_P, resolve_reg_p(), SET_DEST, SET_SRC, simplify_gen_subreg_concatn(), simplify_gen_unary(), single_set(), start_sequence(), twice_word_mode, word_mode, and XEXP.
Referenced by decompose_multiword_subregs().
Decompose the registers used in a simple move SET within INSN. If we don't change anything, return INSN, otherwise return the start of the sequence of moves.
References add_reg_note(), adjust_automodify_address_nv, apply_change_group(), AUTO_INC_DEC, can_decompose_p(), CONST0_RTX, copy_reg_eh_region_note_forward(), copy_rtx(), delete_insn(), emit_clobber(), emit_insn_before(), emit_move_insn(), end_sequence(), find_reg_note(), gcc_assert, gcc_unreachable, gen_reg_rtx(), GET_CODE, get_insns(), GET_MODE, GET_MODE_SIZE(), HARD_REGISTER_NUM_P, i, in_sequence_p(), insns, int_mode_for_mode(), interesting_mode_p(), MEM_P, NULL_RTX, operand_for_swap_move_operator(), push_operand(), REG_ATTRS, reg_overlap_mentioned_p(), REG_P, REGNO, remove_insn(), opt_mode< T >::require(), resolve_operand_for_swap_move_operator(), resolve_reg_p(), resolve_simple_move(), resolve_subreg_p(), resolve_subreg_use(), SCALAR_INT_MODE_P, SET_DEST, SET_SRC, side_effects_p(), simplify_gen_subreg(), simplify_gen_subreg_concatn(), single_set(), STACK_GROWS_DOWNWARD, start_sequence(), SUBREG_BYTE, SUBREG_REG, word_mode, XEXP, and XVECEXP.
Referenced by decompose_multiword_subregs(), and resolve_simple_move().
Return whether X is a SUBREG of a register which we need to resolve.
References GET_CODE, resolve_reg_p(), and SUBREG_REG.
Referenced by resolve_clobber(), resolve_debug(), resolve_simple_move(), resolve_subreg_use(), and resolve_use().
Look for SUBREGs in *LOC which need to be decomposed.
References FOR_EACH_SUBRTX_PTR, gcc_assert, GET_MODE, resolve_reg_p(), resolve_subreg_p(), simplify_subreg_concatn(), SUBREG_BYTE, SUBREG_REG, and validate_change().
Referenced by decompose_multiword_subregs(), resolve_reg_notes(), and resolve_simple_move().
A USE of a decomposed register is no longer meaningful. Return whether we changed something.
References delete_insn(), resolve_reg_notes(), resolve_reg_p(), resolve_subreg_p(), and XEXP.
Referenced by decompose_multiword_subregs().
|
static |
Return the cost of a CODE shift in mode MODE by OP1 bits, using the rtxes in RTXES. SPEED_P selects between the speed and size cost.
References gen_int_shift_amount(), PUT_CODE, PUT_MODE(), set_src_cost(), cost_rtxes::shift, cost_rtxes::source, and XEXP.
Referenced by compute_splitting_shift().
If INSN is a single set between two objects that we want to split, return the single set. SPEED_P says whether we are optimizing INSN for speed or size. INSN should have been passed to recog and extract_insn before this is called.
References choices, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, int_mode_for_size(), recog_data_d::n_operands, NULL_RTX, recog_data_d::operand, operand_for_swap_move_operator(), recog_data, SCALAR_INT_MODE_P, cost_rtxes::set, SET_DEST, SET_SRC, simple_move_operand(), single_set(), and targetm.
Referenced by decompose_multiword_subregs().
References GET_CODE, MEM_ADDR_SPACE, MEM_P, MEM_VOLATILE_P, mode_dependent_address_p(), OBJECT_P, SUBREG_REG, and XEXP.
Referenced by operand_for_swap_move_operator(), and simple_move().
|
static |
Wrapper around simplify_gen_subreg which handles CONCATN.
References CONST0_RTX, gcc_assert, GET_CODE, GET_MODE, GET_MODE_SIZE(), known_eq, NULL_RTX, paradoxical_subreg_p(), simplify_gen_subreg(), simplify_gen_subreg_concatn(), simplify_subreg_concatn(), SUBREG_BYTE, and SUBREG_REG.
Referenced by resolve_clobber(), resolve_shift_zext(), resolve_simple_move(), and simplify_gen_subreg_concatn().
|
static |
Get a SUBREG of a CONCATN.
References gcc_assert, gcc_unreachable, GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_INNER, interesting_mode_p(), mode_for_size(), NULL_RTX, opt_mode< T >::require(), simplify_gen_subreg(), poly_int< N, C >::to_constant(), VECTOR_MODE_P, XVECEXP, and XVECLEN.
Referenced by resolve_debug(), resolve_subreg_use(), and simplify_gen_subreg_concatn().
|
static |
Bit N in this bitmap is set if regno N is used in a context in which we can decompose it.
Referenced by decompose_multiword_subregs(), find_decomposable_shift_zext(), find_decomposable_subregs(), and propagate_pseudo_copies().
struct target_lower_subreg default_target_lower_subreg |
|
static |
Bit N in this bitmap is set if regno N is used in a context in which it cannot be decomposed.
Referenced by decompose_multiword_subregs(), find_decomposable_subregs(), and propagate_pseudo_copies().
Bit N in the bitmap in element M of this array is set if there is a copy from reg M to reg N.
Referenced by decompose_multiword_subregs(), find_pseudo_copy(), and propagate_pseudo_copies().
|
static |
Bit N in this bitmap is set if regno N is used in a subreg which changes the mode but not the size. This typically happens when the register accessed as a floating-point value; we want to avoid generating accesses to its subwords in integer modes.
Referenced by can_decompose_p(), decompose_multiword_subregs(), and find_decomposable_subregs().