Commit 176f9a7b by Bernd Schmidt Committed by Bernd Schmidt

Treat ready list as a (for now, semi-)abstract datatype. Lose max_priority.

From-SVN: r37710
parent 222de5be
2000-11-24 Bernd Schmidt <bernds@redhat.co.uk> 2000-11-24 Bernd Schmidt <bernds@redhat.co.uk>
* haifa-sched.c (struct ready_list): New.
(ready_lastpos, ready_add, ready_remove_first, ready_sort): New static
functions.
(schedule_insn): Replace args READY and N_READY with a pointer to a
ready_list; return void. Use the new functions to access the ready
list. All callers changed.
(queue_to_ready, debug_ready_list): Likewise.
(schedule_block): Initialize a ready_list structure. Use new
functions to access it.
(max_priority): Remove unused variable.
(schedule_insn): Don't set it.
* c-common.c (verify_tree): Don't recurse into CONSTRUCTORs. * c-common.c (verify_tree): Don't recurse into CONSTRUCTORs.
* combine.c (cant_combine_insn_p): New function. * combine.c (cant_combine_insn_p): New function.
......
...@@ -477,6 +477,22 @@ static int q_size = 0; ...@@ -477,6 +477,22 @@ static int q_size = 0;
#define NEXT_Q(X) (((X)+1) & (INSN_QUEUE_SIZE-1)) #define NEXT_Q(X) (((X)+1) & (INSN_QUEUE_SIZE-1))
#define NEXT_Q_AFTER(X, C) (((X)+C) & (INSN_QUEUE_SIZE-1)) #define NEXT_Q_AFTER(X, C) (((X)+C) & (INSN_QUEUE_SIZE-1))
/* Describe the ready list of the scheduler.
VEC holds space enough for all insns in the current region. VECLEN
says how many exactly.
FIRST is the index of the element with the highest priority; i.e. the
last one in the ready list, since elements are ordered by ascending
priority.
N_READY determines how many insns are on the ready list. */
struct ready_list
{
rtx *vec;
int veclen;
int first;
int n_ready;
};
/* Forward declarations. */ /* Forward declarations. */
static void add_dependence PARAMS ((rtx, rtx, enum reg_note)); static void add_dependence PARAMS ((rtx, rtx, enum reg_note));
static void remove_dependence PARAMS ((rtx, rtx)); static void remove_dependence PARAMS ((rtx, rtx));
...@@ -502,7 +518,7 @@ static void sched_analyze PARAMS ((struct deps *, rtx, rtx)); ...@@ -502,7 +518,7 @@ static void sched_analyze PARAMS ((struct deps *, rtx, rtx));
static int rank_for_schedule PARAMS ((const PTR, const PTR)); static int rank_for_schedule PARAMS ((const PTR, const PTR));
static void swap_sort PARAMS ((rtx *, int)); static void swap_sort PARAMS ((rtx *, int));
static void queue_insn PARAMS ((rtx, int)); static void queue_insn PARAMS ((rtx, int));
static int schedule_insn PARAMS ((rtx, rtx *, int, int)); static void schedule_insn PARAMS ((rtx, struct ready_list *, int));
static void find_insn_reg_weight PARAMS ((int)); static void find_insn_reg_weight PARAMS ((int));
static int schedule_block PARAMS ((int, int)); static int schedule_block PARAMS ((int, int));
static char *safe_concat PARAMS ((char *, char *, const char *)); static char *safe_concat PARAMS ((char *, char *, const char *));
...@@ -773,9 +789,14 @@ static rtx reemit_notes PARAMS ((rtx, rtx)); ...@@ -773,9 +789,14 @@ static rtx reemit_notes PARAMS ((rtx, rtx));
static void get_block_head_tail PARAMS ((int, rtx *, rtx *)); static void get_block_head_tail PARAMS ((int, rtx *, rtx *));
static void get_bb_head_tail PARAMS ((int, rtx *, rtx *)); static void get_bb_head_tail PARAMS ((int, rtx *, rtx *));
static int queue_to_ready PARAMS ((rtx[], int)); static void ready_add PARAMS ((struct ready_list *, rtx));
static rtx *ready_lastpos PARAMS ((struct ready_list *));
static void ready_sort PARAMS ((struct ready_list *));
static rtx ready_remove_first PARAMS ((struct ready_list *));
static void queue_to_ready PARAMS ((struct ready_list *));
static void debug_ready_list PARAMS ((rtx[], int)); static void debug_ready_list PARAMS ((struct ready_list *));
static void init_target_units PARAMS ((void)); static void init_target_units PARAMS ((void));
static void insn_print_units PARAMS ((rtx)); static void insn_print_units PARAMS ((rtx));
static int get_visual_tbl_length PARAMS ((void)); static int get_visual_tbl_length PARAMS ((void));
...@@ -4184,8 +4205,6 @@ swap_sort (a, n) ...@@ -4184,8 +4205,6 @@ swap_sort (a, n)
a[i + 1] = insn; a[i + 1] = insn;
} }
static int max_priority;
/* Add INSN to the insn queue so that it can be executed at least /* Add INSN to the insn queue so that it can be executed at least
N_CYCLES after the currently executing insn. Preserve insns N_CYCLES after the currently executing insn. Preserve insns
chain for debugging purposes. */ chain for debugging purposes. */
...@@ -4209,7 +4228,66 @@ queue_insn (insn, n_cycles) ...@@ -4209,7 +4228,66 @@ queue_insn (insn, n_cycles)
fprintf (dump, "queued for %d cycles.\n", n_cycles); fprintf (dump, "queued for %d cycles.\n", n_cycles);
} }
}
/* Return a pointer to the bottom of the ready list, i.e. the insn
with the lowest priority. */
HAIFA_INLINE static rtx *
ready_lastpos (ready)
struct ready_list *ready;
{
if (ready->n_ready == 0)
abort ();
return ready->vec + ready->first - ready->n_ready + 1;
}
/* Add an element INSN to the ready list so that it ends up with the lowest
priority. */
HAIFA_INLINE static void
ready_add (ready, insn)
struct ready_list *ready;
rtx insn;
{
if (ready->first == ready->n_ready)
{
memmove (ready->vec + ready->veclen - ready->n_ready,
ready_lastpos (ready),
ready->n_ready * sizeof (rtx));
ready->first = ready->veclen - 1;
}
ready->vec[ready->first - ready->n_ready] = insn;
ready->n_ready++;
}
/* Remove the element with the highest priority from the ready list and
return it. */
HAIFA_INLINE static rtx
ready_remove_first (ready)
struct ready_list *ready;
{
rtx t;
if (ready->n_ready == 0)
abort ();
t = ready->vec[ready->first--];
ready->n_ready--;
/* If the queue becomes empty, reset it. */
if (ready->n_ready == 0)
ready->first = ready->veclen - 1;
return t;
}
/* Sort the ready list READY by ascending priority, using the SCHED_SORT
macro. */
HAIFA_INLINE static void
ready_sort (ready)
struct ready_list *ready;
{
rtx *first = ready_lastpos (ready);
SCHED_SORT (first, ready->n_ready);
} }
/* PREV is an insn that is ready to execute. Adjust its priority if that /* PREV is an insn that is ready to execute. Adjust its priority if that
...@@ -4236,15 +4314,14 @@ adjust_priority (prev) ...@@ -4236,15 +4314,14 @@ adjust_priority (prev)
static int last_clock_var; static int last_clock_var;
/* INSN is the "currently executing insn". Launch each insn which was /* INSN is the "currently executing insn". Launch each insn which was
waiting on INSN. READY is a vector of insns which are ready to fire. waiting on INSN. READY is the ready list which contains the insns
N_READY is the number of elements in READY. CLOCK is the current that are ready to fire. CLOCK is the current cycle.
cycle. */ */
static int static void
schedule_insn (insn, ready, n_ready, clock) schedule_insn (insn, ready, clock)
rtx insn; rtx insn;
rtx *ready; struct ready_list *ready;
int n_ready;
int clock; int clock;
{ {
rtx link; rtx link;
...@@ -4267,13 +4344,7 @@ schedule_insn (insn, ready, n_ready, clock) ...@@ -4267,13 +4344,7 @@ schedule_insn (insn, ready, n_ready, clock)
schedule_unit (unit, insn, clock); schedule_unit (unit, insn, clock);
if (INSN_DEPEND (insn) == 0) if (INSN_DEPEND (insn) == 0)
return n_ready; return;
/* This is used by the function adjust_priority above. */
if (n_ready > 0)
max_priority = MAX (INSN_PRIORITY (ready[0]), INSN_PRIORITY (insn));
else
max_priority = INSN_PRIORITY (insn);
for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1)) for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
{ {
...@@ -4315,7 +4386,7 @@ schedule_insn (insn, ready, n_ready, clock) ...@@ -4315,7 +4386,7 @@ schedule_insn (insn, ready, n_ready, clock)
list or queue it. */ list or queue it. */
adjust_priority (next); adjust_priority (next);
if (effective_cost < 1) if (effective_cost < 1)
ready[n_ready++] = next; ready_add (ready, next);
else else
queue_insn (next, effective_cost); queue_insn (next, effective_cost);
} }
...@@ -4331,8 +4402,6 @@ schedule_insn (insn, ready, n_ready, clock) ...@@ -4331,8 +4402,6 @@ schedule_insn (insn, ready, n_ready, clock)
PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode); PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
last_clock_var = clock; last_clock_var = clock;
} }
return n_ready;
} }
/* Functions for handling of notes. */ /* Functions for handling of notes. */
...@@ -4729,10 +4798,9 @@ static int clock_var; ...@@ -4729,10 +4798,9 @@ static int clock_var;
/* Move insns that became ready to fire from queue to ready list. */ /* Move insns that became ready to fire from queue to ready list. */
static int static void
queue_to_ready (ready, n_ready) queue_to_ready (ready)
rtx ready[]; struct ready_list *ready;
int n_ready;
{ {
rtx insn; rtx insn;
rtx link; rtx link;
...@@ -4743,7 +4811,6 @@ queue_to_ready (ready, n_ready) ...@@ -4743,7 +4811,6 @@ queue_to_ready (ready, n_ready)
ready list. */ ready list. */
for (link = insn_queue[q_ptr]; link; link = XEXP (link, 1)) for (link = insn_queue[q_ptr]; link; link = XEXP (link, 1))
{ {
insn = XEXP (link, 0); insn = XEXP (link, 0);
q_size -= 1; q_size -= 1;
...@@ -4753,7 +4820,7 @@ queue_to_ready (ready, n_ready) ...@@ -4753,7 +4820,7 @@ queue_to_ready (ready, n_ready)
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb) if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
fprintf (dump, "(b%d) ", BLOCK_NUM (insn)); fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
ready[n_ready++] = insn; ready_add (ready, insn);
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, "moving to ready without stalls\n"); fprintf (dump, "moving to ready without stalls\n");
} }
...@@ -4761,7 +4828,7 @@ queue_to_ready (ready, n_ready) ...@@ -4761,7 +4828,7 @@ queue_to_ready (ready, n_ready)
/* If there are no ready insns, stall until one is ready and add all /* If there are no ready insns, stall until one is ready and add all
of the pending insns at that point to the ready list. */ of the pending insns at that point to the ready list. */
if (n_ready == 0) if (ready->n_ready == 0)
{ {
register int stalls; register int stalls;
...@@ -4781,13 +4848,13 @@ queue_to_ready (ready, n_ready) ...@@ -4781,13 +4848,13 @@ queue_to_ready (ready, n_ready)
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb) if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
fprintf (dump, "(b%d) ", BLOCK_NUM (insn)); fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
ready[n_ready++] = insn; ready_add (ready, insn);
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, "moving to ready with %d stalls\n", stalls); fprintf (dump, "moving to ready with %d stalls\n", stalls);
} }
insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0; insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
if (n_ready) if (ready->n_ready)
break; break;
} }
} }
...@@ -4797,23 +4864,26 @@ queue_to_ready (ready, n_ready) ...@@ -4797,23 +4864,26 @@ queue_to_ready (ready, n_ready)
q_ptr = NEXT_Q_AFTER (q_ptr, stalls); q_ptr = NEXT_Q_AFTER (q_ptr, stalls);
clock_var += stalls; clock_var += stalls;
} }
return n_ready;
} }
/* Print the ready list for debugging purposes. Callable from debugger. */ /* Print the ready list for debugging purposes. Callable from debugger. */
static void static void
debug_ready_list (ready, n_ready) debug_ready_list (ready)
rtx ready[]; struct ready_list *ready;
int n_ready;
{ {
rtx *p;
int i; int i;
for (i = 0; i < n_ready; i++) if (ready->n_ready == 0)
return;
p = ready_lastpos (ready);
for (i = 0; i < ready->n_ready; i++)
{ {
fprintf (dump, " %d", INSN_UID (ready[i])); fprintf (dump, " %d", INSN_UID (p[i]));
if (current_nr_blocks > 1 && INSN_BB (ready[i]) != target_bb) if (current_nr_blocks > 1 && INSN_BB (p[i]) != target_bb)
fprintf (dump, "/b%d", BLOCK_NUM (ready[i])); fprintf (dump, "/b%d", BLOCK_NUM (p[i]));
} }
fprintf (dump, "\n"); fprintf (dump, "\n");
} }
...@@ -5817,8 +5887,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -5817,8 +5887,7 @@ schedule_block (bb, rgn_n_insns)
{ {
/* Local variables. */ /* Local variables. */
rtx insn, last; rtx insn, last;
rtx *ready; struct ready_list ready;
int n_ready = 0;
int can_issue_more; int can_issue_more;
/* Flow block of this bb. */ /* Flow block of this bb. */
...@@ -5933,7 +6002,10 @@ schedule_block (bb, rgn_n_insns) ...@@ -5933,7 +6002,10 @@ schedule_block (bb, rgn_n_insns)
clear_units (); clear_units ();
/* Allocate the ready list. */ /* Allocate the ready list. */
ready = (rtx *) xmalloc ((rgn_n_insns + 1) * sizeof (rtx)); ready.veclen = rgn_n_insns + 1 + ISSUE_RATE;
ready.first = ready.veclen - 1;
ready.vec = (rtx *) xmalloc (ready.veclen * sizeof (rtx));
ready.n_ready = 0;
/* Print debugging information. */ /* Print debugging information. */
if (sched_verbose >= 5) if (sched_verbose >= 5)
...@@ -5941,7 +6013,6 @@ schedule_block (bb, rgn_n_insns) ...@@ -5941,7 +6013,6 @@ schedule_block (bb, rgn_n_insns)
/* Initialize ready list with all 'ready' insns in target block. /* Initialize ready list with all 'ready' insns in target block.
Count number of insns in the target block being scheduled. */ Count number of insns in the target block being scheduled. */
n_ready = 0;
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
{ {
rtx next; rtx next;
...@@ -5952,7 +6023,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -5952,7 +6023,7 @@ schedule_block (bb, rgn_n_insns)
if (INSN_DEP_COUNT (insn) == 0 if (INSN_DEP_COUNT (insn) == 0
&& (SCHED_GROUP_P (next) == 0 || ! INSN_P (next))) && (SCHED_GROUP_P (next) == 0 || ! INSN_P (next)))
ready[n_ready++] = insn; ready_add (&ready, insn);
if (!(SCHED_GROUP_P (insn))) if (!(SCHED_GROUP_P (insn)))
target_n_insns++; target_n_insns++;
} }
...@@ -5995,7 +6066,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -5995,7 +6066,7 @@ schedule_block (bb, rgn_n_insns)
&& (! next && (! next
|| SCHED_GROUP_P (next) == 0 || SCHED_GROUP_P (next) == 0
|| ! INSN_P (next))) || ! INSN_P (next)))
ready[n_ready++] = insn; ready_add (&ready, insn);
} }
} }
} }
...@@ -6034,25 +6105,25 @@ schedule_block (bb, rgn_n_insns) ...@@ -6034,25 +6105,25 @@ schedule_block (bb, rgn_n_insns)
If there are no ready insns, increment clock until one If there are no ready insns, increment clock until one
is ready and add all pending insns at that point to the ready is ready and add all pending insns at that point to the ready
list. */ list. */
n_ready = queue_to_ready (ready, n_ready); queue_to_ready (&ready);
if (n_ready == 0) if (ready.n_ready == 0)
abort (); abort ();
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
fprintf (dump, ";;\t\tReady list after queue_to_ready: "); fprintf (dump, ";;\t\tReady list after queue_to_ready: ");
debug_ready_list (ready, n_ready); debug_ready_list (&ready);
} }
/* Sort the ready list based on priority. */ /* Sort the ready list based on priority. */
SCHED_SORT (ready, n_ready); ready_sort (&ready);
/* Allow the target to reorder the list, typically for /* Allow the target to reorder the list, typically for
better instruction bundling. */ better instruction bundling. */
#ifdef MD_SCHED_REORDER #ifdef MD_SCHED_REORDER
MD_SCHED_REORDER (dump, sched_verbose, ready, n_ready, clock_var, MD_SCHED_REORDER (dump, sched_verbose, ready_lastpos (&ready),
can_issue_more); ready.n_ready, clock_var, can_issue_more);
#else #else
can_issue_more = issue_rate; can_issue_more = issue_rate;
#endif #endif
...@@ -6060,14 +6131,14 @@ schedule_block (bb, rgn_n_insns) ...@@ -6060,14 +6131,14 @@ schedule_block (bb, rgn_n_insns)
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, "\n;;\tReady list (t =%3d): ", clock_var); fprintf (dump, "\n;;\tReady list (t =%3d): ", clock_var);
debug_ready_list (ready, n_ready); debug_ready_list (&ready);
} }
/* Issue insns from ready list. */ /* Issue insns from ready list. */
while (n_ready != 0 && can_issue_more) while (ready.n_ready != 0 && can_issue_more)
{ {
/* Select and remove the insn from the ready list. */ /* Select and remove the insn from the ready list. */
rtx insn = ready[--n_ready]; rtx insn = ready_remove_first (&ready);
int cost = actual_hazard (insn_unit (insn), insn, clock_var, 0); int cost = actual_hazard (insn_unit (insn), insn, clock_var, 0);
if (cost >= 1) if (cost >= 1)
...@@ -6148,7 +6219,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6148,7 +6219,7 @@ schedule_block (bb, rgn_n_insns)
can_issue_more--; can_issue_more--;
#endif #endif
n_ready = schedule_insn (insn, ready, n_ready, clock_var); schedule_insn (insn, &ready, clock_var);
/* Close this block after scheduling its jump. */ /* Close this block after scheduling its jump. */
if (GET_CODE (last_scheduled_insn) == JUMP_INSN) if (GET_CODE (last_scheduled_insn) == JUMP_INSN)
...@@ -6164,7 +6235,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6164,7 +6235,7 @@ schedule_block (bb, rgn_n_insns)
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, ";;\tReady list (final): "); fprintf (dump, ";;\tReady list (final): ");
debug_ready_list (ready, n_ready); debug_ready_list (&ready);
print_block_visualization (b, ""); print_block_visualization (b, "");
} }
...@@ -6220,7 +6291,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6220,7 +6291,7 @@ schedule_block (bb, rgn_n_insns)
free (bblst_table); free (bblst_table);
free (bitlst_table); free (bitlst_table);
} }
free (ready); free (ready.vec);
return (sched_n_insns); return (sched_n_insns);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment