#include "insn-attr.h"
#include "rtlhooks-def.h"
#include "expr.h"
-#include "params.h"
#include "tree-pass.h"
#include "valtrack.h"
#include "rtl-iter.h"
#include "print-rtl.h"
+#include "function-abi.h"
/* Number of attempts to combine instructions in this function. */
case SYMBOL_REF:
CASE_CONST_ANY:
case CLOBBER:
- case CLOBBER_HIGH:
return 0;
case SET:
subst_low_luid = DF_INSN_LUID (insn);
subst_insn = insn;
- note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies,
- insn);
+ note_stores (insn, set_nonzero_bits_and_sign_copies, insn);
record_dead_and_set_regs (insn);
if (AUTO_INC_DEC)
insn);
/* Record the current insn_cost of this instruction. */
- if (NONJUMP_INSN_P (insn))
- INSN_COST (insn) = insn_cost (insn, optimize_this_for_speed_p);
+ INSN_COST (insn) = insn_cost (insn, optimize_this_for_speed_p);
if (dump_file)
{
fprintf (dump_file, "insn_cost %d for ", INSN_COST (insn));
init_reg_last ();
setup_incoming_promotions (first);
last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
- int max_combine = PARAM_VALUE (PARAM_MAX_COMBINE_INSNS);
+ int max_combine = param_max_combine_insns;
FOR_EACH_BB_FN (this_basic_block, cfun)
{
function lie within the current compilation unit. (This does
take into account the exporting of a function via taking its
address, and so forth.) */
- strictly_local = cgraph_node::local_info (current_function_decl)->local;
+ strictly_local
+ = cgraph_node::local_info_node (current_function_decl)->local;
/* The mode and signedness of the argument before any promotions happen
(equal to the mode of the pseudo holding it at that stage). */
return;
}
- /* Should not happen as we only using pseduo registers. */
- gcc_assert (GET_CODE (set) != CLOBBER_HIGH);
-
/* If this register is being initialized using itself, and the
register is uninitialized in this basic block, and there are
no LOG_LINKS which set the register, then part of the
/* We can ignore CLOBBERs. */
case CLOBBER:
- case CLOBBER_HIGH:
break;
case SET:
is_volatile_p = volatile_refs_p (PATTERN (insn))
? volatile_refs_p
: volatile_insn_p;
-
+
for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
if (INSN_P (p) && p != succ && p != succ2 && is_volatile_p (PATTERN (p)))
return 0;
/* If INSN contains an autoincrement or autodecrement, make sure that
register is not used between there and I3, and not already used in
I3 either. Neither must it be used in PRED or SUCC, if they exist.
- Also insist that I3 not be a jump; if it were one
- and the incremented register were spilled, we would lose. */
+ Also insist that I3 not be a jump if using LRA; if it were one
+ and the incremented register were spilled, we would lose.
+ Reload handles this correctly. */
if (AUTO_INC_DEC)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC
- && (JUMP_P (i3)
+ && ((JUMP_P (i3) && targetm.lra_p ())
|| reg_used_between_p (XEXP (link, 0), insn, i3)
|| (pred != NULL_RTX
&& reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (pred)))
info.mask = mask;
for (p = PREV_INSN (use); info.mask && p != insn; p = PREV_INSN (p))
if (INSN_P (p))
- note_stores (PATTERN (p), likely_spilled_retval_1, &info);
+ note_stores (p, likely_spilled_retval_1, &info);
mask = info.mask;
/* Check if any of the (probably) live return value registers is
if (XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
return false;
break;
- case CLOBBER_HIGH:
- break;
default:
return false;
}
for (i = 0; ok && i < XVECLEN (p2, 0); i++)
{
if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
- || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER
- || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER_HIGH)
+ || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
&& reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
SET_DEST (XVECEXP (p2, 0, i))))
ok = false;
been made to this insn. The order is important, because newi2pat
can affect nonzero_bits of newpat. */
if (newi2pat)
- note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
- note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
+ note_pattern_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
+ note_pattern_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
}
if (undobuf.other_insn != NULL_RTX)
}
else if (CONST_SCALAR_INT_P (new_rtx)
&& (GET_CODE (x) == ZERO_EXTEND
+ || GET_CODE (x) == SIGN_EXTEND
|| GET_CODE (x) == FLOAT
|| GET_CODE (x) == UNSIGNED_FLOAT))
{
mode, VOIDmode,
cond, cop1),
mode);
- else
- return gen_rtx_IF_THEN_ELSE (mode,
- simplify_gen_relational (cond_code,
- mode,
- VOIDmode,
- cond,
- cop1),
- true_rtx, false_rtx);
code = GET_CODE (x);
op0_mode = VOIDmode;
|| reg_mentioned_p (true_rtx, false_rtx)
|| rtx_equal_p (false_rtx, XEXP (cond, 0))))
{
- true_code = reversed_comparison_code (cond, NULL);
SUBST (XEXP (x, 0), reversed_comparison (cond, GET_MODE (cond)));
SUBST (XEXP (x, 1), false_rtx);
SUBST (XEXP (x, 2), true_rtx);
For memory, assume that the desired extraction_mode and pos_mode
are the same as for a register operation, since at present we don't
have named patterns for aligned memory structures. */
- struct extraction_insn insn;
+ class extraction_insn insn;
unsigned int inner_size;
if (GET_MODE_BITSIZE (inner_mode).is_constant (&inner_size)
&& get_best_reg_extraction_insn (&insn, pattern, inner_size, mode))
/* If X is (minus C Y) where C's least set bit is larger than any bit
in the mask, then we may replace with (neg Y). */
if (poly_int_rtx_p (XEXP (x, 0), &const_op0)
- && (unsigned HOST_WIDE_INT) known_alignment (const_op0) > mask)
+ && known_alignment (poly_uint64 (const_op0)) > mask)
{
x = simplify_gen_unary (NEG, xmode, XEXP (x, 1), xmode);
return force_to_mode (x, mode, mask, next_select);
/* If X is a comparison operator, rewrite it in a new mode. This
probably won't match, but may allow further simplifications. */
- else if (COMPARISON_P (x))
+ else if (COMPARISON_P (x)
+ && SCALAR_INT_MODE_P (imode)
+ && SCALAR_INT_MODE_P (omode))
return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1));
/* If we couldn't simplify X any other way, just enclose it in a
{
/* If there are two or more occurrences of REG in VALUE,
prevent the value from growing too much. */
- if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
+ if (count_rtxs (tem) > param_max_last_value_rtl)
tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
}
? SET_SRC (setter)
: gen_lowpart (GET_MODE (dest),
SET_SRC (setter)));
- else if (GET_CODE (setter) == CLOBBER_HIGH)
- {
- reg_stat_type *rsp = ®_stat[REGNO (dest)];
- if (rsp->last_set_value
- && reg_is_clobbered_by_clobber_high
- (REGNO (dest), GET_MODE (rsp->last_set_value),
- XEXP (setter, 0)))
- record_value_for_reg (dest, NULL, NULL_RTX);
- }
else
record_value_for_reg (dest, record_dead_insn, NULL_RTX);
}
if (CALL_P (insn))
{
+ HARD_REG_SET callee_clobbers
+ = insn_callee_abi (insn).full_and_partial_reg_clobbers ();
hard_reg_set_iterator hrsi;
- EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, i, hrsi)
+ EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, i, hrsi)
{
reg_stat_type *rsp;
+ /* ??? We could try to preserve some information from the last
+ set of register I if the call doesn't actually clobber
+ (reg:last_set_mode I), which might be true for ABIs with
+ partial clobbers. However, it would be difficult to
+ update last_set_nonzero_bits and last_sign_bit_copies
+ to account for the part of I that actually was clobbered.
+ It wouldn't help much anyway, since we rarely see this
+ situation before RA. */
rsp = ®_stat[i];
rsp->last_set_invalid = 1;
rsp->last_set = insn;
the return value register is set at this LUID. We could
still replace a register with the return value from the
wrong subroutine call! */
- note_stores (PATTERN (insn), record_dead_and_set_regs_1, NULL_RTX);
+ note_stores (insn, record_dead_and_set_regs_1, NULL_RTX);
}
else
- note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
+ note_stores (insn, record_dead_and_set_regs_1, insn);
}
/* If a SUBREG has the promoted bit set, it is in fact a property of the
if (!REG_P (dest))
return;
- if (GET_CODE (x) == CLOBBER_HIGH
- && !reg_is_clobbered_by_clobber_high (reg_dead_reg, XEXP (x, 0)))
- return;
-
regno = REGNO (dest);
endregno = END_REGNO (dest);
if (reg_dead_endregno > regno && reg_dead_regno < endregno)
if (find_regno_note (insn, REG_UNUSED, reg_dead_regno))
return 1;
- note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
+ note_stores (insn, reg_dead_at_p_1, NULL);
if (reg_dead_flag)
return reg_dead_flag == 1 ? 1 : 0;