/* Try to unroll loops, and split induction variables.
Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003
+ 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by James E. Wilson, Cygnus Support/UC Berkeley.
/* If the last instruction is not a BARRIER or a JUMP_INSN, then
don't do anything. */
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
{
/* Delete the jump insn. This will delete the barrier also. */
last_loop_insn = PREV_INSN (last_loop_insn);
}
- if (ujump && GET_CODE (last_loop_insn) == JUMP_INSN)
+ if (ujump && JUMP_P (last_loop_insn))
{
#ifdef HAVE_cc0
rtx prev = PREV_INSN (last_loop_insn);
Just return without unrolling the loop in such cases. */
insn = loop_start;
- while (GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != JUMP_INSN)
+ while (!LABEL_P (insn) && !JUMP_P (insn))
insn = NEXT_INSN (insn);
- if (GET_CODE (insn) == JUMP_INSN)
+ if (JUMP_P (insn))
return;
}
insert_before = NEXT_INSN (last_loop_insn);
/* Set copy_end to the insn before the jump at the end of the loop. */
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
copy_end = PREV_INSN (PREV_INSN (last_loop_insn));
- else if (GET_CODE (last_loop_insn) == JUMP_INSN)
+ else if (JUMP_P (last_loop_insn))
{
copy_end = PREV_INSN (last_loop_insn);
#ifdef HAVE_cc0
/* Set insert_before to the jump insn at the end of the loop.
Set copy_end to before the jump insn at the end of the loop. */
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
{
insert_before = PREV_INSN (last_loop_insn);
copy_end = PREV_INSN (insert_before);
}
- else if (GET_CODE (last_loop_insn) == JUMP_INSN)
+ else if (JUMP_P (last_loop_insn))
{
insert_before = last_loop_insn;
#ifdef HAVE_cc0
/* Normal case: Must copy the compare and branch instructions at the
end of the loop. */
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
{
/* Loop ends with an unconditional jump and a barrier.
Handle this like above, don't copy jump and barrier.
insert_before = PREV_INSN (last_loop_insn);
copy_end = PREV_INSN (insert_before);
}
- else if (GET_CODE (last_loop_insn) == JUMP_INSN)
+ else if (JUMP_P (last_loop_insn))
{
/* Set insert_before to immediately after the JUMP_INSN, so that
NOTEs at the end of the loop will be correctly handled by
exit_label = gen_label_rtx ();
insn = loop_start;
- while (GET_CODE (insn) != CODE_LABEL && GET_CODE (insn) != JUMP_INSN)
+ while (!LABEL_P (insn) && !JUMP_P (insn))
insn = NEXT_INSN (insn);
- if (GET_CODE (insn) == JUMP_INSN)
+ if (JUMP_P (insn))
{
/* The loop starts with a jump down to the exit condition test.
Start copying the loop after the barrier following this
/* This should always be the first label in the loop. */
start_label = NEXT_INSN (copy_start);
/* There may be a line number note and/or a loop continue note here. */
- while (GET_CODE (start_label) == NOTE)
+ while (NOTE_P (start_label))
start_label = NEXT_INSN (start_label);
- if (GET_CODE (start_label) != CODE_LABEL)
+ if (!LABEL_P (start_label))
{
/* This can happen as a result of jump threading. If the first insns in
the loop test the same condition as the loop's backward jump, or the
}
if (unroll_type == UNROLL_NAIVE
- && GET_CODE (last_loop_insn) == BARRIER
- && GET_CODE (PREV_INSN (last_loop_insn)) == JUMP_INSN
+ && BARRIER_P (last_loop_insn)
+ && JUMP_P (PREV_INSN (last_loop_insn))
&& start_label != JUMP_LABEL (PREV_INSN (last_loop_insn)))
{
/* In this case, we must copy the jump and barrier, because they will
}
if (unroll_type == UNROLL_NAIVE
- && GET_CODE (last_loop_insn) == JUMP_INSN
+ && JUMP_P (last_loop_insn)
&& start_label != JUMP_LABEL (last_loop_insn))
{
/* ??? The loop ends with a conditional branch that does not branch back
{
rtx note;
- if (GET_CODE (insn) == CODE_LABEL)
+ if (LABEL_P (insn))
local_label[CODE_LABEL_NUMBER (insn)] = 1;
- else if (GET_CODE (insn) == JUMP_INSN)
+ else if (JUMP_P (insn))
{
if (JUMP_LABEL (insn))
set_label_in_map (map,
map->insn_map = xmalloc (max_insnno * sizeof (rtx));
- /* Set this to zero, to indicate that we are doing loop unrolling,
- not function inlining. */
- map->inline_target = 0;
-
/* The register and constant maps depend on the number of registers
present, so the final maps can't be created until after
find_splittable_regs is called. However, they are needed for
/* If a register is used in the jump insn, we must not duplicate it
since it will also be used outside the loop. */
- if (GET_CODE (copy_end) == JUMP_INSN)
+ if (JUMP_P (copy_end))
copy_end_luid--;
/* If we have a target that uses cc0, then we also must not duplicate
the insn that sets cc0 before the jump insn, if one is present. */
#ifdef HAVE_cc0
- if (GET_CODE (copy_end) == JUMP_INSN
+ if (JUMP_P (copy_end)
&& sets_cc0_p (PREV_INSN (copy_end)))
copy_end_luid--;
#endif
and then reset it inside the loop when get to the last
copy. */
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
copy_end = PREV_INSN (PREV_INSN (last_loop_insn));
- else if (GET_CODE (last_loop_insn) == JUMP_INSN)
+ else if (JUMP_P (last_loop_insn))
{
copy_end = PREV_INSN (last_loop_insn);
#ifdef HAVE_cc0
if (i == unroll_number - 1)
{
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
copy_end = PREV_INSN (PREV_INSN (last_loop_insn));
else
copy_end = last_loop_insn;
}
emit_label_after (labels[0], PREV_INSN (loop_start));
- if (GET_CODE (last_loop_insn) == BARRIER)
+ if (BARRIER_P (last_loop_insn))
{
insert_before = PREV_INSN (last_loop_insn);
copy_end = PREV_INSN (insert_before);
if (unroll_type == UNROLL_MODULO)
{
insn = NEXT_INSN (copy_end);
- if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
+ if (NONJUMP_INSN_P (insn) || JUMP_P (insn))
PATTERN (insn) = remap_split_bivs (loop, PATTERN (insn));
}
associated LABEL_DECL to point to one of the new label instances. */
/* ??? Likewise, we can't delete a NOTE_INSN_DELETED_LABEL note. */
if (insn != start_label
- && ! (GET_CODE (insn) == CODE_LABEL && LABEL_NAME (insn))
- && ! (GET_CODE (insn) == NOTE
+ && ! (LABEL_P (insn) && LABEL_NAME (insn))
+ && ! (NOTE_P (insn)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
insn = delete_related_insns (insn);
else
{
rtx t, insn;
- t = simplify_relational_operation (code, mode, op0, op1);
+ t = simplify_const_relational_operation (code, mode, op0, op1);
if (!t)
{
enum rtx_code scode = signed_condition (code);
against max_reg_before_loop to make sure that the register is in
the range covered by loop_invariant_p. If it isn't, then it is
most likely a biv/giv which by definition are not invariant. */
- if ((GET_CODE (loop_info->final_value) == REG
+ if ((REG_P (loop_info->final_value)
&& REGNO (loop_info->final_value) >= max_reg_before_loop)
|| (GET_CODE (loop_info->final_value) == PLUS
&& REGNO (XEXP (loop_info->final_value, 0)) >= max_reg_before_loop)
/* Some ports store large constants in memory and add a REG_EQUAL
note to the store insn. */
- else if (GET_CODE (increment) == MEM)
+ else if (MEM_P (increment))
{
rtx note = find_reg_note (src_insn, REG_EQUAL, 0);
if (note)
/* Check that the source register is the same as the register we expected
to see as the source. If not, something is seriously wrong. */
- if (GET_CODE (XEXP (SET_SRC (pattern), 0)) != REG
+ if (!REG_P (XEXP (SET_SRC (pattern), 0))
|| REGNO (XEXP (SET_SRC (pattern), 0)) != regno)
{
/* Some machines (e.g. the romp), may emit two add instructions for
SET_DEST to a new register. */
if ((set = single_set (insn))
- && GET_CODE (SET_DEST (set)) == REG
+ && REG_P (SET_DEST (set))
&& addr_combined_regs[REGNO (SET_DEST (set))])
{
struct iv_class *bl;
/* tv->dest_reg will be either a bare register,
or else a register plus a constant. */
- if (GET_CODE (tv->dest_reg) == REG)
+ if (REG_P (tv->dest_reg))
dest_reg = tv->dest_reg;
else
dest_reg = XEXP (tv->dest_reg, 0);
dest_reg_was_split = 0;
if ((set = single_set (insn))
- && GET_CODE (SET_DEST (set)) == REG
+ && REG_P (SET_DEST (set))
&& splittable_regs[REGNO (SET_DEST (set))])
{
unsigned int regno = REGNO (SET_DEST (set));
}
}
- if (label && GET_CODE (label) == CODE_LABEL)
+ if (label && LABEL_P (label))
JUMP_LABEL (copy) = label;
else
{
do
{
insn = NEXT_INSN (insn);
- if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
- || GET_CODE (insn) == CALL_INSN)
+ if (INSN_P (insn)
&& map->insn_map[INSN_UID (insn)])
final_reg_note_copy (®_NOTES (map->insn_map[INSN_UID (insn)]), map);
}
instructions before the last insn in the loop, COPY_NOTES_FROM
can be a NOTE_INSN_LOOP_CONT note if there is no VTOP note,
as in a do .. while loop. */
- if (GET_CODE (insn) == NOTE
+ if (NOTE_P (insn)
&& ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
/* Stop before we get to the backward branch at the end of the loop. */
loop_end = prev_nonnote_insn (loop_end);
- if (GET_CODE (loop_end) == BARRIER)
+ if (BARRIER_P (loop_end))
loop_end = PREV_INSN (loop_end);
/* Check in case insn has been deleted, search forward for first non
for (p = NEXT_INSN (insn); p != loop_end; p = NEXT_INSN (p))
{
- if (GET_CODE (p) == JUMP_INSN)
+ if (JUMP_P (p))
{
target_insn = JUMP_LABEL (p);
PLUS, we don't know how to split it. */
for (v = bl->biv; biv_splittable && v; v = v->next_iv)
if ((tem = single_set (v->insn)) == 0
- || GET_CODE (SET_DEST (tem)) != REG
+ || !REG_P (SET_DEST (tem))
|| REGNO (SET_DEST (tem)) != bl->regno
|| GET_CODE (SET_SRC (tem)) != PLUS)
biv_splittable = 0;
register, or it isn't invariant, then we must create a new
pseudo reg to hold the initial value of the biv. */
- if (GET_CODE (bl->initial_value) == REG
+ if (REG_P (bl->initial_value)
&& (REGNO (bl->initial_value) == bl->regno
|| REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER
|| ! loop_invariant_p (loop, bl->initial_value)))
if (splittable_regs[bl->regno])
biv_initial_value = splittable_regs[bl->regno];
- else if (GET_CODE (bl->initial_value) != REG
+ else if (!REG_P (bl->initial_value)
|| (REGNO (bl->initial_value) != bl->regno
&& REGNO (bl->initial_value) >= FIRST_PSEUDO_REGISTER))
biv_initial_value = bl->initial_value;
is going before the loop start. */
if (unroll_type == UNROLL_COMPLETELY
&& GET_CODE (value) != CONST_INT
- && GET_CODE (value) != REG
+ && !REG_P (value)
&& (GET_CODE (value) != PLUS
- || GET_CODE (XEXP (value, 0)) != REG
+ || !REG_P (XEXP (value, 0))
|| GET_CODE (XEXP (value, 1)) != CONST_INT))
{
rtx tem = gen_reg_rtx (v->mode);
a splittable register. Don't need to do anything for address givs
where this may not be a register. */
- if (GET_CODE (v->new_reg) == REG)
+ if (REG_P (v->new_reg))
{
int count = 1;
if (! v->ignore)
if (GET_CODE (v->dest_reg) == CONST_INT)
regnum = -1;
- else if (GET_CODE (v->dest_reg) != REG)
+ else if (!REG_P (v->dest_reg))
regnum = REGNO (XEXP (v->dest_reg, 0));
else
regnum = REGNO (v->dest_reg);
reg_dead_after_loop (const struct loop *loop, rtx reg)
{
rtx insn, label;
- enum rtx_code code;
int jump_count = 0;
int label_count = 0;
insn = NEXT_INSN (XEXP (label, 0));
while (insn)
{
- code = GET_CODE (insn);
- if (GET_RTX_CLASS (code) == 'i')
+ if (INSN_P (insn))
{
rtx set, note;
set = single_set (insn);
if (set && rtx_equal_p (SET_DEST (set), reg))
break;
- }
- if (code == JUMP_INSN)
- {
- if (GET_CODE (PATTERN (insn)) == RETURN)
- break;
- else if (!any_uncondjump_p (insn)
- /* Prevent infinite loop following infinite loops. */
- || jump_count++ > 20)
- return 0;
- else
- insn = JUMP_LABEL (insn);
+ if (JUMP_P (insn))
+ {
+ if (GET_CODE (PATTERN (insn)) == RETURN)
+ break;
+ else if (!any_uncondjump_p (insn)
+ /* Prevent infinite loop following infinite loops. */
+ || jump_count++ > 20)
+ return 0;
+ else
+ insn = JUMP_LABEL (insn);
+ }
}
insn = NEXT_INSN (insn);
ret = reg;
for (insn = PREV_INSN (loop_start); insn; insn = PREV_INSN (insn))
{
- if (GET_CODE (insn) == CODE_LABEL)
+ if (LABEL_P (insn))
break;
else if (INSN_P (insn) && reg_set_p (reg, insn))
static rtx
find_common_reg_term (rtx op0, rtx op1)
{
- if ((GET_CODE (op0) == REG || GET_CODE (op0) == PLUS)
- && (GET_CODE (op1) == REG || GET_CODE (op1) == PLUS))
+ if ((REG_P (op0) || GET_CODE (op0) == PLUS)
+ && (REG_P (op1) || GET_CODE (op1) == PLUS))
{
rtx op00;
rtx op01;
/* ??? We should probably try harder to find the jump insn
at the end of the loop. The following code assumes that
the last loop insn is a jump to the top of the loop. */
- if (GET_CODE (last_loop_insn) != JUMP_INSN)
+ if (!JUMP_P (last_loop_insn))
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
do
{
- if (GET_CODE (temp) == JUMP_INSN)
+ if (JUMP_P (temp))
{
/* There are some kinds of jumps we can't deal with easily. */
if (JUMP_LABEL (temp) == 0)
iteration_var = XEXP (comparison, 0);
comparison_value = XEXP (comparison, 1);
- if (GET_CODE (iteration_var) != REG)
+ if (!REG_P (iteration_var))
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
/* Try swapping the comparison to identify a suitable iv. */
if (REG_IV_TYPE (ivs, REGNO (iteration_var)) != BASIC_INDUCT
&& REG_IV_TYPE (ivs, REGNO (iteration_var)) != GENERAL_INDUCT
- && GET_CODE (comparison_value) == REG
+ && REG_P (comparison_value)
&& REGNO (comparison_value) < ivs->n_regs)
{
rtx temp = comparison_value;
its value from the insns before the start of the loop. */
final_value = comparison_value;
- if (GET_CODE (comparison_value) == REG
+ if (REG_P (comparison_value)
&& loop_invariant_p (loop, comparison_value))
{
final_value = loop_find_equiv_value (loop, comparison_value);
/* If we have a REG, check to see if REG holds a constant value. */
/* ??? Other RTL, such as (neg (reg)) is possible here, but it isn't
clear if it is worthwhile to try to handle such RTL. */
- if (GET_CODE (increment) == REG || GET_CODE (increment) == SUBREG)
+ if (REG_P (increment) || GET_CODE (increment) == SUBREG)
increment = loop_find_equiv_value (loop, increment);
if (GET_CODE (increment) != CONST_INT)
while (INSN_UID (p) != first_uid)
{
- if (GET_CODE (p) == JUMP_INSN)
+ if (JUMP_P (p))
passed_jump = 1;
/* Could not find FIRST_UID. */
if (p == copy_end)
{
/* If we see a CODE_LABEL between FIRST_UID and LAST_UID, then we
can not be sure that FIRST_UID dominates LAST_UID. */
- if (GET_CODE (p) == CODE_LABEL)
+ if (LABEL_P (p))
return 0;
/* Could not find LAST_UID, but we reached the end of the loop, so
it must be safe. */
/* Examine insn after loop continuation note. Return if not a label. */
label = next_nonnote_insn (loop_cont);
- if (label == 0 || GET_CODE (label) != CODE_LABEL)
+ if (label == 0 || !LABEL_P (label))
return NULL_RTX;
/* Return the loop start if the branch label matches the code label. */