This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH / RFA]: Load hoisting fix
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 Dec 2001 11:08:08 -0500
- Subject: [PATCH / RFA]: Load hoisting fix
With my last message I did not make it clear that I was submitting
the patch for approval. As mentioned yesterday, the patch has been
bootstrapped on both powerpc-ibm-aix4.3.3.0 and i686-pc-linux-gnu with no
new regressions. This fixes the divconst-3.c regressions on AIX.
Thanks, David
* loop.c (scan_loop, move_movables, count_one_set): Do not
overlook hard registers when computing statistics.
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.372
diff -c -p -r1.372 loop.c
*** loop.c 2001/12/13 14:23:21 1.372
--- loop.c 2001/12/17 18:52:17
*************** scan_loop (loop, flags)
*** 607,613 ****
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
! int i;
rtx loop_start = loop->start;
rtx loop_end = loop->end;
rtx p;
--- 607,613 ----
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
! int i, nregs;
rtx loop_start = loop->start;
rtx loop_end = loop->end;
rtx p;
*************** scan_loop (loop, flags)
*** 893,899 ****
SET_DEST (set), copy_rtx (SET_SRC (set)));
delete_insn (p);
! regs->array[regno].set_in_loop = 0;
continue;
}
--- 893,903 ----
SET_DEST (set), copy_rtx (SET_SRC (set)));
delete_insn (p);
! nregs = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! : 1;
! for (i = 0; i < nregs; i++)
! regs->array[regno+i].set_in_loop = 0;
continue;
}
*************** scan_loop (loop, flags)
*** 923,929 ****
m->savings = regs->array[regno].n_times_set;
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
m->savings += libcall_benefit (p);
! regs->array[regno].set_in_loop = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
--- 927,937 ----
m->savings = regs->array[regno].n_times_set;
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
m->savings += libcall_benefit (p);
! nregs = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! : 1;
! for (i = 0; i < nregs; i++)
! regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
*************** scan_loop (loop, flags)
*** 1024,1030 ****
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
m->savings = 1;
! regs->array[regno].set_in_loop = -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
}
--- 1032,1042 ----
m->match = 0;
m->lifetime = LOOP_REG_LIFETIME (loop, regno);
m->savings = 1;
! nregs = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! : 1;
! for (i = 0; i < nregs; i++)
! regs->array[regno+i].set_in_loop = -1;
/* Add M to the end of the chain MOVABLES. */
loop_movables_add (movables, m);
}
*************** move_movables (loop, movables, threshold
*** 2145,2151 ****
/* The reg set here is now invariant. */
if (! m->partial)
! regs->array[regno].set_in_loop = 0;
m->done = 1;
--- 2157,2169 ----
/* The reg set here is now invariant. */
if (! m->partial)
! {
! int i, n = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (m->set_dest))
! : 1;
! for (i = 0; i < n; i++)
! regs->array[regno+i].set_in_loop = 0;
! }
m->done = 1;
*************** move_movables (loop, movables, threshold
*** 2205,2211 ****
/* The reg merged here is now invariant,
if the reg it matches is invariant. */
if (! m->partial)
! regs->array[m1->regno].set_in_loop = 0;
}
}
else if (loop_dump_stream)
--- 2223,2235 ----
/* The reg merged here is now invariant,
if the reg it matches is invariant. */
if (! m->partial)
! {
! int i, n = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (m1->set_dest))
! : 1;
! for (i = 0; i < n; i++)
! regs->array[m1->regno+i].set_in_loop = 0;
! }
}
}
else if (loop_dump_stream)
*************** count_one_set (regs, insn, x, last_set)
*** 3445,3467 ****
dest = XEXP (dest, 0);
if (GET_CODE (dest) == REG)
{
int regno = REGNO (dest);
! /* If this is the first setting of this reg
! in current basic block, and it was set before,
! it must be set in two basic blocks, so it cannot
! be moved out of the loop. */
! if (regs->array[regno].set_in_loop > 0
! && last_set == 0)
! regs->array[regno].may_not_optimize = 1;
! /* If this is not first setting in current basic block,
! see if reg was used in between previous one and this.
! If so, neither one can be moved. */
! if (last_set[regno] != 0
! && reg_used_between_p (dest, last_set[regno], insn))
! regs->array[regno].may_not_optimize = 1;
! if (regs->array[regno].set_in_loop < 127)
! ++regs->array[regno].set_in_loop;
! last_set[regno] = insn;
}
}
}
--- 3469,3498 ----
dest = XEXP (dest, 0);
if (GET_CODE (dest) == REG)
{
+ int i;
int regno = REGNO (dest);
! int nregs = regno < FIRST_PSEUDO_REGISTER
! ? HARD_REGNO_NREGS (regno, GET_MODE (dest))
! : 1;
! for (i = 0; i < nregs; i++)
! {
! /* If this is the first setting of this reg
! in current basic block, and it was set before,
! it must be set in two basic blocks, so it cannot
! be moved out of the loop. */
! if (regs->array[regno].set_in_loop > 0
! && last_set == 0)
! regs->array[regno+i].may_not_optimize = 1;
! /* If this is not first setting in current basic block,
! see if reg was used in between previous one and this.
! If so, neither one can be moved. */
! if (last_set[regno] != 0
! && reg_used_between_p (dest, last_set[regno], insn))
! regs->array[regno+i].may_not_optimize = 1;
! if (regs->array[regno+i].set_in_loop < 127)
! ++regs->array[regno+i].set_in_loop;
! last_set[regno+i] = insn;
! }
}
}
}