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> 2005-07-27 Jeff Law <law@redhat.com>
* tree-vrp.c (vrp_meet): Intersect the equivalency sets when * tree-vrp.c (vrp_meet): Intersect the equivalency sets when
......
...@@ -454,7 +454,8 @@ add_deps_for_risky_insns (rtx head, rtx tail) ...@@ -454,7 +454,8 @@ add_deps_for_risky_insns (rtx head, rtx tail)
/* We can not change the mode of the backward /* We can not change the mode of the backward
dependency because REG_DEP_ANTI has the lowest dependency because REG_DEP_ANTI has the lowest
rank. */ 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); add_forward_dependence (prev, insn, REG_DEP_ANTI);
break; break;
......
...@@ -331,6 +331,7 @@ enum INSN_TRAP_CLASS ...@@ -331,6 +331,7 @@ enum INSN_TRAP_CLASS
extern void print_insn (char *, rtx, int); extern void print_insn (char *, rtx, int);
/* Functions in sched-deps.c. */ /* Functions in sched-deps.c. */
extern bool sched_insns_conditions_mutex_p (rtx, rtx);
extern int add_dependence (rtx, rtx, enum reg_note); extern int add_dependence (rtx, rtx, enum reg_note);
extern void sched_analyze (struct deps *, rtx, rtx); extern void sched_analyze (struct deps *, rtx, rtx);
extern void init_deps (struct deps *); extern void init_deps (struct deps *);
......
...@@ -1883,6 +1883,8 @@ add_branch_dependences (rtx head, rtx tail) ...@@ -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 cc0 setters remain at the end because they can't be moved away from
their cc0 user. 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) Insns setting CLASS_LIKELY_SPILLED_P registers (usually return values)
are not moved before reload because we can wind up with register are not moved before reload because we can wind up with register
allocation failures. */ allocation failures. */
...@@ -1906,7 +1908,8 @@ add_branch_dependences (rtx head, rtx tail) ...@@ -1906,7 +1908,8 @@ add_branch_dependences (rtx head, rtx tail)
{ {
if (last != 0 && !find_insn_list (insn, LOG_LINKS (last))) 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)++; INSN_REF_COUNT (insn)++;
} }
...@@ -1932,9 +1935,61 @@ add_branch_dependences (rtx head, rtx tail) ...@@ -1932,9 +1935,61 @@ add_branch_dependences (rtx head, rtx tail)
if (INSN_REF_COUNT (insn) != 0) if (INSN_REF_COUNT (insn) != 0)
continue; 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; 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 /* 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