/* Perform instruction reorganizations for delay slot filling.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu).
Hacked by Michael Tiemann (tiemann@cygnus.com).
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* Instruction reorganization pass.
static void fix_reg_dead_note (rtx, rtx);
static void update_reg_unused_notes (rtx, rtx);
static void fill_simple_delay_slots (int);
-static rtx fill_slots_from_thread (rtx, rtx, rtx, rtx, int, int, int, int,
+static rtx fill_slots_from_thread (rtx, rtx, rtx, rtx,
+ int, int, int, int,
int *, rtx);
static void fill_eager_delay_slots (void);
static void relax_delay_slots (rtx);
remove_note (tem, note);
break;
- case REG_LABEL:
+ case REG_LABEL_OPERAND:
+ case REG_LABEL_TARGET:
/* Keep the label reference count up to date. */
if (LABEL_P (XEXP (note, 0)))
LABEL_NUSES (XEXP (note, 0)) ++;
prev = PREV_INSN (seq_insn);
trial = XVECEXP (seq, 0, 0);
delete_related_insns (seq_insn);
- add_insn_after (trial, prev);
+ add_insn_after (trial, prev, NULL);
/* If there was a barrier after the old SEQUENCE, remit it. */
if (had_barrier)
/* We are moving this insn, not deleting it. We must
temporarily increment the use count on any referenced
label lest it be deleted by delete_related_insns. */
- note = find_reg_note (trial, REG_LABEL, 0);
- /* REG_LABEL could be NOTE_INSN_DELETED_LABEL too. */
- if (note && LABEL_P (XEXP (note, 0)))
+ for (note = REG_NOTES (trial);
+ note != NULL;
+ note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
+ || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
+ {
+ /* REG_LABEL_OPERAND could be
+ NOTE_INSN_DELETED_LABEL too. */
+ if (LABEL_P (XEXP (note, 0)))
+ LABEL_NUSES (XEXP (note, 0))++;
+ else
+ gcc_assert (REG_NOTE_KIND (note)
+ == REG_LABEL_OPERAND);
+ }
+ if (JUMP_P (trial) && JUMP_LABEL (trial))
LABEL_NUSES (XEXP (note, 0))++;
delete_related_insns (trial);
- if (note && LABEL_P (XEXP (note, 0)))
+ for (note = REG_NOTES (trial);
+ note != NULL;
+ note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
+ || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
+ {
+ /* REG_LABEL_OPERAND could be
+ NOTE_INSN_DELETED_LABEL too. */
+ if (LABEL_P (XEXP (note, 0)))
+ LABEL_NUSES (XEXP (note, 0))--;
+ else
+ gcc_assert (REG_NOTE_KIND (note)
+ == REG_LABEL_OPERAND);
+ }
+ if (JUMP_P (trial) && JUMP_LABEL (trial))
LABEL_NUSES (XEXP (note, 0))--;
}
else
&& REG_P (SET_DEST (pat)))
{
int dest_regno = REGNO (SET_DEST (pat));
- int dest_endregno
- = (dest_regno
- + (dest_regno < FIRST_PSEUDO_REGISTER
- ? hard_regno_nregs[dest_regno]
- [GET_MODE (SET_DEST (pat))] : 1));
+ int dest_endregno = END_REGNO (SET_DEST (pat));
int regno = REGNO (reg);
- int endregno
- = (regno
- + (regno < FIRST_PSEUDO_REGISTER
- ? hard_regno_nregs[regno][GET_MODE (reg)] : 1));
+ int endregno = END_REGNO (reg);
if (dest_regno >= regno
&& dest_endregno <= endregno)
for (i = 0; i < XVECLEN (pat, 0); i++)
{
rtx this_insn = XVECEXP (pat, 0, i);
- add_insn_after (this_insn, after);
+ add_insn_after (this_insn, after, NULL);
after = this_insn;
}
delete_scheduled_jump (delay_insn);
for (i = 0; i < XVECLEN (pat, 0); i++)
{
rtx this_insn = XVECEXP (pat, 0, i);
- add_insn_after (this_insn, after);
+ add_insn_after (this_insn, after, NULL);
after = this_insn;
}
delete_scheduled_jump (delay_insn);
if (INSN_UID (insn) > max_uid)
max_uid = INSN_UID (insn);
if (NOTE_P (insn)
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
+ && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
epilogue_insn = insn;
}
relax_delay_slots (first);
}
- /* Delete any USE insns made by update_block; subsequent passes don't need
- them or know how to deal with them. */
- for (insn = first; insn; insn = next)
- {
- next = NEXT_INSN (insn);
-
- if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
- && INSN_P (XEXP (PATTERN (insn), 0)))
- next = delete_related_insns (insn);
- }
-
/* If we made an end of function label, indicate that it is now
safe to delete it by undoing our prior adjustment to LABEL_NUSES.
If it is now unused, delete it. */
make_return_insns (first);
#endif
+ /* Delete any USE insns made by update_block; subsequent passes don't need
+ them or know how to deal with them. */
+ for (insn = first; insn; insn = next)
+ {
+ next = NEXT_INSN (insn);
+
+ if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
+ && INSN_P (XEXP (PATTERN (insn), 0)))
+ next = delete_related_insns (insn);
+ }
+
obstack_free (&unfilled_slots_obstack, unfilled_firstobj);
/* It is not clear why the line below is needed, but it does seem to be. */
link = XEXP (link, 1))
INSN_LOCATOR (XEXP (link, 0)) = 0;
}
+
#endif
}
#endif /* DELAY_SLOTS */
{
#ifdef DELAY_SLOTS
return flag_delayed_branch;
-#else
+#else
return 0;
#endif
}
dbr_schedule (get_insns ());
#endif
return 0;
-}
+}
struct tree_opt_pass pass_delay_slots =
{
TODO_ggc_collect, /* todo_flags_finish */
'M' /* letter */
};
-