aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorBob Manson <manson@charmed.cygnus.com>1999-02-02 21:22:52 +0000
committerRichard Henderson <rth@gcc.gnu.org>1999-02-02 13:22:52 -0800
commitca545bb569b7560793928e1c597bb1df499f8855 (patch)
treebf741c1416516d6d4b65f9e54691a31b98962066 /gcc/recog.c
parentee0d2cf3227a2bddf6a1ff20971284e8e6823d78 (diff)
downloadgcc-ca545bb569b7560793928e1c597bb1df499f8855.zip
gcc-ca545bb569b7560793928e1c597bb1df499f8855.tar.gz
gcc-ca545bb569b7560793928e1c597bb1df499f8855.tar.bz2
Bob Manson <manson@charmed.cygnus.com>
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. From-SVN: r24982
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index c62929c..a62027d 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;
+ }
+}