aboutsummaryrefslogtreecommitdiff
path: root/gcc/sched.c
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1997-02-19 13:42:25 -0800
committerJim Wilson <wilson@gcc.gnu.org>1997-02-19 13:42:25 -0800
commite02fbefc82748bc33629bcb6a7ef3e6302711908 (patch)
treefd1052f64fe1d85a36e7aaf1fe0d6312142628ba /gcc/sched.c
parent101c1a3d93648d82511f33d826f1c64d33371463 (diff)
downloadgcc-e02fbefc82748bc33629bcb6a7ef3e6302711908.zip
gcc-e02fbefc82748bc33629bcb6a7ef3e6302711908.tar.gz
gcc-e02fbefc82748bc33629bcb6a7ef3e6302711908.tar.bz2
(schedule_insns): If there was no first scheduling pass,
split instructions after reload. (update_flow_info): Tolerate some idiosyncrasies after reload. From-SVN: r13666
Diffstat (limited to 'gcc/sched.c')
-rw-r--r--gcc/sched.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/gcc/sched.c b/gcc/sched.c
index 3560711..edd5f65 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -4452,6 +4452,15 @@ update_flow_info (notes, first, last, orig_insn)
pattern, so we can safely ignore it. */
if (insn == first)
{
+ /* After reload, REG_DEAD notes come sometimes an
+ instruction after the register actually dies. */
+ if (reload_completed && REG_NOTE_KIND (note) == REG_DEAD)
+ {
+ XEXP (note, 1) = REG_NOTES (insn);
+ REG_NOTES (insn) = note;
+ break;
+ }
+
if (REG_NOTE_KIND (note) != REG_UNUSED)
abort ();
@@ -4480,6 +4489,15 @@ update_flow_info (notes, first, last, orig_insn)
uses it. */
break;
}
+ /* If this note refers to a multiple word hard
+ register, it may have been split into several smaller
+ hard register references. We could split the notes,
+ but simply dropping them is good enough. */
+ if (GET_CODE (orig_dest) == REG
+ && REGNO (orig_dest) < FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_NREGS (REGNO (orig_dest),
+ GET_MODE (orig_dest)) > 1)
+ break;
/* It must be set somewhere, fail if we couldn't find where it
was set. */
if (insn == last)
@@ -4516,7 +4534,22 @@ update_flow_info (notes, first, last, orig_insn)
/* The original dest must still be set someplace. Abort if we
couldn't find it. */
if (insn == first)
- abort ();
+ {
+ /* However, if this note refers to a multiple word hard
+ register, it may have been split into several smaller
+ hard register references. We could split the notes,
+ but simply dropping them is good enough. */
+ if (GET_CODE (orig_dest) == REG
+ && REGNO (orig_dest) < FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_NREGS (REGNO (orig_dest),
+ GET_MODE (orig_dest)) > 1)
+ break;
+ /* Likewise for multi-word memory references. */
+ if (GET_CODE (orig_dest) == MEM
+ && SIZE_FOR_MODE (orig_dest) > MOVE_MAX)
+ break;
+ abort ();
+ }
}
break;
@@ -4563,6 +4596,9 @@ update_flow_info (notes, first, last, orig_insn)
break;
case REG_INC:
+ /* reload sometimes leaves obsolete REG_INC notes around. */
+ if (reload_completed)
+ break;
/* This should be moved to whichever instruction now has the
increment operation. */
abort ();
@@ -4945,7 +4981,10 @@ schedule_insns (dump_file)
/* Split insns here to get max fine-grain parallelism. */
prev = PREV_INSN (insn);
- if (reload_completed == 0)
+ /* It is probably not worthwhile to try to split again in the
+ second pass. However, if flag_schedule_insns is not set,
+ the first and only (if any) scheduling pass is after reload. */
+ if (reload_completed == 0 || ! flag_schedule_insns)
{
rtx last, first = PREV_INSN (insn);
rtx notes = REG_NOTES (insn);