GCC Middle and Back End API Reference
|
Data Structures | |
struct | reg_stat_struct |
struct | insn_link |
struct | undo |
struct | undobuf |
struct | likely_spilled_retval_info |
Typedefs | |
typedef struct reg_stat_struct | reg_stat_type |
Enumerations | |
enum | undo_kind { UNDO_RTX, UNDO_INT, UNDO_MODE, UNDO_LINKS } |
typedef struct reg_stat_struct reg_stat_type |
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(), and remove_reg_equal_equiv_notes().
Referenced by try_combine().
|
staticread |
Allocate a link.
References insn_link::insn, insn_link_obstack, and insn_link::next.
Referenced by adjust_for_new_dest(), create_log_links(), and try_combine().
|
static |
See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c) if so.
References apply_distributive_law(), expand_compound_operation(), rtx_equal_p(), simplify_gen_binary(), and simplify_gen_unary().
|
static |
Return TRUE if combine can reuse reg X in mode MODE. ADDED_SETS is nonzero if the original set is still required.
References REG_N_SETS(), and likely_spilled_retval_info::regno.
Referenced by simplify_set(), and try_combine().
|
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 0 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 1.
References expand_field_assignment(), find_reg_fusage(), find_reg_note(), global_regs, insn_nothrow_p(), last_call_luid, next_active_insn(), prev_nonnote_insn(), reg_overlap_mentioned_p(), reg_set_between_p(), reg_used_between_p(), rtx_equal_p(), SET, sets_cc0_p(), side_effects_p(), subst_low_luid, use_crosses_set_p(), volatile_insn_p(), and volatile_refs_p().
Referenced by try_combine().
Referenced by canon_reg_for_combine(), and make_field_assignment().
|
static |
If X refers to a register that equals REG in value, replace these references with REG.
References canon_reg_for_combine(), copy_rtx(), get_last_value(), 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(), and simplify_gen_unary().
|
static |
Referenced by try_combine().
|
static |
Determine whether INSN can be used in a combination. Return nonzero if not. This is used in try_combine to detect early some cases where we can't perform combinations.
References targetm.
Referenced by check_promoted_subreg(), and combine_instructions().
|
static |
Scan X for promoted SUBREGs. For each one found, note what it implies to the registers used in it.
References check_promoted_subreg(), and record_promoted_value().
|
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 1 if the combination is valid, zero otherwise.
References reg_overlap_mentioned_p(), reg_referenced_p(), rtx_equal_p(), and SET.
Referenced by try_combine().
|
static |
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 combiner has turned an indirect jump instruction into a direct jump.
References cc0_rtx, 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(), dump_file, find_reg_equal_equiv_note(), first, free(), undobuf::frees, general_rtl_hooks, get_max_uid(), 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_link_obstack, insn_rtx_cost(), label_tick, label_tick_ebb_start, last_bb, last_call_luid, max_uid_known, mem_last_set, mode_for_size(), insn_link::next, undo::next, nonzero_bits_mode, nonzero_sign_valid, note_stores(), note_uses(), optimize_bb_for_speed_p(), optimize_this_for_speed_p, prev_nonnote_insn(), purge_all_dead_edges(), record_dead_and_set_regs(), record_truncated_values(), reg_mentioned_p(), reg_stat, rtl_profile_for_bb(), SET, set_nonzero_bits_and_sign_copies(), sets_cc0_p(), setup_incoming_promotions(), single_pred(), single_pred_p(), subst_insn, subst_low_luid, this_basic_block, total_attempts, total_extras, total_merges, total_successes, try_combine(), uid_insn_cost, uid_log_links, and unmentioned_reg_p().
Referenced by rest_of_handle_combine().
|
static |
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 nonzero if we are inside a SET_DEST. IN_COND is nonzero if we are at the top level of a condition.
References apply_distributive_law(), const_true_rtx, copy_rtx(), distribute_and_simplify_rtx(), exact_log2(), expand_compound_operation(), false_rtx, force_to_mode(), gen_int_mode(), gen_lowpart_common(), general_operand(), get_last_value(), HOST_WIDE_INT, undo::i, if_then_else_cond(), make_compound_operation(), mode_dependent_address_p(), nonzero_bits(), num_sign_bit_copies(), pc_rtx, plus_constant(), 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, 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(), subreg_lowpart_offset(), subst(), swap_commutative_operands_p(), true_rtx, and val_signbit_p().
Referenced by subst().
|
static |
Try to split PATTERN found in INSN. This returns NULL_RTX if PATTERN can not 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_rtx_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, insn_rtx_cost(), new_cost(), optimize_this_for_speed_p, and undobuf::other_insn.
Referenced by try_combine().
|
static |
Referenced by contains_muldiv(), and try_combine().
|
static |
Return 1 if X is an arithmetic expression that contains a multiplication and division. We don't count multiplications by powers of two here.
References contains_muldiv(), and exact_log2().
|
static |
Utility function for record_value_for_reg. Count number of rtxs in X.
References RTX_BIN_ARITH, and RTX_COMM_ARITH.
Referenced by record_value_for_reg().
|
static |
Fill in log links field for all insns.
References alloc_insn_link(), asm_noperands(), DF_REF_CALL_STACK_USAGE, DF_REF_PRE_POST_MODIFY, free(), insn_link::insn, max_reg_num(), and reload_completed.
Referenced by combine_instructions().
|
static |
Delete any insns that copy a register to itself.
References delete_insn_and_edges(), dump_file, insn_link::insn, insn_link::next, and noop_move_p().
Referenced by combine_instructions().
Referenced by combine_simplify_rtx(), and simplify_logical().
|
static |
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(), optimize_this_for_speed_p, set_src_cost(), and simplify_gen_binary().
|
static |
Referenced by adjust_for_new_dest(), distribute_notes(), and try_combine().
|
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, find_reg_fusage(), insn_link::insn, insn_link::next, basic_block_def::next_bb, reg_overlap_mentioned_p(), reg_referenced_p(), reg_set_p(), and this_basic_block.
|
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 add_reg_note(), alloc_reg_note(), function::can_throw_non_call_exceptions, cc0_rtx, cfun, dead_or_set_p(), dead_or_set_regno_p(), distribute_links(), find_reg_fusage(), find_reg_note(), find_regno_fusage(), find_regno_note(), fixup_args_size_notes(), global_regs, i2, i2mod, i2mod_new_rhs, i2mod_old_rhs, reg_stat_struct::last_death, may_trap_p(), next_nonnote_nondebug_insn(), noop_move_p(), pc_rtx, prev_cc0_setter(), refers_to_regno_p(), reg_bitfield_target_p(), reg_mentioned_p(), reg_overlap_mentioned_p(), reg_referenced_p(), reg_set_p(), reg_stat, regno_reg_rtx, rtx_equal_p(), sets_cc0_p(), side_effects_p(), and this_basic_block.
Referenced by try_combine().
|
static |
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 undobuf::frees, undo::kind, undo::next, undo::old_contents, undo::r, trunc_int_for_mode(), UNDO_RTX, undobuf::undos, and undo::where.
|
static |
|
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.
|
static |
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.
|
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, undo::kind, undo::m, undo::next, undo::old_contents, undo::r, UNDO_MODE, undobuf::undos, and undo::where.
DEBUG_FUNCTION void dump_combine_stats | ( | ) |
References combine_attempts, combine_extras, combine_merges, and combine_successes.
void dump_combine_total_stats | ( | ) |
References total_attempts, total_extras, total_merges, and total_successes.
Referenced by print_combine_total_stats().
|
static |
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 expand_compound_operation(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, len, nonzero_bits(), optimize_this_for_speed_p, set_src_cost(), simplify_and_const_int(), simplify_shift_const(), and subreg_lowpart_p().
Referenced by can_combine_p(), and set_nonzero_bits_and_sign_copies().
|
static |
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 copy_rtx(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, len, mode_for_size(), nonzero_sign_valid, simplify_gen_binary(), simplify_gen_unary(), subreg_lowpart_p(), and subreg_lsb().
unsigned int extended_count | ( | ) |
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(), nonzero_bits(), nonzero_sign_valid, and num_sign_bit_copies().
Referenced by extract_left_shift(), and make_compound_operation().
|
static |
See if X 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 extract_left_shift(), HOST_WIDE_INT, simplify_gen_binary(), simplify_gen_unary(), and simplify_shift_const().
|
static |
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. If DEST is cc0_rtx, we look only at the next insn. In that case, we don't care about REG_DEAD notes or LOG_LINKS. 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 cc0_rtx, dead_or_set_p(), find_single_use_1(), insn_link::insn, and insn_link::next.
Referenced by find_split_point(), simplify_set(), and try_combine().
|
static |
This is used by find_single_use to locate an rtx in LOC that contains exactly one use of DEST, which is typically either a REG or CC0. 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 SET.
Referenced by find_single_use().
Referenced by find_split_point(), and try_combine().
|
static |
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 cc0_rtx, combine_split_insns(), exact_log2(), find_single_use(), find_split_point(), gen_int_mode(), get_address_mode(), HOST_WIDE_INT, len, make_extraction(), memory_address_addr_space_p(), nonzero_bits(), reg_mentioned_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, side_effects_p(), simplify_gen_binary(), subst_insn, and trunc_int_for_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 nonzero, 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 exact_log2(), expand_compound_operation(), floor_log2(), gen_int_mode(), gen_lowpart_common(), gen_lowpart_or_truncate(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, nonzero_bits(), num_sign_bit_copies(), optimize_this_for_speed_p, plus_constant(), set_src_cost(), side_effects_p(), simplify_and_const_int(), simplify_binary_operation(), simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), subreg_lowpart_p(), and val_signbit_p().
Referenced by combine_simplify_rtx(), make_compound_operation(), make_extraction(), make_field_assignment(), simplify_and_const_int_1(), simplify_comparison(), and simplify_set().
|
static |
|
static |
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 gen_lowpart_common(), gen_rtx_SUBREG(), int_mode_for_mode(), mode_dependent_address_p(), offset, simplify_gen_subreg(), and subreg_lowpart_offset().
Referenced by force_to_mode(), and simplify_shift_const_1().
|
static |
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 int_mode_for_mode(), reg_truncated_to_mode(), and simplify_gen_unary().
|
static |
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 copy_rtx(), get_last_value(), get_last_value_validate(), label_tick, label_tick_ebb_start, reg_stat_struct::last_set, reg_stat_struct::last_set_label, reg_stat_struct::last_set_value, paradoxical_subreg_p(), REG_N_SETS(), reg_stat, subreg_lowpart_p(), and subst_low_luid.
Referenced by get_last_value(), get_last_value_validate(), and record_value_for_reg().
|
static |
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 0 if some are not. If REPLACE is nonzero, replace the invalid references with (clobber (const_int 0)) and return 1. 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 get_last_value_validate(), label_tick, reg_stat_struct::last_set_label, len, mem_last_set, REG_N_SETS(), and reg_stat.
|
static |
Referenced by make_field_assignment().
|
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(), exact_log2(), and len.
Referenced by combine_simplify_rtx(), and if_then_else_cond().
|
static |
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 const_true_rtx, copy_rtx(), exact_log2(), gen_int_mode(), get_last_value(), HOST_WIDE_INT, if_then_else_cond(), nonzero_bits(), num_sign_bit_copies(), reversed_comparison_code(), rtx_equal_p(), side_effects_p(), simplify_gen_binary(), simplify_gen_relational(), simplify_gen_subreg(), simplify_gen_unary(), and swap_condition().
|
static |
Wipe the last_xxx fields of reg_stat in preparation for another pass.
References undo::i, memset(), and reg_stat.
Referenced by combine_instructions().
|
static |
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. We also check the implicit dependency created by a cc0 setter/user pair.
References insn_link::insn, and sets_cc0_p().
Referenced by try_combine().
Referenced by known_cond(), and simplify_if_then_else().
|
static |
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 comparison_dominates_p(), const_true_rtx, known_cond(), reverse_condition(), reversed_comparison_code(), rtx_equal_p(), side_effects_p(), simplify_gen_unary(), simplify_subreg(), simplify_unary_operation(), and swap_condition().
|
static |
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, and likely_spilled_retval_info::regno.
Referenced by likely_spilled_retval_p().
|
static |
Return nonzero 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 likely_spilled_retval_1(), likely_spilled_retval_info::mask, note_stores(), likely_spilled_retval_info::nregs, likely_spilled_retval_info::regno, targetm, and this_basic_block.
Referenced by try_combine().
rtx make_compound_operation | ( | ) |
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 (inside a MEM, PLUS or minus, the latter two being kludges), it is MEM. When processing the arguments of a comparison or a COMPARE against zero, it is COMPARE.
References count, exact_log2(), extract_left_shift(), force_to_mode(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, make_extraction(), nonzero_bits(), rtx_equal_p(), SET, simplify_const_unary_operation(), simplify_gen_binary(), simplify_gen_unary(), simplify_subreg(), subreg_lowpart_p(), swap_commutative_operands_p(), and trunc_int_for_mode().
Referenced by combine_simplify_rtx(), propagate_for_debug_subst(), simplify_comparison(), simplify_if_then_else(), and simplify_set().
|
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 nonzero for an unsigned reference and zero for a signed one. IN_DEST is nonzero 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 nonzero 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 EP_extv, EP_extzv, EP_insv, extraction_insn::field_mode, force_to_mode(), gen_rtx_SUBREG(), get_best_reg_extraction_insn(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, mode_dependent_address_p(), mode_for_size(), nonzero_bits(), offset, optimize_this_for_speed_p, extraction_insn::pos_mode, reg_truncated_to_mode(), set_src_cost(), simplify_gen_unary(), simplify_unary_operation(), smallest_mode_for_size(), extraction_insn::struct_mode, subreg_lowpart_p(), validate_subreg(), and word_mode.
Referenced by find_split_point(), make_compound_operation(), and make_field_assignment().
Referenced by simplify_set().
|
static |
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(), expand_compound_operation(), force_to_mode(), gen_int_mode(), get_pos_from_mask(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, len, make_extraction(), nonzero_bits(), rtx_equal_for_field_assignment_p(), simplify_shift_const(), and subreg_lowpart_p().
rtl_opt_pass* make_pass_combine | ( | ) |
|
static |
Referenced by mark_used_regs_combine(), and try_combine().
|
static |
Note hard registers in X that are used.
References add_to_hard_reg_set(), mark_used_regs_combine(), newpat_used_regs, and SET.
|
static |
Referenced by simplify_shift_const_1().
|
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 1 if we can do the operation and update *POP0 and *PCONST0 with the resulting operation. *PCOMP_P is set to 1 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 0 and do not change *POP0, *PCONST0, and *PCOMP_P.
References HOST_WIDE_INT, SET, and trunc_int_for_mode().
|
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(), len, offset, reg_referenced_p(), reg_set_p(), reg_stat, regno_reg_rtx, remove_death(), and SET.
Referenced by try_combine().
Referenced by simplify_set(), and try_combine().
|
static |
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. 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 add_clobbers(), alloc_reg_note(), check_asm_operands(), dump_file, dump_flags, insn_code_number, print_rtl_single(), recog(), reg_dead_at_p(), rtvec_alloc(), SET, set_noop_p(), and targetm.
|
static |
Referenced by combine_instructions().
|
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 last_call_luid, reg_stat_struct::last_death, reg_stat_struct::last_set, reg_stat_struct::last_set_nonzero_bits, reg_stat_struct::last_set_sign_bit_copies, reg_stat_struct::last_set_value, mem_last_set, note_stores(), record_dead_and_set_regs_1(), record_value_for_reg(), and reg_stat.
Referenced by record_dead_and_set_regs().
|
static |
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 mem_last_set, push_operand(), record_value_for_reg(), SET, and subreg_lowpart_p().
Referenced by check_promoted_subreg().
|
static |
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 HOST_BITS_PER_WIDE_INT, insn_link::insn, reg_stat_struct::last_set, reg_stat_struct::last_set_nonzero_bits, insn_link::next, and reg_stat.
|
static |
Referenced by record_truncated_values().
|
static |
Callback for for_each_rtx. If *P is a hard reg or a subreg record the mode that the register is accessed in. For non-TRULY_NOOP_TRUNCATION targets we might be able to turn a truncate into a subreg using this information. Return -1 if traversing *P is complete or 0 otherwise.
References label_tick, label_tick_ebb_start, and reg_stat.
|
static |
Referenced by combine_instructions().
|
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_rtx(), and record_truncated_value().
Referenced by record_dead_and_set_regs(), record_dead_and_set_regs_1(), setup_incoming_promotions(), and try_combine().
|
static |
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 copy_rtx(), count_occurrences(), count_rtxs(), get_last_value(), get_last_value_validate(), label_tick, label_tick_ebb_start, reg_stat_struct::last_death, reg_stat_struct::last_set, reg_stat_struct::last_set_label, reg_stat_struct::last_set_nonzero_bits, reg_stat_struct::last_set_sign_bit_copies, reg_stat_struct::last_set_table_tick, reg_stat_struct::last_set_value, nonzero_bits(), nonzero_bits_mode, num_sign_bit_copies(), reg_overlap_mentioned_p(), reg_stat, replace_rtx(), subst_low_luid, and update_table_tick().
Referenced by distribute_notes(), and reg_bitfield_target_p().
|
static |
Return 1 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(), reg_bitfield_target_p(), and SET.
Referenced by recog_for_combine().
|
static |
Return nonzero 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 df_get_live_in(), find_regno_note(), newpat_used_regs, note_stores(), reg_dead_at_p_1(), reg_dead_endregno, reg_dead_flag, and reg_dead_regno.
Referenced by reg_dead_at_p().
|
static |
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 reg_dead_endregno, reg_dead_flag, and reg_dead_regno.
|
static |
Given a REG, X, compute which bits in X can be nonzero. We don't care about bits outside of those defined in 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 get_last_value(), HOST_WIDE_INT, label_tick, label_tick_ebb_start, reg_stat_struct::last_set, reg_stat_struct::last_set_label, reg_stat_struct::last_set_nonzero_bits, reg_stat_struct::last_set_value, nonzero_sign_valid, REG_N_SETS(), reg_stat, subst_low_luid, and val_signbit_known_set_p().
|
static |
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; if MODE is VOIDmode, X will be used in its own mode. The returned value will always be between 1 and the number of bits in MODE.
References get_last_value(), label_tick, label_tick_ebb_start, reg_stat_struct::last_set, reg_stat_struct::last_set_label, reg_stat_struct::last_set_sign_bit_copies, reg_stat_struct::last_set_value, nonzero_sign_valid, REG_N_SETS(), reg_stat, and subst_low_luid.
|
static |
Check whether X, the destination of a set, refers to part of the register specified by REG.
Referenced by try_combine().
|
static |
Referenced by gen_lowpart_or_truncate(), make_extraction(), and simplify_comparison().
|
static |
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, and reg_stat.
rtx remove_death | ( | ) |
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(), and remove_note().
Referenced by fixup_match_2(), move_deaths(), and update_equiv_regs().
|
static |
Try combining insns through substitution.
References cleanup_cfg(), combine_instructions(), df_analyze(), DF_DEFER_INSN_RESCAN, DF_LR_RUN_DCE, df_note_add_problem(), df_set_flags(), get_insns(), max_reg_num(), rebuild_jump_labels(), regstat_free_n_sets_and_refs(), regstat_init_n_sets_and_refs(), timevar_pop(), and timevar_push().
Referenced by make_field_assignment().
|
static |
See if X and Y are equal for the purposes of seeing if we can rewrite an assignment as a field assignment.
References rtx_equal_p().
Referenced by combine_instructions(), and try_combine().
|
static |
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 dead_or_set_p(), expand_field_assignment(), HOST_WIDE_INT, insn_link::insn, nonzero_bits(), nonzero_bits_mode, num_sign_bit_copies(), paradoxical_subreg_p(), reg_referenced_p(), reg_stat, and val_signbit_known_set_p().
|
static |
Referenced by combine_instructions().
|
static |
Set up any promoted values for incoming argument registers.
References cfun, cgraph_local_info(), current_function_decl, function::decl, cgraph_local_info::local, promote_function_mode(), and record_value_for_reg().
|
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(), simplify_and_const_int_1(), and simplify_gen_binary().
Referenced by combine_simplify_rtx(), expand_compound_operation(), force_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(), exact_log2(), force_to_mode(), gen_int_mode(), HOST_WIDE_INT, nonzero_bits(), simplify_and_const_int(), simplify_gen_binary(), and simplify_shift_const().
Referenced by simplify_and_const_int().
Referenced by simplify_comparison(), and try_combine().
|
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. *POP1 may be updated.
References exact_log2(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, nonzero_bits(), num_sign_bit_copies(), and trunc_int_for_mode().
Referenced by combine_simplify_rtx(), and simplify_set().
|
static |
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 changed, exact_log2(), expand_compound_operation(), force_to_mode(), gen_int_mode(), get_last_value(), have_insn_for(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, make_compound_operation(), mode_for_size(), nonzero_bits(), num_sign_bit_copies(), paradoxical_subreg_p(), reg_truncated_to_mode(), reverse_condition(), reversed_comparison_code(), rtx_equal_p(), SET, simplify_and_const_int(), simplify_binary_operation(), simplify_compare_const(), simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), simplify_unary_operation(), subreg_lowpart_p(), swap_commutative_operands_p(), swap_condition(), target_canonicalize_comparison(), trunc_int_for_mode(), unsigned_condition(), and val_signbit_known_set_p().
Referenced by combine_simplify_rtx().
|
static |
Simplify X, an IF_THEN_ELSE expression. Return the new expression.
References const_true_rtx, copy_rtx(), exact_log2(), false_rtx, gen_int_mode(), HOST_WIDE_INT, undo::i, known_cond(), undo::m, make_compound_operation(), nonzero_bits(), num_sign_bit_copies(), pc_rtx, reg_mentioned_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(), subreg_lowpart_p(), subst(), and true_rtx.
Referenced by combine_simplify_rtx().
|
static |
Simplify, X, and AND, IOR, or XOR operation, and return the simplified result.
References distribute_and_simplify_rtx(), and simplify_and_const_int().
Referenced by combine_simplify_rtx().
|
static |
Simplify X, a SET expression. Return the new expression.
References can_change_dest_mode(), can_conditionally_move_p(), cc0_rtx, check_asm_operands(), exact_log2(), false_rtx, find_single_use(), force_to_mode(), gen_rtx_REG(), HOST_WIDE_INT, make_compound_operation(), make_field_assignment(), nonzero_bits(), num_sign_bit_copies(), undobuf::other_insn, paradoxical_subreg_p(), pc_rtx, recog_for_combine(), regno_reg_rtx, rtx_equal_p(), SET, side_effects_p(), simplify_comparison(), simplify_gen_binary(), simplify_gen_unary(), simplify_relational_operation(), simplify_rtx(), subreg_lowpart_p(), subst_insn, true_rtx, and val_signbit_known_clear_p().
|
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 simplify_gen_binary(), and simplify_shift_const_1().
Referenced by combine_simplify_rtx(), expand_compound_operation(), extract_left_shift(), force_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 apply_distributive_law(), count, exact_log2(), expand_compound_operation(), gen_lowpart_or_truncate(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, mask_rtx(), merge_outer_ops(), mode_dependent_address_p(), mode_for_size(), mode_signbit_p(), nonzero_bits(), num_sign_bit_copies(), rtx_equal_p(), RTX_UNARY, SET, side_effects_p(), simplify_and_const_int(), simplify_const_binary_operation(), simplify_gen_binary(), simplify_gen_unary(), simplify_shift_const(), subreg_lowpart_p(), trunc_int_for_mode(), try_widen_shift_mode(), and val_signbit_known_clear_p().
Referenced by simplify_shift_const().
|
static |
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 nonzero if we are processing the SET_DEST of a SET. IN_COND is nonzero if we are at the top level of a condition. UNIQUE_COPY is nonzero 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(), cc0_rtx, combine_simplify_rtx(), copy_rtx(), undo::i, len, n_occurrences, reg_overlap_mentioned_p(), SET, simplify_subreg(), simplify_unary_operation(), and subst().
|
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 a nonzero value 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, adjust_for_new_dest(), adjust_reg_mode(), alloc_insn_link(), alloc_reg_note(), double_int::and_not(), any_uncondjump_p(), asm_noperands(), can_change_dest_mode(), can_combine_p(), cant_combine_insn_p(), cc0_rtx, check_asm_operands(), combinable_i3pat(), combine_attempts, combine_extras, combine_merges, combine_split_insns(), combine_successes, combine_validate_cost(), contains_muldiv(), copy_rtx(), copy_rtx_if_shared(), dead_or_set_p(), df_insn_rescan(), distribute_links(), distribute_notes(), dump_file, dump_flags, dump_insn_slim(), rtvec_def::elem, exact_log2(), find_reg_note(), find_single_use(), find_split_point(), first, undobuf::frees, gen_raw_REG(), gen_rtvec(), gen_rtx_REG(), HOST_BITS_PER_INT, i1, i2, immed_double_int_const(), insn_link::insn, insn_a_feeds_b(), insn_code_number, insn_nothrow_p(), undo::kind, last, len, likely_spilled_retval_p(), double_int::llshift(), lowpart_subreg(), undo::m, mark_jump_label(), mark_used_regs_combine(), double_int::mask(), max_reg_num(), memcpy(), move_deaths(), n_occurrences, new_mode(), newpat_used_regs, undo::next, next_active_insn(), basic_block_def::next_bb, next_nonnote_nondebug_insn(), nonzero_bits(), note_stores(), rtvec_def::num_elem, offset, undo::old_contents, undobuf::other_insn, pc_rtx, prev_nonnote_insn(), propagate_for_debug(), undo::r, recog_for_combine(), record_value_for_reg(), reg_mentioned_p(), reg_overlap_mentioned_p(), reg_referenced_p(), reg_set_p(), reg_stat, reg_subword_p(), reg_used_between_p(), regno_reg_rtx, remove_note(), replace_rtx(), reset_used_flags(), returnjump_p(), rtvec_alloc(), rtx_equal_p(), rtx_to_double_int(), SET, set_nonzero_bits_and_sign_copies(), sets_cc0_p(), side_effects_p(), simplify_compare_const(), simplify_gen_binary(), subreg_lowpart_p(), subst(), subst_insn, subst_low_luid, target_canonicalize_comparison(), targetm, this_basic_block, undo_all(), undo_commit(), UNDO_MODE, undobuf::undos, update_cfg_for_uncondjump(), use_crosses_set_p(), undo::where, and word_mode.
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 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 adjust_reg_mode(), undobuf::frees, undo::i, undo::kind, undo::l, undo::m, undo::next, undo::old_contents, undo::r, UNDO_INT, UNDO_LINKS, UNDO_MODE, UNDO_RTX, undobuf::undos, and undo::where.
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().
Referenced by combine_instructions().
|
static |
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_rtx(), and unmentioned_reg_p_1().
|
static |
Referenced by unmentioned_reg_p().
|
static |
Subroutine of unmentioned_reg_p and callback from for_each_rtx. Check whether the expression pointer to by LOC is a register or memory, and if so return 1 if it isn't mentioned in the rtx EXPR. Otherwise return zero.
References reg_mentioned_p().
|
static |
Delete the unconditional jump INSN and adjust the CFG correspondingly. Note that the INSN should be deleted *after* removing dead edges, so that the kept edge is the fallthrough edge for a (set (pc) (pc)) but not for a (set (pc) (label_ref FOO)).
References delete_insn(), edge_def::flags, purge_dead_edges(), single_succ_edge(), and basic_block_def::succs.
Referenced by try_combine().
|
static |
Referenced by record_value_for_reg(), and update_table_tick().
|
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.c
References label_tick, reg_stat_struct::last_set_table_tick, reg_stat, and update_table_tick().
|
static |
Referenced by can_combine_p(), try_combine(), and use_crosses_set_p().
|
static |
Return nonzero if expression X refers to a REG or to memory that is set in an instruction more recent than FROM_LUID.
References label_tick, reg_stat_struct::last_set, reg_stat_struct::last_set_label, mem_last_set, reg_stat, and use_crosses_set_p().
|
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 |
@verbatim Optimize by combining instructions for GNU compiler.
Copyright (C) 1987-2013 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 of success. LOG_LINKS does not have links for use of the CC0. They don't need to, because the insn that sets the CC0 is always immediately before the insn that tests it. So we always regard a branch insn as having a logical link to the preceding insn. The same is true for an insn explicitly using CC0. We check (with use_crosses_set_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. Since we do not represent assignments to CC0 explicitly except when that is all an insn does, there is no LOG_LINKS entry in an insn that uses the condition code for the insn that set the condition code. Fortunately, these two insns must be consecutive. Therefore, every JUMP_INSN is taken to have an implicit logical link to the preceding insn. This is not quite right, since non-jumps can also use the condition code; but in practice such insns would not combine anyway.
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(), dump_combine_stats(), and try_combine().
|
static |
Number of instructions combined with added SETs in this function.
Referenced by combine_instructions(), dump_combine_stats(), and try_combine().
|
static |
Number of attempts that got as far as substitution in this function.
Referenced by combine_instructions(), dump_combine_stats(), and try_combine().
|
static |
Referenced by combine_instructions().
|
static |
Number of instructions combined in this function.
Referenced by combine_instructions(), dump_combine_stats(), 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(), update_table_tick(), and use_crosses_set_p().
|
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().
|
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(), record_dead_and_set_regs_1(), and use_crosses_set_p().
|
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 set_nonzero_bits_and_sign_copies().
|
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().
|
static |
Define three variables used for communication between the following routines.
Referenced by reg_dead_at_p(), and reg_dead_at_p_1().
|
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_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(), update_table_tick(), and use_crosses_set_p().
|
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(), and try_combine().
|
static |
Totals over entire compilation.
Referenced by combine_instructions(), and dump_combine_total_stats().
|
static |
Referenced by combine_instructions(), and dump_combine_total_stats().
|
static |
Referenced by combine_instructions(), and dump_combine_total_stats().
|
static |
Referenced by combine_instructions(), and dump_combine_total_stats().
|
static |
The following array records the insn_rtx_cost for every insn in the instruction stream.
Referenced by combine_instructions().
|
static |
Referenced by combine_instructions().