Haifa cleanup, part 1

From-SVN: r37949
This commit is contained in:
Bernd Schmidt 2000-12-02 10:47:42 +00:00 committed by Bernd Schmidt
parent 692344cfed
commit a88f02e7a7
2 changed files with 285 additions and 205 deletions

View File

@ -1,3 +1,14 @@
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>
* cppexp.c (parse_number): Update diagnostic test.

View File

@ -215,7 +215,10 @@ static int nr_inter, nr_spec;
/* Debugging file. All printouts are sent to dump, which is always set,
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
of the -fsched-verbose=N option. */
@ -749,7 +752,7 @@ static int is_prisky 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 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 compute_block_backward_dependences PARAMS ((int));
void debug_dependencies PARAMS ((void));
@ -816,6 +819,11 @@ static rtx move_insn PARAMS ((rtx, rtx));
static rtx group_leader PARAMS ((rtx));
static int set_priorities PARAMS ((int));
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 propagate_deps PARAMS ((int, struct deps *, int));
@ -1074,6 +1082,53 @@ set_sched_group_p (insn)
for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
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
void
@ -1391,12 +1446,12 @@ debug_regions ()
{
int rgn, bb;
fprintf (dump, "\n;; ------------ REGIONS ----------\n\n");
fprintf (sched_dump, "\n;; ------------ REGIONS ----------\n\n");
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);
fprintf (dump, ";;\tbb/block: ");
fprintf (sched_dump, ";;\tbb/block: ");
for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
{
@ -1405,10 +1460,10 @@ debug_regions ()
if (bb != BLOCK_TO_BB (BB_TO_BLOCK (bb)))
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)
BITSET_DIFFER (pot_split[bb], ancestor_edges[bb], edgeset_size);
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]));
}
@ -2130,29 +2185,29 @@ debug_candidate (i)
if (candidate_table[i].is_speculative)
{
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++)
{
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++)
{
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
{
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)
{
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);
for (i = trg + 1; i < current_nr_blocks; i++)
debug_candidate (i);
@ -4229,12 +4284,12 @@ queue_insn (insn, n_cycles)
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)
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)
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_print_units (insn);
fprintf (dump, "\n");
fprintf (sched_dump, "\n");
}
if (sched_verbose && unit == -1)
@ -4378,16 +4433,16 @@ schedule_insn (insn, ready, clock)
if (sched_verbose >= 2)
{
fprintf (dump, ";;\t\tdependences resolved: insn %d ",
fprintf (sched_dump, ";;\t\tdependences resolved: insn %d ",
INSN_UID (next));
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)
fprintf (dump, "into ready\n");
fprintf (sched_dump, "into ready\n");
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
@ -4660,7 +4715,7 @@ restore_line_notes (bb)
}
}
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
@ -4709,7 +4764,7 @@ rm_redundant_line_notes ()
active_insn++;
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
@ -4823,14 +4878,14 @@ queue_to_ready (ready)
q_size -= 1;
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)
fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
fprintf (sched_dump, "(b%d) ", BLOCK_NUM (insn));
ready_add (ready, insn);
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;
@ -4850,15 +4905,15 @@ queue_to_ready (ready)
q_size -= 1;
if (sched_verbose >= 2)
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ",
fprintf (sched_dump, ";;\t\tQ-->Ready: insn %d: ",
INSN_UID (insn));
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);
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;
@ -4889,11 +4944,11 @@ debug_ready_list (ready)
p = ready_lastpos (ready);
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)
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. */
@ -4906,20 +4961,20 @@ insn_print_units (insn)
int unit = insn_unit (insn);
if (unit == -1)
fprintf (dump, "none");
fprintf (sched_dump, "none");
else if (unit >= 0)
fprintf (dump, "%s", function_units[unit].name);
fprintf (sched_dump, "%s", function_units[unit].name);
else
{
fprintf (dump, "[");
fprintf (sched_dump, "[");
for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
if (unit & 1)
{
fprintf (dump, "%s", function_units[i].name);
fprintf (sched_dump, "%s", function_units[i].name);
if (unit != 1)
fprintf (dump, " ");
fprintf (sched_dump, " ");
}
fprintf (dump, "]");
fprintf (sched_dump, "]");
}
}
@ -5663,25 +5718,25 @@ print_block_visualization (b, s)
int unit, i;
/* 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. */
fprintf (dump, ";; %-8s", "clock");
fprintf (sched_dump, ";; %-8s", "clock");
for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
if (function_units[unit].bitmask & target_units)
for (i = 0; i < function_units[unit].multiplicity; i++)
fprintf (dump, " %-33s", function_units[unit].name);
fprintf (dump, " %-8s\n", "no-unit");
fprintf (sched_dump, " %-33s", function_units[unit].name);
fprintf (sched_dump, " %-8s\n", "no-unit");
fprintf (dump, ";; %-8s", "=====");
fprintf (sched_dump, ";; %-8s", "=====");
for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
if (function_units[unit].bitmask & target_units)
for (i = 0; i < function_units[unit].multiplicity; i++)
fprintf (dump, " %-33s", "==============================");
fprintf (dump, " %-8s\n", "=======");
fprintf (sched_dump, " %-33s", "==============================");
fprintf (sched_dump, " %-8s\n", "=======");
/* 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. */
@ -5976,13 +6031,13 @@ schedule_block (bb, rgn_n_insns)
/* Debug info. */
if (sched_verbose)
{
fprintf (dump, ";; ======================================================\n");
fprintf (dump,
fprintf (sched_dump, ";; ======================================================\n");
fprintf (sched_dump,
";; -- basic block %d from %d to %d -- %s reload\n",
b, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)),
(reload_completed ? "after" : "before"));
fprintf (dump, ";; ======================================================\n");
fprintf (dump, "\n");
fprintf (sched_dump, ";; ======================================================\n");
fprintf (sched_dump, "\n");
visual_tbl = (char *) alloca (get_visual_tbl_length ());
init_block_visualization ();
@ -6090,7 +6145,7 @@ schedule_block (bb, rgn_n_insns)
}
#ifdef MD_SCHED_INIT
MD_SCHED_INIT (dump, sched_verbose);
MD_SCHED_INIT (sched_dump, sched_verbose);
#endif
/* No insns scheduled in this block yet. */
@ -6130,7 +6185,7 @@ schedule_block (bb, rgn_n_insns)
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);
}
@ -6140,7 +6195,7 @@ schedule_block (bb, rgn_n_insns)
/* Allow the target to reorder the list, typically for
better instruction bundling. */
#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);
#else
can_issue_more = issue_rate;
@ -6148,7 +6203,7 @@ schedule_block (bb, rgn_n_insns)
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);
}
@ -6231,7 +6286,7 @@ schedule_block (bb, rgn_n_insns)
sched_n_insns++;
#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);
#else
can_issue_more--;
@ -6252,7 +6307,7 @@ schedule_block (bb, rgn_n_insns)
/* Debug info. */
if (sched_verbose)
{
fprintf (dump, ";;\tReady list (final): ");
fprintf (sched_dump, ";;\tReady list (final): ");
debug_ready_list (&ready);
print_block_visualization (b, "");
}
@ -6296,9 +6351,9 @@ schedule_block (bb, rgn_n_insns)
/* Debugging. */
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)));
fprintf (dump, ";; new basic block end = %d\n\n",
fprintf (sched_dump, ";; new basic block end = %d\n\n",
INSN_UID (BLOCK_END (b)));
}
@ -6324,25 +6379,24 @@ debug_reg_vector (s)
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
forward dependences in INSN_DEPEND. */
/* Examine insns in the range [ HEAD, TAIL ] and Use the backward
dependences from LOG_LINKS to build forward dependences in
INSN_DEPEND. */
static void
compute_block_forward_dependences (bb)
int bb;
compute_forward_dependences (head, tail)
rtx head, tail;
{
rtx insn, link;
rtx tail, head;
rtx next_tail;
enum reg_note dep_type;
get_bb_head_tail (bb, &head, &tail);
next_tail = NEXT_INSN (tail);
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
{
@ -6417,6 +6471,31 @@ init_deps (deps)
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
block. */
@ -6668,7 +6747,6 @@ static void
compute_block_backward_dependences (bb)
int bb;
{
int i;
rtx head, tail;
int max_reg = max_reg_num ();
struct deps tmp_deps;
@ -6683,22 +6761,8 @@ compute_block_backward_dependences (bb)
if (current_nr_blocks > 1)
propagate_deps (bb, &tmp_deps, max_reg);
/* Free up the INSN_LISTs.
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]);
}
/* Free up the INSN_LISTs. */
free_deps (&tmp_deps);
/* Assert that we won't need bb_reg_last_* for this block anymore. */
free (bb_deps[bb].reg_last_uses);
@ -6716,7 +6780,7 @@ debug_dependencies ()
{
int bb;
fprintf (dump, ";; --------------- forward dependences: ------------ \n");
fprintf (sched_dump, ";; --------------- forward dependences: ------------ \n");
for (bb = 0; bb < current_nr_blocks; bb++)
{
if (1)
@ -6727,12 +6791,12 @@ debug_dependencies ()
get_bb_head_tail (bb, &head, &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);
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");
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))
{
@ -6742,18 +6806,18 @@ debug_dependencies ()
if (! INSN_P (insn))
{
int n;
fprintf (dump, ";; %6d ", INSN_UID (insn));
fprintf (sched_dump, ";; %6d ", INSN_UID (insn));
if (GET_CODE (insn) == NOTE)
{
n = NOTE_LINE_NUMBER (insn);
if (n < 0)
fprintf (dump, "%s\n", GET_NOTE_INSN_NAME (n));
fprintf (sched_dump, "%s\n", GET_NOTE_INSN_NAME (n));
else
fprintf (dump, "line %d, file %s\n", n,
fprintf (sched_dump, "line %d, file %s\n", n,
NOTE_SOURCE_FILE (insn));
}
else
fprintf (dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
fprintf (sched_dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
continue;
}
@ -6761,7 +6825,7 @@ debug_dependencies ()
range = (unit < 0
|| function_units[unit].blockage_range_function == 0) ? 0 :
function_units[unit].blockage_range_function (insn);
fprintf (dump,
fprintf (sched_dump,
";; %s%5d%6d%6d%6d%6d%6d %3d -%3d ",
(SCHED_GROUP_P (insn) ? "+" : " "),
INSN_UID (insn),
@ -6773,14 +6837,14 @@ debug_dependencies ()
(int) MIN_BLOCKAGE_COST (range),
(int) MAX_BLOCKAGE_COST (range));
insn_print_units (insn);
fprintf (dump, "\t: ");
fprintf (sched_dump, "\t: ");
for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
fprintf (dump, "%d ", INSN_UID (XEXP (link, 0)));
fprintf (dump, "\n");
fprintf (sched_dump, "%d ", INSN_UID (XEXP (link, 0)));
fprintf (sched_dump, "\n");
}
}
}
fprintf (dump, "\n");
fprintf (sched_dump, "\n");
}
/* Set_priorities: compute priority of each insn in the block. */
@ -6850,7 +6914,12 @@ schedule_region (rgn)
/* Compute INSN_DEPEND. */
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. */
for (bb = 0; bb < current_nr_blocks; bb++)
@ -6950,42 +7019,29 @@ schedule_region (rgn)
}
}
/* The one entry point in this file. DUMP_FILE is the dump file for
this pass. */
/* Initialize some global state for the scheduler. DUMP_FILE is to be used
for debugging output. */
void
schedule_insns (dump_file)
static void
sched_init (dump_file)
FILE *dump_file;
{
int *deaths_in_region;
sbitmap blocks, large_region_blocks;
int max_uid;
int b;
int luid, b;
rtx insn;
int rgn;
int luid;
int any_large_regions;
/* Disable speculative loads in their presence if cc0 defined. */
#ifdef HAVE_cc0
flag_schedule_speculative_load = 0;
#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
dump-file was specified, but -fsched-verbose=N (any N), print to stderr.
For -fsched-verbose=N, N>=10, print everything to stderr. */
sched_verbose = sched_verbose_param;
if (sched_verbose_param == 0 && dump_file)
sched_verbose = 1;
dump = ((sched_verbose_param >= 10 || !dump_file) ? stderr : dump_file);
nr_inter = 0;
nr_spec = 0;
sched_dump = ((sched_verbose_param >= 10 || !dump_file)
? stderr : dump_file);
/* Initialize issue_rate. */
issue_rate = ISSUE_RATE;
@ -6994,9 +7050,9 @@ schedule_insns (dump_file)
/* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
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;
luid = 1;
@ -7017,26 +7073,68 @@ schedule_insns (dump_file)
break;
}
/* ?!? 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)
init_dependency_caches (luid);
compute_bb_for_insn (old_max_uid);
init_alias_analysis ();
if (write_symbols != NO_DEBUG)
{
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
rtx line;
line_note_head = (rtx *) xcalloc (n_basic_blocks, sizeof (rtx));
/* Save-line-note-head:
Determine the line-number at the start of each basic block.
This must be computed and saved now, because after a basic block's
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++)
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;
rgn_table = (region *) xmalloc ((n_basic_blocks) * sizeof (region));
rgn_bb_table = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
@ -7044,9 +7142,6 @@ schedule_insns (dump_file)
containing_rgn = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
blocks = sbitmap_alloc (n_basic_blocks);
large_region_blocks = sbitmap_alloc (n_basic_blocks);
compute_bb_for_insn (max_uid);
/* Compute regions for scheduling. */
if (reload_completed
@ -7107,54 +7202,11 @@ schedule_insns (dump_file)
deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
init_alias_analysis ();
if (write_symbols != NO_DEBUG)
{
rtx line;
line_note_head = (rtx *) xcalloc (n_basic_blocks, sizeof (rtx));
/* Save-line-note-head:
Determine the line-number at the start of each basic block.
This must be computed and saved now, because after a basic block's
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++)
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);
/* Remove all death notes from the subroutine. */
for (rgn = 0; rgn < nr_regions; rgn++)
{
int b;
sbitmap_zero (blocks);
for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
@ -7162,6 +7214,32 @@ schedule_insns (dump_file)
deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1);
}
sbitmap_free (blocks);
}
/* The one entry point in this file. DUMP_FILE is the dump file for
this pass. */
void
schedule_insns (dump_file)
FILE *dump_file;
{
sbitmap large_region_blocks, blocks;
int rgn;
int any_large_regions;
/* Taking care of this degenerate case makes the rest of
this code simpler. */
if (n_basic_blocks == 0)
return;
nr_inter = 0;
nr_spec = 0;
sched_init (dump_file);
init_regions ();
/* Schedule every region in the subroutine. */
for (rgn = 0; rgn < nr_regions; rgn++)
schedule_region (rgn);
@ -7180,11 +7258,14 @@ schedule_insns (dump_file)
best way to test for this kind of thing... */
allocate_reg_life_data ();
compute_bb_for_insn (max_uid);
compute_bb_for_insn (old_max_uid);
any_large_regions = 0;
large_region_blocks = sbitmap_alloc (n_basic_blocks);
sbitmap_ones (large_region_blocks);
blocks = sbitmap_alloc (n_basic_blocks);
for (rgn = 0; rgn < nr_regions; rgn++)
if (RGN_NR_BLOCKS (rgn) > 1)
any_large_regions = 1;
@ -7230,7 +7311,7 @@ schedule_insns (dump_file)
{
if (reload_completed == 0 && flag_schedule_interblock)
{
fprintf (dump,
fprintf (sched_dump,
"\n;; Procedure interblock/speculative motions == %d/%d \n",
nr_inter, nr_spec);
}
@ -7239,25 +7320,13 @@ schedule_insns (dump_file)
if (nr_inter > 0)
abort ();
}
fprintf (dump, "\n\n");
fprintf (sched_dump, "\n\n");
}
/* Clean up. */
end_alias_analysis ();
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
}
free_dependency_caches ();
free (rgn_table);
free (rgn_bb_table);
free (block_to_bb);