This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH to hoist loads/stores out of loops
On Mon, Jul 20, 1998 at 05:19:59PM -0700, Mark Mitchell wrote:
> Actually, the code I submitted does do this. What, you say, it didn't
> when you tried it? Oops, I forgot to tell you that I haven't yet
> implemented C's `restrict'.
Following up on my own message (which hasn't shown up yet) looking
at the actual code rather than the patch brings to my attention that
load_mems is run before movables are found and moved. Duh.
Just moving the call of load_mem to the end of scan_loop as pictured
below, was enough to get Toon's test case to work. Also cleaned is
the REG_USERVAR_P nonsense, since we now happen after moveables.
I don't know if calling record_base_value is helpful or not. The only
time it would matter is if your induced value were used in an address,
and I can't immediately come up with a way that could occur directly.
r~
--- loop.c.mm Tue Jul 21 00:32:36 1998
+++ loop.c Tue Jul 21 00:55:16 1998
@@ -781,35 +781,6 @@ scan_loop (loop_start, end, unroll_p)
may_not_optimize[i] = 1, n_times_set[i] = 1;
bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (int));
- /* Load MEMs into REGs for the duration of the loop, if
- appropriate. Note that calculate n_times_set, etc., before this
- point so that we can tell what things are loop-invariant in
- load_mems. */
- load_mems (scan_start, end, loop_top, loop_start);
-
- /* Recalculate n_times_set and friends since load_mems may have
- created new registers. */
- if (max_reg_num () > nregs - loop_mems_idx)
- {
- bzero ((char *) n_times_set, nregs * sizeof (int));
- bzero (may_not_optimize, nregs);
- if (loop_has_call)
- bzero ((char *) reg_single_usage, nregs * sizeof (rtx));
-
- count_loop_regs_set (loop_top ? loop_top : loop_start, end,
- may_not_optimize, reg_single_usage,
- &insn_count, nregs);
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- may_not_optimize[i] = 1, n_times_set[i] = 1;
- bcopy ((char *) n_times_set, (char *) n_times_used,
- nregs * sizeof (int));
-
- /* Set nregs to reflect the real number of registers. There's no
- need to include any extra slop. */
- nregs = max_reg_num ();
- }
-
if (loop_dump_stream)
{
fprintf (loop_dump_stream, "\nLoop from %d to %d: %d real insns.\n",
@@ -1182,6 +1153,11 @@ scan_loop (loop_start, end, unroll_p)
if (n_times_set[i] < 0)
n_times_set[i] = n_times_used[i];
+ /* Load MEMs into REGs for the duration of the loop, if appropriate.
+ Note that the adjust of n_times_set is before this point so that
+ we can tell what things are loop-invariant in load_mems. */
+ load_mems (scan_start, end, loop_top, loop_start);
+
if (flag_strength_reduce)
{
the_movables = movables;
@@ -8534,13 +8510,12 @@ load_mems (scan_start, end, loop_top, st
loop, but later discovered that we could not. */
continue;
- /* Allocate a pseudo for this MEM. We set REG_USERVAR_P in
- order to keep scan_loop from moving stores to this MEM
- out of the loop just because this REG is neither a
- user-variable nor used in the loop test. */
+ /* Allocate a pseudo for this MEM. Initialize n_times_set for
+ this reg; note that it is zero by design -- our one set is
+ outside the loop under consideration. */
reg = gen_reg_rtx (GET_MODE (mem));
- REG_USERVAR_P (reg) = 1;
loop_mems[i].reg = reg;
+ n_times_set[REGNO (reg)] = 0;
/* Now, replace all references to the MEM with the
corresponding pesudos. */
@@ -8580,6 +8555,14 @@ load_mems (scan_start, end, loop_top, st
the NOTE_LOOP_END. */
set = gen_rtx_SET (GET_MODE (reg), mem, reg);
emit_insn_after (set, label);
+ }
+
+ if (loop_dump_stream)
+ {
+ fprintf (loop_dump_stream, "Hoisted regno %d %s from ",
+ REGNO (reg), (written ? "r/w" : "r/o"));
+ print_rtl (loop_dump_stream, mem);
+ fputc ('\n', loop_dump_stream);
}
}
}