#endif
static rtx skip_consec_insns (rtx, int);
static int libcall_benefit (rtx);
+static rtx libcall_other_reg (rtx, rtx);
+static void record_excess_regs (rtx, rtx, rtx *);
static void ignore_some_movables (struct loop_movables *);
static void force_movables (struct loop_movables *);
static void combine_movables (struct loop_movables *, struct loop_regs *);
/* Add elements to *OUTPUT to record all the pseudo-regs
mentioned in IN_THIS but not mentioned in NOT_IN_THIS. */
-void
+static void
record_excess_regs (rtx in_this, rtx not_in_this, rtx *output)
{
enum rtx_code code;
If there are none, return 0.
If there are one or more, return an EXPR_LIST containing all of them. */
-rtx
+static rtx
libcall_other_reg (rtx insn, rtx equiv)
{
rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
/* If loop_invariant_p ever returned 2, we return 2. */
return 1 + (value & 2);
}
-
-#if 0
-/* I don't think this condition is sufficient to allow INSN
- to be moved, so we no longer test it. */
-
-/* Return 1 if all insns in the basic block of INSN and following INSN
- that set REG are invariant according to TABLE. */
-
-static int
-all_sets_invariant_p (rtx reg, rtx insn, short *table)
-{
- rtx p = insn;
- int regno = REGNO (reg);
-
- while (1)
- {
- enum rtx_code code;
- p = NEXT_INSN (p);
- code = GET_CODE (p);
- if (code == CODE_LABEL || code == JUMP_INSN)
- return 1;
- if (code == INSN && GET_CODE (PATTERN (p)) == SET
- && GET_CODE (SET_DEST (PATTERN (p))) == REG
- && REGNO (SET_DEST (PATTERN (p))) == regno)
- {
- if (! loop_invariant_p (loop, SET_SRC (PATTERN (p)), table))
- return 0;
- }
- }
-}
-#endif /* 0 */
\f
/* Look at all uses (not sets) of registers in X. For each, if it is
the single use, set USAGE[REGNO] to INSN; if there was a previous use in
if (code != GET_CODE (y))
return 0;
- code = GET_CODE (x);
-
- if (GET_RTX_CLASS (code) == 'c')
+ if (COMMUTATIVE_ARITH_P (x))
{
return ((rtx_equal_for_prefetch_p (XEXP (x, 0), XEXP (y, 0))
&& rtx_equal_for_prefetch_p (XEXP (x, 1), XEXP (y, 1)))
|| (rtx_equal_for_prefetch_p (XEXP (x, 0), XEXP (y, 1))
&& rtx_equal_for_prefetch_p (XEXP (x, 1), XEXP (y, 0))));
}
+
/* Compare the elements. If any pair of corresponding elements fails to
match, return 0 for the whole thing. */
&& unrolled_insn_copies <= insn_count))
unroll_loop (loop, insn_count, 1);
-#ifdef HAVE_doloop_end
- if (HAVE_doloop_end && (flags & LOOP_BCT) && flag_branch_on_count_reg)
- doloop_optimize (loop);
-#endif /* HAVE_doloop_end */
-
- /* In case number of iterations is known, drop branch prediction note
- in the branch. Do that only in second loop pass, as loop unrolling
- may change the number of iterations performed. */
- if (flags & LOOP_BCT)
- {
- unsigned HOST_WIDE_INT n
- = loop_info->n_iterations / loop_info->unroll_number;
- if (n > 1)
- predict_insn (prev_nonnote_insn (loop->end), PRED_LOOP_ITERATIONS,
- REG_BR_PROB_BASE - REG_BR_PROB_BASE / n);
- }
-
if (loop_dump_stream)
fprintf (loop_dump_stream, "\n");
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
rtx reg;
+ enum machine_mode mode;
rtx jump_label;
rtx final_value;
rtx start_value;
/* Save some info needed to produce the new insns. */
reg = bl->biv->dest_reg;
+ mode = GET_MODE (reg);
jump_label = condjump_label (PREV_INSN (loop_end));
new_add_val = GEN_INT (-INTVAL (bl->biv->add_val));
if (initial_value == const0_rtx
&& GET_CODE (comparison_value) == CONST_INT)
{
- start_value = GEN_INT (comparison_val - add_adjust);
+ start_value
+ = gen_int_mode (comparison_val - add_adjust, mode);
loop_insn_hoist (loop, gen_move_insn (reg, start_value));
}
else if (GET_CODE (initial_value) == CONST_INT)
{
- enum machine_mode mode = GET_MODE (reg);
rtx offset = GEN_INT (-INTVAL (initial_value) - add_adjust);
rtx add_insn = gen_add3_insn (reg, comparison_value, offset);
}
else if (! add_adjust)
{
- enum machine_mode mode = GET_MODE (reg);
rtx sub_insn = gen_sub3_insn (reg, comparison_value,
initial_value);
/* Add new compare/branch insn at end of loop. */
start_sequence ();
emit_cmp_and_jump_insns (reg, const0_rtx, cmp_code, NULL_RTX,
- GET_MODE (reg), 0,
+ mode, 0,
XEXP (jump_label, 0));
tem = get_insns ();
end_sequence ();
rtx note;
/* If this is a libcall that sets a giv, skip ahead to its end. */
- if (GET_RTX_CLASS (code) == 'i')
+ if (INSN_P (p))
{
note = find_reg_note (p, REG_LIBCALL, NULL_RTX);
the same tests as a function of STORE_FLAG_VALUE as find_comparison_args
in cse.c */
- while (GET_RTX_CLASS (code) == '<'
+ while ((GET_RTX_CLASS (code) == RTX_COMPARE
+ || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
&& op1 == CONST0_RTX (GET_MODE (op0))
&& op0 != want_reg)
{
REAL_VALUE_NEGATIVE (fsfv)))
#endif
))
- && GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'))
+ && COMPARISON_P (SET_SRC (set))))
&& (((GET_MODE_CLASS (mode) == MODE_CC)
== (GET_MODE_CLASS (inner_mode) == MODE_CC))
|| mode == VOIDmode || inner_mode == VOIDmode))
REAL_VALUE_NEGATIVE (fsfv)))
#endif
))
- && GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'
+ && COMPARISON_P (SET_SRC (set))
&& (((GET_MODE_CLASS (mode) == MODE_CC)
== (GET_MODE_CLASS (inner_mode) == MODE_CC))
|| mode == VOIDmode || inner_mode == VOIDmode))
if (x)
{
- if (GET_RTX_CLASS (GET_CODE (x)) == '<')
+ if (COMPARISON_P (x))
code = GET_CODE (x);
if (reverse_code)
{
;
prev_ebb_head = p;
- cselib_init ();
+ cselib_init (true);
/* Build table of mems that get set to constant values before the
loop. */