improperly shared rtl. */
diff = expand_binop (mode, sub_optab, copy_rtx (final_value),
- copy_rtx (initial_value), 0, 0,
+ copy_rtx (initial_value), NULL_RTX, 0,
OPTAB_LIB_WIDEN);
/* Now calculate (diff % (unroll * abs (increment))) by using an
and instruction. */
diff = expand_binop (GET_MODE (diff), and_optab, diff,
- gen_rtx (CONST_INT, VOIDmode,
- unroll_number * abs_inc - 1),
- 0, 0, OPTAB_LIB_WIDEN);
+ GEN_INT (unroll_number * abs_inc - 1),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN);
/* Now emit a sequence of branches to jump to the proper precond
loop entry point. */
else
cmp_const = i;
- emit_cmp_insn (diff, gen_rtx (CONST_INT, VOIDmode,
- abs_inc * cmp_const),
- EQ, 0, mode, 0, 0);
+ emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
+ EQ, NULL_RTX, mode, 0, 0);
if (i == 0)
emit_jump_insn (gen_beq (labels[i]));
else
cmp_const = abs_inc * (unroll_number - 1) + 1;
- emit_cmp_insn (diff, gen_rtx (CONST_INT, VOIDmode, cmp_const),
- EQ, 0, mode, 0, 0);
+ emit_cmp_insn (diff, GEN_INT (cmp_const), EQ, NULL_RTX,
+ mode, 0, 0);
if (neg_inc)
emit_jump_insn (gen_ble (labels[0]));
not taken. */
if (exit_label)
emit_label_after (exit_label, loop_end);
-
- /* If debugging, we must replicate the tree nodes corresponding to the blocks
- inside the loop, so that the original one to one mapping will remain. */
-
- if (write_symbols != NO_DEBUG)
- {
- int copies = unroll_number;
-
- if (loop_preconditioned)
- copies += unroll_number - 1;
-
- unroll_block_trees (uid_loop_num[INSN_UID (loop_start)], copies);
- }
}
\f
/* Return true if the loop can be safely, and profitably, preconditioned
{
*initial_value = const0_rtx;
*increment = const1_rtx;
- *final_value = gen_rtx (CONST_INT, VOIDmode, loop_n_iterations);
+ *final_value = GEN_INT (loop_n_iterations);
if (loop_dump_stream)
fprintf (loop_dump_stream,
copy_notes_from)
rtx copy_start, copy_end;
struct inline_remap *map;
+ rtx exit_label;
int last_iteration;
enum unroll_types unroll_type;
rtx start_label, loop_end, insert_before, copy_notes_from;
#endif
splittable_regs[regno]
- = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (giv_inc)
+ = GEN_INT (INTVAL (giv_inc)
+ INTVAL (splittable_regs[regno]));
giv_inc = splittable_regs[regno];
int fall_through;
/* Never map the label in this case. */
- pattern = copy_rtx (PATTERN (insn));
+ rtx tmp_pattern = copy_rtx (PATTERN (insn));
- /* Assume a conditional branch, since the code above
- does not let unconditional branches be copied. */
- if (! condjump_p (insn))
+ /* Set the fall through case to the exit label. If we
+ can't do this in place, abort for now. Maybe
+ we can do something more sophisticated eventually. */
+
+ if (! invert_exp (tmp_pattern, insn)
+ || ! redirect_exp (&tmp_pattern, JUMP_LABEL (insn),
+ exit_label, insn))
abort ();
- fall_through
- = (XEXP (SET_SRC (PATTERN (insn)), 2) == pc_rtx) + 1;
- /* Set the fall through case to the exit label. Must
- create a new label_ref since they can't be shared. */
- XEXP (SET_SRC (pattern), fall_through)
- = gen_rtx (LABEL_REF, VOIDmode, exit_label);
-
- /* Set the original branch case to fall through. */
- XEXP (SET_SRC (pattern), 3 - fall_through)
- = pc_rtx;
+ pattern = tmp_pattern;
}
else
pattern = copy_rtx_and_substitute (PATTERN (insn), map);
break;
case NOTE:
- if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
+ /* VTOP notes are valid only before the loop exit test. If placed
+ anywhere else, loop may generate bad code. */
+
+ if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
+ && (NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
+ || (last_iteration && unroll_type != UNROLL_COMPLETELY)))
copy = emit_note (NOTE_SOURCE_FILE (insn),
NOTE_LINE_NUMBER (insn));
else
/* Check for the case where the pseudo is set by a shift/add
sequence, in which case the first insn setting the pseudo
is the first insn of the shift/add sequence. */
- && (! (tem = find_reg_note (v->insn, REG_RETVAL, 0))
+ && (! (tem = find_reg_note (v->insn, REG_RETVAL, NULL_RTX))
|| (regno_first_uid[REGNO (v->dest_reg)]
!= INSN_UID (XEXP (tem, 0)))))
/* Line above always fails if INSN was moved by loop opt. */
/* If the giv is an address destination, it could be something other
than a simple register, these have to be treated differently. */
else if (v->giv_type == DEST_REG)
- splittable_regs[REGNO (v->new_reg)] = value;
+ {
+ /* If value is not a constant, register, or register plus
+ constant, then compute its value into a register before
+ loop start. This prevents illegal rtx sharing, and should
+ generate better code. We can use bl->initial_value here
+ instead of splittable_regs[bl->regno] because this code
+ is going before the loop start. */
+ if (unroll_type == UNROLL_COMPLETELY
+ && GET_CODE (value) != CONST_INT
+ && GET_CODE (value) != REG
+ && (GET_CODE (value) != PLUS
+ || GET_CODE (XEXP (value, 0)) != REG
+ || GET_CODE (XEXP (value, 1)) != CONST_INT))
+ {
+ rtx tem = gen_reg_rtx (v->mode);
+ emit_iv_add_mult (bl->initial_value, v->mult_val,
+ v->add_val, tem, loop_start);
+ value = tem;
+ }
+
+ splittable_regs[REGNO (v->new_reg)] = value;
+ }
else
{
/* Splitting address givs is useful since it will often allow us
case it is needed later. */
tem = gen_reg_rtx (bl->biv->mode);
- emit_iv_add_mult (increment,
- gen_rtx (CONST_INT, VOIDmode, loop_n_iterations),
+ emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
bl->initial_value, tem, NEXT_INSN (loop_end));
if (loop_dump_stream)
/* Put the final biv value in tem. */
tem = gen_reg_rtx (bl->biv->mode);
- emit_iv_add_mult (increment,
- gen_rtx (CONST_INT, VOIDmode, loop_n_iterations),
+ emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
bl->initial_value, tem, insert_before);
/* Subtract off extra increments as we find them. */
start_sequence ();
tem = expand_binop (GET_MODE (tem), sub_optab, tem,
- XEXP (SET_SRC (pattern), 1), 0, 0,
+ XEXP (SET_SRC (pattern), 1), NULL_RTX, 0,
OPTAB_LIB_WIDEN);
seq = gen_sequence ();
end_sequence ();
/* Calculate the number of loop iterations. Returns the exact number of loop
iterations if it can be calculated, otherwise returns zero. */
-unsigned long
+unsigned HOST_WIDE_INT
loop_iterations (loop_start, loop_end)
rtx loop_start, loop_end;
{
rtx comparison, comparison_value;
rtx iteration_var, initial_value, increment, final_value;
enum rtx_code comparison_code;
- int i, increment_dir;
+ HOST_WIDE_INT i;
+ int increment_dir;
int unsigned_compare, compare_dir, final_larger;
unsigned long tempu;
rtx last_loop_insn;
&& (set = single_set (insn))
&& (SET_DEST (set) == comparison_value))
{
- rtx note = find_reg_note (insn, REG_EQUAL, 0);
+ rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
comparison_value = XEXP (note, 0);
/* Final_larger is 1 if final larger, 0 if they are equal, otherwise -1. */
if (unsigned_compare)
final_larger
- = ((unsigned) INTVAL (final_value) > (unsigned) INTVAL (initial_value)) -
- ((unsigned) INTVAL (final_value) < (unsigned) INTVAL (initial_value));
+ = ((unsigned HOST_WIDE_INT) INTVAL (final_value)
+ > (unsigned HOST_WIDE_INT) INTVAL (initial_value))
+ - ((unsigned HOST_WIDE_INT) INTVAL (final_value)
+ < (unsigned HOST_WIDE_INT) INTVAL (initial_value));
else
- final_larger = (INTVAL (final_value) > INTVAL (initial_value)) -
- (INTVAL (final_value) < INTVAL (initial_value));
+ final_larger = (INTVAL (final_value) > INTVAL (initial_value))
+ - (INTVAL (final_value) < INTVAL (initial_value));
if (INTVAL (increment) > 0)
increment_dir = 1;