static rtx loop_insn_emit_after PARAMS((const struct loop *, basic_block,
rtx, rtx));
-static rtx loop_insn_emit_before PARAMS((const struct loop *, basic_block,
- rtx, rtx));
+static rtx loop_call_insn_emit_before PARAMS((const struct loop *,
+ basic_block, rtx, rtx));
+static rtx loop_call_insn_hoist PARAMS((const struct loop *, rtx));
static rtx loop_insn_sink_or_swim PARAMS((const struct loop *, rtx));
static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int));
if (GET_CODE (temp) == CALL_INSN
&& fn_address != 0
&& reg_referenced_p (fn_reg, body))
- emit_insn_after (gen_move_insn (fn_reg,
- fn_address),
- fn_address_insn);
+ loop_insn_emit_after (loop, 0, fn_address_insn,
+ gen_move_insn
+ (fn_reg, fn_address));
if (GET_CODE (temp) == CALL_INSN)
{
- i1 = emit_call_insn_before (body, loop_start);
+ i1 = loop_call_insn_hoist (loop, body);
/* Because the USAGE information potentially
contains objects other than hard registers
we need to copy it. */
}
else if (GET_CODE (p) == CALL_INSN)
{
- i1 = emit_call_insn_before (PATTERN (p), loop_start);
+ i1 = loop_call_insn_hoist (loop, PATTERN (p));
/* Because the USAGE information potentially
contains objects other than hard registers
we need to copy it. */
{
/* Not replaceable; emit an insn to set the original giv reg from
the reduced giv, same as above. */
- emit_insn_after (gen_move_insn (v->dest_reg, v->new_reg),
- v->insn);
+ loop_insn_emit_after (loop, 0, v->insn,
+ gen_move_insn (v->dest_reg, v->new_reg));
}
/* When a loop is reversed, givs which depend on the reversed
&& benefit > 0
&& GET_CODE (v->mult_val) == CONST_INT)
{
+ int size = GET_MODE_SIZE (GET_MODE (v->mem));
+
if (HAVE_POST_INCREMENT
- && INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+ && INTVAL (v->mult_val) == size)
benefit += add_cost * bl->biv_count;
else if (HAVE_PRE_INCREMENT
- && INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+ && INTVAL (v->mult_val) == size)
benefit += add_cost * bl->biv_count;
else if (HAVE_POST_DECREMENT
- && -INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+ && -INTVAL (v->mult_val) == size)
benefit += add_cost * bl->biv_count;
else if (HAVE_PRE_DECREMENT
- && -INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+ && -INTVAL (v->mult_val) == size)
benefit += add_cost * bl->biv_count;
}
#endif
int ze_ok = 0, se_ok = 0, info_ok = 0;
enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
HOST_WIDE_INT start_val;
- unsigned HOST_WIDE_INT u_end_val, u_start_val;
+ unsigned HOST_WIDE_INT u_end_val = 0;
+ unsigned HOST_WIDE_INT u_start_val = 0;
rtx incr = pc_rtx;
struct induction *v;
if (bl->giv_count == 0 && ! loop->exit_count)
{
rtx bivreg = regno_reg_rtx[bl->regno];
+ struct iv_class *blt;
/* If there are no givs for this biv, and the only exit is the
fall through at the end of the loop, then
break;
}
}
+
+ /* A biv has uses besides counting if it is used to set another biv. */
+ for (blt = ivs->list; blt; blt = blt->next)
+ if (blt->init_set && reg_mentioned_p (bivreg, SET_SRC (blt->init_set)))
+ {
+ no_use_except_counting = 0;
+ break;
+ }
}
if (no_use_except_counting)
tem = gen_sequence ();
end_sequence ();
- p = emit_insn_before (tem, bl->biv->insn);
+ p = loop_insn_emit_before (loop, 0, bl->biv->insn, tem);
delete_insn (bl->biv->insn);
/* Update biv info to reflect its new status. */
into a register (it will be a loop invariant.) */
tem = gen_reg_rtx (GET_MODE (v->new_reg));
- emit_insn_before (gen_move_insn (tem, copy_rtx (v->add_val)),
- where_insn);
+ loop_insn_emit_before (loop, 0, where_insn,
+ gen_move_insn (tem,
+ copy_rtx (v->add_val)));
/* Substitute the new register for its invariant value in
the compare expression. */
rtx tem;
rtx op0, op1;
int reverse_code = 0;
- int did_reverse_condition = 0;
enum machine_mode mode;
code = GET_CODE (cond);
op1 = XEXP (cond, 1);
if (reverse)
- {
- code = reverse_condition (code);
- did_reverse_condition ^= 1;
- }
+ code = reversed_comparison_code (cond, insn);
+ if (code == UNKNOWN)
+ return 0;
if (earliest)
*earliest = insn;
if ((prev = prev_nonnote_insn (prev)) == 0
|| GET_CODE (prev) != INSN
- || FIND_REG_INC_NOTE (prev, 0)
- || (set = single_set (prev)) == 0)
+ || FIND_REG_INC_NOTE (prev, 0))
+ break;
+
+ set = set_of (op0, prev);
+
+ if (set
+ && (GET_CODE (set) != SET
+ || !rtx_equal_p (SET_DEST (set), op0)))
break;
/* If this is setting OP0, get what it sets it to if it looks
relevant. */
- if (rtx_equal_p (SET_DEST (set), op0))
+ if (set)
{
enum machine_mode inner_mode = GET_MODE (SET_DEST (set));
|| mode == VOIDmode || inner_mode == VOIDmode))
{
- /* We might have reversed a LT to get a GE here. But this wasn't
- actually the comparison of data, so we don't flag that we
- have had to reverse the condition. */
- did_reverse_condition ^= 1;
reverse_code = 1;
x = SET_SRC (set);
}
code = GET_CODE (x);
if (reverse_code)
{
- code = reverse_condition (code);
+ code = reversed_comparison_code (x, prev);
if (code == UNKNOWN)
return 0;
- did_reverse_condition ^= 1;
reverse_code = 0;
}
}
}
- /* If this was floating-point and we reversed anything other than an
- EQ or NE or (UN)ORDERED, return zero. */
- if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
- && did_reverse_condition
- && code != NE && code != EQ && code != UNORDERED && code != ORDERED
- && ! flag_fast_math
- && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
- return 0;
-
#ifdef HAVE_cc0
/* Never return CC0; return zero instead. */
if (op0 == cc0_rtx)
rtx end_label;
/* Nonzero if the next instruction may never be executed. */
int next_maybe_never = 0;
- int last_max_reg = max_reg_num ();
+ unsigned int last_max_reg = max_reg_num ();
if (loop_info->mems_idx == 0)
return;
/* Store the memory immediately after END, which is
the NOTE_LOOP_END. */
set = gen_move_insn (copy_rtx (mem), reg);
- emit_insn_after (set, label);
+ loop_insn_emit_after (loop, 0, label, set);
}
if (loop_dump_stream)
unsigned int regno;
{
rtx insn;
- rtx set;
+ rtx set = NULL_RTX;
unsigned int new_regno;
new_regno = REGNO (replacement);
insn = next_insn_in_loop (loop, insn))
{
/* Search for the insn that copies REGNO to NEW_REGNO? */
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ if (INSN_P (insn)
&& (set = single_set (insn))
&& GET_CODE (SET_DEST (set)) == REG
&& REGNO (SET_DEST (set)) == new_regno
break;
}
- if (insn != NULL_RTX)
+ if (set)
{
rtx prev_insn;
rtx prev_set;
prev_insn = PREV_INSN (insn);
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ if (INSN_P (insn)
&& (prev_set = single_set (prev_insn))
&& GET_CODE (SET_DEST (prev_set)) == REG
&& REGNO (SET_DEST (prev_set)) == regno)
in basic block WHERE_BB (ignored in the interim) within the loop
otherwise hoist PATTERN into the loop pre-header. */
-static rtx
+rtx
loop_insn_emit_before (loop, where_bb, where_insn, pattern)
const struct loop *loop;
basic_block where_bb ATTRIBUTE_UNUSED;
}
+/* Emit call insn for PATTERN before WHERE_INSN in basic block
+ WHERE_BB (ignored in the interim) within the loop. */
+
+static rtx
+loop_call_insn_emit_before (loop, where_bb, where_insn, pattern)
+ const struct loop *loop ATTRIBUTE_UNUSED;
+ basic_block where_bb ATTRIBUTE_UNUSED;
+ rtx where_insn;
+ rtx pattern;
+{
+ return emit_call_insn_before (pattern, where_insn);
+}
+
+
/* Hoist insn for PATTERN into the loop pre-header. */
rtx
}
+/* Hoist call insn for PATTERN into the loop pre-header. */
+
+static rtx
+loop_call_insn_hoist (loop, pattern)
+ const struct loop *loop;
+ rtx pattern;
+{
+ return loop_call_insn_emit_before (loop, 0, loop->start, pattern);
+}
+
+
/* Sink insn for PATTERN after the loop end. */
rtx