This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to fix sched2 REG_DEAD note handling
- To: egcs-patches at egcs dot cygnus dot com
- Subject: Patch to fix sched2 REG_DEAD note handling
- From: John Wehle <john at feith dot com>
- Date: Thu, 17 Jun 1999 12:37:57 -0400 (EDT)
This patch causes gcc to recreate the REG_DEAD notes during sched2 which
allows delete_computation to be more aggressive.
Notes:
1) The actual changes are very minor. The patch is rather large simply
because of identing changes.
2) Haifa will be addressed in a separate patch.
ChangeLog:
Thu Jun 17 01:45:09 EDT 1999 John Wehle (john@feith.com)
* sched.c (attach_deaths_insn): Skip prologue and epilogue insns.
(schedule_block): Also recreate REG_DEAD notes after reload.
(schedule_insns): Allocate and free the necessary resources to do so.
(schedule_insns): Mark prologue and epilogue insns.
* rtl.h (rtx_def): Update "used" field comment.
* jump.c (delete_computation): Recursively delete insns even if
the traditional scheduler was run after reload.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/sched.c.ORIGINAL Wed Jun 16 00:20:45 1999
--- gcc/sched.c Thu Jun 17 01:42:32 1999
*************** Boston, MA 02111-1307, USA. */
*** 125,130 ****
--- 125,131 ----
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
+ #include "insn-flags.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
*************** attach_deaths_insn (insn)
*** 2425,2430 ****
--- 2426,2436 ----
register RTX_CODE code = GET_CODE (x);
rtx link;
+ /* Skip prologue and epilogue instructions since they are not processed
+ by flow. */
+ if (insn->used)
+ return;
+
if (code == SET)
{
attach_deaths (SET_SRC (x), insn, 0);
*************** schedule_block (b, file)
*** 2881,2972 ****
Recreate the register life information for the end of this basic
block. */
! if (reload_completed == 0)
! {
! COPY_REG_SET (bb_live_regs, BASIC_BLOCK (b)->global_live_at_start);
! CLEAR_REG_SET (bb_dead_regs);
! if (b == 0)
! {
! /* This is the first block in the function. There may be insns
! before head that we can't schedule. We still need to examine
! them though for accurate register lifetime analysis. */
! /* We don't want to remove any REG_DEAD notes as the code below
! does. */
! for (insn = BLOCK_HEAD (b); insn != head;
! insn = NEXT_INSN (insn))
! if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
! /* See if the register gets born here. */
! /* We must check for registers being born before we check for
! registers dying. It is possible for a register to be born
! and die in the same insn, e.g. reading from a volatile
! memory location into an otherwise unused register. Such
! a register must be marked as dead after this insn. */
! if (GET_CODE (PATTERN (insn)) == SET
! || GET_CODE (PATTERN (insn)) == CLOBBER)
! sched_note_set (PATTERN (insn), 0);
! else if (GET_CODE (PATTERN (insn)) == PARALLEL)
! {
! int j;
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
! || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
!
! /* ??? This code is obsolete and should be deleted. It
! is harmless though, so we will leave it in for now. */
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == USE)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
! }
! /* Each call clobbers (makes live) all call-clobbered regs
! that are not global or fixed. Note that the function-value
! reg is a call_clobbered reg. */
! if (GET_CODE (insn) == CALL_INSN)
! {
! int j;
! for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
! if (call_used_regs[j] && ! global_regs[j]
! && ! fixed_regs[j])
! {
! SET_REGNO_REG_SET (bb_live_regs, j);
! CLEAR_REGNO_REG_SET (bb_dead_regs, j);
! }
! }
! for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
! if ((REG_NOTE_KIND (link) == REG_DEAD
! || REG_NOTE_KIND (link) == REG_UNUSED)
! /* Verify that the REG_NOTE has a valid value. */
! && GET_CODE (XEXP (link, 0)) == REG)
! {
! register int regno = REGNO (XEXP (link, 0));
! if (regno < FIRST_PSEUDO_REGISTER)
! {
! int j = HARD_REGNO_NREGS (regno,
! GET_MODE (XEXP (link, 0)));
! while (--j >= 0)
! {
! CLEAR_REGNO_REG_SET (bb_live_regs, regno + j);
! SET_REGNO_REG_SET (bb_dead_regs, regno + j);
! }
! }
! else
{
! CLEAR_REGNO_REG_SET (bb_live_regs, regno);
! SET_REGNO_REG_SET (bb_dead_regs, regno);
}
}
}
}
! }
}
/* If debugging information is being produced, keep track of the line
--- 2887,2975 ----
Recreate the register life information for the end of this basic
block. */
! COPY_REG_SET (bb_live_regs, BASIC_BLOCK (b)->global_live_at_start);
! CLEAR_REG_SET (bb_dead_regs);
! if (b == 0)
! {
! /* This is the first block in the function. There may be insns
! before head that we can't schedule. We still need to examine
! them though for accurate register lifetime analysis. */
! /* We don't want to remove any REG_DEAD notes as the code below
! does. */
! for (insn = BLOCK_HEAD (b); insn != head;
! insn = NEXT_INSN (insn))
! if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
! {
! /* See if the register gets born here. */
! /* We must check for registers being born before we check for
! registers dying. It is possible for a register to be born
! and die in the same insn, e.g. reading from a volatile
! memory location into an otherwise unused register. Such
! a register must be marked as dead after this insn. */
! if (GET_CODE (PATTERN (insn)) == SET
! || GET_CODE (PATTERN (insn)) == CLOBBER)
! sched_note_set (PATTERN (insn), 0);
! else if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
! int j;
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
! || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
!
! /* ??? This code is obsolete and should be deleted. It
! is harmless though, so we will leave it in for now. */
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == USE)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
! }
! /* Each call clobbers (makes live) all call-clobbered regs
! that are not global or fixed. Note that the function-value
! reg is a call_clobbered reg. */
! if (GET_CODE (insn) == CALL_INSN)
! {
! int j;
! for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
! if (call_used_regs[j] && ! global_regs[j]
! && ! fixed_regs[j])
! {
! SET_REGNO_REG_SET (bb_live_regs, j);
! CLEAR_REGNO_REG_SET (bb_dead_regs, j);
! }
! }
! for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! {
! if ((REG_NOTE_KIND (link) == REG_DEAD
! || REG_NOTE_KIND (link) == REG_UNUSED)
! /* Verify that the REG_NOTE has a valid value. */
! && GET_CODE (XEXP (link, 0)) == REG)
{
! register int regno = REGNO (XEXP (link, 0));
! if (regno < FIRST_PSEUDO_REGISTER)
! {
! int j = HARD_REGNO_NREGS (regno,
! GET_MODE (XEXP (link, 0)));
! while (--j >= 0)
{
! CLEAR_REGNO_REG_SET (bb_live_regs, regno + j);
! SET_REGNO_REG_SET (bb_dead_regs, regno + j);
}
}
+ else
+ {
+ CLEAR_REGNO_REG_SET (bb_live_regs, regno);
+ SET_REGNO_REG_SET (bb_dead_regs, regno);
+ }
}
}
! }
}
/* If debugging information is being produced, keep track of the line
*************** schedule_block (b, file)
*** 3006,3013 ****
abort ();
}
! if (reload_completed == 0
! && GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
/* See if the register gets born here. */
/* We must check for registers being born before we check for
--- 3009,3015 ----
abort ();
}
! if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
/* See if the register gets born here. */
/* We must check for registers being born before we check for
*************** schedule_block (b, file)
*** 3096,3118 ****
}
}
! if (reload_completed == 0)
! {
! /* Keep track of register lives. */
! old_live_regs = ALLOCA_REG_SET ();
! regs_sometimes_live
! = (struct sometimes *) alloca (max_regno * sizeof (struct sometimes));
! sometimes_max = 0;
!
! /* Start with registers live at end. */
! COPY_REG_SET (old_live_regs, bb_live_regs);
! EXECUTE_IF_SET_IN_REG_SET (bb_live_regs, 0, j,
! {
! sometimes_max
! = new_sometimes_live (regs_sometimes_live,
! j, sometimes_max);
! });
! }
SCHED_SORT (ready, n_ready, 1);
--- 3098,3117 ----
}
}
! /* Keep track of register lives. */
! old_live_regs = ALLOCA_REG_SET ();
! regs_sometimes_live
! = (struct sometimes *) alloca (max_regno * sizeof (struct sometimes));
! sometimes_max = 0;
!
! /* Start with registers live at end. */
! COPY_REG_SET (old_live_regs, bb_live_regs);
! EXECUTE_IF_SET_IN_REG_SET (bb_live_regs, 0, j,
! {
! sometimes_max
! = new_sometimes_live (regs_sometimes_live,
! j, sometimes_max);
! });
SCHED_SORT (ready, n_ready, 1);
*************** schedule_block (b, file)
*** 3241,3352 ****
if (DONE_PRIORITY_P (insn))
abort ();
! if (reload_completed == 0)
{
! /* Process this insn, and each insn linked to this one which must
! be immediately output after this insn. */
! do
! {
! /* First we kill registers set by this insn, and then we
! make registers used by this insn live. This is the opposite
! order used above because we are traversing the instructions
! backwards. */
!
! /* Strictly speaking, we should scan REG_UNUSED notes and make
! every register mentioned there live, however, we will just
! kill them again immediately below, so there doesn't seem to
! be any reason why we bother to do this. */
!
! /* See if this is the last notice we must take of a register. */
! if (GET_CODE (PATTERN (insn)) == SET
! || GET_CODE (PATTERN (insn)) == CLOBBER)
! sched_note_set (PATTERN (insn), 1);
! else if (GET_CODE (PATTERN (insn)) == PARALLEL)
! {
! int j;
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
! || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 1);
! }
!
! /* This code keeps life analysis information up to date. */
! if (GET_CODE (insn) == CALL_INSN)
! {
! register struct sometimes *p;
! /* A call kills all call used registers that are not
! global or fixed, except for those mentioned in the call
! pattern which will be made live again later. */
! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (call_used_regs[i] && ! global_regs[i]
! && ! fixed_regs[i])
! {
! CLEAR_REGNO_REG_SET (bb_live_regs, i);
! SET_REGNO_REG_SET (bb_dead_regs, i);
! }
! /* Regs live at the time of a call instruction must not
! go in a register clobbered by calls. Record this for
! all regs now live. Note that insns which are born or
! die in a call do not cross a call, so this must be done
! after the killings (above) and before the births
! (below). */
! p = regs_sometimes_live;
! for (i = 0; i < sometimes_max; i++, p++)
! if (REGNO_REG_SET_P (bb_live_regs, p->regno))
! p->calls_crossed += 1;
! }
! /* Make every register used live, and add REG_DEAD notes for
! registers which were not live before we started. */
! attach_deaths_insn (insn);
!
! /* Find registers now made live by that instruction. */
! EXECUTE_IF_AND_COMPL_IN_REG_SET (bb_live_regs, old_live_regs, 0, i,
! {
! sometimes_max
! = new_sometimes_live (regs_sometimes_live,
! i, sometimes_max);
! });
! IOR_REG_SET (old_live_regs, bb_live_regs);
! /* Count lengths of all regs we are worrying about now,
! and handle registers no longer live. */
! for (i = 0; i < sometimes_max; i++)
! {
! register struct sometimes *p = ®s_sometimes_live[i];
! int regno = p->regno;
! p->live_length += 1;
! if (!REGNO_REG_SET_P (bb_live_regs, p->regno))
! {
! /* This is the end of one of this register's lifetime
! segments. Save the lifetime info collected so far,
! and clear its bit in the old_live_regs entry. */
! sched_reg_live_length[regno] += p->live_length;
! sched_reg_n_calls_crossed[regno] += p->calls_crossed;
! CLEAR_REGNO_REG_SET (old_live_regs, p->regno);
!
! /* Delete the reg_sometimes_live entry for this reg by
! copying the last entry over top of it. */
! *p = regs_sometimes_live[--sometimes_max];
! /* ...and decrement i so that this newly copied entry
! will be processed. */
! i--;
! }
}
-
- link = insn;
- insn = PREV_INSN (insn);
}
- while (SCHED_GROUP_P (link));
! /* Set INSN back to the insn we are scheduling now. */
! insn = ready[0];
}
/* Schedule INSN. Remove it from the ready list. */
ready += 1;
--- 3240,3348 ----
if (DONE_PRIORITY_P (insn))
abort ();
! /* Process this insn, and each insn linked to this one which must
! be immediately output after this insn. */
! do
{
! /* First we kill registers set by this insn, and then we
! make registers used by this insn live. This is the opposite
! order used above because we are traversing the instructions
! backwards. */
!
! /* Strictly speaking, we should scan REG_UNUSED notes and make
! every register mentioned there live, however, we will just
! kill them again immediately below, so there doesn't seem to
! be any reason why we bother to do this. */
! /* See if this is the last notice we must take of a register. */
! if (GET_CODE (PATTERN (insn)) == SET
! || GET_CODE (PATTERN (insn)) == CLOBBER)
! sched_note_set (PATTERN (insn), 1);
! else if (GET_CODE (PATTERN (insn)) == PARALLEL)
! {
! int j;
! for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
! if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
! || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
! sched_note_set (XVECEXP (PATTERN (insn), 0, j), 1);
! }
!
! /* This code keeps life analysis information up to date. */
! if (GET_CODE (insn) == CALL_INSN)
! {
! register struct sometimes *p;
! /* A call kills all call used registers that are not
! global or fixed, except for those mentioned in the call
! pattern which will be made live again later. */
! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (call_used_regs[i] && ! global_regs[i]
! && ! fixed_regs[i])
! {
! CLEAR_REGNO_REG_SET (bb_live_regs, i);
! SET_REGNO_REG_SET (bb_dead_regs, i);
! }
! /* Regs live at the time of a call instruction must not
! go in a register clobbered by calls. Record this for
! all regs now live. Note that insns which are born or
! die in a call do not cross a call, so this must be done
! after the killings (above) and before the births
! (below). */
! p = regs_sometimes_live;
! for (i = 0; i < sometimes_max; i++, p++)
! if (REGNO_REG_SET_P (bb_live_regs, p->regno))
! p->calls_crossed += 1;
! }
!
! /* Make every register used live, and add REG_DEAD notes for
! registers which were not live before we started. */
! attach_deaths_insn (insn);
!
! /* Find registers now made live by that instruction. */
! EXECUTE_IF_AND_COMPL_IN_REG_SET (bb_live_regs, old_live_regs, 0, i,
! {
! sometimes_max
! = new_sometimes_live (regs_sometimes_live,
! i, sometimes_max);
! });
! IOR_REG_SET (old_live_regs, bb_live_regs);
! /* Count lengths of all regs we are worrying about now,
! and handle registers no longer live. */
! for (i = 0; i < sometimes_max; i++)
! {
! register struct sometimes *p = ®s_sometimes_live[i];
! int regno = p->regno;
! p->live_length += 1;
! if (!REGNO_REG_SET_P (bb_live_regs, p->regno))
! {
! /* This is the end of one of this register's lifetime
! segments. Save the lifetime info collected so far,
! and clear its bit in the old_live_regs entry. */
! sched_reg_live_length[regno] += p->live_length;
! sched_reg_n_calls_crossed[regno] += p->calls_crossed;
! CLEAR_REGNO_REG_SET (old_live_regs, p->regno);
!
! /* Delete the reg_sometimes_live entry for this reg by
! copying the last entry over top of it. */
! *p = regs_sometimes_live[--sometimes_max];
! /* ...and decrement i so that this newly copied entry
! will be processed. */
! i--;
}
}
! link = insn;
! insn = PREV_INSN (insn);
}
+ while (SCHED_GROUP_P (link));
+
+ /* Set INSN back to the insn we are scheduling now. */
+ insn = ready[0];
/* Schedule INSN. Remove it from the ready list. */
ready += 1;
*************** schedule_block (b, file)
*** 3421,3428 ****
if (q_size != 0)
abort ();
! if (reload_completed == 0)
! finish_sometimes_live (regs_sometimes_live, sometimes_max);
/* HEAD is now the first insn in the chain of insns that
been scheduled by the loop above.
--- 3417,3423 ----
if (q_size != 0)
abort ();
! finish_sometimes_live (regs_sometimes_live, sometimes_max);
/* HEAD is now the first insn in the chain of insns that
been scheduled by the loop above.
*************** schedule_insns (dump_file)
*** 4222,4227 ****
--- 4217,4224 ----
{
int max_uid = MAX_INSNS_PER_SPLIT * (get_max_uid () + 1);
int b;
+ int prologue_insns;
+ int epilogue_insns;
rtx insn;
/* Taking care of this degenerate case makes the rest of
*************** schedule_insns (dump_file)
*** 4263,4284 ****
insn_blockage = (unsigned int *) xmalloc (max_uid * sizeof (unsigned int));
insn_ref_count = (int *) xmalloc (max_uid * sizeof (int));
! if (reload_completed == 0)
! {
! sched_reg_n_calls_crossed = (int *) alloca (max_regno * sizeof (int));
! sched_reg_live_length = (int *) alloca (max_regno * sizeof (int));
! bb_dead_regs = ALLOCA_REG_SET ();
! bb_live_regs = ALLOCA_REG_SET ();
! bzero ((char *) sched_reg_n_calls_crossed, max_regno * sizeof (int));
! bzero ((char *) sched_reg_live_length, max_regno * sizeof (int));
! }
! else
! {
! sched_reg_n_calls_crossed = 0;
! sched_reg_live_length = 0;
! bb_dead_regs = 0;
! bb_live_regs = 0;
! }
init_alias_analysis ();
if (write_symbols != NO_DEBUG)
--- 4260,4272 ----
insn_blockage = (unsigned int *) xmalloc (max_uid * sizeof (unsigned int));
insn_ref_count = (int *) xmalloc (max_uid * sizeof (int));
! sched_reg_n_calls_crossed = (int *) alloca (max_regno * sizeof (int));
! sched_reg_live_length = (int *) alloca (max_regno * sizeof (int));
! bb_dead_regs = ALLOCA_REG_SET ();
! bb_live_regs = ALLOCA_REG_SET ();
! bzero ((char *) sched_reg_n_calls_crossed, max_regno * sizeof (int));
! bzero ((char *) sched_reg_live_length, max_regno * sizeof (int));
!
init_alias_analysis ();
if (write_symbols != NO_DEBUG)
*************** schedule_insns (dump_file)
*** 4329,4340 ****
--- 4317,4358 ----
&& GET_CODE (NEXT_INSN (insn)) == BARRIER)))
emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks-1));
+ #ifdef HAVE_prologue
+ prologue_insns = 1;
+ #else
+ prologue_insns = 0;
+ #endif
+
for (b = 0; b < n_basic_blocks; b++)
{
note_list = 0;
split_block_insns (b, reload_completed == 0 || ! flag_schedule_insns);
+ /* Mark the prologue and epilogue instructions so that
+ attach_deaths_insn can skip them. */
+ for (epilogue_insns = 0, insn = BLOCK_HEAD (b);
+ insn && insn != NEXT_INSN (BLOCK_END (b));
+ insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == NOTE)
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
+ prologue_insns = 0;
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
+ epilogue_insns = 1;
+
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ insn->used = prologue_insns || epilogue_insns;
+
+ /* USE instructions are not (for attach_deaths_insn purposes)
+ part of the epilogue. This may lose if gen_epilogue ever
+ outputs a USE instruction. */
+ if (epilogue_insns
+ && GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == USE)
+ insn->used = 0;
+ }
+
schedule_block (b, dump_file);
#ifdef USE_C_ALLOCA
*************** schedule_insns (dump_file)
*** 4460,4470 ****
if (write_symbols != NO_DEBUG)
free (line_note);
! if (reload_completed == 0)
! {
! FREE_REG_SET (bb_dead_regs);
! FREE_REG_SET (bb_live_regs);
! }
!
}
#endif /* INSN_SCHEDULING */
--- 4478,4484 ----
if (write_symbols != NO_DEBUG)
free (line_note);
! FREE_REG_SET (bb_dead_regs);
! FREE_REG_SET (bb_live_regs);
}
#endif /* INSN_SCHEDULING */
*** gcc/rtl.h.ORIGINAL Mon May 31 11:22:57 1999
--- gcc/rtl.h Wed Jun 16 23:38:51 1999
*************** typedef struct rtx_def
*** 157,163 ****
In a REG, this is not needed for that purpose, and used instead
in `leaf_renumber_regs_insn'.
In a SYMBOL_REF, means that emit_library_call
! has used it as the function. */
unsigned int used : 1;
/* Nonzero if this rtx came from procedure integration.
In a REG, nonzero means this reg refers to the return value
--- 157,165 ----
In a REG, this is not needed for that purpose, and used instead
in `leaf_renumber_regs_insn'.
In a SYMBOL_REF, means that emit_library_call
! has used it as the function.
! 1 in an INSN, JUMP_INSN, or CALL_INSN if this insn is part of the
! prologue or epilogue. Valid only within sched. */
unsigned int used : 1;
/* Nonzero if this rtx came from procedure integration.
In a REG, nonzero means this reg refers to the return value
*** gcc/jump.c.ORIGINAL Wed Jun 16 00:18:28 1999
--- gcc/jump.c Wed Jun 16 01:33:26 1999
*************** delete_computation (insn)
*** 3835,3844 ****
}
#endif
! #ifdef INSN_SCHEDULING
! /* ?!? The schedulers do not keep REG_DEAD notes accurate after
! reload has completed. The schedulers need to be fixed. Until
! they are, we must not rely on the death notes here. */
if (reload_completed && flag_schedule_insns_after_reload)
{
delete_insn (insn);
--- 3835,3844 ----
}
#endif
! #ifdef HAIFA
! /* ?!? The haifa scheduler does not keep REG_DEAD notes accurate after
! reload has completed. The scheduler need to be fixed. Until
! it is, we must not rely on the death notes here. */
if (reload_completed && flag_schedule_insns_after_reload)
{
delete_insn (insn);
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------