diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-02 21:22:52 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-02 21:22:52 +0000 |
commit | 29bd1808340d56f994e393a956ebd4266565b242 (patch) | |
tree | bf741c1416516d6d4b65f9e54691a31b98962066 /gcc/recog.c | |
parent | 31a0482ddd058487fa2d22824997c09c00742d98 (diff) | |
download | gcc-29bd1808340d56f994e393a956ebd4266565b242.tar.gz |
Bob Manson <manson@charmed.cygnus.com>
* resource.c, resource.h: New files.
* haifa-sched.c (regno_use_in): Moved to rtlanal.c.
(split_block_insns): Moved to recog.c.
(update_flow_info): Make public.
* reorg.c: Moved the functions dealing with computing resource
usage to resource.c.
* sched.c (regno_use_in): Moved to rtlanal.c.
(update_flow_info): Make public.
(schedule_insns): Use split_block_insns.
* recog.c (split_block_insns): New function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24982 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index c62929c4938..a62027db0b7 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "real.h" #include "toplev.h" +#include "basic-block.h" #ifndef STACK_PUSH_CODE #ifdef STACK_GROWS_DOWNWARD @@ -2596,3 +2597,83 @@ reg_fits_class_p (operand, class, offset, mode) } #endif /* REGISTER_CONSTRAINTS */ + +/* Do the splitting of insns in the block B. Only try to actually split if + DO_SPLIT is true; otherwise, just remove nops. */ + +void +split_block_insns (b, do_split) + int b; + int do_split; +{ + rtx insn, next; + + for (insn = BLOCK_HEAD (b);; insn = next) + { + rtx set; + + /* Can't use `next_real_insn' because that + might go across CODE_LABELS and short-out basic blocks. */ + next = NEXT_INSN (insn); + if (GET_CODE (insn) != INSN) + { + if (insn == BLOCK_END (b)) + break; + + continue; + } + + /* Don't split no-op move insns. These should silently disappear + later in final. Splitting such insns would break the code + that handles REG_NO_CONFLICT blocks. */ + set = single_set (insn); + if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set))) + { + if (insn == BLOCK_END (b)) + break; + + /* Nops get in the way while scheduling, so delete them now if + register allocation has already been done. It is too risky + to try to do this before register allocation, and there are + unlikely to be very many nops then anyways. */ + if (reload_completed) + { + + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + } + + continue; + } + + if (do_split) + { + /* Split insns here to get max fine-grain parallelism. */ + rtx first = PREV_INSN (insn); + rtx notes = REG_NOTES (insn); + rtx last = try_split (PATTERN (insn), insn, 1); + + if (last != insn) + { + /* try_split returns the NOTE that INSN became. */ + first = NEXT_INSN (first); + update_flow_info (notes, first, last, insn); + + PUT_CODE (insn, NOTE); + NOTE_SOURCE_FILE (insn) = 0; + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + if (insn == BLOCK_HEAD (b)) + BLOCK_HEAD (b) = first; + if (insn == BLOCK_END (b)) + { + BLOCK_END (b) = last; + break; + } + } + } + + if (insn == BLOCK_END (b)) + break; + } +} |