Commit b953c2b8 by Bernd Schmidt Committed by Bernd Schmidt

haifa-sched.c (schedule_insns): Remove outdated comment.

	* haifa-sched.c (schedule_insns): Remove outdated comment.
	(schedule_block): When computing a known value for TODO_SPEC,
	just set it rather than using logical operations.
	(try_ready): Likewise.  Use a local variable rather than a
	pointer to TODO_SPEC.  Reorder an if statement to move the
	easy case to the then block.
	* sched-deps.c (dep_spec_p): New static function.
	(update_dep): Use it to decide whether to call
	change_spec_dep_to_hard.
	(get_back_and_forw_lists): Use it.
	(sd_resolve_dep): Likewise.
	(init_dep): If !USE_DEPS_LIST, use zero to initialize status.
	(haifa_note_mem_dep): Likewise.
	(check_dep): Likewise.
	(sd_add_dep): Also clear SPECULATIVE bits if not DO_SPECULATION.
	(sched_free_deps): Free in two passes.

From-SVN: r176271
parent 1f098f07
2011-07-14 Bernd Schmidt <bernds@codesourcery.com>
* haifa-sched.c (schedule_insns): Remove outdated comment.
(schedule_block): When computing a known value for TODO_SPEC,
just set it rather than using logical operations.
(try_ready): Likewise. Use a local variable rather than a
pointer to TODO_SPEC. Reorder an if statement to move the
easy case to the then block.
* sched-deps.c (dep_spec_p): New static function.
(update_dep): Use it to decide whether to call
change_spec_dep_to_hard.
(get_back_and_forw_lists): Use it.
(sd_resolve_dep): Likewise.
(init_dep): If !USE_DEPS_LIST, use zero to initialize status.
(haifa_note_mem_dep): Likewise.
(check_dep): Likewise.
(sd_add_dep): Also clear SPECULATIVE bits if not DO_SPECULATION.
(sched_free_deps): Free in two passes.
2011-07-14 Richard Sandiford <richard.sandiford@linaro.org> 2011-07-14 Richard Sandiford <richard.sandiford@linaro.org>
PR middle-end/49736 PR middle-end/49736
......
...@@ -2004,18 +2004,6 @@ schedule_insn (rtx insn) ...@@ -2004,18 +2004,6 @@ schedule_insn (rtx insn)
} }
} }
/* This is the place where scheduler doesn't *basically* need backward and
forward dependencies for INSN anymore. Nevertheless they are used in
heuristics in rank_for_schedule (), early_queue_to_ready () and in
some targets (e.g. rs6000). Thus the earliest place where we *can*
remove dependencies is after targetm.sched.finish () call in
schedule_block (). But, on the other side, the safest place to remove
dependencies is when we are finishing scheduling entire region. As we
don't generate [many] dependencies during scheduling itself, we won't
need memory until beginning of next region.
Bottom line: Dependencies are removed for all insns in the end of
scheduling the region. */
/* Annotate the instruction with issue information -- TImode /* Annotate the instruction with issue information -- TImode
indicates that the instruction is expected not to be able indicates that the instruction is expected not to be able
to issue on the same cycle as the previous insn. A machine to issue on the same cycle as the previous insn. A machine
...@@ -3906,7 +3894,7 @@ schedule_block (basic_block *target_bb) ...@@ -3906,7 +3894,7 @@ schedule_block (basic_block *target_bb)
/* We normally get here only if we don't want to move /* We normally get here only if we don't want to move
insn from the split block. */ insn from the split block. */
{ {
TODO_SPEC (insn) = (TODO_SPEC (insn) & ~SPECULATIVE) | HARD_DEP; TODO_SPEC (insn) = HARD_DEP;
goto restart_choose_ready; goto restart_choose_ready;
} }
...@@ -4049,7 +4037,7 @@ schedule_block (basic_block *target_bb) ...@@ -4049,7 +4037,7 @@ schedule_block (basic_block *target_bb)
x = ready_element (&ready, i); x = ready_element (&ready, i);
QUEUE_INDEX (x) = QUEUE_NOWHERE; QUEUE_INDEX (x) = QUEUE_NOWHERE;
TODO_SPEC (x) = (TODO_SPEC (x) & ~SPECULATIVE) | HARD_DEP; TODO_SPEC (x) = HARD_DEP;
} }
if (q_size) if (q_size)
...@@ -4062,7 +4050,7 @@ schedule_block (basic_block *target_bb) ...@@ -4062,7 +4050,7 @@ schedule_block (basic_block *target_bb)
x = XEXP (link, 0); x = XEXP (link, 0);
QUEUE_INDEX (x) = QUEUE_NOWHERE; QUEUE_INDEX (x) = QUEUE_NOWHERE;
TODO_SPEC (x) = (TODO_SPEC (x) & ~SPECULATIVE) | HARD_DEP; TODO_SPEC (x) = HARD_DEP;
} }
free_INSN_LIST_list (&insn_queue[i]); free_INSN_LIST_list (&insn_queue[i]);
} }
...@@ -4492,10 +4480,9 @@ static int haifa_speculate_insn (rtx, ds_t, rtx *); ...@@ -4492,10 +4480,9 @@ static int haifa_speculate_insn (rtx, ds_t, rtx *);
int int
try_ready (rtx next) try_ready (rtx next)
{ {
ds_t old_ts, *ts; ds_t old_ts, new_ts;
ts = &TODO_SPEC (next); old_ts = TODO_SPEC (next);
old_ts = *ts;
gcc_assert (!(old_ts & ~(SPECULATIVE | HARD_DEP)) gcc_assert (!(old_ts & ~(SPECULATIVE | HARD_DEP))
&& ((old_ts & HARD_DEP) && ((old_ts & HARD_DEP)
...@@ -4503,22 +4490,15 @@ try_ready (rtx next) ...@@ -4503,22 +4490,15 @@ try_ready (rtx next)
if (sd_lists_empty_p (next, SD_LIST_BACK)) if (sd_lists_empty_p (next, SD_LIST_BACK))
/* NEXT has all its dependencies resolved. */ /* NEXT has all its dependencies resolved. */
{ new_ts = 0;
/* Remove HARD_DEP bit from NEXT's status. */
*ts &= ~HARD_DEP;
if (current_sched_info->flags & DO_SPECULATION)
/* Remove all speculative bits from NEXT's status. */
*ts &= ~SPECULATIVE;
}
else else
{ {
/* One of the NEXT's dependencies has been resolved. /* One of the NEXT's dependencies has been resolved.
Recalculate NEXT's status. */ Recalculate NEXT's status. */
*ts &= ~SPECULATIVE & ~HARD_DEP; if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
new_ts = HARD_DEP;
if (sd_lists_empty_p (next, SD_LIST_HARD_BACK)) else
/* Now we've got NEXT with speculative deps only. /* Now we've got NEXT with speculative deps only.
1. Look at the deps to see what we have to do. 1. Look at the deps to see what we have to do.
2. Check if we can do 'todo'. */ 2. Check if we can do 'todo'. */
...@@ -4527,6 +4507,8 @@ try_ready (rtx next) ...@@ -4527,6 +4507,8 @@ try_ready (rtx next)
dep_t dep; dep_t dep;
bool first_p = true; bool first_p = true;
new_ts = 0;
FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep) FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep)
{ {
ds_t ds = DEP_STATUS (dep) & SPECULATIVE; ds_t ds = DEP_STATUS (dep) & SPECULATIVE;
...@@ -4539,25 +4521,23 @@ try_ready (rtx next) ...@@ -4539,25 +4521,23 @@ try_ready (rtx next)
{ {
first_p = false; first_p = false;
*ts = ds; new_ts = ds;
} }
else else
*ts = ds_merge (*ts, ds); new_ts = ds_merge (new_ts, ds);
} }
if (ds_weak (*ts) < spec_info->data_weakness_cutoff) if (ds_weak (new_ts) < spec_info->data_weakness_cutoff)
/* Too few points. */ /* Too few points. */
*ts = (*ts & ~SPECULATIVE) | HARD_DEP; new_ts = HARD_DEP;
} }
else
*ts |= HARD_DEP;
} }
if (*ts & HARD_DEP) if (new_ts & HARD_DEP)
gcc_assert (*ts == old_ts gcc_assert (new_ts == HARD_DEP && new_ts == old_ts
&& QUEUE_INDEX (next) == QUEUE_NOWHERE); && QUEUE_INDEX (next) == QUEUE_NOWHERE);
else if (current_sched_info->new_ready) else if (current_sched_info->new_ready)
*ts = current_sched_info->new_ready (next, *ts); new_ts = current_sched_info->new_ready (next, new_ts);
/* * if !(old_ts & SPECULATIVE) (e.g. HARD_DEP or 0), then insn might /* * if !(old_ts & SPECULATIVE) (e.g. HARD_DEP or 0), then insn might
have its original pattern or changed (speculative) one. This is due have its original pattern or changed (speculative) one. This is due
...@@ -4565,29 +4545,29 @@ try_ready (rtx next) ...@@ -4565,29 +4545,29 @@ try_ready (rtx next)
* But if (old_ts & SPECULATIVE), then we are pretty sure that insn * But if (old_ts & SPECULATIVE), then we are pretty sure that insn
has speculative pattern. has speculative pattern.
We can't assert (!(*ts & HARD_DEP) || *ts == old_ts) here because We can't assert (!(new_ts & HARD_DEP) || new_ts == old_ts) here because
control-speculative NEXT could have been discarded by sched-rgn.c control-speculative NEXT could have been discarded by sched-rgn.c
(the same case as when discarded by can_schedule_ready_p ()). */ (the same case as when discarded by can_schedule_ready_p ()). */
if ((*ts & SPECULATIVE) if ((new_ts & SPECULATIVE)
/* If (old_ts == *ts), then (old_ts & SPECULATIVE) and we don't /* If (old_ts == new_ts), then (old_ts & SPECULATIVE) and we don't
need to change anything. */ need to change anything. */
&& *ts != old_ts) && new_ts != old_ts)
{ {
int res; int res;
rtx new_pat; rtx new_pat;
gcc_assert ((*ts & SPECULATIVE) && !(*ts & ~SPECULATIVE)); gcc_assert (!(new_ts & ~SPECULATIVE));
res = haifa_speculate_insn (next, *ts, &new_pat); res = haifa_speculate_insn (next, new_ts, &new_pat);
switch (res) switch (res)
{ {
case -1: case -1:
/* It would be nice to change DEP_STATUS of all dependences, /* It would be nice to change DEP_STATUS of all dependences,
which have ((DEP_STATUS & SPECULATIVE) == *ts) to HARD_DEP, which have ((DEP_STATUS & SPECULATIVE) == new_ts) to HARD_DEP,
so we won't reanalyze anything. */ so we won't reanalyze anything. */
*ts = (*ts & ~SPECULATIVE) | HARD_DEP; new_ts = HARD_DEP;
break; break;
case 0: case 0:
...@@ -4611,14 +4591,16 @@ try_ready (rtx next) ...@@ -4611,14 +4591,16 @@ try_ready (rtx next)
} }
} }
/* We need to restore pattern only if (*ts == 0), because otherwise it is /* We need to restore pattern only if (new_ts == 0), because otherwise it is
either correct (*ts & SPECULATIVE), either correct (new_ts & SPECULATIVE),
or we simply don't care (*ts & HARD_DEP). */ or we simply don't care (new_ts & HARD_DEP). */
gcc_assert (!ORIG_PAT (next) gcc_assert (!ORIG_PAT (next)
|| !IS_SPECULATION_BRANCHY_CHECK_P (next)); || !IS_SPECULATION_BRANCHY_CHECK_P (next));
if (*ts & HARD_DEP) TODO_SPEC (next) = new_ts;
if (new_ts & HARD_DEP)
{ {
/* We can't assert (QUEUE_INDEX (next) == QUEUE_NOWHERE) here because /* We can't assert (QUEUE_INDEX (next) == QUEUE_NOWHERE) here because
control-speculative NEXT could have been discarded by sched-rgn.c control-speculative NEXT could have been discarded by sched-rgn.c
...@@ -4628,7 +4610,8 @@ try_ready (rtx next) ...@@ -4628,7 +4610,8 @@ try_ready (rtx next)
change_queue_index (next, QUEUE_NOWHERE); change_queue_index (next, QUEUE_NOWHERE);
return -1; return -1;
} }
else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !IS_SPECULATION_CHECK_P (next)) else if (!(new_ts & BEGIN_SPEC)
&& ORIG_PAT (next) && !IS_SPECULATION_CHECK_P (next))
/* We should change pattern of every previously speculative /* We should change pattern of every previously speculative
instruction - and we determine if NEXT was speculative by using instruction - and we determine if NEXT was speculative by using
ORIG_PAT field. Except one case - speculation checks have ORIG_PAT ORIG_PAT field. Except one case - speculation checks have ORIG_PAT
...@@ -4640,18 +4623,16 @@ try_ready (rtx next) ...@@ -4640,18 +4623,16 @@ try_ready (rtx next)
if (sched_verbose >= 2) if (sched_verbose >= 2)
{ {
int s = TODO_SPEC (next);
fprintf (sched_dump, ";;\t\tdependencies resolved: insn %s", fprintf (sched_dump, ";;\t\tdependencies resolved: insn %s",
(*current_sched_info->print_insn) (next, 0)); (*current_sched_info->print_insn) (next, 0));
if (spec_info && spec_info->dump) if (spec_info && spec_info->dump)
{ {
if (s & BEGIN_DATA) if (new_ts & BEGIN_DATA)
fprintf (spec_info->dump, "; data-spec;"); fprintf (spec_info->dump, "; data-spec;");
if (s & BEGIN_CONTROL) if (new_ts & BEGIN_CONTROL)
fprintf (spec_info->dump, "; control-spec;"); fprintf (spec_info->dump, "; control-spec;");
if (s & BE_IN_CONTROL) if (new_ts & BE_IN_CONTROL)
fprintf (spec_info->dump, "; in-control-spec;"); fprintf (spec_info->dump, "; in-control-spec;");
} }
......
...@@ -121,7 +121,7 @@ init_dep (dep_t dep, rtx pro, rtx con, enum reg_note kind) ...@@ -121,7 +121,7 @@ init_dep (dep_t dep, rtx pro, rtx con, enum reg_note kind)
if ((current_sched_info->flags & USE_DEPS_LIST)) if ((current_sched_info->flags & USE_DEPS_LIST))
ds = dk_to_ds (kind); ds = dk_to_ds (kind);
else else
ds = -1; ds = 0;
init_dep_1 (dep, pro, con, kind, ds); init_dep_1 (dep, pro, con, kind, ds);
} }
...@@ -414,6 +414,16 @@ clear_deps_list (deps_list_t l) ...@@ -414,6 +414,16 @@ clear_deps_list (deps_list_t l)
while (1); while (1);
} }
/* Decide whether a dependency should be treated as a hard or a speculative
dependency. */
static bool
dep_spec_p (dep_t dep)
{
if (current_sched_info->flags & DO_SPECULATION)
return (DEP_STATUS (dep) & SPECULATIVE) != 0;
return false;
}
static regset reg_pending_sets; static regset reg_pending_sets;
static regset reg_pending_clobbers; static regset reg_pending_clobbers;
static regset reg_pending_uses; static regset reg_pending_uses;
...@@ -1064,6 +1074,7 @@ update_dep (dep_t dep, dep_t new_dep, ...@@ -1064,6 +1074,7 @@ update_dep (dep_t dep, dep_t new_dep,
{ {
enum DEPS_ADJUST_RESULT res = DEP_PRESENT; enum DEPS_ADJUST_RESULT res = DEP_PRESENT;
enum reg_note old_type = DEP_TYPE (dep); enum reg_note old_type = DEP_TYPE (dep);
bool was_spec = dep_spec_p (dep);
/* If this is a more restrictive type of dependence than the /* If this is a more restrictive type of dependence than the
existing one, then change the existing dependence to this existing one, then change the existing dependence to this
...@@ -1082,20 +1093,13 @@ update_dep (dep_t dep, dep_t new_dep, ...@@ -1082,20 +1093,13 @@ update_dep (dep_t dep, dep_t new_dep,
ds_t new_status = ds | dep_status; ds_t new_status = ds | dep_status;
if (new_status & SPECULATIVE) if (new_status & SPECULATIVE)
/* Either existing dep or a dep we're adding or both are
speculative. */
{ {
/* Either existing dep or a dep we're adding or both are
speculative. */
if (!(ds & SPECULATIVE) if (!(ds & SPECULATIVE)
|| !(dep_status & SPECULATIVE)) || !(dep_status & SPECULATIVE))
/* The new dep can't be speculative. */ /* The new dep can't be speculative. */
{ new_status &= ~SPECULATIVE;
new_status &= ~SPECULATIVE;
if (dep_status & SPECULATIVE)
/* The old dep was speculative, but now it
isn't. */
change_spec_dep_to_hard (sd_it);
}
else else
{ {
/* Both are speculative. Merge probabilities. */ /* Both are speculative. Merge probabilities. */
...@@ -1120,6 +1124,10 @@ update_dep (dep_t dep, dep_t new_dep, ...@@ -1120,6 +1124,10 @@ update_dep (dep_t dep, dep_t new_dep,
} }
} }
if (was_spec && !dep_spec_p (dep))
/* The old dep was speculative, but now it isn't. */
change_spec_dep_to_hard (sd_it);
if (true_dependency_cache != NULL if (true_dependency_cache != NULL
&& res == DEP_CHANGED) && res == DEP_CHANGED)
update_dependency_caches (dep, old_type); update_dependency_caches (dep, old_type);
...@@ -1220,8 +1228,7 @@ get_back_and_forw_lists (dep_t dep, bool resolved_p, ...@@ -1220,8 +1228,7 @@ get_back_and_forw_lists (dep_t dep, bool resolved_p,
if (!resolved_p) if (!resolved_p)
{ {
if ((current_sched_info->flags & DO_SPECULATION) if (dep_spec_p (dep))
&& (DEP_STATUS (dep) & SPECULATIVE))
*back_list_ptr = INSN_SPEC_BACK_DEPS (con); *back_list_ptr = INSN_SPEC_BACK_DEPS (con);
else else
*back_list_ptr = INSN_HARD_BACK_DEPS (con); *back_list_ptr = INSN_HARD_BACK_DEPS (con);
...@@ -1248,8 +1255,8 @@ sd_add_dep (dep_t dep, bool resolved_p) ...@@ -1248,8 +1255,8 @@ sd_add_dep (dep_t dep, bool resolved_p)
gcc_assert (INSN_P (insn) && INSN_P (elem) && insn != elem); gcc_assert (INSN_P (insn) && INSN_P (elem) && insn != elem);
if ((current_sched_info->flags & DO_SPECULATION) if ((current_sched_info->flags & DO_SPECULATION) == 0
&& !sched_insn_is_legitimate_for_speculation_p (insn, DEP_STATUS (dep))) || !sched_insn_is_legitimate_for_speculation_p (insn, DEP_STATUS (dep)))
DEP_STATUS (dep) &= ~SPECULATIVE; DEP_STATUS (dep) &= ~SPECULATIVE;
copy_dep (DEP_NODE_DEP (n), dep); copy_dep (DEP_NODE_DEP (n), dep);
...@@ -1289,8 +1296,7 @@ sd_resolve_dep (sd_iterator_def sd_it) ...@@ -1289,8 +1296,7 @@ sd_resolve_dep (sd_iterator_def sd_it)
rtx pro = DEP_PRO (dep); rtx pro = DEP_PRO (dep);
rtx con = DEP_CON (dep); rtx con = DEP_CON (dep);
if ((current_sched_info->flags & DO_SPECULATION) if (dep_spec_p (dep))
&& (DEP_STATUS (dep) & SPECULATIVE))
move_dep_link (DEP_NODE_BACK (node), INSN_SPEC_BACK_DEPS (con), move_dep_link (DEP_NODE_BACK (node), INSN_SPEC_BACK_DEPS (con),
INSN_RESOLVED_BACK_DEPS (con)); INSN_RESOLVED_BACK_DEPS (con));
else else
...@@ -1705,7 +1711,7 @@ haifa_note_mem_dep (rtx mem, rtx pending_mem, rtx pending_insn, ds_t ds) ...@@ -1705,7 +1711,7 @@ haifa_note_mem_dep (rtx mem, rtx pending_mem, rtx pending_insn, ds_t ds)
dep_def _dep, *dep = &_dep; dep_def _dep, *dep = &_dep;
init_dep_1 (dep, pending_insn, cur_insn, ds_to_dt (ds), init_dep_1 (dep, pending_insn, cur_insn, ds_to_dt (ds),
current_sched_info->flags & USE_DEPS_LIST ? ds : -1); current_sched_info->flags & USE_DEPS_LIST ? ds : 0);
maybe_add_or_update_dep_1 (dep, false, pending_mem, mem); maybe_add_or_update_dep_1 (dep, false, pending_mem, mem);
} }
...@@ -3512,18 +3518,23 @@ sched_free_deps (rtx head, rtx tail, bool resolved_p) ...@@ -3512,18 +3518,23 @@ sched_free_deps (rtx head, rtx tail, bool resolved_p)
rtx insn; rtx insn;
rtx next_tail = NEXT_INSN (tail); rtx next_tail = NEXT_INSN (tail);
/* We make two passes since some insns may be scheduled before their
dependencies are resolved. */
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
if (INSN_P (insn) && INSN_LUID (insn) > 0) if (INSN_P (insn) && INSN_LUID (insn) > 0)
{ {
/* Clear resolved back deps together with its dep_nodes. */
delete_dep_nodes_in_back_deps (insn, resolved_p);
/* Clear forward deps and leave the dep_nodes to the /* Clear forward deps and leave the dep_nodes to the
corresponding back_deps list. */ corresponding back_deps list. */
if (resolved_p) if (resolved_p)
clear_deps_list (INSN_RESOLVED_FORW_DEPS (insn)); clear_deps_list (INSN_RESOLVED_FORW_DEPS (insn));
else else
clear_deps_list (INSN_FORW_DEPS (insn)); clear_deps_list (INSN_FORW_DEPS (insn));
}
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
if (INSN_P (insn) && INSN_LUID (insn) > 0)
{
/* Clear resolved back deps together with its dep_nodes. */
delete_dep_nodes_in_back_deps (insn, resolved_p);
sd_finish_insn (insn); sd_finish_insn (insn);
} }
...@@ -4164,7 +4175,7 @@ check_dep (dep_t dep, bool relaxed_p) ...@@ -4164,7 +4175,7 @@ check_dep (dep_t dep, bool relaxed_p)
if (!(current_sched_info->flags & USE_DEPS_LIST)) if (!(current_sched_info->flags & USE_DEPS_LIST))
{ {
gcc_assert (ds == -1); gcc_assert (ds == 0);
return; return;
} }
......
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