Commit 3ec2b590 by J"orn Rennecke Committed by Joern Rennecke

rtl.h (insn_first_p): Declare.

	* rtl.h (insn_first_p): Declare.
	* rtlanal.c (insn_first_p): New function.
	* loop.h (varray.h): Include.
	(struct induction): Change combined_with to unsigned.
	New members derived, ix and last_use.
	(reg_iv_type, reg_iv_info): Now varray_type.  All references changed.
	(REG_IV_TYPE, REG_IV_INFO): Define.
	(first_increment_giv, last_increment_giv): Declare.
	* loop.c (loop_number_loop_cont): New static variable.
	(loop_number_cont_dominator): Likewise.
	(reg_iv_type, reg_iv_info): Now varray_type.
	(first_increment_giv, last_increment_giv): New variables.
	(compute_luids, verify_dominator, find_life_end): New functions.
	(cmp_recombine_givs_stats, recombine_givs): Likewise.
	(loop_optimize): Allocate loop_number_loop_cont and
	loop_number_cont_dominator.  Use compute_luids.
	(find_and_verify_loops): Initialize loop_number_loop_cont and
	loop_number_cont_dominator.
	(strength_reduce): Try to find bivs that can be expressed as givs
	of another biv, and to convert biv increments into givs.
	Call recombine_givs.  Handle derived givs.
	(record_biv): New argument location.  All callers changed.
	(record_giv): Initialize derived and last_use fields.
	(basic_induction_var): New argument location.  All callers changed.
	(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
	Increment combined_with instead of setting to 1.
	* unroll.c (derived_regs): New static variable.
	(unroll_loop): Initialize it.
	Allocate local_regno according to max_reg_num.
	(copy_loop_body): Cope with derived givs.
	(find_splittable_givs): Check for Givs made from biv increments.
	Set derived_regs for givs.
	* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .

From-SVN: r24889
parent a9c70c22
Wed Jan 27 23:39:53 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
Wed Jan 27 19:31:36 1999 J"orn Rennecke <amylaar@cygnus.co.uk> Wed Jan 27 19:31:36 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* function.c (purge_addressof_1): Handle case when a register * function.c (purge_addressof_1): Handle case when a register
......
...@@ -1474,7 +1474,7 @@ function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ ...@@ -1474,7 +1474,7 @@ function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h insn-config.h $(RECOG_H) output.h toplev.h except.h
stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \ stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \ insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \
loop.h $(RECOG_H) toplev.h output.h loop.h $(RECOG_H) toplev.h output.h varray.h
except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \ function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h except.h toplev.h insn-config.h $(RECOG_H) output.h except.h toplev.h
...@@ -1527,9 +1527,9 @@ profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \ ...@@ -1527,9 +1527,9 @@ profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \
gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h insn-config.h gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h insn-config.h
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \ loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \
insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \ insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \
toplev.h toplev.h varray.h
unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \ unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h varray.h
flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-config.h \ flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h recog.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h recog.h
combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h \ combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h \
......
...@@ -18,6 +18,8 @@ along with GNU CC; see the file COPYING. If not, write to ...@@ -18,6 +18,8 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include "varray.h"
/* Get the luid of an insn. Catch the error of trying to reference the LUID /* Get the luid of an insn. Catch the error of trying to reference the LUID
of an insn added during loop, since these don't have LUIDs. */ of an insn added during loop, since these don't have LUIDs. */
...@@ -54,6 +56,8 @@ struct induction ...@@ -54,6 +56,8 @@ struct induction
For a DEST_ADDR type giv, this is 0. */ For a DEST_ADDR type giv, this is 0. */
rtx *location; /* Place in the insn where this giv occurs. rtx *location; /* Place in the insn where this giv occurs.
If GIV_TYPE is DEST_REG, this is 0. */ If GIV_TYPE is DEST_REG, this is 0. */
/* For a biv, this is the place where add_val
was found. */
enum machine_mode mode; /* The mode of this biv or giv */ enum machine_mode mode; /* The mode of this biv or giv */
enum machine_mode mem_mode; /* For DEST_ADDR, mode of the memory object. */ enum machine_mode mem_mode; /* For DEST_ADDR, mode of the memory object. */
rtx mult_val; /* Multiplicative factor for src_reg. */ rtx mult_val; /* Multiplicative factor for src_reg. */
...@@ -63,6 +67,9 @@ struct induction ...@@ -63,6 +67,9 @@ struct induction
final value could be calculated, it is put final value could be calculated, it is put
here, and the giv is made replaceable. Set here, and the giv is made replaceable. Set
the giv to this value before the loop. */ the giv to this value before the loop. */
unsigned combined_with; /* The number of givs this giv has been
combined with. If nonzero, this giv
cannot combine with any other giv. */
unsigned replaceable : 1; /* 1 if we can substitute the strength-reduced unsigned replaceable : 1; /* 1 if we can substitute the strength-reduced
variable for the original variable. variable for the original variable.
0 means they must be kept separate and the 0 means they must be kept separate and the
...@@ -85,8 +92,6 @@ struct induction ...@@ -85,8 +92,6 @@ struct induction
another giv. This occurs in many cases another giv. This occurs in many cases
where a giv's lifetime spans an update to where a giv's lifetime spans an update to
a biv. */ a biv. */
unsigned combined_with : 1; /* 1 if this giv has been combined with. It
then cannot combine with any other giv. */
unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case, unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case,
we won't use it to eliminate a biv, it we won't use it to eliminate a biv, it
would probably lose. */ would probably lose. */
...@@ -96,6 +101,8 @@ struct induction ...@@ -96,6 +101,8 @@ struct induction
initialized in unrolled loop. */ initialized in unrolled loop. */
unsigned shared : 1; unsigned shared : 1;
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */ unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
unsigned derived : 1; /* For a giv, 1 if we decided to derive this
giv from another one. */
int lifetime; /* Length of life of this giv */ int lifetime; /* Length of life of this giv */
rtx derive_adjustment; /* If nonzero, is an adjustment to be rtx derive_adjustment; /* If nonzero, is an adjustment to be
subtracted from add_val when this giv subtracted from add_val when this giv
...@@ -112,10 +119,14 @@ struct induction ...@@ -112,10 +119,14 @@ struct induction
is split, and a constant is eliminated from is split, and a constant is eliminated from
the address, the -constant is stored here the address, the -constant is stored here
for later use. */ for later use. */
int ix; /* Used by recombine_givs, as n index into
the stats array. */
struct induction *same_insn; /* If there are multiple identical givs in struct induction *same_insn; /* If there are multiple identical givs in
the same insn, then all but one have this the same insn, then all but one have this
field set, and they all point to the giv field set, and they all point to the giv
that doesn't have this field set. */ that doesn't have this field set. */
rtx last_use; /* For a giv made from a biv increment, this is
a substitute for the lifetime information. */
}; };
/* A `struct iv_class' is created for each biv. */ /* A `struct iv_class' is created for each biv. */
...@@ -197,11 +208,19 @@ extern int max_reg_before_loop; ...@@ -197,11 +208,19 @@ extern int max_reg_before_loop;
extern FILE *loop_dump_stream; extern FILE *loop_dump_stream;
extern enum iv_mode *reg_iv_type; extern varray_type reg_iv_type;
extern struct induction **reg_iv_info; extern varray_type reg_iv_info;
#define REG_IV_TYPE(n) \
(*(enum iv_mode *) &VARRAY_INT(reg_iv_type, (n)))
#define REG_IV_INFO(n) \
(*(struct induction **) &VARRAY_GENERIC_PTR(reg_iv_info, (n)))
extern struct iv_class **reg_biv_class; extern struct iv_class **reg_biv_class;
extern struct iv_class *loop_iv_list; extern struct iv_class *loop_iv_list;
extern int first_increment_giv, last_increment_giv;
/* Forward declarations for non-static functions declared in loop.c and /* Forward declarations for non-static functions declared in loop.c and
unroll.c. */ unroll.c. */
int invariant_p PROTO((rtx)); int invariant_p PROTO((rtx));
......
...@@ -1008,6 +1008,7 @@ extern int reg_set_between_p PROTO((rtx, rtx, rtx)); ...@@ -1008,6 +1008,7 @@ extern int reg_set_between_p PROTO((rtx, rtx, rtx));
extern int regs_set_between_p PROTO((rtx, rtx, rtx)); extern int regs_set_between_p PROTO((rtx, rtx, rtx));
extern int modified_between_p PROTO((rtx, rtx, rtx)); extern int modified_between_p PROTO((rtx, rtx, rtx));
extern int no_labels_between_p PROTO((rtx, rtx)); extern int no_labels_between_p PROTO((rtx, rtx));
extern int no_jumps_between_p PROTO((rtx, rtx));
extern int modified_in_p PROTO((rtx, rtx)); extern int modified_in_p PROTO((rtx, rtx));
extern int reg_set_p PROTO((rtx, rtx)); extern int reg_set_p PROTO((rtx, rtx));
extern rtx single_set PROTO((rtx)); extern rtx single_set PROTO((rtx));
...@@ -1035,6 +1036,7 @@ extern rtx replace_regs PROTO((rtx, rtx *, int, int)); ...@@ -1035,6 +1036,7 @@ extern rtx replace_regs PROTO((rtx, rtx *, int, int));
extern int computed_jump_p PROTO((rtx)); extern int computed_jump_p PROTO((rtx));
typedef int (*rtx_function) PROTO((rtx *, void *)); typedef int (*rtx_function) PROTO((rtx *, void *));
extern int for_each_rtx PROTO((rtx *, rtx_function, void *)); extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
extern int insn_first_p PROTO((rtx, rtx));
/* flow.c */ /* flow.c */
......
...@@ -326,6 +326,20 @@ no_labels_between_p (beg, end) ...@@ -326,6 +326,20 @@ no_labels_between_p (beg, end)
return 1; return 1;
} }
/* Return 1 if in between BEG and END, exclusive of BEG and END, there is
no JUMP_INSN insn. */
int
no_jumps_between_p (beg, end)
rtx beg, end;
{
register rtx p;
for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
if (GET_CODE (p) == JUMP_INSN)
return 0;
return 1;
}
/* Nonzero if register REG is used in an insn between /* Nonzero if register REG is used in an insn between
FROM_INSN and TO_INSN (exclusive of those two). */ FROM_INSN and TO_INSN (exclusive of those two). */
...@@ -2187,3 +2201,20 @@ for_each_rtx (x, f, data) ...@@ -2187,3 +2201,20 @@ for_each_rtx (x, f, data)
return 0; return 0;
} }
/* INSN and REFERENCE are instructions in the same insn chain.
Return non-zero if INSN is first. */
int
insn_first_p (insn, reference)
rtx insn, reference;
{
rtx p, q;
for (p = insn, q = reference; ; p = NEXT_INSN (p), q = NEXT_INSN (q))
{
if (p == reference || ! q)
return 1;
if (q == insn || ! p)
return 0;
}
}
...@@ -180,6 +180,10 @@ static struct induction **addr_combined_regs; ...@@ -180,6 +180,10 @@ static struct induction **addr_combined_regs;
static rtx *splittable_regs; static rtx *splittable_regs;
/* Indexed by register number, if this is a splittable induction variable, /* 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 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 the induction variable. Used to ensure that only the last insn modifying
a split iv will update the original iv of the dest. */ a split iv will update the original iv of the dest. */
...@@ -761,16 +765,15 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -761,16 +765,15 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
splittable_regs = (rtx *) alloca (maxregnum * sizeof (rtx)); splittable_regs = (rtx *) alloca (maxregnum * sizeof (rtx));
bzero ((char *) splittable_regs, maxregnum * sizeof (rtx)); bzero ((char *) splittable_regs, maxregnum * sizeof (rtx));
derived_regs = alloca (maxregnum);
bzero (derived_regs, maxregnum);
splittable_regs_updates = (int *) alloca (maxregnum * sizeof (int)); splittable_regs_updates = (int *) alloca (maxregnum * sizeof (int));
bzero ((char *) splittable_regs_updates, maxregnum * sizeof (int)); bzero ((char *) splittable_regs_updates, maxregnum * sizeof (int));
addr_combined_regs addr_combined_regs
= (struct induction **) alloca (maxregnum * sizeof (struct induction *)); = (struct induction **) alloca (maxregnum * sizeof (struct induction *));
bzero ((char *) addr_combined_regs, maxregnum * sizeof (struct induction *)); bzero ((char *) addr_combined_regs, maxregnum * sizeof (struct induction *));
/* We must limit it to max_reg_before_loop, because only these pseudo local_regno = (char *) alloca (maxregnum);
registers have valid regno_first_uid info. Any register created after bzero (local_regno, maxregnum);
that is unlikely to be local to the loop anyways. */
local_regno = (char *) alloca (max_reg_before_loop);
bzero (local_regno, max_reg_before_loop);
/* Mark all local registers, i.e. the ones which are referenced only /* Mark all local registers, i.e. the ones which are referenced only
inside the loop. */ inside the loop. */
...@@ -793,6 +796,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -793,6 +796,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* If a pseudo's lifetime is entirely contained within this loop, then we /* If a pseudo's lifetime is entirely contained within this loop, then we
can use a different pseudo in each unrolled copy of the loop. This can use a different pseudo in each unrolled copy of the loop. This
results in better code. */ results in better code. */
/* We must limit the generic test to max_reg_before_loop, because only
these pseudo registers have valid regno_first_uid info. */
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; ++j) for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; ++j)
if (REGNO_FIRST_UID (j) > 0 && REGNO_FIRST_UID (j) <= max_uid_for_loop if (REGNO_FIRST_UID (j) > 0 && REGNO_FIRST_UID (j) <= max_uid_for_loop
&& uid_luid[REGNO_FIRST_UID (j)] >= copy_start_luid && uid_luid[REGNO_FIRST_UID (j)] >= copy_start_luid
...@@ -821,6 +826,14 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -821,6 +826,14 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
j); j);
} }
} }
/* Givs that have been created from multiple biv increments always have
local registers. */
for (j = first_increment_giv; j <= last_increment_giv; j++)
{
local_regno[j] = 1;
if (loop_dump_stream)
fprintf (loop_dump_stream, "Marked reg %d as local\n", j);
}
} }
/* If this loop requires exit tests when unrolled, check to see if we /* If this loop requires exit tests when unrolled, check to see if we
...@@ -1041,7 +1054,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -1041,7 +1054,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
if (local_label[j]) if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ()); set_label_in_map (map, j, gen_label_rtx ());
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) for (j = FIRST_PSEUDO_REGISTER; j < maxregnum; j++)
if (local_regno[j]) if (local_regno[j])
{ {
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
...@@ -1197,7 +1210,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -1197,7 +1210,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
if (local_label[j]) if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ()); set_label_in_map (map, j, gen_label_rtx ());
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) for (j = FIRST_PSEUDO_REGISTER; j < maxregnum; j++)
if (local_regno[j]) if (local_regno[j])
{ {
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
...@@ -1701,7 +1714,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1701,7 +1714,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
we might accidentally delete insns generated immediately we might accidentally delete insns generated immediately
below by emit_unrolled_add. */ below by emit_unrolled_add. */
giv_inc = calculate_giv_inc (set, insn, regno); if (! derived_regs[regno])
giv_inc = calculate_giv_inc (set, insn, regno);
/* Now find all address giv's that were combined with this /* Now find all address giv's that were combined with this
giv 'v'. */ giv 'v'. */
...@@ -1780,16 +1794,25 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1780,16 +1794,25 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
&& splittable_regs[REGNO (SET_DEST (set))]) && splittable_regs[REGNO (SET_DEST (set))])
{ {
int regno = REGNO (SET_DEST (set)); int regno = REGNO (SET_DEST (set));
int src_regno;
dest_reg_was_split = 1; dest_reg_was_split = 1;
/* 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_dest_reg = SET_DEST (set); giv_dest_reg = SET_DEST (set);
giv_src_reg = SET_DEST (set); if (derived_regs[regno])
{
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);
}
src_regno = REGNO (giv_src_reg);
if (unroll_type == UNROLL_COMPLETELY) if (unroll_type == UNROLL_COMPLETELY)
{ {
...@@ -1799,7 +1822,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1799,7 +1822,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
/* The value in splittable_regs may be an invariant /* The value in splittable_regs may be an invariant
value, so we must use plus_constant here. */ value, so we must use plus_constant here. */
splittable_regs[regno] splittable_regs[regno]
= plus_constant (splittable_regs[regno], INTVAL (giv_inc)); = plus_constant (splittable_regs[src_regno],
INTVAL (giv_inc));
if (GET_CODE (splittable_regs[regno]) == PLUS) if (GET_CODE (splittable_regs[regno]) == PLUS)
{ {
...@@ -1830,7 +1854,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1830,7 +1854,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
induction entry by find_splittable_regs. */ induction entry by find_splittable_regs. */
if (regno < max_reg_before_loop if (regno < max_reg_before_loop
&& reg_iv_type[regno] == BASIC_INDUCT) && REG_IV_TYPE (regno) == BASIC_INDUCT)
{ {
giv_src_reg = reg_biv_class[regno]->biv->src_reg; giv_src_reg = reg_biv_class[regno]->biv->src_reg;
giv_dest_reg = giv_src_reg; giv_dest_reg = giv_src_reg;
...@@ -1844,7 +1868,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1844,7 +1868,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
splittable_regs[regno] splittable_regs[regno]
= GEN_INT (INTVAL (giv_inc) = GEN_INT (INTVAL (giv_inc)
+ INTVAL (splittable_regs[regno])); + INTVAL (splittable_regs[src_regno]));
giv_inc = splittable_regs[regno]; giv_inc = splittable_regs[regno];
/* Now split the induction variable by changing the dest /* Now split the induction variable by changing the dest
...@@ -2338,7 +2362,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) ...@@ -2338,7 +2362,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
/* If this is a new register, can't handle it since we don't have any /* If this is a new register, can't handle it since we don't have any
reg_iv_type entry for it. */ reg_iv_type entry for it. */
if (REGNO (iteration_var) >= max_reg_before_loop) if ((unsigned) REGNO (iteration_var) > reg_iv_type->num_elements)
{ {
if (loop_dump_stream) if (loop_dump_stream)
fprintf (loop_dump_stream, fprintf (loop_dump_stream,
...@@ -2364,7 +2388,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) ...@@ -2364,7 +2388,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
"Loop unrolling: Iteration var not an integer.\n"); "Loop unrolling: Iteration var not an integer.\n");
return; return;
} }
else if (reg_iv_type[REGNO (iteration_var)] == BASIC_INDUCT) else if (REG_IV_TYPE (REGNO (iteration_var)) == BASIC_INDUCT)
{ {
/* Grab initial value, only useful if it is a constant. */ /* Grab initial value, only useful if it is a constant. */
bl = reg_biv_class[REGNO (iteration_var)]; bl = reg_biv_class[REGNO (iteration_var)];
...@@ -2372,7 +2396,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) ...@@ -2372,7 +2396,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
*increment = biv_total_increment (bl, loop_start, loop_end); *increment = biv_total_increment (bl, loop_start, loop_end);
} }
else if (reg_iv_type[REGNO (iteration_var)] == GENERAL_INDUCT) else if (REG_IV_TYPE (REGNO (iteration_var)) == GENERAL_INDUCT)
{ {
#if 1 #if 1
/* ??? The code below does not work because the incorrect number of /* ??? The code below does not work because the incorrect number of
...@@ -2390,7 +2414,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) ...@@ -2390,7 +2414,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
#else #else
/* Initial value is mult_val times the biv's initial value plus /* Initial value is mult_val times the biv's initial value plus
add_val. Only useful if it is a constant. */ add_val. Only useful if it is a constant. */
v = reg_iv_info[REGNO (iteration_var)]; v = REG_IV_INFO (REGNO (iteration_var));
bl = reg_biv_class[REGNO (v->src_reg)]; bl = reg_biv_class[REGNO (v->src_reg)];
*initial_value = fold_rtx_mult_add (v->mult_val, bl->initial_value, *initial_value = fold_rtx_mult_add (v->mult_val, bl->initial_value,
v->add_val, v->mode); v->add_val, v->mode);
...@@ -2708,6 +2732,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2708,6 +2732,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
/* Line above always fails if INSN was moved by loop opt. */ /* Line above always fails if INSN was moved by loop opt. */
|| (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))] || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))]
>= INSN_LUID (loop_end))) >= INSN_LUID (loop_end)))
/* Givs made from biv increments are missed by the above test, so
test explicitly for them. */
&& (REGNO (v->dest_reg) < first_increment_giv
|| REGNO (v->dest_reg) > last_increment_giv)
&& ! (final_value = v->final_value)) && ! (final_value = v->final_value))
continue; continue;
...@@ -2808,6 +2836,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2808,6 +2836,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
} }
splittable_regs[REGNO (v->new_reg)] = value; splittable_regs[REGNO (v->new_reg)] = value;
derived_regs[REGNO (v->new_reg)] = v->derived;
} }
else else
{ {
...@@ -2991,6 +3020,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2991,6 +3020,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
Make sure that it's giv is marked as splittable here. */ Make sure that it's giv is marked as splittable here. */
splittable_regs[REGNO (v->new_reg)] = value; splittable_regs[REGNO (v->new_reg)] = value;
derived_regs[REGNO (v->new_reg)] = v->derived;
/* Make it appear to depend upon itself, so that the /* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */ giv will be properly split in the main loop above. */
...@@ -3902,7 +3932,7 @@ remap_split_bivs (x) ...@@ -3902,7 +3932,7 @@ remap_split_bivs (x)
have to remap those givs also. */ have to remap those givs also. */
#endif #endif
if (REGNO (x) < max_reg_before_loop if (REGNO (x) < max_reg_before_loop
&& reg_iv_type[REGNO (x)] == BASIC_INDUCT) && REG_IV_TYPE (REGNO (x)) == BASIC_INDUCT)
return reg_biv_class[REGNO (x)]->biv->src_reg; return reg_biv_class[REGNO (x)]->biv->src_reg;
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment