/* Register renaming for the GNU compiler.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
+ 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 version.
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#define REG_OK_STRICT
rtx *loc;
enum reg_class class;
unsigned int need_caller_save_reg:1;
+ unsigned int earlyclobber:1;
};
enum scan_actions
{
- note_reference,
terminate_all_read,
terminate_overlapping_read,
terminate_write,
static const char * const scan_actions_name[] =
{
- "note_reference",
"terminate_all_read",
"terminate_overlapping_read",
"terminate_write",
static void do_replace PARAMS ((struct du_chain *, int));
static void scan_rtx_reg PARAMS ((rtx, rtx *, enum reg_class,
- enum scan_actions, enum op_type));
+ enum scan_actions, enum op_type, int));
static void scan_rtx_address PARAMS ((rtx, rtx *, enum reg_class,
enum scan_actions, enum machine_mode));
static void scan_rtx PARAMS ((rtx, rtx *, enum reg_class,
- enum scan_actions, enum op_type));
-static struct du_chain *build_def_use PARAMS ((basic_block, HARD_REG_SET *));
+ enum scan_actions, enum op_type, int));
+static struct du_chain *build_def_use PARAMS ((basic_block));
static void dump_def_use_chain PARAMS ((struct du_chain *));
+static void note_sets PARAMS ((rtx, rtx, void *));
+static void clear_dead_regs PARAMS ((HARD_REG_SET *, enum machine_mode, rtx));
+static void merge_overlapping_regs PARAMS ((basic_block, HARD_REG_SET *,
+ struct du_chain *));
+
+/* Called through note_stores from update_life. Find sets of registers, and
+ record them in *DATA (which is actually a HARD_REG_SET *). */
+
+static void
+note_sets (x, set, data)
+ rtx x;
+ rtx set ATTRIBUTE_UNUSED;
+ void *data;
+{
+ HARD_REG_SET *pset = (HARD_REG_SET *) data;
+ unsigned int regno;
+ int nregs;
+ if (GET_CODE (x) != REG)
+ return;
+ regno = REGNO (x);
+ nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
+ while (nregs-- > 0)
+ SET_HARD_REG_BIT (*pset, regno + nregs);
+}
+
+/* Clear all registers from *PSET for which a note of kind KIND can be found
+ in the list NOTES. */
+
+static void
+clear_dead_regs (pset, kind, notes)
+ HARD_REG_SET *pset;
+ enum machine_mode kind;
+ rtx notes;
+{
+ rtx note;
+ for (note = notes; note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == kind && REG_P (XEXP (note, 0)))
+ {
+ rtx reg = XEXP (note, 0);
+ unsigned int regno = REGNO (reg);
+ int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ while (nregs-- > 0)
+ CLEAR_HARD_REG_BIT (*pset, regno + nregs);
+ }
+}
+
+/* For a def-use chain CHAIN in basic block B, find which registers overlap
+ its lifetime and set the corresponding bits in *PSET. */
+
+static void
+merge_overlapping_regs (b, pset, chain)
+ basic_block b;
+ HARD_REG_SET *pset;
+ struct du_chain *chain;
+{
+ struct du_chain *t = chain;
+ rtx insn;
+ HARD_REG_SET live;
+
+ REG_SET_TO_HARD_REG_SET (live, b->global_live_at_start);
+ insn = b->head;
+ while (t)
+ {
+ /* Search forward until the next reference to the register to be
+ renamed. */
+ while (insn != t->insn)
+ {
+ if (INSN_P (insn))
+ {
+ clear_dead_regs (&live, REG_DEAD, REG_NOTES (insn));
+ note_stores (PATTERN (insn), note_sets, (void *) &live);
+ /* Only record currently live regs if we are inside the
+ reg's live range. */
+ if (t != chain)
+ IOR_HARD_REG_SET (*pset, live);
+ clear_dead_regs (&live, REG_UNUSED, REG_NOTES (insn));
+ }
+ insn = NEXT_INSN (insn);
+ }
+
+ IOR_HARD_REG_SET (*pset, live);
+
+ /* For the last reference, also merge in all registers set in the
+ same insn.
+ @@@ We only have take earlyclobbered sets into account. */
+ if (! t->next_use)
+ note_stores (PATTERN (insn), note_sets, (void *) pset);
+
+ t = t->next_use;
+ }
+}
+
+/* Perform register renaming on the current function. */
void
regrename_optimize ()
{
+ int tick[FIRST_PSEUDO_REGISTER];
+ int this_tick = 0;
int b;
char *first_obj;
+ memset (tick, 0, sizeof tick);
+
gcc_obstack_init (&rename_obstack);
first_obj = (char *) obstack_alloc (&rename_obstack, 0);
{
basic_block bb = BASIC_BLOCK (b);
struct du_chain *all_chains = 0;
- HARD_REG_SET regs_used;
HARD_REG_SET unavailable;
HARD_REG_SET regs_seen;
- CLEAR_HARD_REG_SET (regs_used);
CLEAR_HARD_REG_SET (unavailable);
if (rtl_dump_file)
fprintf (rtl_dump_file, "\nBasic block %d:\n", b);
- all_chains = build_def_use (bb, ®s_used);
+ all_chains = build_def_use (bb);
if (rtl_dump_file)
dump_def_use_chain (all_chains);
- /* Available registers are not: used in the block, live at the start
- live at the end, a register we've renamed to. */
- REG_SET_TO_HARD_REG_SET (unavailable, bb->global_live_at_start);
- REG_SET_TO_HARD_REG_SET (regs_seen, bb->global_live_at_end);
- IOR_HARD_REG_SET (unavailable, regs_seen);
- IOR_HARD_REG_SET (unavailable, regs_used);
-
+ CLEAR_HARD_REG_SET (unavailable);
/* Don't clobber traceback for noreturn functions. */
if (frame_pointer_needed)
{
- SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM);
+ int i;
+
+ for (i = HARD_REGNO_NREGS (FRAME_POINTER_REGNUM, Pmode); i--;)
+ SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM + i);
+
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM);
+ for (i = HARD_REGNO_NREGS (HARD_FRAME_POINTER_REGNUM, Pmode); i--;)
+ SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM + i);
#endif
}
CLEAR_HARD_REG_SET (regs_seen);
while (all_chains)
{
+ int new_reg, best_new_reg = -1;
int n_uses;
struct du_chain *this = all_chains;
struct du_chain *tmp, *last;
HARD_REG_SET this_unavailable;
- int reg = REGNO (*this->loc), treg;
- int nregs = HARD_REGNO_NREGS (reg, GET_MODE (*this->loc));
+ int reg = REGNO (*this->loc);
int i;
all_chains = this->next_chain;
-
+
+#if 0 /* This just disables optimization opportunities. */
/* Only rename once we've seen the reg more than once. */
if (! TEST_HARD_REG_BIT (regs_seen, reg))
{
SET_HARD_REG_BIT (regs_seen, reg);
continue;
}
+#endif
- if (fixed_regs[reg] || global_regs[reg])
+ if (fixed_regs[reg] || global_regs[reg]
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
+#else
+ || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
+#endif
+ )
continue;
COPY_HARD_REG_SET (this_unavailable, unavailable);
IOR_COMPL_HARD_REG_SET (this_unavailable,
reg_class_contents[last->class]);
- if (last->need_caller_save_reg)
+ if (this->need_caller_save_reg)
IOR_HARD_REG_SET (this_unavailable, call_used_reg_set);
+ merge_overlapping_regs (bb, &this_unavailable, this);
+
/* Now potential_regs is a reasonable approximation, let's
have a closer look at each register still in there. */
- for (treg = 0; treg < FIRST_PSEUDO_REGISTER; treg++)
+ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
{
+ int nregs = HARD_REGNO_NREGS (new_reg, GET_MODE (*this->loc));
+
for (i = nregs - 1; i >= 0; --i)
- if (TEST_HARD_REG_BIT (this_unavailable, treg+i)
- || fixed_regs[treg+i]
- || global_regs[treg+i]
+ if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
+ || fixed_regs[new_reg + i]
+ || global_regs[new_reg + i]
/* Can't use regs which aren't saved by the prologue. */
- || (! regs_ever_live[treg+i] && ! call_used_regs[treg+i])
+ || (! regs_ever_live[new_reg + i]
+ && ! call_used_regs[new_reg + i])
+#ifdef LEAF_REGISTERS
+ /* We can't use a non-leaf register if we're in a
+ leaf function. */
+ || (current_function_is_leaf
+ && !LEAF_REGISTERS[new_reg + i])
+#endif
#ifdef HARD_REGNO_RENAME_OK
- || ! HARD_REGNO_RENAME_OK (reg+i, treg+i)
+ || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
#endif
)
break;
/* See whether it accepts all modes that occur in
definition and uses. */
for (tmp = this; tmp; tmp = tmp->next_use)
- if (! HARD_REGNO_MODE_OK (treg, GET_MODE (*tmp->loc)))
+ if (! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc)))
break;
if (! tmp)
- break;
+ {
+ if (best_new_reg == -1
+ || tick[best_new_reg] > tick[new_reg])
+ best_new_reg = new_reg;
+ }
}
if (rtl_dump_file)
fprintf (rtl_dump_file, " crosses a call");
}
- if (treg == FIRST_PSEUDO_REGISTER)
+ if (best_new_reg == -1)
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "; no available registers\n");
continue;
}
-
- for (i = nregs - 1; i >= 0; --i)
- SET_HARD_REG_BIT (unavailable, treg+i);
- do_replace (this, treg);
+ do_replace (this, best_new_reg);
+ tick[best_new_reg] = this_tick++;
if (rtl_dump_file)
- fprintf (rtl_dump_file, ", renamed as %s\n", reg_names[treg]);
+ fprintf (rtl_dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
}
obstack_free (&rename_obstack, first_obj);
{
while (chain)
{
- *chain->loc = gen_rtx_REG (GET_MODE (*chain->loc), reg);
+ unsigned int regno = ORIGINAL_REGNO (*chain->loc);
+ *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ ORIGINAL_REGNO (*chain->loc) = regno;
chain = chain->next_use;
}
}
-static HARD_REG_SET *referenced_regs;
static struct du_chain *open_chains;
static struct du_chain *closed_chains;
static void
-scan_rtx_reg (insn, loc, class, action, type)
+scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
rtx insn;
rtx *loc;
enum reg_class class;
enum scan_actions action;
enum op_type type;
+ int earlyclobber;
{
struct du_chain **p;
rtx x = *loc;
int this_regno = REGNO (x);
int this_nregs = HARD_REGNO_NREGS (this_regno, mode);
- if (action == note_reference)
- {
- while (this_nregs-- > 0)
- SET_HARD_REG_BIT (*referenced_regs, this_regno + this_nregs);
- return;
- }
-
if (action == mark_write)
{
if (type == OP_OUT)
this->insn = insn;
this->class = class;
this->need_caller_save_reg = 0;
+ this->earlyclobber = earlyclobber;
open_chains = this;
}
return;
for (p = &open_chains; *p;)
{
struct du_chain *this = *p;
- int regno = REGNO (*this->loc);
- int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
- int exact_match = (regno == this_regno && nregs == this_nregs);
- if (regno + nregs <= this_regno
- || this_regno + this_nregs <= regno)
- p = &this->next_chain;
- else if (action == mark_read)
- {
- if (! exact_match)
- abort ();
- if (class == NO_REGS)
- abort ();
+ /* Check if the chain has been terminated if it has then skip to
+ the next chain.
- this = (struct du_chain *)
- obstack_alloc (&rename_obstack, sizeof (struct du_chain));
- this->next_use = *p;
- this->next_chain = (*p)->next_chain;
- this->loc = loc;
- this->insn = insn;
- this->class = class;
- this->need_caller_save_reg = 0;
- *p = this;
- return;
- }
- else if (action != terminate_overlapping_read || ! exact_match)
- {
- struct du_chain *next = this->next_chain;
+ This can happen when we've already appended the location to
+ the chain in Step 3, but are trying to hide in-out operands
+ from terminate_write in Step 5. */
- /* Whether the terminated chain can be used for renaming
- depends on the action and this being an exact match.
- In either case, we remove this element from open_chains. */
+ if (*this->loc == cc0_rtx)
+ p = &this->next_chain;
+ else
+ {
+ int regno = REGNO (*this->loc);
+ int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
+ int exact_match = (regno == this_regno && nregs == this_nregs);
- if ((action == terminate_dead || action == terminate_write)
- && exact_match)
+ if (regno + nregs <= this_regno
+ || this_regno + this_nregs <= regno)
{
- this->next_chain = closed_chains;
- closed_chains = this;
- if (rtl_dump_file)
- fprintf (rtl_dump_file,
- "Closing chain %s at insn %d (%s)\n",
- reg_names[REGNO (*this->loc)], INSN_UID (insn),
- scan_actions_name[(int) action]);
+ p = &this->next_chain;
+ continue;
}
- else
+
+ if (action == mark_read)
{
- if (rtl_dump_file)
- fprintf (rtl_dump_file,
- "Discarding chain %s at insn %d (%s)\n",
- reg_names[REGNO (*this->loc)], INSN_UID (insn),
- scan_actions_name[(int) action]);
+ if (! exact_match)
+ abort ();
+
+ /* ??? Class NO_REGS can happen if the md file makes use of
+ EXTRA_CONSTRAINTS to match registers. Which is arguably
+ wrong, but there we are. Since we know not what this may
+ be replaced with, terminate the chain. */
+ if (class != NO_REGS)
+ {
+ this = (struct du_chain *)
+ obstack_alloc (&rename_obstack, sizeof (struct du_chain));
+ this->next_use = 0;
+ this->next_chain = (*p)->next_chain;
+ this->loc = loc;
+ this->insn = insn;
+ this->class = class;
+ this->need_caller_save_reg = 0;
+ while (*p)
+ p = &(*p)->next_use;
+ *p = this;
+ return;
+ }
+ }
+
+ if (action != terminate_overlapping_read || ! exact_match)
+ {
+ struct du_chain *next = this->next_chain;
+
+ /* Whether the terminated chain can be used for renaming
+ depends on the action and this being an exact match.
+ In either case, we remove this element from open_chains. */
+
+ if ((action == terminate_dead || action == terminate_write)
+ && exact_match)
+ {
+ this->next_chain = closed_chains;
+ closed_chains = this;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Closing chain %s at insn %d (%s)\n",
+ reg_names[REGNO (*this->loc)], INSN_UID (insn),
+ scan_actions_name[(int) action]);
+ }
+ else
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Discarding chain %s at insn %d (%s)\n",
+ reg_names[REGNO (*this->loc)], INSN_UID (insn),
+ scan_actions_name[(int) action]);
+ }
+ *p = next;
}
- *p = next;
+ else
+ p = &this->next_chain;
}
- else
- p = &this->next_chain;
}
}
return;
case REG:
- scan_rtx_reg (insn, loc, class, action, OP_IN);
+ scan_rtx_reg (insn, loc, class, action, OP_IN, 0);
return;
default:
}
static void
-scan_rtx (insn, loc, class, action, type)
+scan_rtx (insn, loc, class, action, type, earlyclobber)
rtx insn;
rtx *loc;
enum reg_class class;
enum scan_actions action;
enum op_type type;
+ int earlyclobber;
{
const char *fmt;
rtx x = *loc;
return;
case REG:
- scan_rtx_reg (insn, loc, class, action, type);
+ scan_rtx_reg (insn, loc, class, action, type, earlyclobber);
return;
case MEM:
return;
case SET:
- scan_rtx (insn, &SET_SRC (x), class, action, OP_IN);
- scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT);
+ scan_rtx (insn, &SET_SRC (x), class, action, OP_IN, 0);
+ scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 0);
return;
case STRICT_LOW_PART:
- scan_rtx (insn, &XEXP (x, 0), class, action, OP_INOUT);
+ scan_rtx (insn, &XEXP (x, 0), class, action, OP_INOUT, earlyclobber);
return;
case ZERO_EXTRACT:
case SIGN_EXTRACT:
scan_rtx (insn, &XEXP (x, 0), class, action,
- type == OP_IN ? OP_IN : OP_INOUT);
- scan_rtx (insn, &XEXP (x, 1), class, action, OP_IN);
- scan_rtx (insn, &XEXP (x, 2), class, action, OP_IN);
+ type == OP_IN ? OP_IN : OP_INOUT, earlyclobber);
+ scan_rtx (insn, &XEXP (x, 1), class, action, OP_IN, 0);
+ scan_rtx (insn, &XEXP (x, 2), class, action, OP_IN, 0);
return;
case POST_INC:
abort ();
case CLOBBER:
- scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT);
+ scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 1);
return;
case EXPR_LIST:
- scan_rtx (insn, &XEXP (x, 0), class, action, type);
+ scan_rtx (insn, &XEXP (x, 0), class, action, type, 0);
if (XEXP (x, 1))
- scan_rtx (insn, &XEXP (x, 1), class, action, type);
+ scan_rtx (insn, &XEXP (x, 1), class, action, type, 0);
return;
default:
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- scan_rtx (insn, &XEXP (x, i), class, action, type);
+ scan_rtx (insn, &XEXP (x, i), class, action, type, 0);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- scan_rtx (insn, &XVECEXP (x, i, j), class, action, type);
+ scan_rtx (insn, &XVECEXP (x, i, j), class, action, type, 0);
}
}
/* Build def/use chain */
static struct du_chain *
-build_def_use (bb, regs_used)
+build_def_use (bb)
basic_block bb;
- HARD_REG_SET *regs_used;
{
rtx insn;
open_chains = closed_chains = NULL;
- referenced_regs = regs_used;
for (insn = bb->head; ; insn = NEXT_INSN (insn))
{
int alt;
int predicated;
- /* Record all mentioned registers in regs_used. */
- scan_rtx (insn, &PATTERN (insn), NO_REGS, note_reference, OP_IN);
-
/* Process the insn, determining its effect on the def-use
chains. We perform the following steps with the register
references in the insn:
for (i = 0; i < n_ops; i++)
scan_rtx (insn, recog_data.operand_loc[i],
NO_REGS, terminate_overlapping_read,
- recog_data.operand_type[i]);
+ recog_data.operand_type[i], 0);
/* Step 2: Close chains for which we have reads outside operands.
We do this by munging all operands into CC0, and closing
*recog_data.dup_loc[i] = cc0_rtx;
}
- scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read, OP_IN);
+ scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_all_read,
+ OP_IN, 0);
for (i = 0; i < recog_data.n_dups; i++)
*recog_data.dup_loc[i] = old_dups[i];
/* Step 2B: Can't rename function call argument registers. */
if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn))
scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
- NO_REGS, terminate_all_read, OP_IN);
+ NO_REGS, terminate_all_read, OP_IN, 0);
/* Step 3: Append to chains for reads inside operands. */
for (i = 0; i < n_ops + recog_data.n_dups; i++)
if (recog_op_alt[opn][alt].is_address)
scan_rtx_address (insn, loc, class, mark_read, VOIDmode);
else
- scan_rtx (insn, loc, class, mark_read, type);
+ scan_rtx (insn, loc, class, mark_read, type, 0);
}
- /* Step 4: Close chains for registers that die here. */
+ /* Step 4: Close chains for registers that die here.
+ Also record updates for REG_INC notes. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD)
- scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead, OP_IN);
+ {
+ if (REG_NOTE_KIND (note) == REG_DEAD)
+ scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
+ OP_IN, 0);
+ else if (REG_NOTE_KIND (note) == REG_INC)
+ scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
+ OP_INOUT, 0);
+ }
/* Step 4B: If this is a call, any chain live at this point
requires a caller-saved reg. */
{
struct du_chain *p;
for (p = open_chains; p; p = p->next_chain)
- {
- struct du_chain *p2;
- for (p2 = p; p2->next_use; p2 = p2->next_use)
- /* nothing */;
- p2->need_caller_save_reg = 1;
- }
+ p->need_caller_save_reg = 1;
}
/* Step 5: Close open chains that overlap writes. Similar to
*recog_data.dup_loc[i] = cc0_rtx;
}
- scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN);
+ scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN, 0);
for (i = 0; i < recog_data.n_dups; i++)
*recog_data.dup_loc[i] = old_dups[i];
enum reg_class class = recog_op_alt[opn][alt].class;
if (recog_data.operand_type[opn] == OP_OUT)
- scan_rtx (insn, loc, class, mark_write, OP_OUT);
+ scan_rtx (insn, loc, class, mark_write, OP_OUT,
+ recog_op_alt[opn][alt].earlyclobber);
}
/* Step 7: Close chains for registers that were never
really used here. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_UNUSED)
- scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead, OP_IN);
+ scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
+ OP_IN, 0);
}
if (insn == bb->end)
break;