Loop movables patch
Michael Hayes
mhayes@redhat.com
Sun Dec 31 03:07:00 GMT 2000
The purpose of this patch is to allow a number of independent loops
to be optimised at the same time. It also gets rid of another global
variable :-) Tested by bootstrapping gcc for i686-pc-gnu-linux.
2000-12-27 Michael Hayes <mhayes@redhat.com>
* loop.h (struct loop_movables): New.
(LOOP_MOVABLES): New.
(struct loop_info): Add movables field.
* loop.c (struct movables): Delete. Replace all uses
with struct loop_movables.
(the_movables): Delete. Replace all uses with movables
field in loop_info.
(loop_movables_add, loop_movables_free): New functions.
(scan_loop): Use xmalloc instead of alloca for movables.
Call loop_movables_free.
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.299
diff -c -3 -p -r1.299 loop.c
*** loop.c 2000/11/30 06:31:17 1.299
--- loop.c 2000/12/27 03:40:54
*************** struct movable
*** 132,148 ****
struct movable *next;
};
- struct movables
- {
- /* Head of movable chain. */
- struct movable *head;
- /* Last movable in chain. */
- struct movable *last;
- /* Number of movables in the loop. */
- int num;
- };
-
- static struct movables the_movables;
FILE *loop_dump_stream;
--- 132,137 ----
*************** static void replace_call_address PARAMS
*** 170,184 ****
#endif
static rtx skip_consec_insns PARAMS ((rtx, int));
static int libcall_benefit PARAMS ((rtx));
! static void ignore_some_movables PARAMS ((struct movables *));
! static void force_movables PARAMS ((struct movables *));
! static void combine_movables PARAMS ((struct movables *, struct loop_regs *));
! static int regs_match_p PARAMS ((rtx, rtx, struct movables *));
! static int rtx_equal_for_loop_p PARAMS ((rtx, rtx, struct movables *,
struct loop_regs *));
static void add_label_notes PARAMS ((rtx, rtx));
! static void move_movables PARAMS ((struct loop *loop, struct movables *,
int, int));
static int count_nonfixed_reads PARAMS ((const struct loop *, rtx));
static void strength_reduce PARAMS ((struct loop *, int, int));
static void find_single_use_in_loop PARAMS ((rtx, rtx, varray_type));
--- 159,177 ----
#endif
static rtx skip_consec_insns PARAMS ((rtx, int));
static int libcall_benefit PARAMS ((rtx));
! static void ignore_some_movables PARAMS ((struct loop_movables *));
! static void force_movables PARAMS ((struct loop_movables *));
! static void combine_movables PARAMS ((struct loop_movables *,
! struct loop_regs *));
! static int regs_match_p PARAMS ((rtx, rtx, struct loop_movables *));
! static int rtx_equal_for_loop_p PARAMS ((rtx, rtx, struct loop_movables *,
struct loop_regs *));
static void add_label_notes PARAMS ((rtx, rtx));
! static void move_movables PARAMS ((struct loop *loop, struct loop_movables *,
int, int));
+ static void loop_movables_add PARAMS((struct loop_movables *,
+ struct movable *));
+ static void loop_movables_free PARAMS((struct loop_movables *));
static int count_nonfixed_reads PARAMS ((const struct loop *, rtx));
static void strength_reduce PARAMS ((struct loop *, int, int));
static void find_single_use_in_loop PARAMS ((rtx, rtx, varray_type));
*************** scan_loop (loop, flags)
*** 516,522 ****
/* The SET from an insn, if it is the only SET in the insn. */
rtx set, set1;
/* Chain describing insns movable in current loop. */
! struct movables *movables = &the_movables;
/* Ratio of extra register life span we can justify
for saving an instruction. More if loop doesn't call subroutines
since in that case saving an insn makes more difference
--- 509,515 ----
/* The SET from an insn, if it is the only SET in the insn. */
rtx set, set1;
/* Chain describing insns movable in current loop. */
! struct loop_movables *movables = LOOP_MOVABLES (loop);
/* Ratio of extra register life span we can justify
for saving an instruction. More if loop doesn't call subroutines
since in that case saving an insn makes more difference
*************** scan_loop (loop, flags)
*** 808,814 ****
continue;
}
! m = (struct movable *) alloca (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_src = src;
--- 801,807 ----
continue;
}
! m = (struct movable *) xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_src = src;
*************** scan_loop (loop, flags)
*** 840,850 ****
m->savings += libcall_benefit (p);
VARRAY_INT (regs->set_in_loop, regno) = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
! if (movables->head == 0)
! movables->head = m;
! else
! movables->last->next = m;
! movables->last = m;
if (m->consec > 0)
{
--- 833,839 ----
m->savings += libcall_benefit (p);
VARRAY_INT (regs->set_in_loop, regno) = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
! loop_movables_add (movables, m);
if (m->consec > 0)
{
*************** scan_loop (loop, flags)
*** 949,959 ****
m->savings = 1;
VARRAY_INT (regs->set_in_loop, regno) = -1;
/* Add M to the end of the chain MOVABLES. */
! if (movables->head == 0)
! movables->head = m;
! else
! movables->last->next = m;
! movables->last = m;
}
}
}
--- 938,944 ----
m->savings = 1;
VARRAY_INT (regs->set_in_loop, regno) = -1;
/* Add M to the end of the chain MOVABLES. */
! loop_movables_add (movables, m);
}
}
}
*************** scan_loop (loop, flags)
*** 1056,1061 ****
--- 1041,1050 ----
delete_insn (update_end);
}
+
+ /* The movable information is required for strength reduction. */
+ loop_movables_free (movables);
+
VARRAY_FREE (regs->single_usage);
VARRAY_FREE (regs->set_in_loop);
VARRAY_FREE (regs->n_times_set);
*************** skip_consec_insns (insn, count)
*** 1255,1261 ****
static void
ignore_some_movables (movables)
! struct movables *movables;
{
register struct movable *m, *m1;
--- 1244,1250 ----
static void
ignore_some_movables (movables)
! struct loop_movables *movables;
{
register struct movable *m, *m1;
*************** ignore_some_movables (movables)
*** 1287,1293 ****
static void
force_movables (movables)
! struct movables *movables;
{
register struct movable *m, *m1;
for (m1 = movables->head; m1; m1 = m1->next)
--- 1276,1282 ----
static void
force_movables (movables)
! struct loop_movables *movables;
{
register struct movable *m, *m1;
for (m1 = movables->head; m1; m1 = m1->next)
*************** force_movables (movables)
*** 1326,1332 ****
static void
combine_movables (movables, regs)
! struct movables *movables;
struct loop_regs *regs;
{
register struct movable *m;
--- 1315,1321 ----
static void
combine_movables (movables, regs)
! struct loop_movables *movables;
struct loop_regs *regs;
{
register struct movable *m;
*************** combine_movables (movables, regs)
*** 1446,1452 ****
static int
regs_match_p (x, y, movables)
rtx x, y;
! struct movables *movables;
{
unsigned int xn = REGNO (x);
unsigned int yn = REGNO (y);
--- 1435,1441 ----
static int
regs_match_p (x, y, movables)
rtx x, y;
! struct loop_movables *movables;
{
unsigned int xn = REGNO (x);
unsigned int yn = REGNO (y);
*************** regs_match_p (x, y, movables)
*** 1475,1481 ****
static int
rtx_equal_for_loop_p (x, y, movables, regs)
rtx x, y;
! struct movables *movables;
struct loop_regs *regs;
{
register int i;
--- 1464,1470 ----
static int
rtx_equal_for_loop_p (x, y, movables, regs)
rtx x, y;
! struct loop_movables *movables;
struct loop_regs *regs;
{
register int i;
*************** add_label_notes (x, insns)
*** 1632,1638 ****
static void
move_movables (loop, movables, threshold, insn_count)
struct loop *loop;
! struct movables *movables;
int threshold;
int insn_count;
{
--- 1621,1627 ----
static void
move_movables (loop, movables, threshold, insn_count)
struct loop *loop;
! struct loop_movables *movables;
int threshold;
int insn_count;
{
*************** move_movables (loop, movables, threshold
*** 2135,2140 ****
--- 2124,2157 ----
free (reg_map);
free (already_moved);
}
+
+
+ static void
+ loop_movables_add (movables, m)
+ struct loop_movables *movables;
+ struct movable *m;
+ {
+ if (movables->head == 0)
+ movables->head = m;
+ else
+ movables->last->next = m;
+ movables->last = m;
+ }
+
+
+ static void
+ loop_movables_free (movables)
+ struct loop_movables *movables;
+ {
+ struct movable *m;
+ struct movable *m_next;
+
+ for (m = movables->head; m; m = m_next)
+ {
+ m_next = m->next;
+ free (m);
+ }
+ }
#if 0
/* Scan X and replace the address of any MEM in it with ADDR.
*************** simplify_giv_expr (loop, x, ext_val, ben
*** 6019,6026 ****
if (loop_invariant_p (loop, x) == 1)
{
struct movable *m;
! for (m = the_movables.head; m; m = m->next)
if (rtx_equal_p (x, m->set_dest))
{
/* Ok, we found a match. Substitute and simplify. */
--- 6036,6044 ----
if (loop_invariant_p (loop, x) == 1)
{
struct movable *m;
+ struct loop_movables *movables = LOOP_MOVABLES (loop);
! for (m = movables->head; m; m = m->next)
if (rtx_equal_p (x, m->set_dest))
{
/* Ok, we found a match. Substitute and simplify. */
*************** check_dbra_loop (loop, insn_count)
*** 7316,7322 ****
&& ! loop_info->has_volatile
&& reversible_mem_store
&& (bl->giv_count + bl->biv_count + loop_info->num_mem_sets
! + the_movables.num + compare_and_branch == insn_count)
&& (bl == ivs->loop_iv_list && bl->next == 0))
|| no_use_except_counting)
{
--- 7334,7340 ----
&& ! loop_info->has_volatile
&& reversible_mem_store
&& (bl->giv_count + bl->biv_count + loop_info->num_mem_sets
! + LOOP_MOVABLES (loop)->num + compare_and_branch == insn_count)
&& (bl == ivs->loop_iv_list && bl->next == 0))
|| no_use_except_counting)
{
Index: loop.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 loop.h
*** loop.h 2000/09/19 16:01:13 1.40
--- loop.h 2000/12/27 03:40:54
*************** Boston, MA 02111-1307, USA. */
*** 28,33 ****
--- 28,36 ----
/* Get the loop info pointer of a loop. */
#define LOOP_INFO(LOOP) ((struct loop_info *) (LOOP)->aux)
+ /* Get a pointer to the loop movables structure. */
+ #define LOOP_MOVABLES(LOOP) (&LOOP_INFO (loop)->movables)
+
/* Get a pointer to the loop registers structure. */
#define LOOP_REGS(LOOP) (&LOOP_INFO (loop)->regs)
*************** struct loop_regs
*** 236,247 ****
--- 239,266 ----
int multiple_uses;
};
+
+ struct loop_movables
+ {
+ /* Head of movable chain. */
+ struct movable *head;
+ /* Last movable in chain. */
+ struct movable *last;
+ /* Number of movables in the loop. */
+ int num;
+ };
+
+
/* Information pertaining to a loop. */
struct loop_info
{
/* Nonzero if there is a subroutine call in the current loop. */
int has_call;
+ /* Nonzero if there is a libcall in the current loop. */
+ int has_libcall;
+ /* Nonzero if there is a non constant call in the current loop. */
+ int has_nonconst_call;
/* Nonzero if there is a volatile memory reference in the current
loop. */
int has_volatile;
*************** struct loop_info
*** 304,309 ****
--- 323,330 ----
int num_mem_sets;
/* The insn where the first of these was found. */
rtx first_loop_store_insn;
+ /* The chain of movable insns in loop. */
+ struct loop_movables movables;
/* The registers used the in loop. */
struct loop_regs regs;
/* The induction variable information in loop. */
More information about the Gcc-patches
mailing list