diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-04 17:46:14 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-04 17:46:14 +0000 |
commit | 37cde9fbd87fa48654189caaa91a1dd9da27f1e5 (patch) | |
tree | 100d6f14c9cba9eedae456288118fc9c150d270b /gcc/sched-deps.c | |
parent | f16b610238f6abc257898e58253e27a3aa5ca622 (diff) | |
download | gcc-37cde9fbd87fa48654189caaa91a1dd9da27f1e5.tar.gz |
* sched-int.h (struct deps): New field libcall_block_tail_insn.
* sched_deps.c (init_deps): Initialize libcall_block_tail_insn.
* sched_deps.c (sched_analyze_insn): If libcall_block_tail_insn
is set, then mark the current insn as being part of a libcall
scheduling group.
(sched_analyze): Set and clear libcall_block_tail_insn appropriately.
* haifa-sched.c (schedule_block): Do not count USE or CLOBBER
insns against the issue rate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54251 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sched-deps.c')
-rw-r--r-- | gcc/sched-deps.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 268f58e6cd1..ec18f9d1973 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -1163,6 +1163,16 @@ sched_analyze_insn (deps, x, insn, loop_notes) CLEAR_REG_SET (reg_pending_clobbers); CLEAR_REG_SET (reg_pending_sets); + /* If we are currently in a libcall scheduling group, then mark the + current insn as being in a scheduling group and that it can not + be moved into a different basic block. */ + + if (deps->libcall_block_tail_insn) + { + set_sched_group_p (insn); + CANT_MOVE (insn) = 1; + } + /* If a post-call group is still open, see if it should remain so. This insn must be a simple move of a hard reg to a pseudo or vice-versa. @@ -1226,6 +1236,8 @@ sched_analyze (deps, head, tail) for (insn = head;; insn = NEXT_INSN (insn)) { + rtx link, end_seq, r0, set, note; + if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) { /* Clear out the stale LOG_LINKS from flow. */ @@ -1340,6 +1352,46 @@ sched_analyze (deps, head, tail) if (current_sched_info->use_cselib) cselib_process_insn (insn); + + /* Now that we have completed handling INSN, check and see if it is + a CLOBBER beginning a libcall block. If it is, record the + end of the libcall sequence. + + We want to schedule libcall blocks as a unit before reload. While + this restricts scheduling, it preserves the meaning of a libcall + block. + + As a side effect, we may get better code due to decreased register + pressure as well as less chance of a foreign insn appearing in + a libcall block. */ + if (!reload_completed + /* Note we may have nested libcall sequences. We only care about + the outermost libcall sequence. */ + && deps->libcall_block_tail_insn == 0 + /* The sequence must start with a clobber of a register. */ + && GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == CLOBBER + && (r0 = XEXP (PATTERN (insn), 0), GET_CODE (r0) == REG) + && GET_CODE (XEXP (PATTERN (insn), 0)) == REG + /* The CLOBBER must also have a REG_LIBCALL note attached. */ + && (link = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0 + && (end_seq = XEXP (link, 0)) != 0 + /* The insn referenced by the REG_LIBCALL note must be a + simple nop copy with the same destination as the register + mentioned in the clobber. */ + && (set = single_set (end_seq)) != 0 + && SET_DEST (set) == r0 && SET_SRC (set) == r0 + /* And finally the insn referenced by the REG_LIBCALL must + also contain a REG_EQUAL note and a REG_RETVAL note. */ + && find_reg_note (end_seq, REG_EQUAL, NULL_RTX) != 0 + && find_reg_note (end_seq, REG_RETVAL, NULL_RTX) != 0) + deps->libcall_block_tail_insn = XEXP (link, 0); + + /* If we have reached the end of a libcall block, then close the + block. */ + if (deps->libcall_block_tail_insn == insn) + deps->libcall_block_tail_insn = 0; + if (insn == tail) { if (current_sched_info->use_cselib) @@ -1433,6 +1485,7 @@ init_deps (deps) deps->last_function_call = 0; deps->sched_before_next_call = 0; deps->in_post_call_group_p = false; + deps->libcall_block_tail_insn = 0; } /* Free insn lists found in DEPS. */ |