Commit 2bd1e239 by Steven Bosscher Committed by Steven Bosscher

re PR rtl-optimization/17808 (Scheduler overly conservative in sched-deps)

	PR rtl-optimization/17808
	* sched-deps.c (sched_get_condition): Enable #if 0'ed code.
	(sched_insns_conditions_mutex_p): Split out from...
	(add_dependence): ...here.  But don't call it from here.
	(add_dependence_list): Check sched_insns_conditions_mutex_p
	before calling add_dependence.
	(add_dependence_list_and_free): Likewise.
	(fixup_sched_groups): Likewise.
	(sched_analyze_1): Likewise.
	(sched_analyze_2): Likewise (and replace a "0" with REG_DEP_TRUE).
	(sched_analyze): Likewise.
	(sched_analyze_insn): Likewise.
	* sched-ebb.c (add_deps_for_risky_insns): Likewise.
	* sched-rgn.c (add_branch_dependences): Likewise.  Also, add
	dependencies on all COND_EXEC insns to jumps ending basic blocks
	when doing intrablock scheduling.
	* sched-int.h (sched_insns_conditions_mutex_p): Add prototype.

From-SVN: r102433
parent 880031e1
2005-07-27 Steven Bosscher <stevenb@suse.de>
PR rtl-optimization/17808
* sched-deps.c (sched_get_condition): Enable #if 0'ed code.
(sched_insns_conditions_mutex_p): Split out from...
(add_dependence): ...here. But don't call it from here.
(add_dependence_list): Check sched_insns_conditions_mutex_p
before calling add_dependence.
(add_dependence_list_and_free): Likewise.
(fixup_sched_groups): Likewise.
(sched_analyze_1): Likewise.
(sched_analyze_2): Likewise (and replace a "0" with REG_DEP_TRUE).
(sched_analyze): Likewise.
(sched_analyze_insn): Likewise.
* sched-ebb.c (add_deps_for_risky_insns): Likewise.
* sched-rgn.c (add_branch_dependences): Likewise. Also, add
dependencies on all COND_EXEC insns to jumps ending basic blocks
when doing intrablock scheduling.
* sched-int.h (sched_insns_conditions_mutex_p): Add prototype.
2005-07-27 Jeff Law <law@redhat.com>
* tree-vrp.c (vrp_meet): Intersect the equivalency sets when
......
......@@ -454,7 +454,8 @@ add_deps_for_risky_insns (rtx head, rtx tail)
/* We can not change the mode of the backward
dependency because REG_DEP_ANTI has the lowest
rank. */
if (add_dependence (insn, prev, REG_DEP_ANTI))
if (! sched_insns_conditions_mutex_p (insn, prev)
&& add_dependence (insn, prev, REG_DEP_ANTI))
add_forward_dependence (prev, insn, REG_DEP_ANTI);
break;
......
......@@ -331,6 +331,7 @@ enum INSN_TRAP_CLASS
extern void print_insn (char *, rtx, int);
/* Functions in sched-deps.c. */
extern bool sched_insns_conditions_mutex_p (rtx, rtx);
extern int add_dependence (rtx, rtx, enum reg_note);
extern void sched_analyze (struct deps *, rtx, rtx);
extern void init_deps (struct deps *);
......
......@@ -1883,6 +1883,8 @@ add_branch_dependences (rtx head, rtx tail)
cc0 setters remain at the end because they can't be moved away from
their cc0 user.
COND_EXEC insns cannot be moved past a branch (see e.g. PR17808).
Insns setting CLASS_LIKELY_SPILLED_P registers (usually return values)
are not moved before reload because we can wind up with register
allocation failures. */
......@@ -1906,7 +1908,8 @@ add_branch_dependences (rtx head, rtx tail)
{
if (last != 0 && !find_insn_list (insn, LOG_LINKS (last)))
{
add_dependence (last, insn, REG_DEP_ANTI);
if (! sched_insns_conditions_mutex_p (last, insn))
add_dependence (last, insn, REG_DEP_ANTI);
INSN_REF_COUNT (insn)++;
}
......@@ -1932,9 +1935,61 @@ add_branch_dependences (rtx head, rtx tail)
if (INSN_REF_COUNT (insn) != 0)
continue;
add_dependence (last, insn, REG_DEP_ANTI);
if (! sched_insns_conditions_mutex_p (last, insn))
add_dependence (last, insn, REG_DEP_ANTI);
INSN_REF_COUNT (insn) = 1;
}
#ifdef HAVE_conditional_execution
/* Finally, if the block ends in a jump, and we are doing intra-block
scheduling, make sure that the branch depends on any COND_EXEC insns
inside the block to avoid moving the COND_EXECs past the branch insn.
We only have to do this after reload, because (1) before reload there
are no COND_EXEC insns, and (2) the region scheduler is an intra-block
scheduler after reload.
FIXME: We could in some cases move COND_EXEC insns past the branch if
this scheduler would be a little smarter. Consider this code:
T = [addr]
C ? addr += 4
!C ? X += 12
C ? T += 1
C ? jump foo
On a target with a one cycle stall on a memory access the optimal
sequence would be:
T = [addr]
C ? addr += 4
C ? T += 1
C ? jump foo
!C ? X += 12
We don't want to put the 'X += 12' before the branch because it just
wastes a cycle of execution time when the branch is taken.
Note that in the example "!C" will always be true. That is another
possible improvement for handling COND_EXECs in this scheduler: it
could remove always-true predicates. */
if (!reload_completed || ! JUMP_P (tail))
return;
insn = PREV_INSN (tail);
while (insn != head)
{
/* Note that we want to add this dependency even when
sched_insns_conditions_mutex_p returns true. The whole point
is that we _want_ this dependency, even if these insns really
are independent. */
if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
add_dependence (tail, insn, REG_DEP_ANTI);
insn = PREV_INSN (insn);
}
#endif
}
/* Data structures for the computation of data dependences in a regions. We
......
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