diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1997-02-19 13:42:25 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1997-02-19 13:42:25 -0800 |
commit | e02fbefc82748bc33629bcb6a7ef3e6302711908 (patch) | |
tree | fd1052f64fe1d85a36e7aaf1fe0d6312142628ba /gcc/sched.c | |
parent | 101c1a3d93648d82511f33d826f1c64d33371463 (diff) | |
download | gcc-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.c | 43 |
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); |