diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-27 16:28:34 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-27 16:28:34 +0000 |
commit | e6a25dc9635fe730190bb10c51710cd8193fc599 (patch) | |
tree | 1ce25616a076bf403e50c4f0efdf41ea5dca0507 /gcc/sched-rgn.c | |
parent | 98ab8375b04ae1edeb6e56f9ee3f1a41f5aa6563 (diff) | |
download | gcc-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.c | 59 |
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 |