Commit a88f02e7 by Bernd Schmidt Committed by Bernd Schmidt

Haifa cleanup, part 1

From-SVN: r37949
parent 692344cf
2000-12-02 Bernd Schmidt <bernds@redhat.co.uk>
* haifa-sched.c (sched_dump): Renamed from dump. All users changed.
(old_max_uid): New variable.
(compute_forward_dependences): Renamed from
compute_block_forward_dependences; changed to accept block head and
tail instead of block number. Caller changed.
(free_deps, init_dependency_caches, free_dependency_caches,
init_regions, sched_init): New functions, split out from
schedule_insns and compute_block_backward_dependences.
2000-12-02 Neil Booth <neilb@earthling.net> 2000-12-02 Neil Booth <neilb@earthling.net>
* cppexp.c (parse_number): Update diagnostic test. * cppexp.c (parse_number): Update diagnostic test.
......
...@@ -215,7 +215,10 @@ static int nr_inter, nr_spec; ...@@ -215,7 +215,10 @@ static int nr_inter, nr_spec;
/* Debugging file. All printouts are sent to dump, which is always set, /* Debugging file. All printouts are sent to dump, which is always set,
either to stderr, or to the dump listing file (-dRS). */ either to stderr, or to the dump listing file (-dRS). */
static FILE *dump = 0; static FILE *sched_dump = 0;
/* Highest uid before scheduling. */
static int old_max_uid;
/* fix_sched_param() is called from toplev.c upon detection /* fix_sched_param() is called from toplev.c upon detection
of the -fsched-verbose=N option. */ of the -fsched-verbose=N option. */
...@@ -749,7 +752,7 @@ static int is_prisky PARAMS ((rtx, int, int)); ...@@ -749,7 +752,7 @@ static int is_prisky PARAMS ((rtx, int, int));
static int is_exception_free PARAMS ((rtx, int, int)); static int is_exception_free PARAMS ((rtx, int, int));
static char find_insn_mem_list PARAMS ((rtx, rtx, rtx, rtx)); static char find_insn_mem_list PARAMS ((rtx, rtx, rtx, rtx));
static void compute_block_forward_dependences PARAMS ((int)); static void compute_forward_dependences PARAMS ((rtx, rtx));
static void add_branch_dependences PARAMS ((rtx, rtx)); static void add_branch_dependences PARAMS ((rtx, rtx));
static void compute_block_backward_dependences PARAMS ((int)); static void compute_block_backward_dependences PARAMS ((int));
void debug_dependencies PARAMS ((void)); void debug_dependencies PARAMS ((void));
...@@ -816,6 +819,11 @@ static rtx move_insn PARAMS ((rtx, rtx)); ...@@ -816,6 +819,11 @@ static rtx move_insn PARAMS ((rtx, rtx));
static rtx group_leader PARAMS ((rtx)); static rtx group_leader PARAMS ((rtx));
static int set_priorities PARAMS ((int)); static int set_priorities PARAMS ((int));
static void init_deps PARAMS ((struct deps *)); static void init_deps PARAMS ((struct deps *));
static void free_deps PARAMS ((struct deps *));
static void init_dependency_caches PARAMS ((int));
static void free_dependency_caches PARAMS ((void));
static void init_regions PARAMS ((void));
static void sched_init PARAMS ((FILE *));
static void schedule_region PARAMS ((int)); static void schedule_region PARAMS ((int));
static void propagate_deps PARAMS ((int, struct deps *, int)); static void propagate_deps PARAMS ((int, struct deps *, int));
...@@ -1074,6 +1082,53 @@ set_sched_group_p (insn) ...@@ -1074,6 +1082,53 @@ set_sched_group_p (insn)
for (link = LOG_LINKS (prev); link; link = XEXP (link, 1)) for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link)); add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
} }
/* If it is profitable to use them, initialize caches for tracking
dependency informatino. LUID is the number of insns to be scheduled,
it is used in the estimate of profitability. */
static void
init_dependency_caches (luid)
int luid;
{
/* ?!? We could save some memory by computing a per-region luid mapping
which could reduce both the number of vectors in the cache and the size
of each vector. Instead we just avoid the cache entirely unless the
average number of instructions in a basic block is very high. See
the comment before the declaration of true_dependency_cache for
what we consider "very high". */
if (luid / n_basic_blocks > 100 * 5)
{
true_dependency_cache = sbitmap_vector_alloc (luid, luid);
sbitmap_vector_zero (true_dependency_cache, luid);
anti_dependency_cache = sbitmap_vector_alloc (luid, luid);
sbitmap_vector_zero (anti_dependency_cache, luid);
output_dependency_cache = sbitmap_vector_alloc (luid, luid);
sbitmap_vector_zero (output_dependency_cache, luid);
#ifdef ENABLE_CHECKING
forward_dependency_cache = sbitmap_vector_alloc (luid, luid);
sbitmap_vector_zero (forward_dependency_cache, luid);
#endif
}
}
/* Free the caches allocated in init_dependency_caches. */
static void
free_dependency_caches ()
{
if (true_dependency_cache)
{
free (true_dependency_cache);
true_dependency_cache = NULL;
free (anti_dependency_cache);
anti_dependency_cache = NULL;
free (output_dependency_cache);
output_dependency_cache = NULL;
#ifdef ENABLE_CHECKING
free (forward_dependency_cache);
forward_dependency_cache = NULL;
#endif
}
}
#ifndef INSN_SCHEDULING #ifndef INSN_SCHEDULING
void void
...@@ -1391,12 +1446,12 @@ debug_regions () ...@@ -1391,12 +1446,12 @@ debug_regions ()
{ {
int rgn, bb; int rgn, bb;
fprintf (dump, "\n;; ------------ REGIONS ----------\n\n"); fprintf (sched_dump, "\n;; ------------ REGIONS ----------\n\n");
for (rgn = 0; rgn < nr_regions; rgn++) for (rgn = 0; rgn < nr_regions; rgn++)
{ {
fprintf (dump, ";;\trgn %d nr_blocks %d:\n", rgn, fprintf (sched_dump, ";;\trgn %d nr_blocks %d:\n", rgn,
rgn_table[rgn].rgn_nr_blocks); rgn_table[rgn].rgn_nr_blocks);
fprintf (dump, ";;\tbb/block: "); fprintf (sched_dump, ";;\tbb/block: ");
for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++) for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
{ {
...@@ -1405,10 +1460,10 @@ debug_regions () ...@@ -1405,10 +1460,10 @@ debug_regions ()
if (bb != BLOCK_TO_BB (BB_TO_BLOCK (bb))) if (bb != BLOCK_TO_BB (BB_TO_BLOCK (bb)))
abort (); abort ();
fprintf (dump, " %d/%d ", bb, BB_TO_BLOCK (bb)); fprintf (sched_dump, " %d/%d ", bb, BB_TO_BLOCK (bb));
} }
fprintf (dump, "\n\n"); fprintf (sched_dump, "\n\n");
} }
} }
...@@ -1992,7 +2047,7 @@ compute_dom_prob_ps (bb) ...@@ -1992,7 +2047,7 @@ compute_dom_prob_ps (bb)
BITSET_DIFFER (pot_split[bb], ancestor_edges[bb], edgeset_size); BITSET_DIFFER (pot_split[bb], ancestor_edges[bb], edgeset_size);
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, ";; bb_prob(%d, %d) = %3d\n", bb, BB_TO_BLOCK (bb), fprintf (sched_dump, ";; bb_prob(%d, %d) = %3d\n", bb, BB_TO_BLOCK (bb),
(int) (100.0 * prob[bb])); (int) (100.0 * prob[bb]));
} }
...@@ -2130,29 +2185,29 @@ debug_candidate (i) ...@@ -2130,29 +2185,29 @@ debug_candidate (i)
if (candidate_table[i].is_speculative) if (candidate_table[i].is_speculative)
{ {
int j; int j;
fprintf (dump, "src b %d bb %d speculative \n", BB_TO_BLOCK (i), i); fprintf (sched_dump, "src b %d bb %d speculative \n", BB_TO_BLOCK (i), i);
fprintf (dump, "split path: "); fprintf (sched_dump, "split path: ");
for (j = 0; j < candidate_table[i].split_bbs.nr_members; j++) for (j = 0; j < candidate_table[i].split_bbs.nr_members; j++)
{ {
int b = candidate_table[i].split_bbs.first_member[j]; int b = candidate_table[i].split_bbs.first_member[j];
fprintf (dump, " %d ", b); fprintf (sched_dump, " %d ", b);
} }
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
fprintf (dump, "update path: "); fprintf (sched_dump, "update path: ");
for (j = 0; j < candidate_table[i].update_bbs.nr_members; j++) for (j = 0; j < candidate_table[i].update_bbs.nr_members; j++)
{ {
int b = candidate_table[i].update_bbs.first_member[j]; int b = candidate_table[i].update_bbs.first_member[j];
fprintf (dump, " %d ", b); fprintf (sched_dump, " %d ", b);
} }
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
else else
{ {
fprintf (dump, " src %d equivalent\n", BB_TO_BLOCK (i)); fprintf (sched_dump, " src %d equivalent\n", BB_TO_BLOCK (i));
} }
} }
...@@ -2164,7 +2219,7 @@ debug_candidates (trg) ...@@ -2164,7 +2219,7 @@ debug_candidates (trg)
{ {
int i; int i;
fprintf (dump, "----------- candidate table: target: b=%d bb=%d ---\n", fprintf (sched_dump, "----------- candidate table: target: b=%d bb=%d ---\n",
BB_TO_BLOCK (trg), trg); BB_TO_BLOCK (trg), trg);
for (i = trg + 1; i < current_nr_blocks; i++) for (i = trg + 1; i < current_nr_blocks; i++)
debug_candidate (i); debug_candidate (i);
...@@ -4229,12 +4284,12 @@ queue_insn (insn, n_cycles) ...@@ -4229,12 +4284,12 @@ queue_insn (insn, n_cycles)
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
fprintf (dump, ";;\t\tReady-->Q: insn %d: ", INSN_UID (insn)); fprintf (sched_dump, ";;\t\tReady-->Q: insn %d: ", INSN_UID (insn));
if (INSN_BB (insn) != target_bb) if (INSN_BB (insn) != target_bb)
fprintf (dump, "(b%d) ", BLOCK_NUM (insn)); fprintf (sched_dump, "(b%d) ", BLOCK_NUM (insn));
fprintf (dump, "queued for %d cycles.\n", n_cycles); fprintf (sched_dump, "queued for %d cycles.\n", n_cycles);
} }
} }
...@@ -4339,10 +4394,10 @@ schedule_insn (insn, ready, clock) ...@@ -4339,10 +4394,10 @@ schedule_insn (insn, ready, clock)
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
fprintf (dump, ";;\t\t--> scheduling insn <<<%d>>> on unit ", fprintf (sched_dump, ";;\t\t--> scheduling insn <<<%d>>> on unit ",
INSN_UID (insn)); INSN_UID (insn));
insn_print_units (insn); insn_print_units (insn);
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
if (sched_verbose && unit == -1) if (sched_verbose && unit == -1)
...@@ -4378,16 +4433,16 @@ schedule_insn (insn, ready, clock) ...@@ -4378,16 +4433,16 @@ schedule_insn (insn, ready, clock)
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
fprintf (dump, ";;\t\tdependences resolved: insn %d ", fprintf (sched_dump, ";;\t\tdependences resolved: insn %d ",
INSN_UID (next)); INSN_UID (next));
if (current_nr_blocks > 1 && INSN_BB (next) != target_bb) if (current_nr_blocks > 1 && INSN_BB (next) != target_bb)
fprintf (dump, "/b%d ", BLOCK_NUM (next)); fprintf (sched_dump, "/b%d ", BLOCK_NUM (next));
if (effective_cost < 1) if (effective_cost < 1)
fprintf (dump, "into ready\n"); fprintf (sched_dump, "into ready\n");
else else
fprintf (dump, "into queue with cost=%d\n", effective_cost); fprintf (sched_dump, "into queue with cost=%d\n", effective_cost);
} }
/* Adjust the priority of NEXT and either put it on the ready /* Adjust the priority of NEXT and either put it on the ready
...@@ -4660,7 +4715,7 @@ restore_line_notes (bb) ...@@ -4660,7 +4715,7 @@ restore_line_notes (bb)
} }
} }
if (sched_verbose && added_notes) if (sched_verbose && added_notes)
fprintf (dump, ";; added %d line-number notes\n", added_notes); fprintf (sched_dump, ";; added %d line-number notes\n", added_notes);
} }
/* After scheduling the function, delete redundant line notes from the /* After scheduling the function, delete redundant line notes from the
...@@ -4709,7 +4764,7 @@ rm_redundant_line_notes () ...@@ -4709,7 +4764,7 @@ rm_redundant_line_notes ()
active_insn++; active_insn++;
if (sched_verbose && notes) if (sched_verbose && notes)
fprintf (dump, ";; deleted %d line-number notes\n", notes); fprintf (sched_dump, ";; deleted %d line-number notes\n", notes);
} }
/* Delete notes between head and tail and put them in the chain /* Delete notes between head and tail and put them in the chain
...@@ -4823,14 +4878,14 @@ queue_to_ready (ready) ...@@ -4823,14 +4878,14 @@ queue_to_ready (ready)
q_size -= 1; q_size -= 1;
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn)); fprintf (sched_dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn));
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 (sched_dump, "(b%d) ", BLOCK_NUM (insn));
ready_add (ready, insn); ready_add (ready, insn);
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, "moving to ready without stalls\n"); fprintf (sched_dump, "moving to ready without stalls\n");
} }
insn_queue[q_ptr] = 0; insn_queue[q_ptr] = 0;
...@@ -4850,15 +4905,15 @@ queue_to_ready (ready) ...@@ -4850,15 +4905,15 @@ queue_to_ready (ready)
q_size -= 1; q_size -= 1;
if (sched_verbose >= 2) if (sched_verbose >= 2)
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", fprintf (sched_dump, ";;\t\tQ-->Ready: insn %d: ",
INSN_UID (insn)); INSN_UID (insn));
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 (sched_dump, "(b%d) ", BLOCK_NUM (insn));
ready_add (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 (sched_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;
...@@ -4889,11 +4944,11 @@ debug_ready_list (ready) ...@@ -4889,11 +4944,11 @@ debug_ready_list (ready)
p = ready_lastpos (ready); p = ready_lastpos (ready);
for (i = 0; i < ready->n_ready; i++) for (i = 0; i < ready->n_ready; i++)
{ {
fprintf (dump, " %d", INSN_UID (p[i])); fprintf (sched_dump, " %d", INSN_UID (p[i]));
if (current_nr_blocks > 1 && INSN_BB (p[i]) != target_bb) if (current_nr_blocks > 1 && INSN_BB (p[i]) != target_bb)
fprintf (dump, "/b%d", BLOCK_NUM (p[i])); fprintf (sched_dump, "/b%d", BLOCK_NUM (p[i]));
} }
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
/* Print names of units on which insn can/should execute, for debugging. */ /* Print names of units on which insn can/should execute, for debugging. */
...@@ -4906,20 +4961,20 @@ insn_print_units (insn) ...@@ -4906,20 +4961,20 @@ insn_print_units (insn)
int unit = insn_unit (insn); int unit = insn_unit (insn);
if (unit == -1) if (unit == -1)
fprintf (dump, "none"); fprintf (sched_dump, "none");
else if (unit >= 0) else if (unit >= 0)
fprintf (dump, "%s", function_units[unit].name); fprintf (sched_dump, "%s", function_units[unit].name);
else else
{ {
fprintf (dump, "["); fprintf (sched_dump, "[");
for (i = 0, unit = ~unit; unit; i++, unit >>= 1) for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
if (unit & 1) if (unit & 1)
{ {
fprintf (dump, "%s", function_units[i].name); fprintf (sched_dump, "%s", function_units[i].name);
if (unit != 1) if (unit != 1)
fprintf (dump, " "); fprintf (sched_dump, " ");
} }
fprintf (dump, "]"); fprintf (sched_dump, "]");
} }
} }
...@@ -5663,25 +5718,25 @@ print_block_visualization (b, s) ...@@ -5663,25 +5718,25 @@ print_block_visualization (b, s)
int unit, i; int unit, i;
/* Print header. */ /* Print header. */
fprintf (dump, "\n;; ==================== scheduling visualization for block %d %s \n", b, s); fprintf (sched_dump, "\n;; ==================== scheduling visualization for block %d %s \n", b, s);
/* Print names of units. */ /* Print names of units. */
fprintf (dump, ";; %-8s", "clock"); fprintf (sched_dump, ";; %-8s", "clock");
for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++) for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
if (function_units[unit].bitmask & target_units) if (function_units[unit].bitmask & target_units)
for (i = 0; i < function_units[unit].multiplicity; i++) for (i = 0; i < function_units[unit].multiplicity; i++)
fprintf (dump, " %-33s", function_units[unit].name); fprintf (sched_dump, " %-33s", function_units[unit].name);
fprintf (dump, " %-8s\n", "no-unit"); fprintf (sched_dump, " %-8s\n", "no-unit");
fprintf (dump, ";; %-8s", "====="); fprintf (sched_dump, ";; %-8s", "=====");
for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++) for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
if (function_units[unit].bitmask & target_units) if (function_units[unit].bitmask & target_units)
for (i = 0; i < function_units[unit].multiplicity; i++) for (i = 0; i < function_units[unit].multiplicity; i++)
fprintf (dump, " %-33s", "=============================="); fprintf (sched_dump, " %-33s", "==============================");
fprintf (dump, " %-8s\n", "======="); fprintf (sched_dump, " %-8s\n", "=======");
/* Print insns in each cycle. */ /* Print insns in each cycle. */
fprintf (dump, "%s\n", visual_tbl); fprintf (sched_dump, "%s\n", visual_tbl);
} }
/* Print insns in the 'no_unit' column of visualization. */ /* Print insns in the 'no_unit' column of visualization. */
...@@ -5976,13 +6031,13 @@ schedule_block (bb, rgn_n_insns) ...@@ -5976,13 +6031,13 @@ schedule_block (bb, rgn_n_insns)
/* Debug info. */ /* Debug info. */
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, ";; ======================================================\n"); fprintf (sched_dump, ";; ======================================================\n");
fprintf (dump, fprintf (sched_dump,
";; -- basic block %d from %d to %d -- %s reload\n", ";; -- basic block %d from %d to %d -- %s reload\n",
b, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)), b, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)),
(reload_completed ? "after" : "before")); (reload_completed ? "after" : "before"));
fprintf (dump, ";; ======================================================\n"); fprintf (sched_dump, ";; ======================================================\n");
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
visual_tbl = (char *) alloca (get_visual_tbl_length ()); visual_tbl = (char *) alloca (get_visual_tbl_length ());
init_block_visualization (); init_block_visualization ();
...@@ -6090,7 +6145,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6090,7 +6145,7 @@ schedule_block (bb, rgn_n_insns)
} }
#ifdef MD_SCHED_INIT #ifdef MD_SCHED_INIT
MD_SCHED_INIT (dump, sched_verbose); MD_SCHED_INIT (sched_dump, sched_verbose);
#endif #endif
/* No insns scheduled in this block yet. */ /* No insns scheduled in this block yet. */
...@@ -6130,7 +6185,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6130,7 +6185,7 @@ schedule_block (bb, rgn_n_insns)
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
fprintf (dump, ";;\t\tReady list after queue_to_ready: "); fprintf (sched_dump, ";;\t\tReady list after queue_to_ready: ");
debug_ready_list (&ready); debug_ready_list (&ready);
} }
...@@ -6140,7 +6195,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6140,7 +6195,7 @@ schedule_block (bb, rgn_n_insns)
/* 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_lastpos (&ready), MD_SCHED_REORDER (sched_dump, sched_verbose, ready_lastpos (&ready),
ready.n_ready, clock_var, can_issue_more); ready.n_ready, clock_var, can_issue_more);
#else #else
can_issue_more = issue_rate; can_issue_more = issue_rate;
...@@ -6148,7 +6203,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6148,7 +6203,7 @@ schedule_block (bb, rgn_n_insns)
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, "\n;;\tReady list (t =%3d): ", clock_var); fprintf (sched_dump, "\n;;\tReady list (t =%3d): ", clock_var);
debug_ready_list (&ready); debug_ready_list (&ready);
} }
...@@ -6231,7 +6286,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6231,7 +6286,7 @@ schedule_block (bb, rgn_n_insns)
sched_n_insns++; sched_n_insns++;
#ifdef MD_SCHED_VARIABLE_ISSUE #ifdef MD_SCHED_VARIABLE_ISSUE
MD_SCHED_VARIABLE_ISSUE (dump, sched_verbose, insn, MD_SCHED_VARIABLE_ISSUE (sched_dump, sched_verbose, insn,
can_issue_more); can_issue_more);
#else #else
can_issue_more--; can_issue_more--;
...@@ -6252,7 +6307,7 @@ schedule_block (bb, rgn_n_insns) ...@@ -6252,7 +6307,7 @@ schedule_block (bb, rgn_n_insns)
/* Debug info. */ /* Debug info. */
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, ";;\tReady list (final): "); fprintf (sched_dump, ";;\tReady list (final): ");
debug_ready_list (&ready); debug_ready_list (&ready);
print_block_visualization (b, ""); print_block_visualization (b, "");
} }
...@@ -6296,9 +6351,9 @@ schedule_block (bb, rgn_n_insns) ...@@ -6296,9 +6351,9 @@ schedule_block (bb, rgn_n_insns)
/* Debugging. */ /* Debugging. */
if (sched_verbose) if (sched_verbose)
{ {
fprintf (dump, ";; total time = %d\n;; new basic block head = %d\n", fprintf (sched_dump, ";; total time = %d\n;; new basic block head = %d\n",
clock_var, INSN_UID (BLOCK_HEAD (b))); clock_var, INSN_UID (BLOCK_HEAD (b)));
fprintf (dump, ";; new basic block end = %d\n\n", fprintf (sched_dump, ";; new basic block end = %d\n\n",
INSN_UID (BLOCK_END (b))); INSN_UID (BLOCK_END (b)));
} }
...@@ -6324,25 +6379,24 @@ debug_reg_vector (s) ...@@ -6324,25 +6379,24 @@ debug_reg_vector (s)
EXECUTE_IF_SET_IN_REG_SET (s, 0, regno, EXECUTE_IF_SET_IN_REG_SET (s, 0, regno,
{ {
fprintf (dump, " %d", regno); fprintf (sched_dump, " %d", regno);
}); });
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
/* Use the backward dependences from LOG_LINKS to build /* Examine insns in the range [ HEAD, TAIL ] and Use the backward
forward dependences in INSN_DEPEND. */ dependences from LOG_LINKS to build forward dependences in
INSN_DEPEND. */
static void static void
compute_block_forward_dependences (bb) compute_forward_dependences (head, tail)
int bb; rtx head, tail;
{ {
rtx insn, link; rtx insn, link;
rtx tail, head;
rtx next_tail; rtx next_tail;
enum reg_note dep_type; enum reg_note dep_type;
get_bb_head_tail (bb, &head, &tail);
next_tail = NEXT_INSN (tail); next_tail = NEXT_INSN (tail);
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
{ {
...@@ -6417,6 +6471,31 @@ init_deps (deps) ...@@ -6417,6 +6471,31 @@ init_deps (deps)
LOG_LINKS (deps->sched_before_next_call) = 0; LOG_LINKS (deps->sched_before_next_call) = 0;
} }
/* Free insn lists found in DEPS. */
static void
free_deps (deps)
struct deps *deps;
{
int max_reg = max_reg_num ();
int i;
/* Note this loop is executed max_reg * nr_regions times. It's first
implementation accounted for over 90% of the calls to free_INSN_LIST_list.
The list was empty for the vast majority of those calls. On the PA, not
calling free_INSN_LIST_list in those cases improves -O2 compile times by
3-5% on average. */
for (i = 0; i < max_reg; ++i)
{
if (deps->reg_last_clobbers[i])
free_INSN_LIST_list (&deps->reg_last_clobbers[i]);
if (deps->reg_last_sets[i])
free_INSN_LIST_list (&deps->reg_last_sets[i]);
if (deps->reg_last_uses[i])
free_INSN_LIST_list (&deps->reg_last_uses[i]);
}
}
/* Add dependences so that branches are scheduled to run last in their /* Add dependences so that branches are scheduled to run last in their
block. */ block. */
...@@ -6668,7 +6747,6 @@ static void ...@@ -6668,7 +6747,6 @@ static void
compute_block_backward_dependences (bb) compute_block_backward_dependences (bb)
int bb; int bb;
{ {
int i;
rtx head, tail; rtx head, tail;
int max_reg = max_reg_num (); int max_reg = max_reg_num ();
struct deps tmp_deps; struct deps tmp_deps;
...@@ -6683,22 +6761,8 @@ compute_block_backward_dependences (bb) ...@@ -6683,22 +6761,8 @@ compute_block_backward_dependences (bb)
if (current_nr_blocks > 1) if (current_nr_blocks > 1)
propagate_deps (bb, &tmp_deps, max_reg); propagate_deps (bb, &tmp_deps, max_reg);
/* Free up the INSN_LISTs. /* Free up the INSN_LISTs. */
free_deps (&tmp_deps);
Note this loop is executed max_reg * nr_regions times. It's first
implementation accounted for over 90% of the calls to free_INSN_LIST_list.
The list was empty for the vast majority of those calls. On the PA, not
calling free_INSN_LIST_list in those cases improves -O2 compile times by
3-5% on average. */
for (i = 0; i < max_reg; ++i)
{
if (tmp_deps.reg_last_clobbers[i])
free_INSN_LIST_list (&tmp_deps.reg_last_clobbers[i]);
if (tmp_deps.reg_last_sets[i])
free_INSN_LIST_list (&tmp_deps.reg_last_sets[i]);
if (tmp_deps.reg_last_uses[i])
free_INSN_LIST_list (&tmp_deps.reg_last_uses[i]);
}
/* Assert that we won't need bb_reg_last_* for this block anymore. */ /* Assert that we won't need bb_reg_last_* for this block anymore. */
free (bb_deps[bb].reg_last_uses); free (bb_deps[bb].reg_last_uses);
...@@ -6716,7 +6780,7 @@ debug_dependencies () ...@@ -6716,7 +6780,7 @@ debug_dependencies ()
{ {
int bb; int bb;
fprintf (dump, ";; --------------- forward dependences: ------------ \n"); fprintf (sched_dump, ";; --------------- forward dependences: ------------ \n");
for (bb = 0; bb < current_nr_blocks; bb++) for (bb = 0; bb < current_nr_blocks; bb++)
{ {
if (1) if (1)
...@@ -6727,12 +6791,12 @@ debug_dependencies () ...@@ -6727,12 +6791,12 @@ debug_dependencies ()
get_bb_head_tail (bb, &head, &tail); get_bb_head_tail (bb, &head, &tail);
next_tail = NEXT_INSN (tail); next_tail = NEXT_INSN (tail);
fprintf (dump, "\n;; --- Region Dependences --- b %d bb %d \n", fprintf (sched_dump, "\n;; --- Region Dependences --- b %d bb %d \n",
BB_TO_BLOCK (bb), bb); BB_TO_BLOCK (bb), bb);
fprintf (dump, ";; %7s%6s%6s%6s%6s%6s%11s%6s\n", fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%11s%6s\n",
"insn", "code", "bb", "dep", "prio", "cost", "blockage", "units"); "insn", "code", "bb", "dep", "prio", "cost", "blockage", "units");
fprintf (dump, ";; %7s%6s%6s%6s%6s%6s%11s%6s\n", fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%11s%6s\n",
"----", "----", "--", "---", "----", "----", "--------", "-----"); "----", "----", "--", "---", "----", "----", "--------", "-----");
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
{ {
...@@ -6742,18 +6806,18 @@ debug_dependencies () ...@@ -6742,18 +6806,18 @@ debug_dependencies ()
if (! INSN_P (insn)) if (! INSN_P (insn))
{ {
int n; int n;
fprintf (dump, ";; %6d ", INSN_UID (insn)); fprintf (sched_dump, ";; %6d ", INSN_UID (insn));
if (GET_CODE (insn) == NOTE) if (GET_CODE (insn) == NOTE)
{ {
n = NOTE_LINE_NUMBER (insn); n = NOTE_LINE_NUMBER (insn);
if (n < 0) if (n < 0)
fprintf (dump, "%s\n", GET_NOTE_INSN_NAME (n)); fprintf (sched_dump, "%s\n", GET_NOTE_INSN_NAME (n));
else else
fprintf (dump, "line %d, file %s\n", n, fprintf (sched_dump, "line %d, file %s\n", n,
NOTE_SOURCE_FILE (insn)); NOTE_SOURCE_FILE (insn));
} }
else else
fprintf (dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn))); fprintf (sched_dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
continue; continue;
} }
...@@ -6761,7 +6825,7 @@ debug_dependencies () ...@@ -6761,7 +6825,7 @@ debug_dependencies ()
range = (unit < 0 range = (unit < 0
|| function_units[unit].blockage_range_function == 0) ? 0 : || function_units[unit].blockage_range_function == 0) ? 0 :
function_units[unit].blockage_range_function (insn); function_units[unit].blockage_range_function (insn);
fprintf (dump, fprintf (sched_dump,
";; %s%5d%6d%6d%6d%6d%6d %3d -%3d ", ";; %s%5d%6d%6d%6d%6d%6d %3d -%3d ",
(SCHED_GROUP_P (insn) ? "+" : " "), (SCHED_GROUP_P (insn) ? "+" : " "),
INSN_UID (insn), INSN_UID (insn),
...@@ -6773,14 +6837,14 @@ debug_dependencies () ...@@ -6773,14 +6837,14 @@ debug_dependencies ()
(int) MIN_BLOCKAGE_COST (range), (int) MIN_BLOCKAGE_COST (range),
(int) MAX_BLOCKAGE_COST (range)); (int) MAX_BLOCKAGE_COST (range));
insn_print_units (insn); insn_print_units (insn);
fprintf (dump, "\t: "); fprintf (sched_dump, "\t: ");
for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1)) for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
fprintf (dump, "%d ", INSN_UID (XEXP (link, 0))); fprintf (sched_dump, "%d ", INSN_UID (XEXP (link, 0)));
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
} }
} }
fprintf (dump, "\n"); fprintf (sched_dump, "\n");
} }
/* Set_priorities: compute priority of each insn in the block. */ /* Set_priorities: compute priority of each insn in the block. */
...@@ -6850,7 +6914,12 @@ schedule_region (rgn) ...@@ -6850,7 +6914,12 @@ schedule_region (rgn)
/* Compute INSN_DEPEND. */ /* Compute INSN_DEPEND. */
for (bb = current_nr_blocks - 1; bb >= 0; bb--) for (bb = current_nr_blocks - 1; bb >= 0; bb--)
compute_block_forward_dependences (bb); {
rtx head, tail;
get_bb_head_tail (bb, &head, &tail);
compute_forward_dependences (head, tail);
}
/* Delete line notes and set priorities. */ /* Delete line notes and set priorities. */
for (bb = 0; bb < current_nr_blocks; bb++) for (bb = 0; bb < current_nr_blocks; bb++)
...@@ -6950,42 +7019,29 @@ schedule_region (rgn) ...@@ -6950,42 +7019,29 @@ schedule_region (rgn)
} }
} }
/* The one entry point in this file. DUMP_FILE is the dump file for /* Initialize some global state for the scheduler. DUMP_FILE is to be used
this pass. */ for debugging output. */
void static void
schedule_insns (dump_file) sched_init (dump_file)
FILE *dump_file; FILE *dump_file;
{ {
int *deaths_in_region; int luid, b;
sbitmap blocks, large_region_blocks;
int max_uid;
int b;
rtx insn; rtx insn;
int rgn;
int luid;
int any_large_regions;
/* Disable speculative loads in their presence if cc0 defined. */ /* Disable speculative loads in their presence if cc0 defined. */
#ifdef HAVE_cc0 #ifdef HAVE_cc0
flag_schedule_speculative_load = 0; flag_schedule_speculative_load = 0;
#endif #endif
/* Taking care of this degenerate case makes the rest of
this code simpler. */
if (n_basic_blocks == 0)
return;
/* Set dump and sched_verbose for the desired debugging output. If no /* Set dump and sched_verbose for the desired debugging output. If no
dump-file was specified, but -fsched-verbose=N (any N), print to stderr. dump-file was specified, but -fsched-verbose=N (any N), print to stderr.
For -fsched-verbose=N, N>=10, print everything to stderr. */ For -fsched-verbose=N, N>=10, print everything to stderr. */
sched_verbose = sched_verbose_param; sched_verbose = sched_verbose_param;
if (sched_verbose_param == 0 && dump_file) if (sched_verbose_param == 0 && dump_file)
sched_verbose = 1; sched_verbose = 1;
dump = ((sched_verbose_param >= 10 || !dump_file) ? stderr : dump_file); sched_dump = ((sched_verbose_param >= 10 || !dump_file)
? stderr : dump_file);
nr_inter = 0;
nr_spec = 0;
/* Initialize issue_rate. */ /* Initialize issue_rate. */
issue_rate = ISSUE_RATE; issue_rate = ISSUE_RATE;
...@@ -6994,9 +7050,9 @@ schedule_insns (dump_file) ...@@ -6994,9 +7050,9 @@ schedule_insns (dump_file)
/* We use LUID 0 for the fake insn (UID 0) which holds dependencies for /* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
pseudos which do not cross calls. */ pseudos which do not cross calls. */
max_uid = get_max_uid () + 1; old_max_uid = get_max_uid () + 1;
h_i_d = (struct haifa_insn_data *) xcalloc (max_uid, sizeof (*h_i_d)); h_i_d = (struct haifa_insn_data *) xcalloc (old_max_uid, sizeof (*h_i_d));
h_i_d[0].luid = 0; h_i_d[0].luid = 0;
luid = 1; luid = 1;
...@@ -7017,26 +7073,68 @@ schedule_insns (dump_file) ...@@ -7017,26 +7073,68 @@ schedule_insns (dump_file)
break; break;
} }
/* ?!? We could save some memory by computing a per-region luid mapping init_dependency_caches (luid);
which could reduce both the number of vectors in the cache and the size
of each vector. Instead we just avoid the cache entirely unless the compute_bb_for_insn (old_max_uid);
average number of instructions in a basic block is very high. See
the comment before the declaration of true_dependency_cache for init_alias_analysis ();
what we consider "very high". */
if (luid / n_basic_blocks > 100 * 5) if (write_symbols != NO_DEBUG)
{ {
true_dependency_cache = sbitmap_vector_alloc (luid, luid); rtx line;
sbitmap_vector_zero (true_dependency_cache, luid);
anti_dependency_cache = sbitmap_vector_alloc (luid, luid); line_note_head = (rtx *) xcalloc (n_basic_blocks, sizeof (rtx));
sbitmap_vector_zero (anti_dependency_cache, luid);
output_dependency_cache = sbitmap_vector_alloc (luid, luid); /* Save-line-note-head:
sbitmap_vector_zero (output_dependency_cache, luid); Determine the line-number at the start of each basic block.
#ifdef ENABLE_CHECKING This must be computed and saved now, because after a basic block's
forward_dependency_cache = sbitmap_vector_alloc (luid, luid); predecessor has been scheduled, it is impossible to accurately
sbitmap_vector_zero (forward_dependency_cache, luid); determine the correct line number for the first insn of the block. */
#endif
for (b = 0; b < n_basic_blocks; b++)
for (line = BLOCK_HEAD (b); line; line = PREV_INSN (line))
if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
{
line_note_head[b] = line;
break;
}
} }
/* Find units used in this fuction, for visualization. */
if (sched_verbose)
init_target_units ();
/* ??? Add a NOTE after the last insn of the last basic block. It is not
known why this is done. */
insn = BLOCK_END (n_basic_blocks - 1);
if (NEXT_INSN (insn) == 0
|| (GET_CODE (insn) != NOTE
&& GET_CODE (insn) != CODE_LABEL
/* Don't emit a NOTE if it would end up between an unconditional
jump and a BARRIER. */
&& !(GET_CODE (insn) == JUMP_INSN
&& GET_CODE (NEXT_INSN (insn)) == BARRIER)))
emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks - 1));
/* Compute INSN_REG_WEIGHT for all blocks. We must do this before
removing death notes. */
for (b = n_basic_blocks - 1; b >= 0; b--)
find_insn_reg_weight (b);
}
/* Indexed by region, holds the number of death notes found in that region.
Used for consistency checks. */
static int *deaths_in_region;
/* Initialize data structures for region scheduling. */
static void
init_regions ()
{
sbitmap blocks;
int rgn;
nr_regions = 0; nr_regions = 0;
rgn_table = (region *) xmalloc ((n_basic_blocks) * sizeof (region)); rgn_table = (region *) xmalloc ((n_basic_blocks) * sizeof (region));
rgn_bb_table = (int *) xmalloc ((n_basic_blocks) * sizeof (int)); rgn_bb_table = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
...@@ -7044,9 +7142,6 @@ schedule_insns (dump_file) ...@@ -7044,9 +7142,6 @@ schedule_insns (dump_file)
containing_rgn = (int *) xmalloc ((n_basic_blocks) * sizeof (int)); containing_rgn = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
blocks = sbitmap_alloc (n_basic_blocks); blocks = sbitmap_alloc (n_basic_blocks);
large_region_blocks = sbitmap_alloc (n_basic_blocks);
compute_bb_for_insn (max_uid);
/* Compute regions for scheduling. */ /* Compute regions for scheduling. */
if (reload_completed if (reload_completed
...@@ -7107,60 +7202,43 @@ schedule_insns (dump_file) ...@@ -7107,60 +7202,43 @@ schedule_insns (dump_file)
deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions); deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
init_alias_analysis (); /* Remove all death notes from the subroutine. */
for (rgn = 0; rgn < nr_regions; rgn++)
if (write_symbols != NO_DEBUG)
{ {
rtx line; int b;
line_note_head = (rtx *) xcalloc (n_basic_blocks, sizeof (rtx));
/* Save-line-note-head: sbitmap_zero (blocks);
Determine the line-number at the start of each basic block. for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
This must be computed and saved now, because after a basic block's SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
predecessor has been scheduled, it is impossible to accurately
determine the correct line number for the first insn of the block. */
for (b = 0; b < n_basic_blocks; b++) deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1);
for (line = BLOCK_HEAD (b); line; line = PREV_INSN (line))
if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
{
line_note_head[b] = line;
break;
}
} }
/* Find units used in this fuction, for visualization. */ sbitmap_free (blocks);
if (sched_verbose) }
init_target_units ();
/* ??? Add a NOTE after the last insn of the last basic block. It is not /* The one entry point in this file. DUMP_FILE is the dump file for
known why this is done. */ this pass. */
insn = BLOCK_END (n_basic_blocks - 1); void
if (NEXT_INSN (insn) == 0 schedule_insns (dump_file)
|| (GET_CODE (insn) != NOTE FILE *dump_file;
&& GET_CODE (insn) != CODE_LABEL {
/* Don't emit a NOTE if it would end up between an unconditional sbitmap large_region_blocks, blocks;
jump and a BARRIER. */ int rgn;
&& !(GET_CODE (insn) == JUMP_INSN int any_large_regions;
&& GET_CODE (NEXT_INSN (insn)) == BARRIER)))
emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks - 1));
/* Compute INSN_REG_WEIGHT for all blocks. We must do this before /* Taking care of this degenerate case makes the rest of
removing death notes. */ this code simpler. */
for (b = n_basic_blocks - 1; b >= 0; b--) if (n_basic_blocks == 0)
find_insn_reg_weight (b); return;
/* Remove all death notes from the subroutine. */ nr_inter = 0;
for (rgn = 0; rgn < nr_regions; rgn++) nr_spec = 0;
{
sbitmap_zero (blocks);
for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1); sched_init (dump_file);
}
init_regions ();
/* Schedule every region in the subroutine. */ /* Schedule every region in the subroutine. */
for (rgn = 0; rgn < nr_regions; rgn++) for (rgn = 0; rgn < nr_regions; rgn++)
...@@ -7180,11 +7258,14 @@ schedule_insns (dump_file) ...@@ -7180,11 +7258,14 @@ schedule_insns (dump_file)
best way to test for this kind of thing... */ best way to test for this kind of thing... */
allocate_reg_life_data (); allocate_reg_life_data ();
compute_bb_for_insn (max_uid); compute_bb_for_insn (old_max_uid);
any_large_regions = 0; any_large_regions = 0;
large_region_blocks = sbitmap_alloc (n_basic_blocks);
sbitmap_ones (large_region_blocks); sbitmap_ones (large_region_blocks);
blocks = sbitmap_alloc (n_basic_blocks);
for (rgn = 0; rgn < nr_regions; rgn++) for (rgn = 0; rgn < nr_regions; rgn++)
if (RGN_NR_BLOCKS (rgn) > 1) if (RGN_NR_BLOCKS (rgn) > 1)
any_large_regions = 1; any_large_regions = 1;
...@@ -7230,7 +7311,7 @@ schedule_insns (dump_file) ...@@ -7230,7 +7311,7 @@ schedule_insns (dump_file)
{ {
if (reload_completed == 0 && flag_schedule_interblock) if (reload_completed == 0 && flag_schedule_interblock)
{ {
fprintf (dump, fprintf (sched_dump,
"\n;; Procedure interblock/speculative motions == %d/%d \n", "\n;; Procedure interblock/speculative motions == %d/%d \n",
nr_inter, nr_spec); nr_inter, nr_spec);
} }
...@@ -7239,25 +7320,13 @@ schedule_insns (dump_file) ...@@ -7239,25 +7320,13 @@ schedule_insns (dump_file)
if (nr_inter > 0) if (nr_inter > 0)
abort (); abort ();
} }
fprintf (dump, "\n\n"); fprintf (sched_dump, "\n\n");
} }
/* Clean up. */ /* Clean up. */
end_alias_analysis (); end_alias_analysis ();
if (true_dependency_cache) free_dependency_caches ();
{
free (true_dependency_cache);
true_dependency_cache = NULL;
free (anti_dependency_cache);
anti_dependency_cache = NULL;
free (output_dependency_cache);
output_dependency_cache = NULL;
#ifdef ENABLE_CHECKING
free (forward_dependency_cache);
forward_dependency_cache = NULL;
#endif
}
free (rgn_table); free (rgn_table);
free (rgn_bb_table); free (rgn_bb_table);
free (block_to_bb); free (block_to_bb);
......
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