This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]