static rtx *splittable_regs;
/* Indexed by register number, if this is a splittable induction variable,
- this indicates if it was made from a derived giv. */
-static char *derived_regs;
-
-/* Indexed by register number, if this is a splittable induction variable,
then this will hold the number of instructions in the loop that modify
the induction variable. Used to ensure that only the last insn modifying
a split iv will update the original iv of the dest. */
to access the splittable_regs[] and addr_combined_regs[] arrays. */
splittable_regs = (rtx *) xcalloc (maxregnum, sizeof (rtx));
- derived_regs = (char *) xcalloc (maxregnum, sizeof (char));
splittable_regs_updates = (int *) xcalloc (maxregnum, sizeof (int));
addr_combined_regs
= (struct induction **) xcalloc (maxregnum, sizeof (struct induction *));
these pseudo registers have valid regno_first_uid info. */
for (r = FIRST_PSEUDO_REGISTER; r < max_reg_before_loop; ++r)
if (REGNO_FIRST_UID (r) > 0 && REGNO_FIRST_UID (r) <= max_uid_for_loop
- && uid_luid[REGNO_FIRST_UID (r)] >= copy_start_luid
+ && REGNO_FIRST_LUID (r) >= copy_start_luid
&& REGNO_LAST_UID (r) > 0 && REGNO_LAST_UID (r) <= max_uid_for_loop
- && uid_luid[REGNO_LAST_UID (r)] <= copy_end_luid)
+ && REGNO_LAST_LUID (r) <= copy_end_luid)
{
/* However, we must also check for loop-carried dependencies.
If the value the pseudo has at the end of iteration X is
r);
}
}
- /* Givs that have been created from multiple biv increments always have
- local registers. */
- for (r = ivs->first_increment_giv; r <= ivs->last_increment_giv; r++)
- {
- local_regno[r] = 1;
- if (loop_dump_stream)
- fprintf (loop_dump_stream, "Marked reg %d as local\n", r);
- }
}
/* If this loop requires exit tests when unrolled, check to see if we
emit_label_after (labels[unroll_number - i],
PREV_INSN (loop_start));
- bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
- bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
- (VARRAY_SIZE (map->const_equiv_varray)
- * sizeof (struct const_equiv_data)));
+ memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
+ memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
+ 0, (VARRAY_SIZE (map->const_equiv_varray)
+ * sizeof (struct const_equiv_data)));
map->const_age = 0;
for (j = 0; j < max_labelno; j++)
/* Search the list of bivs and givs to find ones which need to be remapped
when split, and set their reg_map entry appropriately. */
- for (bl = ivs->loop_iv_list; bl; bl = bl->next)
+ for (bl = ivs->list; bl; bl = bl->next)
{
if (REGNO (bl->biv->src_reg) != bl->regno)
map->reg_map[bl->regno] = bl->biv->src_reg;
}
/* Use our current register alignment and pointer flags. */
- map->regno_pointer_flag = cfun->emit->regno_pointer_flag;
map->regno_pointer_align = cfun->emit->regno_pointer_align;
+ map->x_regno_reg_rtx = cfun->emit->x_regno_reg_rtx;
/* If the loop is being partially unrolled, and the iteration variables
are being split, and are being renamed for the split, then must fix up
for (i = 0; i < unroll_number; i++)
{
- bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
- bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
- VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
+ memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
+ memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0), 0,
+ VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
map->const_age = 0;
for (j = 0; j < max_labelno; j++)
}
free (map->insn_map);
free (splittable_regs);
- free (derived_regs);
free (splittable_regs_updates);
free (addr_combined_regs);
free (local_regno);
/* Fail if loop_info->iteration_var is not live before loop_start,
since we need to test its value in the preconditioning code. */
- if (uid_luid[REGNO_FIRST_UID (REGNO (loop_info->iteration_var))]
+ if (REGNO_FIRST_LUID (REGNO (loop_info->iteration_var))
> INSN_LUID (loop_start))
{
if (loop_dump_stream)
unsigned int regno = REGNO (SET_DEST (set));
v = addr_combined_regs[REGNO (SET_DEST (set))];
- bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+ bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
/* Although the giv_inc amount is not needed here, we must call
calculate_giv_inc here since it might try to delete the
we might accidentally delete insns generated immediately
below by emit_unrolled_add. */
- if (! derived_regs[regno])
- giv_inc = calculate_giv_inc (set, insn, regno);
+ giv_inc = calculate_giv_inc (set, insn, regno);
/* Now find all address giv's that were combined with this
giv 'v'. */
dest_reg_was_split = 1;
giv_dest_reg = SET_DEST (set);
- if (derived_regs[regno])
- {
- /* ??? This relies on SET_SRC (SET) to be of
- the form (plus (reg) (const_int)), and thus
- forces recombine_givs to restrict the kind
- of giv derivations it does before unrolling. */
- giv_src_reg = XEXP (SET_SRC (set), 0);
- giv_inc = XEXP (SET_SRC (set), 1);
- }
- else
- {
- giv_src_reg = giv_dest_reg;
- /* Compute the increment value for the giv, if it wasn't
- already computed above. */
- if (giv_inc == 0)
- giv_inc = calculate_giv_inc (set, insn, regno);
- }
+ giv_src_reg = giv_dest_reg;
+ /* Compute the increment value for the giv, if it wasn't
+ already computed above. */
+ if (giv_inc == 0)
+ giv_inc = calculate_giv_inc (set, insn, regno);
+
src_regno = REGNO (giv_src_reg);
if (unroll_type == UNROLL_COMPLETELY)
for the biv was stored in the biv's first struct
induction entry by find_splittable_regs. */
- if (regno < max_reg_before_loop
+ if (regno < ivs->n_regs
&& REG_IV_TYPE (ivs, regno) == BASIC_INDUCT)
{
- giv_src_reg = ivs->reg_biv_class[regno]->biv->src_reg;
+ giv_src_reg = REG_IV_CLASS (ivs, regno)->biv->src_reg;
giv_dest_reg = giv_src_reg;
}
if (JUMP_LABEL (insn) == start_label && insn == copy_end
&& ! last_iteration)
{
- /* Update JUMP_LABEL correctly to make invert_jump working. */
+ /* Update JUMP_LABEL make invert_jump work correctly. */
JUMP_LABEL (copy) = get_label_from_map (map,
CODE_LABEL_NUMBER
(JUMP_LABEL (insn)));
+ LABEL_NUSES (JUMP_LABEL (copy))++;
+
/* This is a branch to the beginning of the loop; this is the
last insn being copied; and this is not the last iteration.
In this case, we want to change the original fall through
rtx loop_start = loop->start;
rtx loop_end = loop->end;
- for (bl = ivs->loop_iv_list; bl; bl = bl->next)
+ for (bl = ivs->list; bl; bl = bl->next)
{
/* Biv_total_increment must return a constant value,
otherwise we can not calculate the split values. */
biv_final_value = 0;
if (unroll_type != UNROLL_COMPLETELY
&& (loop->exit_count || unroll_type == UNROLL_NAIVE)
- && (uid_luid[REGNO_LAST_UID (bl->regno)] >= INSN_LUID (loop_end)
+ && (REGNO_LAST_LUID (bl->regno) >= INSN_LUID (loop_end)
|| ! bl->init_insn
|| INSN_UID (bl->init_insn) >= max_uid_for_loop
- || (uid_luid[REGNO_FIRST_UID (bl->regno)]
+ || (REGNO_FIRST_LUID (bl->regno)
< INSN_LUID (bl->init_insn))
|| reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
&& ! (biv_final_value = final_biv_value (loop, bl)))
|| (REGNO_FIRST_UID (REGNO (v->dest_reg))
!= INSN_UID (XEXP (tem, 0)))))
/* Line above always fails if INSN was moved by loop opt. */
- || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))]
+ || (REGNO_LAST_LUID (REGNO (v->dest_reg))
>= INSN_LUID (loop->end)))
- /* Givs made from biv increments are missed by the above test, so
- test explicitly for them. */
- && (REGNO (v->dest_reg) < ivs->first_increment_giv
- || REGNO (v->dest_reg) > ivs->last_increment_giv)
&& ! (final_value = v->final_value))
continue;
}
splittable_regs[REGNO (v->new_reg)] = value;
- derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
}
else
{
rtx new_reg = v->new_reg;
record_base_value (REGNO (tem), v->add_val, 0);
- if (same && same->derived_from)
- {
- /* calculate_giv_inc doesn't work for derived givs.
- copy_loop_body works around the problem for the
- DEST_REG givs themselves, but it can't handle
- DEST_ADDR givs that have been combined with
- a derived DEST_REG giv.
- So Handle V as if the giv from which V->SAME has
- been derived has been combined with V.
- recombine_givs only derives givs from givs that
- are reduced the ordinary, so we need not worry
- about same->derived_from being in turn derived. */
-
- same = same->derived_from;
- new_reg = express_from (same, v);
- new_reg = replace_rtx (new_reg, same->dest_reg,
- same->new_reg);
- }
-
/* If the address giv has a constant in its new_reg value,
then this constant can be pulled out and put in value,
instead of being part of the initialization code. */
INSN_UID (v->insn));
continue;
}
- if (v->same && v->same->derived_from)
- {
- /* Handle V as if the giv from which V->SAME has
- been derived has been combined with V. */
-
- v->same = v->same->derived_from;
- v->new_reg = express_from (v->same, v);
- v->new_reg = replace_rtx (v->new_reg, v->same->dest_reg,
- v->same->new_reg);
- }
-
}
/* Store the value of dest_reg into the insn. This sharing
Make sure that it's giv is marked as splittable here. */
splittable_regs[REGNO (v->new_reg)] = value;
- derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
/* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */
{
int count = 1;
if (! v->ignore)
- count = ivs->reg_biv_class[REGNO (v->src_reg)]->biv_count;
-
- if (count > 1 && v->derived_from)
- /* In this case, there is one set where the giv insn was and one
- set each after each biv increment. (Most are likely dead.) */
- count++;
+ count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count;
splittable_regs_updates[REGNO (v->new_reg)] = count;
}
rtx loop_end = loop->end;
unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations;
- bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+ bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
/* The final value for givs which depend on reversed bivs must be calculated
differently than for ordinary givs. In this case, there is already an
will propagate a new pseudo into the old iteration register but
this will be marked by having the REG_USERVAR_P bit set. */
- if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements
+ if ((unsigned) REGNO (iteration_var) >= ivs->n_regs
&& ! REG_USERVAR_P (iteration_var))
abort ();
/* If this is a new register, can't handle it since we don't have any
reg_iv_type entry for it. */
- if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements)
+ if ((unsigned) REGNO (iteration_var) >= ivs->n_regs)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
}
else if (REG_IV_TYPE (ivs, REGNO (iteration_var)) == BASIC_INDUCT)
{
- /* When reg_iv_type / reg_iv_info is resized for biv increments
- that are turned into givs, reg_biv_class is not resized.
- So check here that we don't make an out-of-bounds access. */
- if (REGNO (iteration_var) >= max_reg_before_loop)
+ if (REGNO (iteration_var) >= ivs->n_regs)
abort ();
/* Grab initial value, only useful if it is a constant. */
- bl = ivs->reg_biv_class[REGNO (iteration_var)];
+ bl = REG_IV_CLASS (ivs, REGNO (iteration_var));
initial_value = bl->initial_value;
increment = biv_total_increment (bl);
struct induction *v = REG_IV_INFO (ivs, REGNO (iteration_var));
rtx biv_initial_value;
- if (REGNO (v->src_reg) >= max_reg_before_loop)
+ if (REGNO (v->src_reg) >= ivs->n_regs)
abort ();
- bl = ivs->reg_biv_class[REGNO (v->src_reg)];
+ bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
/* Increment value is mult_val times the increment value of the biv. */
/* If non-reduced/final-value givs were split, then this would also
have to remap those givs also. */
#endif
- if (REGNO (x) < max_reg_before_loop
+ if (REGNO (x) < ivs->n_regs
&& REG_IV_TYPE (ivs, REGNO (x)) == BASIC_INDUCT)
- return ivs->reg_biv_class[REGNO (x)]->biv->src_reg;
+ return REG_IV_CLASS (ivs, REGNO (x))->biv->src_reg;
break;
default: