This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: scheduler bug fixes
- From: Dale Johannesen <dalej at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Dale Johannesen <dalej at apple dot com>
- Date: Thu, 31 Oct 2002 10:44:29 -0800
- Subject: Patch: scheduler bug fixes
(These are bugs in the sense that the code didn't work as obviously
intended. Darwin ppc SPEC timings are rather variable, but it looks
like
there's a real pickup in the 1-2% range on vpr, gcc, mcf, perlbmk,
twolf.
Your machine may differ of course.)
#1: the INSN_REG_WEIGHT computation is not allowing for the case where
an input register is reused as output. You don't want to increment
the weight (a crude measure of register pressure) in this case.
#2: after each insn is scheduled, the ready list needs to be resorted;
processing the insn may have added extra insns to the end of the ready
list,
and it will not in general be sorted correctly at this point.
Previously
this was done only when reorder2 was defined.
Bootstrapped and tested on darwin.
Index: haifa-sched.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/haifa-sched.c,v
retrieving revision 1.213
diff -u -d -b -w -c -3 -p -r1.213 haifa-sched.c
*** haifa-sched.c 28 Sep 2002 15:29:34 -0000 1.213
--- haifa-sched.c 31 Oct 2002 18:29:59 -0000
*************** rm_other_notes (head, tail)
*** 1534,1539 ****
--- 1534,1565 ----
/* Functions for computation of registers live/usage info. */
+ /* This function looks for a new register being defined.
+ If the destination register is already used by the source,
+ a new register is not needed. */
+
+ static int
+ find_set_reg_weight (x)
+ rtx x;
+ {
+ if (GET_CODE (x) == CLOBBER
+ && register_operand (SET_DEST (x), VOIDmode))
+ return 1;
+ if (GET_CODE (x) == SET
+ && register_operand (SET_DEST (x), VOIDmode))
+ {
+ if (GET_CODE (SET_DEST (x)) == REG)
+ {
+ if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
+ return 1;
+ else
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+ }
+
/* Calculate INSN_REG_WEIGHT for all insns of a block. */
static void
*************** find_insn_reg_weight (b)
*** 1556,1573 ****
/* Increment weight for each register born here. */
x = PATTERN (insn);
! if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
! && register_operand (SET_DEST (x), VOIDmode))
! reg_weight++;
! else if (GET_CODE (x) == PARALLEL)
{
int j;
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
{
x = XVECEXP (PATTERN (insn), 0, j);
! if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
! && register_operand (SET_DEST (x), VOIDmode))
! reg_weight++;
}
}
--- 1582,1595 ----
/* Increment weight for each register born here. */
x = PATTERN (insn);
! reg_weight += find_set_reg_weight(x);
! if (GET_CODE (x) == PARALLEL)
{
int j;
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
{
x = XVECEXP (PATTERN (insn), 0, j);
! reg_weight += find_set_reg_weight(x);
}
}
*************** schedule_block (b, rgn_n_insns)
*** 2170,2180 ****
next:
first_cycle_insn_p = 0;
! if (targetm.sched.reorder2)
! {
! /* Sort the ready list based on priority. */
if (ready.n_ready > 0)
ready_sort (&ready);
can_issue_more =
(*targetm.sched.reorder2) (sched_dump,sched_verbose,
ready.n_ready
--- 2192,2205 ----
next:
first_cycle_insn_p = 0;
! /* Sort the ready list based on priority. This must
! be redone here, as schedule_insn may have readied
! additional insns that will not be sorted correctly. */
if (ready.n_ready > 0)
ready_sort (&ready);
+
+ if (targetm.sched.reorder2)
+ {
can_issue_more =
(*targetm.sched.reorder2) (sched_dump,sched_verbose,
ready.n_ready