summaryrefslogtreecommitdiff
path: root/gcc/sched-rgn.c
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-27 16:28:34 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-27 16:28:34 +0000
commite6a25dc9635fe730190bb10c51710cd8193fc599 (patch)
tree1ce25616a076bf403e50c4f0efdf41ea5dca0507 /gcc/sched-rgn.c
parent98ab8375b04ae1edeb6e56f9ee3f1a41f5aa6563 (diff)
downloadgcc-e6a25dc9635fe730190bb10c51710cd8193fc599.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102433 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sched-rgn.c')
-rw-r--r--gcc/sched-rgn.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 1083c5c0cad..a4c19648200 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -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