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 "cfghooks.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "cfgrtl.h"
#include "cfgcleanup.h"
#include "explow.h"
#include "insn-attr.h"
#include "rtlhooks-def.h"
#include "expr.h"
#include "tree-pass.h"
#include "valtrack.h"
#include "rtl-iter.h"
#include "print-rtl.h"
#include "function-abi.h"
#include "rtlanal.h"
Data Structures | |
struct | reg_stat_type |
struct | insn_link |
struct | undo |
struct | undobuf |
struct | likely_spilled_retval_info |
Macros | |
#define | INSN_COST(INSN) |
#define | LOG_LINKS(INSN) |
#define | FOR_EACH_LOG_LINK(L, INSN) |
#define | RTL_HOOKS_GEN_LOWPART gen_lowpart_for_combine |
#define | RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_for_combine |
#define | RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_for_combine |
#define | RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_for_combine |
#define | RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode |
#define | SUBST(INTO, NEWVAL) |
#define | SUBST_INT(INTO, NEWVAL) |
#define | SUBST_LINK(oldval, newval) |
#define | COMBINE_RTX_EQUAL_P(X, Y) |
Enumerations | |
enum | undo_kind { UNDO_RTX , UNDO_INT , UNDO_MODE , UNDO_LINKS } |
#define FOR_EACH_LOG_LINK | ( | L, | |
INSN ) |
Referenced by combine_instructions(), create_log_links(), distribute_links(), find_single_use(), insn_a_feeds_b(), set_nonzero_bits_and_sign_copies(), and try_combine().
#define INSN_COST | ( | INSN | ) |
Referenced by combine_instructions(), and combine_validate_cost().
#define LOG_LINKS | ( | INSN | ) |
Referenced by create_log_links(), distribute_links(), distribute_notes(), record_promoted_value(), and try_combine().
#define RTL_HOOKS_GEN_LOWPART gen_lowpart_for_combine |
It is not safe to use ordinary gen_lowpart in combine. See comments in gen_lowpart_for_combine.
#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_for_combine |
Our implementation of gen_lowpart never emits a new pseudo.
#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_for_combine |
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_for_combine |
#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode |
#define SUBST | ( | INTO, | |
NEWVAL ) |
Referenced by change_zero_ext(), combine_simplify_rtx(), find_split_point(), known_cond(), make_compound_operation(), make_compound_operation_int(), maybe_swap_commutative_operands(), recog_for_combine(), recog_for_combine_1(), simplify_if_then_else(), simplify_set(), subst(), and try_combine().
#define SUBST_INT | ( | INTO, | |
NEWVAL ) |
Referenced by recog_for_combine_1().
#define SUBST_LINK | ( | oldval, | |
newval ) |
Referenced by try_combine().
enum undo_kind |
|
static |
Adjust INSN after we made a change to its destination. Changing the destination can invalidate notes that say something about the results of the insn and a LOG_LINK pointing to the insn.
References alloc_insn_link(), df_insn_rescan(), distribute_links(), gcc_assert, GET_CODE, NULL, REG_P, REGNO, remove_reg_equal_equiv_notes(), SET_DEST, single_set(), and XEXP.
Referenced by try_combine().
|
inlinestatic |
Allocate a link.
References insn_link::insn, insn_link_obstack, insn_link::next, and insn_link::regno.
Referenced by adjust_for_new_dest(), create_log_links(), and try_combine().
See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c) if so.
References apply_distributive_law(), COMMUTATIVE_ARITH_P, expand_compound_operation(), FLOAT_MODE_P, GET_CODE, GET_MODE, OBJECT_P, rtx_equal_p(), simplify_gen_binary(), simplify_gen_unary(), and XEXP.
Referenced by apply_distributive_law(), combine_simplify_rtx(), distribute_and_simplify_rtx(), simplify_and_const_int_1(), and simplify_shift_const_1().
Return TRUE if combine can reuse reg X in mode MODE. ADDED_SETS is trueif the original set is still required.
References GET_MODE, hard_regno_nregs(), REG_N_SETS(), reg_n_sets_max, REG_NREGS, REG_P, REG_USERVAR_P, REGMODE_NATURAL_SIZE, REGNO, likely_spilled_retval_info::regno, and targetm.
Referenced by change_zero_ext(), simplify_set(), and try_combine().
Return false if we do not want to (or cannot) combine DEF.
References DF_REF_FLAGS, DF_REF_PRE_POST_MODIFY, DF_REF_REGNO, fixed_regs, frame_pointer_needed, HARD_FRAME_POINTER_IS_FRAME_POINTER, HARD_FRAME_POINTER_REGNUM, insn_link::regno, and reload_completed.
Referenced by create_log_links().
|
static |
See if INSN can be combined into I3. PRED, PRED2, SUCC and SUCC2 are optionally insns that were previously combined into I3 or that will be combined into the merger of INSN and I3. The order is PRED, PRED2, INSN, SUCC, SUCC2, I3. Return false if the combination is not allowed for any reason. If the combination is allowed, *PDEST will be set to the single destination of INSN and *PSRC to the single source, and this function will return true.
References AUTO_INC_DEC, bool, CALL_P, CONSTANT_P, DF_INSN_LUID, expand_field_assignment(), extract_asm_operands(), find_reg_fusage(), FIND_REG_INC_NOTE, find_reg_note(), fixed_regs, GET_CODE, GET_MODE, global_regs, HARD_REGISTER_P, i, insn_link::insn, insn_nothrow_p(), INSN_P, INSN_UID(), JUMP_P, last_call_luid, MEM_P, MEM_VOLATILE_P, modified_between_p(), next_active_insn(), NEXT_INSN(), NULL_RTX, PATTERN(), PREV_INSN(), REG_NOTE_KIND, REG_NOTES, reg_overlap_mentioned_p(), REG_P, reg_set_between_p(), reg_used_between_p(), REG_USERVAR_P, REGNO, insn_link::regno, rtx_equal_p(), SET, SET_DEST, SET_SRC, side_effects_p(), stack_pointer_rtx, subst_low_luid, targetm, volatile_insn_p(), volatile_refs_p(), XEXP, XVECEXP, and XVECLEN.
Referenced by try_combine().
Return false if we do not want to (or cannot) combine USE.
References DF_REF_CALL_STACK_USAGE, and DF_REF_FLAGS.
Referenced by create_log_links().
Return whether INSN, a PARALLEL of N register SETs (and maybe some CLOBBERs), can be split into individual SETs in that order, without changing semantics.
References i, insn_nothrow_p(), PATTERN(), reg_referenced_p(), SET_DEST, SET_SRC, side_effects_p(), and XVECEXP.
Referenced by try_combine().
If X refers to a register that equals REG in value, replace these references with REG.
References canon_reg_for_combine(), copy_rtx(), GET_CODE, get_last_value(), GET_MODE, GET_RTX_CLASS, GET_RTX_FORMAT, GET_RTX_LENGTH, i, REG_P, RTX_BIN_ARITH, RTX_BITFIELD_OPS, RTX_COMM_ARITH, RTX_COMM_COMPARE, RTX_COMPARE, rtx_equal_p(), RTX_OBJ, RTX_TERNARY, RTX_UNARY, simplify_gen_binary(), simplify_gen_relational(), simplify_gen_ternary(), simplify_gen_unary(), XEXP, XVECEXP, and XVECLEN.
Referenced by canon_reg_for_combine(), and make_field_assignment().
Determine whether INSN can be used in a combination. Return true if not. This is used in try_combine to detect early some cases where we can't perform combinations.
References fixed_reg_set, GET_CODE, HARD_REGISTER_P, insn_link::insn, NONDEBUG_INSN_P, REG_P, REGNO, SET_DEST, SET_SRC, single_set(), SUBREG_REG, targetm, and TEST_HARD_REG_BIT.
Referenced by try_combine().
Change every ZERO_EXTRACT and ZERO_EXTEND of a SUBREG that can be expressed as an AND and maybe an LSHIFTRT, to that formulation. Return whether anything was so changed.
References as_a(), can_change_dest_mode(), changed, CONST_INT_P, FOR_EACH_SUBRTX_PTR, GEN_INT, gen_int_shift_amount(), gen_lowpart_SUBREG(), gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_PRECISION(), HARD_REGISTER_P, immed_wide_int_const(), INTVAL, is_a(), wi::mask(), maybe_swap_commutative_operands(), paradoxical_subreg_p(), REG_P, REGNO, SCALAR_INT_MODE_P, SET_DEST, SET_SRC, wi::shifted_mask(), subreg_lowpart_p(), SUBREG_REG, SUBST, XEXP, and y.
Referenced by recog_for_combine().
Scan X for promoted SUBREGs. For each one found, note what it implies to the registers used in it.
References check_promoted_subreg(), GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, insn_link::insn, record_promoted_value(), REG_P, SUBREG_PROMOTED_VAR_P, SUBREG_REG, XEXP, XVEC, XVECEXP, and XVECLEN.
Referenced by check_promoted_subreg(), and combine_instructions().
|
static |
LOC is the location within I3 that contains its pattern or the component of a PARALLEL of the pattern. We validate that it is valid for combining. One problem is if I3 modifies its output, as opposed to replacing it entirely, we can't allow the output to contain I2DEST, I1DEST or I0DEST as doing so would produce an insn that is not equivalent to the original insns. Consider: (set (reg:DI 101) (reg:DI 100)) (set (subreg:SI (reg:DI 101) 0) <foo>) This is NOT equivalent to: (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>) (set (reg:DI 101) (reg:DI 100))]) Not only does this modify 100 (in which case it might still be valid if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100. We can also run into a problem if I2 sets a register that I1 uses and I1 gets directly substituted into I3 (not via I2). In that case, we would be getting the wrong value of I2DEST into I3, so we must reject the combination. This case occurs when I2 and I1 both feed into I3, rather than when I1 feeds into I2, which feeds into I3. If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source of a SET must prevent combination from occurring. The same situation can occur for I0, in which case I0_NOT_IN_SRC is set. Before doing the above check, we first try to expand a field assignment into a set of logical operations. If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which we place a register that is both set and used within I3. If more than one such register is detected, we fail. Return true if the combination is valid, false otherwise.
References combinable_i3pat(), fixed_regs, GET_CODE, GET_MODE, HARD_FRAME_POINTER_IS_FRAME_POINTER, HARD_FRAME_POINTER_REGNUM, i, MEM_P, partial_subreg_p(), PATTERN(), reg_overlap_mentioned_p(), REG_P, reg_referenced_p(), REGNO, rtx_equal_p(), SET, SET_DEST, SET_SRC, SUBREG_REG, targetm, XEXP, XVECEXP, and XVECLEN.
Referenced by combinable_i3pat(), and try_combine().
Main entry point for combiner. F is the first insn of the function. NREGS is the first unused pseudo-reg number. Return nonzero if the CFG was changed (e.g. if the combiner has turned an indirect jump instruction into a direct jump).
References AUTO_INC_DEC, BB_END, BB_HEAD, BLOCK_FOR_INSN(), cfun, check_promoted_subreg(), clear_bb_flags(), combine_attempts, combine_extras, combine_merges, combine_rtl_hooks, combine_successes, copy_rtx(), create_log_links(), default_rtl_profile(), delete_noop_moves(), rtx_insn::deleted(), DF_INSN_LUID, dump_file, dump_insn_slim(), EDGE_COUNT, ENTRY_BLOCK_PTR_FOR_FN, find_reg_equal_equiv_note(), FOR_BB_INSNS, FOR_EACH_BB_FN, FOR_EACH_LOG_LINK, free(), undobuf::frees, gcc_obstack_init, general_rtl_hooks, GET_CODE, get_max_uid(), GET_MODE, HOST_BITS_PER_WIDE_INT, i2mod, i2mod_new_rhs, i2mod_old_rhs, init_recog(), init_recog_no_volatile(), init_reg_last(), insn_link::insn, INSN_CODE, INSN_COST, insn_cost(), insn_link_obstack, INSN_P, int_mode_for_size(), label_tick, label_tick_ebb_start, last_call_luid, max_uid_known, mem_last_set, insn_link::next, undo::next, NEXT_INSN(), NONDEBUG_INSN_P, nonzero_bits_mode, nonzero_sign_valid, NOTE_P, note_stores(), note_uses(), NULL, NULL_RTX, optimize_bb_for_speed_p(), optimize_this_for_speed_p, PATTERN(), PREV_INSN(), purge_all_dead_edges(), record_dead_and_set_regs(), record_truncated_values(), REG_NOTE_KIND, REG_NOTES, reg_stat, opt_mode< T >::require(), rtl_profile_for_bb(), SCALAR_INT_MODE_P, SET_DEST, set_nonzero_bits_and_sign_copies(), SET_SRC, setup_incoming_promotions(), side_effects_p(), single_pred(), single_pred_p(), single_set(), statistics_counter_event(), subst_insn, subst_low_luid, this_basic_block, try_combine(), uid_insn_cost, uid_log_links, unmentioned_reg_p(), and XEXP.
Referenced by rest_of_handle_combine().
Simplify X, a piece of RTL. We just operate on the expression at the outer level; call `subst' to simplify recursively. Return the new expression. OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is true if we are inside a SET_DEST. IN_COND is true if we are at the top level of a condition.
References apply_distributive_law(), BINARY_P, combine_simplify_rtx(), COMMUTATIVE_ARITH_P, COMPARISON_P, CONST0_RTX, const0_rtx, const1_rtx, CONST_INT_P, const_true_rtx, CONSTANT_P, constm1_rtx, copy_rtx(), distribute_and_simplify_rtx(), exact_log2(), expand_compound_operation(), false_rtx, FLOAT_MODE_P, force_to_mode(), gen_int_mode(), gen_lowpart, gen_lowpart_common(), general_operand(), GET_CODE, get_last_value(), GET_MODE, GET_MODE_CLASS, GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_UNIT_BITSIZE, GET_MODE_UNIT_PRECISION, GET_RTX_CLASS, HOST_WIDE_INT_1U, HWI_COMPUTABLE_MODE_P(), i, if_then_else_cond(), INTEGRAL_MODE_P, INTVAL, is_a(), is_int_mode(), known_eq, lowpart_subreg(), make_compound_operation(), maybe_swap_commutative_operands(), MEM_ADDR_SPACE, MEM_P, MEM_VOLATILE_P, mode_dependent_address_p(), nonzero_bits(), NULL, NULL_RTX, num_sign_bit_copies(), OBJECT_P, pc_rtx, plus_constant(), poly_int_rtx_p(), pow2p_hwi(), REG_P, reversed_comparison_code_parts(), RTX_BIN_ARITH, RTX_BITFIELD_OPS, RTX_COMM_ARITH, RTX_COMM_COMPARE, RTX_COMPARE, rtx_equal_p(), RTX_TERNARY, RTX_UNARY, SET, SHIFT_COUNT_TRUNCATED, side_effects_p(), simplify_and_const_int(), simplify_binary_operation(), simplify_comparison(), simplify_gen_binary(), simplify_gen_relational(), simplify_gen_unary(), simplify_if_then_else(), simplify_logical(), simplify_relational_operation(), simplify_set(), simplify_shift_const(), simplify_subreg(), simplify_ternary_operation(), simplify_unary_operation(), STORE_FLAG_VALUE, SUBREG_BYTE, subreg_lowpart_offset(), SUBREG_REG, SUBST, subst(), true_rtx, TRULY_NOOP_TRUNCATION_MODES_P, UINTVAL, UNARY_P, val_signbit_p(), vec_series_lowpart_p(), and XEXP.
Referenced by combine_simplify_rtx(), and subst().
Try to split PATTERN found in INSN. This returns NULL_RTX if PATTERN cannot be split. Otherwise, it returns an insn sequence. This is a wrapper around split_insns which ensures that the reg_stat vector is made larger if the splitter creates a new register.
References max_reg_num(), reg_stat, and split_insns().
Referenced by find_split_point(), and try_combine().
|
static |
Subroutine of try_combine. Determine whether the replacement patterns NEWPAT, NEWI2PAT and NEWOTHERPAT are cheaper according to insn_cost than the original sequence I0, I1, I2, I3 and undobuf.other_insn. Note that I0, I1 and/or NEWI2PAT may be NULL_RTX. Similarly, NEWOTHERPAT and undobuf.other_insn may also both be NULL_RTX. Return false if the cost of all the instructions can be estimated and the replacements are more expensive than the original sequence.
References dump_file, i1, i2, INSN_CODE, INSN_COST, insn_cost(), INSN_UID(), optimize_this_for_speed_p, undobuf::other_insn, PATTERN(), and reject().
Referenced by try_combine().
Return true if X is an arithmetic expression that contains a multiplication and division. We don't count multiplications by powers of two here.
References BINARY_P, CONST_INT_P, contains_muldiv(), GET_CODE, pow2p_hwi(), UINTVAL, UNARY_P, and XEXP.
Referenced by contains_muldiv(), and try_combine().
Callback function to count autoincs.
Referenced by try_combine().
|
static |
Utility function for record_value_for_reg. Count number of rtxs in X.
References count_rtxs(), GET_CODE, GET_RTX_CLASS, GET_RTX_FORMAT, GET_RTX_LENGTH, i, RTX_BIN_ARITH, RTX_COMM_ARITH, XEXP, XVECEXP, and XVECLEN.
Referenced by count_rtxs(), and record_value_for_reg().
|
static |
Fill in log links field for all insns.
References alloc_insn_link(), asm_noperands(), BLOCK_FOR_INSN(), can_combine_def_p(), can_combine_use_p(), cfun, DF_REF_REGNO, FOR_BB_INSNS_REVERSE, FOR_EACH_BB_FN, FOR_EACH_INSN_DEF, FOR_EACH_INSN_USE, FOR_EACH_LOG_LINK, free(), gcc_assert, insn_link::insn, LOG_LINKS, max_reg_num(), NONDEBUG_INSN_P, NULL, PATTERN(), and insn_link::regno.
Referenced by combine_instructions().
|
static |
Delete any insns that copy a register to itself. Return true if the CFG was changed.
References BB_END, BB_HEAD, cfun, delete_insn_and_edges(), dump_file, FOR_EACH_BB_FN, insn_link::insn, INSN_P, INSN_UID(), insn_link::next, NEXT_INSN(), and noop_move_p().
Referenced by combine_instructions().
See if X is of the form (* (+ A B) C), and if so convert to (+ (* A C) (* B C)) and try to simplify. Most of the time, this results in no change. However, if some of the operands are the same or inverses of each other, simplifications will result. For example, (and (ior A B) (not B)) can occur as the result of expanding a bit field assignment. When we apply the distributive law to this, we get (ior (and (A (not B))) (and (B (not B)))), which then simplifies to (and (A (not B))). Note that no checks happen on the validity of applying the inverse distributive law. This is pointless since we can do it in the few places where this routine is called. N is the index of the term that is decomposed (the arithmetic operation, i.e. (+ A B) in the first example above). !N is the index of the term that is distributed, i.e. of C in the first example above.
References apply_distributive_law(), ARITHMETIC_P, FLOAT_MODE_P, GET_CODE, GET_MODE, NULL_RTX, optimize_this_for_speed_p, set_src_cost(), simplify_gen_binary(), and XEXP.
Referenced by combine_simplify_rtx(), and simplify_logical().
|
static |
Similarly to above, distribute the LOG_LINKS that used to be present on I3, I2, and I1 to new locations. This is also called to add a link pointing at I3 when I3's destination is changed.
References added_links_insn, BB_HEAD, CALL_P, cfun, DEBUG_INSN_P, DF_INSN_LUID, EXIT_BLOCK_PTR_FOR_FN, find_reg_fusage(), FOR_EACH_LOG_LINK, GET_CODE, i, insn_link::insn, INSN_P, LOG_LINKS, link::next, NEXT_INSN(), NOTE_P, NULL, PATTERN(), pc_rtx, reg_overlap_mentioned_p(), REG_P, reg_referenced_p(), reg_set_p(), REGNO, insn_link::regno, SET, SET_DEST, this_basic_block, XEXP, XVECEXP, and XVECLEN.
Referenced by adjust_for_new_dest(), distribute_notes(), and try_combine().
|
static |
Given a chain of REG_NOTES originally from FROM_INSN, try to place them as appropriate. I3 and I2 are the insns resulting from the combination insns including FROM (I2 may be zero). ELIM_I2 and ELIM_I1 are either zero or registers that we know will not need REG_DEAD notes because they are being substituted for. This saves searching in the most common cases. Each note in the list is either ignored or placed on some insns, depending on the type of note.
References ACCUMULATE_OUTGOING_ARGS, add_reg_note(), add_shallow_copy_of_reg_note(), added_notes_insn, alloc_reg_note(), BB_HEAD, CALL_P, can_nonlocal_goto(), cfun, CONSTANT_P, dead_or_set_p(), dead_or_set_regno_p(), DF_INSN_LUID, distribute_links(), distribute_notes(), END_REGNO(), find_reg_fusage(), find_reg_note(), find_regno_fusage(), find_regno_note(), fixup_args_size_notes(), gcc_assert, gcc_unreachable, get_args_size(), GET_CODE, global_regs, hard_regno_nregs(), i, i2, i2mod, i2mod_new_rhs, i2mod_old_rhs, insn_could_throw_p(), INSN_P, INT_MIN, INTVAL, JUMP_LABEL, JUMP_P, LABEL_NUSES, LABEL_P, label_ref_label(), reg_stat_type::last_death, reg_stat_type::last_set, LOG_LINKS, may_trap_p(), next_nonnote_nondebug_insn(), NONDEBUG_INSN_P, noop_move_p(), NULL, NULL_RTX, PATTERN(), pc_rtx, PREV_INSN(), PUT_REG_NOTE_KIND, record_value_for_reg(), refers_to_regno_p(), reg_bitfield_target_p(), reg_mentioned_p(), REG_NOTE_KIND, REG_NOTES, REG_NREGS, reg_overlap_mentioned_p(), REG_P, reg_raw_mode, reg_referenced_p(), reg_set_between_p(), reg_set_p(), reg_stat, REGNO, insn_link::regno, regno_reg_rtx, rtx_equal_p(), SET_DEST, SET_INSN_DELETED, SET_SRC, side_effects_p(), single_set(), this_basic_block, and XEXP.
Referenced by distribute_notes(), and try_combine().
Substitute NEWVAL, an rtx expression, into INTO, a place in some insn. The substitution can be undone by undo_all. If INTO is already set to NEWVAL, do not record this change. Because computing NEWVAL might also call SUBST, we have to compute it before we put anything into the undo table.
References CONST_INT_P, undobuf::frees, gcc_assert, GET_CODE, GET_MODE, GET_MODE_CLASS, INTVAL, undo::kind, undo::next, undo::old_contents, undo::r, SUBREG_REG, trunc_int_for_mode(), UNDO_RTX, undobuf::undos, undo::where, and XEXP.
|
static |
Similar to SUBST, but NEWVAL is an int expression. Note that substitution for the value of a HOST_WIDE_INT value (including CONST_INT) is not safe.
References undobuf::frees, undo::i, undo::kind, undo::next, undo::old_contents, UNDO_INT, undobuf::undos, and undo::where.
Similar to SUBST, but NEWVAL is a LOG_LINKS expression.
References undobuf::frees, undo::kind, undo::l, undo::next, undo::old_contents, UNDO_LINKS, undobuf::undos, and undo::where.
We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound operations" because they can be replaced with two more basic operations. ZERO_EXTEND is also considered "compound" because it can be replaced with an AND operation, which is simpler, though only one operation. The function expand_compound_operation is called with an rtx expression and will convert it to the appropriate shifts and AND operations, simplifying at each stage. The function make_compound_operation is called to convert an expression consisting of shifts and ANDs into the equivalent compound expression. It is the inverse of this function, loosely speaking.
References as_a(), COMPARISON_P, CONST_INT_P, expand_compound_operation(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_SIZE(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HWI_COMPUTABLE_MODE_P(), INTVAL, is_a(), nonzero_bits(), NULL_RTX, optimize_this_for_speed_p, set_src_cost(), simplify_and_const_int(), simplify_shift_const(), STORE_FLAG_VALUE, subreg_lowpart_p(), SUBREG_REG, and XEXP.
Referenced by apply_distributive_law(), combine_simplify_rtx(), expand_compound_operation(), force_int_to_mode(), make_field_assignment(), simplify_comparison(), and simplify_shift_const_1().
X is a SET which contains an assignment of one object into a part of another (such as a bit-field assignment, STRICT_LOW_PART, or certain SUBREGS). If possible, convert it into a series of logical operations. We half-heartedly support variable positions, but do not at all support variable lengths.
References CONST_INT_P, copy_rtx(), FLOAT_MODE_P, GEN_INT, gen_int_mode(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_PRECISION(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, int_mode_for_size(), INTVAL, is_a(), nonzero_sign_valid, read_modify_subreg_p(), SET_DEST, SET_SRC, simplify_gen_binary(), simplify_gen_unary(), subreg_lowpart_p(), subreg_lsb(), SUBREG_REG, targetm, and XEXP.
Referenced by can_combine_p(), and set_nonzero_bits_and_sign_copies().
Return the number of "extended" bits there are in X, when interpreted as a quantity in MODE whose signedness is indicated by UNSIGNEDP. For unsigned quantities, this is the number of high-order zero bits. For signed quantities, this is the number of copies of the sign bit minus 1. In both case, this function returns the number of "spare" bits. For example, if two quantities for which this function returns at least 1 are added, the addition is known not to overflow. This function will always return 0 unless called during combine, which implies that it must be called from a define_split.
References floor_log2(), GET_MODE_PRECISION(), HWI_COMPUTABLE_MODE_P(), is_a(), nonzero_bits(), nonzero_sign_valid, and num_sign_bit_copies().
|
static |
See if X (of mode MODE) contains an ASHIFT of COUNT or more bits that can be commuted with any other operations in X. Return X without that shift if so.
References CONST_INT_P, count, extract_left_shift(), gen_int_mode(), GET_CODE, HOST_WIDE_INT_1U, INTVAL, NULL_RTX, simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), UINTVAL, and XEXP.
Referenced by extract_left_shift(), and make_compound_operation_int().
See if DEST, produced in INSN, is used only a single time in the sequel. If so, return a pointer to the innermost rtx expression in which it is used. If PLOC is nonzero, *PLOC is set to the insn containing the single use. Otherwise, we find the single use by finding an insn that has a LOG_LINKS pointing at INSN and has a REG_DEAD note for DEST. If DEST is only referenced once in that insn, we know that it must be the first and last insn referencing DEST.
References BLOCK_FOR_INSN(), dead_or_set_p(), find_single_use_1(), FOR_EACH_LOG_LINK, insn_link::insn, insn_link::next, NEXT_INSN(), NONDEBUG_INSN_P, PATTERN(), REG_P, and REGNO.
Referenced by find_split_point(), simplify_set(), and try_combine().
This is used by find_single_use to locate an rtx in LOC that contains exactly one use of DEST, which is typically a REG. It returns a pointer to the innermost rtx expression containing DEST. Appearances of DEST that are being used to totally replace it are not counted.
References CASE_CONST_ANY, find_single_use_1(), GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, NULL, read_modify_subreg_p(), REG_P, REGNO, SET, SET_DEST, SET_SRC, SUBREG_REG, XEXP, XVECEXP, and XVECLEN.
Referenced by find_single_use(), and find_single_use_1().
Find the innermost point within the rtx at LOC, possibly LOC itself, where we have an arithmetic expression and return that point. LOC will be inside INSN. try_combine will call this function to see if an insn can be split into two insns.
References BINARY_P, combine_split_insns(), const0_rtx, CONST_INT_P, CONSTANT_P, exact_log2(), find_single_use(), find_split_point(), gen_int_mode(), gen_int_shift_amount(), gen_lowpart, get_address_mode(), GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_PRECISION(), GET_RTX_CLASS, GET_RTX_FORMAT, HOST_WIDE_INT_1U, HWI_COMPUTABLE_MODE_P(), INTVAL, is_a(), is_int_mode(), make_extraction(), MEM_ADDR_SPACE, MEM_P, memory_address_addr_space_p(), NEXT_INSN(), NONJUMP_INSN_P, nonzero_bits(), NULL, NULL_RTX, OBJECT_P, PATTERN(), pow2p_hwi(), reg_mentioned_p(), REG_P, register_operand(), regno_reg_rtx, replace_rtx(), RTX_BIN_ARITH, RTX_BITFIELD_OPS, RTX_COMM_ARITH, RTX_COMM_COMPARE, RTX_COMPARE, RTX_TERNARY, RTX_UNARY, SET, SET_DEST, SET_SRC, side_effects_p(), simplify_gen_binary(), STORE_FLAG_VALUE, SUBREG_REG, SUBST, subst_insn, trunc_int_for_mode(), UINTVAL, UNARY_P, and XEXP.
Referenced by find_split_point(), and try_combine().
|
static |
Subroutine of force_to_mode that handles cases in which both X and the result are scalar integers. MODE is the mode of the result, XMODE is the mode of X, and OP_MODE says which of MODE or XMODE is preferred for simplified versions of X. The other arguments are as for force_to_mode.
References const0_rtx, CONST_INT_P, exact_log2(), expand_compound_operation(), floor_log2(), force_to_mode(), gen_int_mode(), gen_int_shift_amount(), gen_lowpart_or_truncate(), GET_CODE, GET_MODE, GET_MODE_MASK, GET_MODE_PRECISION(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, HWI_COMPUTABLE_MODE_P(), i, INTVAL, nonzero_bits(), NULL_RTX, num_sign_bit_copies(), optimize_this_for_speed_p, plus_constant(), poly_int_rtx_p(), pow2p_hwi(), REG_P, set_src_cost(), simplify_and_const_int(), simplify_binary_operation(), simplify_gen_binary(), simplify_gen_ternary(), simplify_gen_unary(), simplify_shift_const(), STORE_FLAG_VALUE, UINTVAL, val_signbit_p(), XEXP, and y.
Referenced by force_to_mode().
|
static |
See if X can be simplified knowing that we will only refer to it in MODE and will only refer to those bits that are nonzero in MASK. If other bits are being computed or if masking operations are done that select a superset of the bits in MASK, they can sometimes be ignored. Return a possibly simplified expression, but always convert X to MODE. If X is a CONST_INT, AND the CONST_INT with MASK. If JUST_SELECT is true, don't optimize by noticing that bits in MASK are all off in X. This is used when X will be complemented, by either NOT, NEG, or XOR.
References as_a(), const0_rtx, CONST_INT_P, force_int_to_mode(), force_to_mode(), GEN_INT, gen_int_mode(), gen_lowpart, gen_lowpart_common(), gen_lowpart_or_truncate(), GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_MASK, have_insn_for(), INTVAL, is_a(), nonzero_bits(), paradoxical_subreg_p(), partial_subreg_p(), SCALAR_INT_MODE_P, side_effects_p(), subreg_lowpart_p(), and SUBREG_REG.
Referenced by combine_simplify_rtx(), force_int_to_mode(), force_to_mode(), make_compound_operation_int(), make_extraction(), make_field_assignment(), simplify_and_const_int_1(), simplify_comparison(), and simplify_set().
Like gen_lowpart_general but for use by combine. In combine it is not possible to create any new pseudoregs. However, it is safe to create invalid memory addresses, because combine will try to recognize them and all they will do is make the combine attempt fail. If for some reason this cannot do its job, an rtx (clobber (const_int 0)) is returned. An insn containing that will not be recognized.
References adjust_address_nv, byte_lowpart_offset(), COMPARISON_P, const0_rtx, CONST_SCALAR_INT_P, gen_lowpart_common(), gen_rtx_SUBREG(), GET_CODE, GET_MODE, GET_MODE_SIZE(), int_mode_for_mode(), known_eq, lowpart_subreg(), maybe_gt, MEM_ADDR_SPACE, MEM_P, MEM_VOLATILE_P, mode_dependent_address_p(), NULL, paradoxical_subreg_p(), opt_mode< T >::require(), SCALAR_INT_MODE_P, SUBREG_REG, and XEXP.
Return X converted to MODE. If the value is already truncated to MODE we can just return a subreg even though in the general case we would need an explicit truncation.
References CONST_INT_P, gen_lowpart, GET_MODE, int_mode_for_mode(), partial_subreg_p(), REG_P, reg_truncated_to_mode(), require(), SCALAR_INT_MODE_P, simplify_gen_unary(), and TRULY_NOOP_TRUNCATION_MODES_P.
Referenced by force_int_to_mode(), force_to_mode(), simplify_comparison(), and simplify_shift_const_1().
Get the last value assigned to X, if known. Some registers in the value may be replaced with (clobber (const_int 0)) if their value is known longer known reliably.
References cfun, copy_rtx(), DF_INSN_LUID, DF_LR_IN, ENTRY_BLOCK_PTR_FOR_FN, gen_lowpart, GET_CODE, get_last_value(), get_last_value_validate(), GET_MODE, GET_MODE_PRECISION(), label_tick, label_tick_ebb_start, reg_stat_type::last_set, reg_stat_type::last_set_label, reg_stat_type::last_set_mode, reg_stat_type::last_set_value, paradoxical_subreg_p(), REG_N_SETS(), reg_n_sets_max, REG_P, reg_stat, REGNO, insn_link::regno, REGNO_REG_SET_P, subreg_lowpart_p(), SUBREG_REG, and subst_low_luid.
Referenced by canon_reg_for_combine(), combine_simplify_rtx(), get_last_value(), if_then_else_cond(), record_value_for_reg(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), and simplify_comparison().
Verify that all the registers and memory references mentioned in *LOC are still valid. *LOC was part of a value set in INSN when label_tick was equal to TICK. Return false if some are not. If REPLACE is true, replace the invalid references with (clobber (const_int 0)) and return true. This replacement is useful because we often can get useful information about the form of a value (e.g., if it was produced by a shift that always produces -1 or 0) even though we don't know exactly what registers it was produced from.
References ARITHMETIC_P, cfun, const0_rtx, DF_INSN_LUID, DF_LR_IN, END_REGNO(), ENTRY_BLOCK_PTR_FOR_FN, GET_CODE, get_last_value_validate(), GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, insn_link::insn, label_tick, reg_stat_type::last_set_invalid, reg_stat_type::last_set_label, mem_last_set, MEM_P, MEM_READONLY_P, REG_N_SETS(), reg_n_sets_max, REG_P, reg_stat, REGNO, insn_link::regno, REGNO_REG_SET_P, tick, XEXP, XVECEXP, and XVECLEN.
Referenced by get_last_value(), get_last_value_validate(), and record_value_for_reg().
|
static |
Given M see if it is a value that would select a field of bits within an item, but not the entire word. Return -1 if not. Otherwise, return the starting position of the field, where 0 is the low-order bit. *PLEN is set to the length of the field.
References ctz_hwi(), and exact_log2().
Referenced by make_field_assignment().
|
static |
Get a marker for undoing to the current state.
References undobuf::undos.
Referenced by recog_for_combine().
Return nonzero if X is an expression that has one of two values depending on whether some other value is zero or nonzero. In that case, we return the value that is being tested, *PTRUE is set to the value if the rtx being returned has a nonzero value, and *PFALSE is set to the other alternative. If we return zero, we set *PTRUE and *PFALSE to X.
References BINARY_P, COMPARISON_P, const0_rtx, const_true_rtx, CONSTANT_P, constm1_rtx, copy_rtx(), GEN_INT, gen_int_mode(), GET_CODE, get_last_value(), GET_MODE, GET_MODE_PRECISION(), HWI_COMPUTABLE_MODE_P(), if_then_else_cond(), is_a(), nonzero_bits(), NULL, num_sign_bit_copies(), pow2p_hwi(), REG_P, reversed_comparison_code(), rtx_equal_p(), SCALAR_INT_MODE_P, side_effects_p(), simplify_gen_binary(), simplify_gen_relational(), simplify_gen_subreg(), simplify_gen_unary(), STORE_FLAG_VALUE, SUBREG_BYTE, SUBREG_REG, swap_condition(), UNARY_P, and XEXP.
Referenced by combine_simplify_rtx(), and if_then_else_cond().
|
static |
Wipe the last_xxx fields of reg_stat in preparation for another pass.
References FOR_EACH_VEC_ELT, i, offsetof, and reg_stat.
Referenced by combine_instructions().
Walk the LOG_LINKS of insn B to see if we find a reference to A. Return true if we found a LOG_LINK that proves that A feeds B. This only works if there are no instructions between A and B which could have a link depending on A, since in that case we would not record a link for B.
References a, b, FOR_EACH_LOG_LINK, and insn_link::insn.
Referenced by try_combine().
|
inlinestatic |
References gcc_checking_assert, insn_link::insn, INSN_UID(), and max_uid_known.
Return whether X is just a single_set, with the source a general_operand.
References general_operand(), SET_SRC, and single_set().
Referenced by try_combine().
Return whether PAT is a PARALLEL of exactly N register SETs followed by an arbitrary number of CLOBBERs.
References const0_rtx, GET_CODE, i, REG_P, SET, SET_DEST, XEXP, XVECEXP, and XVECLEN.
Referenced by try_combine().
Return the value of expression X given the fact that condition COND is known to be true when applied to REG as its first operand and VAL as its second. X is known to not be shared and so can be modified in place. We only handle the simplest cases, and specifically those cases that arise with IF_THEN_ELSE expressions.
References COMMUTATIVE_ARITH_P, comparison_dominates_p(), COMPARISON_P, CONST0_RTX, const0_rtx, const_true_rtx, FLOAT_MODE_P, GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, known_cond(), NULL, r, reverse_condition(), reversed_comparison_code(), rtx_equal_p(), side_effects_p(), simplify_gen_unary(), simplify_subreg(), simplify_unary_operation(), SUBREG_BYTE, SUBREG_REG, SUBST, swap_condition(), VECTOR_MODE_P, XEXP, XVECEXP, and XVECLEN.
Referenced by known_cond(), and simplify_if_then_else().
Called via note_stores by likely_spilled_retval_p. Remove from info->mask hard registers that are known to be written to / clobbered in full.
References likely_spilled_retval_info::mask, likely_spilled_retval_info::nregs, REG_NREGS, REG_P, REGNO, likely_spilled_retval_info::regno, and XEXP.
Referenced by likely_spilled_retval_p().
Return true iff part of the return value is live during INSN, and it is likely spilled. This can happen when more than one insn is needed to copy the return value, e.g. when we consider to combine into the second copy insn for a complex value.
References BB_END, GET_CODE, INSN_P, likely_spilled_retval_1(), likely_spilled_retval_info::mask, NONJUMP_INSN_P, note_stores(), likely_spilled_retval_info::nregs, PATTERN(), PREV_INSN(), REG_NREGS, REG_P, REGNO, likely_spilled_retval_info::regno, targetm, this_basic_block, and XEXP.
Referenced by try_combine().
Look at the expression rooted at X. Look for expressions equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND. Form these expressions. Return the new rtx, usually just X. Also, for machines like the VAX that don't have logical shift insns, try to convert logical to arithmetic shift operations in cases where they are equivalent. This undoes the canonicalizations to logical shifts done elsewhere. We try, as much as possible, to re-use rtl expressions to save memory. IN_CODE says what kind of expression we are processing. Normally, it is SET. In a memory address it is MEM. When processing the arguments of a comparison or a COMPARE against zero, it is COMPARE, or EQ if more precisely it is an equality comparison against zero.
References COMPARISON_P, const0_rtx, GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, is_a(), make_compound_operation(), make_compound_operation_int(), maybe_swap_commutative_operands(), SET, simplify_unary_operation(), SUBST, XEXP, XVECEXP, and XVECLEN.
Referenced by combine_simplify_rtx(), make_compound_operation(), make_compound_operation_int(), propagate_for_debug_subst(), simplify_comparison(), simplify_if_then_else(), and simplify_set().
|
static |
Subroutine of make_compound_operation. *X_PTR is the rtx at the current level of the expression and MODE is its mode. IN_CODE is as for make_compound_operation. *NEXT_CODE_PTR is the value of IN_CODE that should be used when recursing on operands of *X_PTR. There are two possible actions: - Return null. This tells the caller to recurse on *X_PTR with IN_CODE equal to *NEXT_CODE_PTR, after which *X_PTR holds the final value. - Return a new rtx, which the caller returns directly.
References BITS_PER_WORD, CONST_INT_P, count, exact_log2(), extract_left_shift(), force_to_mode(), gen_int_mode(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_SIZE(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1, HOST_WIDE_INT_M1U, i, INTVAL, is_a(), load_extend_op(), make_compound_operation(), make_extraction(), maybe_swap_commutative_operands(), MEM_P, nonzero_bits(), NULL, NULL_RTX, OBJECT_P, partial_subreg_p(), REG_P, rtx_equal_p(), SET, simplify_gen_binary(), simplify_gen_unary(), simplify_subreg(), SUBREG_BYTE, subreg_lowpart_p(), SUBREG_REG, SUBST, trunc_int_for_mode(), UINTVAL, WORD_REGISTER_OPERATIONS, and XEXP.
Referenced by make_compound_operation().
|
static |
Return an RTX for a reference to LEN bits of INNER. If POS_RTX is nonzero, it is an RTX that represents the (variable) starting position; otherwise, POS is the (constant) starting bit position. Both are counted from the LSB. UNSIGNEDP is true for an unsigned reference and zero for a signed one. IN_DEST is true if this is a reference in the destination of a SET. This is used when a ZERO_ or SIGN_EXTRACT isn't needed. If nonzero, a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will be used. IN_COMPARE is true if we are in a COMPARE. This means that a ZERO_EXTRACT should be built even for bits starting at bit 0. MODE is the desired mode of the result (if IN_DEST == 0). The result is an RTX for the extraction or NULL_RTX if the target can't handle it.
References adjust_address_nv, as_a(), BITS_PER_WORD, bits_to_bytes_round_down, const0_rtx, CONST_INT_P, CONST_SCALAR_INT_P, EP_extv, EP_extzv, EP_insv, exact_log2(), extraction_insn::field_mode, force_to_mode(), GEN_INT, gen_int_mode(), gen_lowpart, gen_rtx_SUBREG(), get_best_reg_extraction_insn(), GET_CODE, GET_MODE, GET_MODE_ALIGNMENT, GET_MODE_BITSIZE(), GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_SIZE(), GET_MODE_WIDER_MODE(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, HWI_COMPUTABLE_MODE_P(), IN_RANGE, int_mode_for_size(), INTVAL, known_le, make_extraction(), maybe_gt, MEM_ADDR_SPACE, MEM_P, MEM_VOLATILE_P, mode_dependent_address_p(), nonzero_bits(), NULL_RTX, optimize_this_for_speed_p, paradoxical_subreg_p(), partial_subreg_p(), extraction_insn::pos_mode, REG_P, reg_truncated_to_mode(), opt_mode< T >::require(), set_src_cost(), simplify_gen_unary(), simplify_unary_operation(), smallest_int_mode_for_size(), extraction_insn::struct_mode, subreg_lowpart_p(), subreg_offset_from_lsb(), SUBREG_REG, TRULY_NOOP_TRUNCATION_MODES_P, UINTVAL, validate_subreg(), word_mode, and XEXP.
Referenced by find_split_point(), make_compound_operation_int(), make_extraction(), and make_field_assignment().
See if X, a SET operation, can be rewritten as a bit-field assignment. Return that assignment if so. We only handle the most common cases.
References canon_reg_for_combine(), const0_rtx, const1_rtx, CONST_INT_P, expand_compound_operation(), force_to_mode(), gen_int_mode(), GET_CODE, GET_MODE, GET_MODE_MASK, GET_MODE_PRECISION(), get_pos_from_mask(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, INTVAL, is_a(), make_extraction(), MEM_P, new_mode(), nonzero_bits(), NULL_RTX, paradoxical_subreg_p(), partial_subreg_p(), rtx_equal_for_field_assignment_p(), SET_DEST, SET_SRC, simplify_shift_const(), subreg_lowpart_p(), SUBREG_REG, UINTVAL, and XEXP.
Referenced by simplify_set().
|
static |
Make pseudo-to-pseudo copies after every hard-reg-to-pseudo-copy, because the reg-to-reg copy can usefully combine with later instructions, but we do not want to combine the hard reg into later instructions, for that restricts register allocation.
References cfun, df_insn_rescan(), emit_insn_before(), fixed_reg_set, FOR_BB_INSNS, FOR_EACH_BB_FN, gen_move_insn(), gen_reg_rtx(), GET_MODE, HARD_REGISTER_P, insn_link::insn, NONDEBUG_INSN_P, REG_P, REGNO, SET_DEST, set_reg_attrs_from_value(), SET_SRC, single_set(), and TEST_HARD_REG_BIT.
Referenced by rest_of_handle_combine().
rtl_opt_pass * make_pass_combine | ( | gcc::context * | ctxt | ) |
|
static |
Note hard registers in X that are used.
References add_to_hard_reg_set(), CASE_CONST_ANY, fixed_regs, GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, HARD_FRAME_POINTER_IS_FRAME_POINTER, HARD_FRAME_POINTER_REGNUM, i, mark_used_regs_combine(), MEM_P, newpat_used_regs, REGNO, insn_link::regno, RTX_CODE, SET, SET_DEST, SET_SRC, XEXP, XVECEXP, and XVECLEN.
Referenced by mark_used_regs_combine(), and try_combine().
|
static |
If X is a commutative operation whose operands are not in the canonical order, use substitutions to swap them.
References COMMUTATIVE_ARITH_P, CONST_INT_P, GEN_INT, GET_CODE, GET_MODE, GET_MODE_NUNITS(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, rtx_equal_p(), SUBST, swap_commutative_operands_p(), UINTVAL, and XEXP.
Referenced by change_zero_ext(), combine_simplify_rtx(), make_compound_operation(), and make_compound_operation_int().
|
static |
This function is called from `simplify_shift_const' to merge two outer operations. Specifically, we have already found that we need to perform operation *POP0 with constant *PCONST0 at the outermost position. We would now like to also perform OP1 with constant CONST1 (with *POP0 being done last). Return true if we can do the operation and update *POP0 and *PCONST0 with the resulting operation. *PCOMP_P is set to true if we would need to complement the innermost operand, otherwise it is unchanged. MODE is the mode in which the operation will be done. No bits outside the width of this mode matter. It is assumed that the width of this mode is smaller than or equal to HOST_BITS_PER_WIDE_INT. If *POP0 or OP1 are UNKNOWN, it means no operation is required. Only NEG, PLUS, IOR, XOR, and AND are supported. We may set *POP0 to SET if the proper result is simply *PCONST0. If the resulting operation cannot be expressed as one operation, we return false and do not change *POP0, *PCONST0, and *PCOMP_P.
References GET_MODE_MASK, SET, and trunc_int_for_mode().
Referenced by simplify_shift_const_1().
|
static |
For each register (hardware or pseudo) used within expression X, if its death is in an instruction with luid between FROM_LUID (inclusive) and TO_INSN (exclusive), put a REG_DEAD note for that register in the list headed by PNOTES. That said, don't move registers killed by maybe_kill_insn. This is done when X is being merged by combination into TO_INSN. These notes will then be distributed as needed.
References add_reg_note(), alloc_reg_note(), BLOCK_FOR_INSN(), dead_or_set_regno_p(), DF_INSN_LUID, END_REGNO(), find_regno_note(), GET_CODE, GET_MODE, GET_RTX_FORMAT, GET_RTX_LENGTH, hard_regno_nregs(), i, insn_link::insn, MEM_P, move_deaths(), partial_subreg_p(), prev_real_nondebug_insn(), read_modify_subreg_p(), REG_NREGS, reg_referenced_p(), reg_set_p(), reg_stat, REGNO, insn_link::regno, regno_reg_rtx, remove_death(), SET, SET_DEST, SET_SRC, SUBREG_REG, XEXP, XVECEXP, and XVECLEN.
Referenced by move_deaths(), and try_combine().
Like recog, but we receive the address of a pointer to a new pattern. We try to match the rtx that the pointer points to. If that fails, we may try to modify or replace the pattern, storing the replacement into the same pointer object. Modifications include deletion or addition of CLOBBERs. If the instruction will still not match, we change ZERO_EXTEND and ZERO_EXTRACT to the equivalent AND and perhaps LSHIFTRT patterns, and try with that (and undo if that fails). PNOTES is a pointer to a location where any REG_UNUSED notes added for the CLOBBERs are placed. The value is the final insn code from the pattern ultimately matched, or -1.
References change_zero_ext(), changed, check_asm_operands(), CONST_INT_P, CONSTANT_P, crtl, force_const_mem(), GET_CODE, GET_MODE, get_undo_marker(), i, recog_for_combine_1(), SET, SET_DEST, SET_SRC, SUBST, undo_to_marker(), XVECEXP, and XVECLEN.
Referenced by simplify_set(), and try_combine().
A subroutine of recog_for_combine. See there for arguments and return value.
References add_clobbers(), alloc_reg_note(), check_asm_operands(), const0_rtx, dump_file, dump_flags, gcc_assert, GET_CODE, i, INSN_CODE, NOOP_MOVE_INSN_CODE, NULL_RTX, PATTERN(), print_rtl_single(), recog(), reg_dead_at_p(), REG_NOTES, REG_P, rtvec_alloc(), SET, set_noop_p(), SUBST, SUBST_INT, targetm, TDF_DETAILS, XEXP, XVECEXP, and XVECLEN.
Referenced by recog_for_combine().
|
static |
Update the records of when each REG was most recently set or killed for the things done by INSN. This is the last thing done in processing INSN in the combiner loop. We update reg_stat[], in particular fields last_set, last_set_value, last_set_mode, last_set_nonzero_bits, last_set_sign_bit_copies, last_death, and also the similar information mem_last_set (which insn most recently modified memory) and last_call_luid (which insn was the most recent subroutine call).
References CALL_P, DF_INSN_LUID, END_REGNO(), EXECUTE_IF_SET_IN_HARD_REG_SET, function_abi::full_and_partial_reg_clobbers(), i, insn_callee_abi(), last_call_luid, reg_stat_type::last_death, reg_stat_type::last_set, reg_stat_type::last_set_invalid, reg_stat_type::last_set_mode, reg_stat_type::last_set_nonzero_bits, reg_stat_type::last_set_sign_bit_copies, reg_stat_type::last_set_value, mem_last_set, note_stores(), NULL_RTX, record_dead_and_set_regs_1(), record_value_for_reg(), REG_NOTE_KIND, REG_NOTES, REG_P, reg_stat, REGNO, reg_stat_type::truncated_to_mode, and XEXP.
Referenced by combine_instructions().
Called via note_stores from record_dead_and_set_regs to handle one SET or CLOBBER in an insn. DATA is the instruction in which the set is occurring.
References BITS_PER_WORD, DF_INSN_LUID, gen_lowpart, GET_CODE, GET_MODE, GET_MODE_MASK, GET_MODE_PRECISION(), known_le, reg_stat_type::last_set_nonzero_bits, reg_stat_type::last_set_sign_bit_copies, mem_last_set, MEM_P, NULL, NULL_RTX, paradoxical_subreg_p(), partial_subreg_p(), push_operand(), record_value_for_reg(), REG_P, reg_stat, REGNO, SET, SET_DEST, SET_SRC, subreg_lowpart_p(), SUBREG_REG, word_register_operation_p(), and WORD_REGISTER_OPERATIONS.
Referenced by record_dead_and_set_regs().
If a SUBREG has the promoted bit set, it is in fact a property of the register present in the SUBREG, so for each such SUBREG go back and adjust nonzero and sign bit information of the registers that are known to have some zero/sign bits set. This is needed because when combine blows the SUBREGs away, the information on zero/sign bits is lost and further combines can be missed because of that.
References GET_MODE, GET_MODE_MASK, HWI_COMPUTABLE_MODE_P(), insn_link::insn, reg_stat_type::last_set, reg_stat_type::last_set_nonzero_bits, LOG_LINKS, insn_link::next, REG_P, reg_stat, REGNO, insn_link::regno, SET_DEST, SET_SRC, single_set(), SUBREG_PROMOTED_UNSIGNED_P, and SUBREG_REG.
Referenced by check_promoted_subreg().
If X is a hard reg or a subreg record the mode that the register is accessed in. For non-TARGET_TRULY_NOOP_TRUNCATION targets we might be able to turn a truncate into a subreg using this information. Return true if traversing X is complete.
References GET_CODE, GET_MODE, label_tick, label_tick_ebb_start, partial_subreg_p(), REG_P, reg_stat, REGNO, SUBREG_REG, TRULY_NOOP_TRUNCATION_MODES_P, reg_stat_type::truncated_to_mode, and reg_stat_type::truncation_label.
Referenced by record_truncated_values().
|
static |
Callback for note_uses. Find hardregs and subregs of pseudos and the modes they are used in. This can help truning TRUNCATEs into SUBREGs.
References FOR_EACH_SUBRTX_VAR, and record_truncated_value().
Referenced by combine_instructions().
Record that REG is set to VALUE in insn INSN. If VALUE is zero, we are saying that the register is clobbered and we no longer know its value. If INSN is zero, don't update reg_stat[].last_set; this is only permitted with VALUE also zero and is used to invalidate the register.
References ARITHMETIC_P, const0_rtx, copy_rtx(), count_occurrences(), count_rtxs(), DF_INSN_LUID, END_REGNO(), GET_CODE, get_last_value(), get_last_value_validate(), GET_MODE, GET_MODE_CLASS, HWI_COMPUTABLE_MODE_P(), i, label_tick, label_tick_ebb_start, reg_stat_type::last_death, reg_stat_type::last_set, reg_stat_type::last_set_invalid, reg_stat_type::last_set_label, reg_stat_type::last_set_mode, reg_stat_type::last_set_nonzero_bits, reg_stat_type::last_set_sign_bit_copies, reg_stat_type::last_set_table_tick, reg_stat_type::last_set_value, nonzero_bits(), nonzero_bits_mode, num_sign_bit_copies(), reg_overlap_mentioned_p(), reg_stat, REGNO, replace_rtx(), subst_low_luid, reg_stat_type::truncated_to_mode, update_table_tick(), and XEXP.
Referenced by distribute_notes(), record_dead_and_set_regs(), record_dead_and_set_regs_1(), setup_incoming_promotions(), and try_combine().
Return true if X is the target of a bit-field assignment in BODY, the pattern of an insn. X must be a REG.
References end_hard_regno(), GET_CODE, GET_MODE, i, reg_bitfield_target_p(), REG_P, REGNO, insn_link::regno, SET, SET_DEST, SUBREG_REG, XEXP, XVECEXP, and XVECLEN.
Referenced by distribute_notes(), and reg_bitfield_target_p().
Return true if REG is known to be dead at INSN. We scan backwards from INSN. If we hit a REG_DEAD note or a CLOBBER referencing REG, it is dead. If we hit a SET referencing REG, it is live. Otherwise, see if it is live or dead at the start of the basic block we are in. Hard regs marked as being live in NEWPAT_USED_REGS must be assumed to be always live.
References BB_HEAD, BLOCK_FOR_INSN(), df_get_live_in(), END_REGNO(), find_regno_note(), fixed_regs, i, insn_link::insn, INSN_P, newpat_used_regs, note_stores(), NULL, PREV_INSN(), reg_dead_at_p_1(), reg_dead_endregno, reg_dead_flag, reg_dead_reg, reg_dead_regno, REGNO, REGNO_REG_SET_P, and TEST_HARD_REG_BIT.
Referenced by recog_for_combine_1().
Function called via note_stores from reg_dead_at_p. If DEST is within [reg_dead_regno, reg_dead_endregno), set reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.
References END_REGNO(), GET_CODE, reg_dead_endregno, reg_dead_flag, reg_dead_regno, REG_P, REGNO, and insn_link::regno.
Referenced by reg_dead_at_p().
|
static |
Given a REG X of mode XMODE, compute which bits in X can be nonzero. We don't care about bits outside of those defined in MODE. We DO care about all the bits in MODE, even if XMODE is smaller than MODE. For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is a shift, AND, or zero_extract, we can do better.
References cfun, DF_INSN_LUID, DF_LR_IN, ENTRY_BLOCK_PTR_FOR_FN, get_last_value(), GET_MODE_CLASS, GET_MODE_MASK, GET_MODE_PRECISION(), label_tick, label_tick_ebb_start, reg_stat_type::last_set, reg_stat_type::last_set_label, reg_stat_type::last_set_mode, reg_stat_type::last_set_nonzero_bits, reg_stat_type::last_set_value, reg_stat_type::nonzero_bits, nonzero_sign_valid, NULL, REG_N_SETS(), reg_n_sets_max, reg_stat, REGNO, REGNO_REG_SET_P, SHORT_IMMEDIATES_SIGN_EXTEND, sign_extend_short_imm(), and subst_low_luid.
|
static |
Given a reg X of mode XMODE, return the number of bits at the high-order end of X that are known to be equal to the sign bit. X will be used in mode MODE; the returned value will always be between 1 and the number of bits in MODE.
References cfun, DF_INSN_LUID, DF_LR_IN, ENTRY_BLOCK_PTR_FOR_FN, get_last_value(), GET_MODE_PRECISION(), label_tick, label_tick_ebb_start, reg_stat_type::last_set, reg_stat_type::last_set_label, reg_stat_type::last_set_mode, reg_stat_type::last_set_sign_bit_copies, reg_stat_type::last_set_value, nonzero_sign_valid, NULL, REG_N_SETS(), reg_n_sets_max, reg_stat, REGNO, REGNO_REG_SET_P, reg_stat_type::sign_bit_copies, and subst_low_luid.
Check whether X, the destination of a set, refers to part of the register specified by REG.
References GET_CODE, GET_MODE, GET_MODE_CLASS, paradoxical_subreg_p(), REG_P, SUBREG_REG, and XEXP.
Referenced by try_combine().
Check if X, a register, is known to contain a value already truncated to MODE. In this case we can use a subreg to refer to the truncated value even though in the generic case we would need an explicit truncation.
References label_tick_ebb_start, partial_subreg_p(), reg_stat, REGNO, TRULY_NOOP_TRUNCATION_MODES_P, reg_stat_type::truncated_to_mode, and reg_stat_type::truncation_label.
Referenced by gen_lowpart_or_truncate(), and make_extraction().
Remove register number REGNO from the dead registers list of INSN. Return the note used to record the death, if there was one.
References find_regno_note(), insn_link::insn, insn_link::regno, and remove_note().
Referenced by combine_and_move_insns(), and move_deaths().
|
static |
Try combining insns through substitution.
References CDI_DOMINATORS, cleanup_cfg(), combine_instructions(), df_analyze(), DF_DEFER_INSN_RESCAN, DF_LR_RUN_DCE, df_note_add_problem(), df_set_flags(), dom_info_available_p(), free_dominance_info(), get_insns(), make_more_copies(), max_reg_num(), rebuild_jump_labels(), reg_n_sets_max, regstat_free_n_sets_and_refs(), regstat_init_n_sets_and_refs(), timevar_pop(), and timevar_push().
See if X and Y are equal for the purposes of seeing if we can rewrite an assignment as a field assignment.
References adjust_address_nv, byte_lowpart_offset(), gen_lowpart, GET_CODE, GET_MODE, MEM_P, paradoxical_subreg_p(), rtx_equal_p(), SUBREG_REG, and y.
Referenced by make_field_assignment().
Called via note_stores. If X is a pseudo that is narrower than HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero. If we are setting only a portion of X and we can't figure out what portion, assume all bits will be used since we don't know what will be happening. Similarly, set how many bits of X are known to be copies of the sign bit at all locations in the function. This is the smallest number implied by any set of X.
References BLOCK_FOR_INSN(), cfun, dead_or_set_p(), DF_LR_IN, ENTRY_BLOCK_PTR_FOR_FN, expand_field_assignment(), FOR_EACH_LOG_LINK, GET_CODE, GET_MODE, GET_MODE_MASK, HWI_COMPUTABLE_MODE_P(), insn_link::insn, is_a(), reg_stat_type::nonzero_bits, paradoxical_subreg_p(), PATTERN(), REG_P, reg_referenced_p(), reg_stat, REGNO, REGNO_REG_SET_P, SET_DEST, reg_stat_type::sign_bit_copies, SUBREG_REG, and update_rsp_from_reg_equal().
Referenced by combine_instructions(), and try_combine().
|
static |
Set up any promoted values for incoming argument registers.
References cfun, const0_rtx, current_function_decl, DECL_ARG_TYPE, DECL_ARGUMENTS, DECL_CHAIN, DECL_INCOMING_RTL, GET_MODE, cgraph_node::local, cgraph_node::local_info_node(), promote_function_mode(), record_value_for_reg(), REG_P, TREE_TYPE, TYPE_MODE, and TYPE_UNSIGNED.
Referenced by combine_instructions().
If MODE has a precision lower than PREC and SRC is a non-negative constant that would appear negative in MODE, sign-extend SRC for use in nonzero_bits because some machines (maybe most) will actually do the sign-extension and this is the conservative approach. ??? For 2.5, try to tighten up the MD files in this regard instead of this kludge.
References CONST_INT_P, GEN_INT, GET_MODE_MASK, GET_MODE_PRECISION(), INTVAL, is_a(), and val_signbit_known_set_p().
Referenced by reg_nonzero_bits_for_combine(), and update_rsp_from_reg_equal().
|
static |
We have X, a logical `and' of VAROP with the constant CONSTOP, to be done in MODE. Return an equivalent form, if different from X. Otherwise, return X. If X is zero, we are to always construct the equivalent form.
References gen_int_mode(), gen_lowpart, GET_MODE, simplify_and_const_int_1(), and simplify_gen_binary().
Referenced by combine_simplify_rtx(), expand_compound_operation(), force_int_to_mode(), simplify_and_const_int_1(), simplify_comparison(), simplify_logical(), and simplify_shift_const_1().
|
static |
Simplify a logical `and' of VAROP with the constant CONSTOP, to be done in MODE. Return an equivalent form, if different from (and VAROP (const_int CONSTOP)). Otherwise, return NULL_RTX.
References apply_distributive_law(), as_a(), BITS_PER_WORD, const0_rtx, CONST_INT_P, exact_log2(), force_to_mode(), gen_int_mode(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_MASK, i, INTVAL, nonzero_bits(), NULL_RTX, pow2p_hwi(), side_effects_p(), simplify_and_const_int(), simplify_gen_binary(), simplify_shift_const(), word_mode, WORD_REGISTER_OPERATIONS, and XEXP.
Referenced by simplify_and_const_int().
|
static |
Try to simplify a comparison between OP0 and a constant OP1, where CODE is the comparison code that will be tested, into a (CODE OP0 const0_rtx) form. The result is a possibly different comparison code to use. *POP0 and *POP1 may be updated.
References adjust_address_nv, dump_file, dump_flags, FOR_EACH_MODE_UNTIL, gcc_fallthrough, GEN_INT, gen_int_mode(), GET_MODE, GET_MODE_MASK, GET_MODE_NAME, GET_MODE_PRECISION(), GET_MODE_SIZE(), GET_RTX_NAME, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, HOST_WIDE_INT_PRINT_HEX, HWI_COMPUTABLE_MODE_P(), INTVAL, is_a(), MEM_P, MEM_VOLATILE_P, nonzero_bits(), num_sign_bit_copies(), pow2p_hwi(), TDF_DETAILS, and trunc_int_for_mode().
Referenced by simplify_comparison(), and try_combine().
Simplify a comparison between *POP0 and *POP1 where CODE is the comparison code that will be tested. The result is a possibly different comparison code to use. *POP0 and *POP1 may be updated. It is possible that we might detect that a comparison is either always true or always false. However, we do not perform general constant folding in combine, so this knowledge isn't useful. Such tautologies should have been detected earlier. Hence we ignore all such cases.
References a, as_a(), BITS_PER_WORD, changed, COMPARISON_P, const0_rtx, const1_rtx, CONST_INT_P, constm1_rtx, exact_log2(), expand_compound_operation(), FOR_EACH_MODE_UNTIL, FOR_EACH_WIDER_MODE, force_to_mode(), GEN_INT, gen_int_mode(), gen_lowpart, gen_lowpart_or_truncate(), GET_CODE, get_last_value(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_SIZE(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1, HOST_WIDE_INT_1U, HWI_COMPUTABLE_MODE_P(), i, int_mode_for_size(), INTVAL, is_a(), is_int_mode(), load_extend_op(), make_compound_operation(), MEM_P, nonzero_bits(), NULL, NULL_RTX, num_sign_bit_copies(), paradoxical_subreg_p(), REG_P, opt_mode< T >::require(), reverse_condition(), reversed_comparison_code(), rtx_equal_p(), SET, SHIFT_COUNT_TRUNCATED, simplify_and_const_int(), simplify_binary_operation(), simplify_compare_const(), simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), simplify_unary_operation(), STORE_FLAG_VALUE, subreg_lowpart_p(), SUBREG_REG, swap_commutative_operands_p(), swap_condition(), target_canonicalize_comparison(), trunc_int_for_mode(), UINTVAL, unsigned_condition(), val_signbit_known_set_p(), WORD_REGISTER_OPERATIONS, and XEXP.
Referenced by combine_simplify_rtx(), and simplify_set().
Simplify X, an IF_THEN_ELSE expression. Return the new expression.
References COMPARISON_P, const0_rtx, CONST_INT_P, const_true_rtx, CONSTANT_P, constm1_rtx, copy_rtx(), exact_log2(), false_rtx, FLOAT_MODE_P, gen_int_mode(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_MASK, GET_MODE_PRECISION(), HONOR_NANS(), HONOR_SIGNED_ZEROS(), HWI_COMPUTABLE_MODE_P(), i, is_a(), is_int_mode(), known_cond(), undo::m, make_compound_operation(), nonzero_bits(), NULL, NULL_RTX, num_sign_bit_copies(), OBJECT_P, pc_rtx, pow2p_hwi(), reg_mentioned_p(), REG_P, reversed_comparison(), reversed_comparison_code(), rtx_equal_p(), SET, side_effects_p(), simplify_gen_binary(), simplify_gen_relational(), simplify_gen_unary(), simplify_shift_const(), STORE_FLAG_VALUE, subreg_lowpart_p(), SUBREG_REG, SUBST, subst(), true_rtx, UINTVAL, and XEXP.
Referenced by combine_simplify_rtx().
Simplify, X, and AND, IOR, or XOR operation, and return the simplified result.
References CONST_INT_P, distribute_and_simplify_rtx(), gcc_unreachable, GET_CODE, GET_MODE, HWI_COMPUTABLE_MODE_P(), INTVAL, is_a(), simplify_and_const_int(), and XEXP.
Referenced by combine_simplify_rtx().
Simplify X, a SET expression. Return the new expression.
References ANY_RETURN_P, can_change_dest_mode(), can_conditionally_move_p(), check_asm_operands(), COMPARISON_P, CONST0_RTX, const0_rtx, CONSTANT_P, false_rtx, find_single_use(), force_to_mode(), gen_int_mode(), gen_lowpart, gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_PRECISION(), GET_MODE_SIZE(), HOST_WIDE_INT_M1U, HWI_COMPUTABLE_MODE_P(), is_int_mode(), load_extend_op(), make_compound_operation(), make_field_assignment(), MEM_P, nonzero_bits(), NULL_RTX, num_sign_bit_copies(), OBJECT_P, undobuf::other_insn, paradoxical_subreg_p(), PATTERN(), pc_rtx, pow2p_hwi(), recog_for_combine(), REG_CAN_CHANGE_MODE_P, REG_P, REGNO, undo::regno, regno_reg_rtx, rtx_equal_p(), SCALAR_INT_MODE_P, SELECT_CC_MODE, SET, SET_DEST, SET_SRC, side_effects_p(), simplify_comparison(), simplify_gen_binary(), simplify_gen_unary(), simplify_relational_operation(), simplify_rtx(), subreg_lowpart_p(), SUBREG_REG, SUBST, subst_insn, subst_mode(), true_rtx, WORD_REGISTER_OPERATIONS, and XEXP.
Referenced by combine_simplify_rtx().
|
static |
Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift. The result of the shift is RESULT_MODE. If we cannot simplify it, return X or, if it is NULL, synthesize the expression with simplify_gen_binary. Otherwise, return a simplified value. The shift is normally computed in the widest mode we find in VAROP, as long as it isn't a different number of words than RESULT_MODE. Exceptions are ASHIFTRT and ROTATE, which are always done in their original mode.
References count, gen_int_shift_amount(), gen_lowpart, GET_MODE, simplify_gen_binary(), and simplify_shift_const_1().
Referenced by combine_simplify_rtx(), expand_compound_operation(), extract_left_shift(), force_int_to_mode(), make_field_assignment(), simplify_and_const_int_1(), simplify_comparison(), simplify_if_then_else(), and simplify_shift_const_1().
|
static |
Simplify a shift of VAROP by ORIG_COUNT bits. CODE says what kind of shift. The result of the shift is RESULT_MODE. Return NULL_RTX if we cannot simplify it. Otherwise, return a simplified value. The shift is normally computed in the widest mode we find in VAROP, as long as it isn't a different number of words than RESULT_MODE. Exceptions are ASHIFTRT and ROTATE, which are always done in their original mode.
References adjust_address_nv, apply_distributive_law(), as_a(), CEIL, const0_rtx, CONST_INT_P, constm1_rtx, count, exact_log2(), expand_compound_operation(), GEN_INT, gen_int_mode(), gen_int_shift_amount(), gen_lowpart, gen_lowpart_or_truncate(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, GET_MODE_INNER, GET_MODE_MASK, GET_MODE_PRECISION(), GET_MODE_SIZE(), GET_MODE_UNIT_BITSIZE, GET_MODE_UNIT_PRECISION, GET_RTX_CLASS, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HWI_COMPUTABLE_MODE_P(), int_mode_for_size(), INTVAL, is_a(), is_int_mode(), mask_rtx(), MEM_ADDR_SPACE, MEM_VOLATILE_P, merge_outer_ops(), mode_dependent_address_p(), mode_signbit_p(), nonzero_bits(), NULL_RTX, num_sign_bit_copies(), rtx_equal_p(), RTX_UNARY, SET, SHIFT_COUNT_TRUNCATED, side_effects_p(), simplify_and_const_int(), simplify_const_binary_operation(), simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), simplify_shift_const_1(), STORE_FLAG_VALUE, subreg_lowpart_p(), SUBREG_REG, trunc_int_for_mode(), try_widen_shift_mode(), UINTVAL, val_signbit_known_clear_p(), and XEXP.
Referenced by simplify_shift_const(), and simplify_shift_const_1().
Throughout X, replace FROM with TO, and return the result. The result is TO if X is FROM; otherwise the result is X, but its contents may have been modified. If they were modified, a record was made in undobuf so that undo_all will (among other things) return X to its original state. If the number of changes necessary is too much to record to undo, the excess changes are not made, so the result is invalid. The changes already made can still be undone. undobuf.num_undo is incremented for such changes, so by testing that the caller can tell whether the result is valid. `n_occurrences' is incremented each time FROM is replaced. IN_DEST is true if we are processing the SET_DEST of a SET. IN_COND is true if we are at the top level of a condition. UNIQUE_COPY is true if each substitution must be unique. We do this by copying if `n_occurrences' is nonzero.
Two expressions are equal if they are identical copies of a shared RTX or if they are both registers with the same register number and mode.
References avoid_constant_pool_reference(), COMBINE_RTX_EQUAL_P, combine_simplify_rtx(), const0_rtx, CONST_SCALAR_INT_P, copy_rtx(), GET_CODE, GET_MODE, GET_RTX_CLASS, GET_RTX_FORMAT, GET_RTX_LENGTH, i, MEM_P, MEM_READONLY_P, n_occurrences, OBJECT_P, reg_overlap_mentioned_p(), REG_P, REGNO, RTX_AUTOINC, SET, SET_DEST, SET_SRC, simplify_subreg(), simplify_subreg_regno(), simplify_unary_operation(), SUBREG_BYTE, SUBREG_REG, SUBST, subst(), targetm, XEXP, XVECEXP, and XVECLEN.
Referenced by calculate_equiv_gains(), combine_simplify_rtx(), curr_insn_transform(), loc_equivalence_callback(), loc_equivalence_change_p(), lower_for(), lra_substitute_pseudo(), self_referential_size(), simplify_if_then_else(), simplify_operand_subreg(), subst(), and try_combine().
|
static |
Similar to SUBST, but just substitute the mode. This is used when changing the mode of a pseudo-register, so that any other references to the entry in the regno_reg_rtx array will change as well.
References adjust_reg_mode(), undobuf::frees, GET_MODE, undo::kind, undo::m, undo::next, undo::old_contents, undo::regno, regno_reg_rtx, UNDO_MODE, undobuf::undos, and undo::where.
Referenced by simplify_set(), and try_combine().
|
inlinestatic |
Convenience wrapper for the canonicalize_comparison target hook. Target hooks cannot use enum rtx_code.
References targetm.
Referenced by simplify_comparison(), and try_combine().
|
static |
Try to combine the insns I0, I1 and I2 into I3. Here I0, I1 and I2 appear earlier than I3. I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into I3. If we are combining more than two insns and the resulting insn is not recognized, try splitting it into two insns. If that happens, I2 and I3 are retained and I1/I0 are pseudo-deleted by turning them into a NOTE. Otherwise, I0, I1 and I2 are pseudo-deleted. Return 0 if the combination does not work. Then nothing is changed. If we did the combination, return the insn at which combine should resume scanning. Set NEW_DIRECT_JUMP_P to true if try_combine creates a new direct jump instruction. LAST_COMBINED_INSN is either I3, or some insn after I3 that has been I3 passed to an earlier try_combine within the same basic block.
References added_links_insn, added_notes_insn, adjust_for_new_dest(), adjust_reg_mode(), alloc_insn_link(), alloc_reg_note(), any_uncondjump_p(), asm_noperands(), AUTO_INC_DEC, BB_HEAD, BINARY_P, BITS_PER_WORD, BLOCK_FOR_INSN(), CALL_INSN_FUNCTION_USAGE, CALL_P, can_change_dest_mode(), can_combine_p(), can_split_parallel_of_n_reg_sets(), cant_combine_insn_p(), cfun, check_asm_operands(), CLEAR_HARD_REG_SET, combinable_i3pat(), combine_attempts, combine_extras, combine_merges, combine_split_insns(), combine_successes, combine_validate_cost(), COMPARISON_P, COMPLEX_MODE_P, const0_rtx, const1_rtx, CONST_INT_P, CONST_SCALAR_INT_P, CONSTANT_P, contains_muldiv(), copy_rtx(), copy_rtx_if_shared(), count_auto_inc(), dead_or_set_p(), DEBUG_INSN_P, DF_INSN_LUID, df_insn_rescan(), distribute_links(), distribute_notes(), dump_file, dump_flags, dump_insn_slim(), rtvec_def::elem, emit_barrier_after_bb(), exact_log2(), EXIT_BLOCK_PTR_FOR_FN, FIND_REG_INC_NOTE, find_reg_note(), find_single_use(), find_split_point(), FLOAT_MODE_P, for_each_inc_dec(), FOR_EACH_LOG_LINK, FOR_EACH_SUBRTX_PTR, undobuf::frees, gcc_assert, gen_int_shift_amount(), gen_lowpart, gen_raw_REG(), gen_rtvec(), gen_rtx_INSN(), gen_rtx_REG(), GET_CODE, GET_MODE, GET_MODE_CLASS, GET_MODE_MASK, GET_MODE_PRECISION(), HOST_BITS_PER_INT, i, i1, i2, immed_wide_int_const(), INC_REG_N_SETS, wi::insert(), insn_link::insn, insn_a_feeds_b(), INSN_CODE, insn_could_throw_p(), INSN_LOCATION(), insn_nothrow_p(), INSN_P, INSN_UID(), INTEGRAL_MODE_P, INTVAL, is_a(), is_just_move(), is_parallel_of_n_reg_sets(), JUMP_P, undo::kind, known_lt, last, likely_spilled_retval_p(), load_extend_op(), LOG_LINKS, lowpart_subreg(), undo::m, mark_jump_label(), mark_used_regs_combine(), max_reg_num(), MAY_HAVE_DEBUG_BIND_INSNS, may_trap_p(), MEM_P, modified_between_p(), move_deaths(), n_occurrences, new_mode(), newpat_used_regs, undo::next, next_active_insn(), NEXT_INSN(), next_nonnote_nondebug_insn(), NONDEBUG_INSN_P, NONJUMP_INSN_P, nonzero_bits(), NOTE_KIND, NOTE_P, note_pattern_stores(), NULL, NULL_RTX, rtvec_def::num_elem, undo::old_contents, undobuf::other_insn, PATTERN(), pc_rtx, propagate_for_debug(), r, recog_for_combine(), record_value_for_reg(), reg_mentioned_p(), reg_n_sets_max, REG_NOTE_KIND, REG_NOTES, reg_or_subregno(), reg_overlap_mentioned_p(), REG_P, reg_referenced_p(), reg_set_between_p(), reg_set_p(), reg_stat, reg_subword_p(), reg_used_between_p(), REGNO, insn_link::regno, undo::regno, regno_reg_rtx, remove_edge(), remove_note(), reset_used_flags(), returnjump_p(), rtvec_alloc(), RTVEC_ELT, rtx_equal_p(), rtx_referenced_p(), SELECT_CC_MODE, SET, SET_DEST, SET_INSN_DELETED, set_nonzero_bits_and_sign_copies(), set_noop_p(), SET_SRC, side_effects_p(), simplify_compare_const(), simplify_gen_binary(), simplify_replace_rtx(), single_set(), split_block(), subreg_lowpart_p(), SUBREG_REG, SUBST, subst(), subst_insn, SUBST_LINK, subst_low_luid, subst_mode(), target_canonicalize_comparison(), targetm, TDF_DETAILS, this_basic_block, UINTVAL, undo_all(), undo_commit(), UNDO_MODE, undobuf::undos, update_cfg_for_uncondjump(), VECTOR_MODE_P, volatile_refs_p(), undo::where, word_mode, XEXP, XVEC, XVECEXP, and XVECLEN.
Referenced by combine_instructions().
|
static |
A helper to simplify_shift_const_1 to determine the mode we can perform the shift in. The original shift operation CODE is performed on OP in ORIG_MODE. Return the wider mode MODE if we can perform the operation in that mode. Return ORIG_MODE otherwise. We can also assume that the result of the shift is subject to operation OUTER_CODE with operand OUTER_CONST.
References count, gcc_assert, gcc_unreachable, GET_MODE_MASK, GET_MODE_PRECISION(), HWI_COMPUTABLE_MODE_P(), low_bitmask_len(), nonzero_bits(), and num_sign_bit_copies().
Referenced by simplify_shift_const_1().
|
static |
Undo all the modifications recorded in undobuf.
References undo_to_marker().
Referenced by try_combine().
|
static |
We've committed to accepting the changes we made. Move all of the undos to the free list.
References undobuf::frees, undo::next, and undobuf::undos.
Referenced by try_combine().
|
static |
Undo the modifications up to the marker.
References adjust_reg_mode(), undobuf::frees, gcc_assert, gcc_unreachable, undo::i, undo::kind, undo::l, undo::m, undo::next, undo::old_contents, undo::r, undo::regno, regno_reg_rtx, UNDO_INT, UNDO_LINKS, UNDO_MODE, UNDO_RTX, undobuf::undos, and undo::where.
Referenced by recog_for_combine(), and undo_all().
Check for any register or memory mentioned in EQUIV that is not mentioned in EXPR. This is used to restrict EQUIV to "specializations" of EXPR where some registers may have been replaced by constants.
References FOR_EACH_SUBRTX, MEM_P, reg_mentioned_p(), and REG_P.
Referenced by combine_instructions().
|
static |
Update RSP for pseudo-register X from INSN's REG_EQUAL note (if one exists) and SET.
References BITS_PER_WORD, find_reg_equal_equiv_note(), GET_MODE, GET_MODE_CLASS, GET_MODE_PRECISION(), HOST_WIDE_INT_M1U, HWI_COMPUTABLE_MODE_P(), nonzero_bits(), reg_stat_type::nonzero_bits, nonzero_bits_mode, NULL, NULL_RTX, num_sign_bit_copies(), SET_SRC, SHORT_IMMEDIATES_SIGN_EXTEND, reg_stat_type::sign_bit_copies, sign_extend_short_imm(), and XEXP.
Referenced by set_nonzero_bits_and_sign_copies().
|
static |
Utility function for following routine. Called when X is part of a value being stored into last_set_value. Sets last_set_table_tick for each register mentioned. Similar to mention_regs in cse.cc
References ARITHMETIC_P, END_REGNO(), GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, label_tick, reg_stat_type::last_set_table_tick, r, reg_stat, REGNO, update_table_tick(), XEXP, XVECEXP, and XVECLEN.
Referenced by record_value_for_reg(), and update_table_tick().
|
static |
This is an insn to which a LOG_LINKS entry has been added. If this insn is the earlier than I2 or I3, combine should rescan starting at that location.
Referenced by distribute_links(), and try_combine().
|
static |
And similarly, for notes.
Referenced by distribute_notes(), and try_combine().
|
static |
Optimize by combining instructions for GNU compiler. Copyright (C) 1987-2025 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>.
This module is essentially the "combiner" phase of the U. of Arizona Portable Optimizer, but redone to work on our list-structured representation for RTL instead of their string representation. The LOG_LINKS of each insn identify the most recent assignment to each REG used in the insn. It is a list of previous insns, each of which contains a SET for a REG that is used in this insn and not used or set in between. LOG_LINKs never cross basic blocks. They were set up by the preceding pass (lifetime analysis). We try to combine each pair of insns joined by a logical link. We also try to combine triplets of insns A, B and C when C has a link back to B and B has a link back to A. Likewise for a small number of quadruplets of insns A, B, C and D for which there's high likelihood of success. We check (with modified_between_p) to avoid combining in such a way as to move a computation to a place where its value would be different. Combination is done by mathematically substituting the previous insn(s) values for the regs they set into the expressions in the later insns that refer to these regs. If the result is a valid insn for our target machine, according to the machine description, we install it, delete the earlier insns, and update the data flow information (LOG_LINKS and REG_NOTES) for what we did. There are a few exceptions where the dataflow information isn't completely updated (however this is only a local issue since it is regenerated before the next pass that uses it): - reg_live_length is not updated - reg_n_refs is not adjusted in the rare case when a register is no longer required in a computation - there are extremely rare cases (see distribute_notes) when a REG_DEAD note is lost - a LOG_LINKS entry that refers to an insn with multiple SETs may be removed because there is no way to know which register it was linking To simplify substitution, we combine only when the earlier insn(s) consist of only a single assignment. To simplify updating afterward, we never combine when a subroutine call appears in the middle.
Include expr.h after insn-config.h so we get HAVE_conditional_move.
Number of attempts to combine instructions in this function.
Referenced by combine_instructions(), and try_combine().
|
static |
Number of instructions combined with added SETs in this function.
Referenced by combine_instructions(), and try_combine().
|
static |
Number of attempts that got as far as substitution in this function.
Referenced by combine_instructions(), and try_combine().
|
static |
Referenced by combine_instructions().
|
static |
Number of instructions combined in this function.
Referenced by combine_instructions(), and try_combine().
|
static |
combine_instructions may try to replace the right hand side of the second instruction with the value of an associated REG_EQUAL note before throwing it at try_combine. That is problematic when there is a REG_DEAD note for a register used in the old right hand side and can cause distribute_notes to do wrong things. This is the second instruction if it has been so modified, null otherwise.
Referenced by combine_instructions(), and distribute_notes().
|
static |
When I2MOD is nonnull, this is a copy of the new right hand side.
Referenced by combine_instructions(), and distribute_notes().
|
static |
When I2MOD is nonnull, this is a copy of the old right hand side.
Referenced by combine_instructions(), and distribute_notes().
|
static |
Links for LOG_LINKS are allocated from this obstack.
Referenced by alloc_insn_link(), and combine_instructions().
|
static |
Incremented for each basic block.
Referenced by combine_instructions(), get_last_value(), get_last_value_validate(), record_truncated_value(), record_value_for_reg(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), and update_table_tick().
|
static |
Reset to label_tick for each extended basic block in scanning order.
Referenced by combine_instructions(), get_last_value(), record_truncated_value(), record_value_for_reg(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), and reg_truncated_to_mode().
|
static |
Record the luid of the last CALL_INSN so we can tell whether a potential combination crosses any calls.
Referenced by can_combine_p(), combine_instructions(), and record_dead_and_set_regs().
|
static |
Length of the currently allocated uid_insn_cost array.
Referenced by combine_instructions(), and insn_uid_check().
|
static |
Record the luid of the last insn that invalidated memory (anything that writes memory, and subroutine calls, but not pushes).
Referenced by combine_instructions(), get_last_value_validate(), record_dead_and_set_regs(), and record_dead_and_set_regs_1().
|
static |
Number of times the pseudo being substituted for was found and replaced.
Referenced by check_operand_nalternatives(), delete_output_reload(), scan_operands(), subst(), and try_combine().
|
static |
This contains any hard registers that are used in newpat; reg_dead_at_p must consider all these registers to be always live.
Referenced by mark_used_regs_combine(), reg_dead_at_p(), and try_combine().
|
static |
Mode used to compute significance in reg_stat[].nonzero_bits. It is the largest integer mode that can fit in HOST_BITS_PER_WIDE_INT.
Referenced by combine_instructions(), record_value_for_reg(), and update_rsp_from_reg_equal().
|
static |
Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can be safely used. It is zero while computing them and after combine has completed. This former test prevents propagating values based on previously set values, which can be incorrect if a variable is modified in a loop.
Referenced by combine_instructions(), expand_field_assignment(), extended_count(), reg_nonzero_bits_for_combine(), and reg_num_sign_bit_copies_for_combine().
|
static |
|
static |
Referenced by reg_dead_at_p(), and reg_dead_at_p_1().
|
static |
Referenced by reg_dead_at_p(), and reg_dead_at_p_1().
rtx reg_dead_reg |
Referenced by reg_dead_at_p().
|
static |
Define three variables used for communication between the following routines.
Referenced by reg_dead_at_p(), and reg_dead_at_p_1().
|
static |
One plus the highest pseudo for which we track REG_N_SETS. regstat_init_n_sets_and_refs allocates the array for REG_N_SETS just once, but during combine_split_insns new pseudos can be created. As we don't have updated DF information in that case, it is hard to initialize the array after growing. The combiner only cares about REG_N_SETS (regno) == 1, so instead of growing the arrays, just assume all newly created pseudos during combine might be set multiple times.
Referenced by can_change_dest_mode(), get_last_value(), get_last_value_validate(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), rest_of_handle_combine(), and try_combine().
|
static |
Referenced by combine_instructions(), combine_split_insns(), distribute_notes(), get_last_value(), get_last_value_validate(), init_reg_last(), move_deaths(), record_dead_and_set_regs(), record_dead_and_set_regs_1(), record_promoted_value(), record_truncated_value(), record_value_for_reg(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), reg_truncated_to_mode(), set_nonzero_bits_and_sign_copies(), try_combine(), and update_table_tick().
|
static |
When `subst' is called, this is the insn that is being modified (by combining in a previous insn). The PATTERN of this insn is still the old pattern partially modified and it should not be looked at, but this may be used to examine the successors of the insn to judge whether a simplification is valid.
Referenced by combine_instructions(), find_split_point(), simplify_set(), and try_combine().
|
static |
This is the lowest LUID that `subst' is currently dealing with. get_last_value will not return a value if the register was set at or after this LUID. If not for this mechanism, we could get confused if I2 or I1 in try_combine were an insn that used the old value of a register to obtain a new value. In that case, we might erroneously get the new value of the register when we wanted the old one.
Referenced by can_combine_p(), combine_instructions(), get_last_value(), record_value_for_reg(), reg_nonzero_bits_for_combine(), reg_num_sign_bit_copies_for_combine(), and try_combine().
|
static |
Basic block in which we are performing combines.
Referenced by combine_instructions(), distribute_links(), distribute_notes(), likely_spilled_retval_p(), propagate_for_debug(), and try_combine().
|
static |
The following array records the insn_cost for every insn in the instruction stream.
Referenced by combine_instructions().
|
static |
Referenced by combine_instructions().
|
static |