diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-26 15:49:44 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-26 15:49:44 +0000 |
commit | fdb1b2b1b851c7da7b2027403c4833abdaa1fa8b (patch) | |
tree | 41e4c6b9bbf40426f2a4b10439f42d63cd539fe6 /gcc/sched-deps.c | |
parent | b30b031c80c745d45199d7052482b98d23413b50 (diff) | |
download | gcc-fdb1b2b1b851c7da7b2027403c4833abdaa1fa8b.tar.gz |
gcc/
* sched-deps.c (fixup_sched_groups): Rename to...
(chain_to_prev_insn): ...this.
(chain_to_prev_insn_p): New function.
(deps_analyze_insn): Use it instead of SCHED_GROUP_P.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186883 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sched-deps.c')
-rw-r--r-- | gcc/sched-deps.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 12ed38a59c4..4a0212112f2 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -477,7 +477,7 @@ static void add_dependence_list (rtx, rtx, int, enum reg_note); static void add_dependence_list_and_free (struct deps_desc *, rtx, rtx *, int, enum reg_note); static void delete_all_dependences (rtx); -static void fixup_sched_groups (rtx); +static void chain_to_prev_insn (rtx); static void flush_pending_lists (struct deps_desc *, rtx, int, int); static void sched_analyze_1 (struct deps_desc *, rtx, rtx); @@ -1652,7 +1652,7 @@ delete_all_dependences (rtx insn) the previous nonnote insn. */ static void -fixup_sched_groups (rtx insn) +chain_to_prev_insn (rtx insn) { sd_iterator_def sd_it; dep_t dep; @@ -3295,7 +3295,7 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn) instructions that follow seem like they should be part of the call group. - Also, if we did, fixup_sched_groups() would move the + Also, if we did, chain_to_prev_insn would move the deps of the debug insn to the call insn, modifying non-debug post-dependency counts of the debug insn dependencies and otherwise messing with the scheduling @@ -3441,6 +3441,37 @@ call_may_noreturn_p (rtx insn) return true; } +/* Return true if INSN should be made dependent on the previous instruction + group, and if all INSN's dependencies should be moved to the first + instruction of that group. */ + +static bool +chain_to_prev_insn_p (rtx insn) +{ + rtx prev, x; + + /* INSN forms a group with the previous instruction. */ + if (SCHED_GROUP_P (insn)) + return true; + + /* If the previous instruction clobbers a register R and this one sets + part of R, the clobber was added specifically to help us track the + liveness of R. There's no point scheduling the clobber and leaving + INSN behind, especially if we move the clobber to another block. */ + prev = prev_nonnote_nondebug_insn (insn); + if (prev + && INSN_P (prev) + && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn) + && GET_CODE (PATTERN (prev)) == CLOBBER) + { + x = XEXP (PATTERN (prev), 0); + if (set_of (x, insn)) + return true; + } + + return false; +} + /* Analyze INSN with DEPS as a context. */ void deps_analyze_insn (struct deps_desc *deps, rtx insn) @@ -3608,8 +3639,9 @@ deps_analyze_insn (struct deps_desc *deps, rtx insn) /* Fixup the dependencies in the sched group. */ if ((NONJUMP_INSN_P (insn) || JUMP_P (insn)) - && SCHED_GROUP_P (insn) && !sel_sched_p ()) - fixup_sched_groups (insn); + && chain_to_prev_insn_p (insn) + && !sel_sched_p ()) + chain_to_prev_insn (insn); } /* Initialize DEPS for the new block beginning with HEAD. */ |