Commit 333e0f7d by Richard Stallman

*** empty log message ***

From-SVN: r562
parent 391b99c9
......@@ -248,6 +248,7 @@ static HARD_REG_SET eliminable_regset;
static int allocno_compare ();
static void mark_reg_store ();
static void mark_reg_clobber ();
static void mark_reg_conflicts ();
static void mark_reg_live_nc ();
static void mark_reg_death ();
static void dump_conflicts ();
......@@ -698,6 +699,31 @@ global_conflicts ()
mark_reg_store (XEXP (link, 0), 0);
#endif
/* If INSN has multiple outputs, then any reg that dies here
and is used inside of an output
must conflict with the other outputs. */
if (GET_CODE (PATTERN (insn)) == PARALLEL && !single_set (insn))
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
{
int used_in_output = 0;
int i;
rtx reg = XEXP (link, 0);
for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
{
rtx set = XVECEXP (PATTERN (insn), 0, i);
if (GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != REG
&& !rtx_equal_p (reg, SET_DEST (set))
&& reg_overlap_mentioned_p (reg, SET_DEST (set)))
used_in_output = 1;
}
if (used_in_output)
mark_reg_conflicts (reg);
}
/* Mark any registers set in INSN and then never used. */
while (n_regs_set > 0)
......@@ -1334,6 +1360,45 @@ mark_reg_clobber (reg, setter)
}
}
}
/* Record that REG has conflicts with all the regs currently live.
Do not mark REG itself as live. */
static void
mark_reg_conflicts (reg)
rtx reg;
{
register int regno;
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
if (GET_CODE (reg) != REG)
return;
regno = REGNO (reg);
if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno];
/* Either this is one of the max_allocno pseudo regs not allocated,
or it is or has a hardware reg. First handle the pseudo-regs. */
if (regno >= FIRST_PSEUDO_REGISTER)
{
if (reg_allocno[regno] >= 0)
record_one_conflict (regno);
}
/* Handle hardware regs (and pseudos allocated to hard regs). */
else if (! fixed_regs[regno])
{
register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
while (regno < last)
{
record_one_conflict (regno);
regno++;
}
}
}
/* Mark REG as being dead (following the insn being scanned now).
Store a 0 in regs_live or allocnos_live for this register. */
......
......@@ -1729,7 +1729,8 @@ reg_is_born (reg, birth)
/* Record the death of REG in the current insn. If OUTPUT_P is non-zero,
REG is an output that is dying (i.e., it is never used), otherwise it
is an input (the normal case). */
is an input (the normal case).
If OUTPUT_P is 1, then we extend the life past the end of this insn. */
static void
wipe_dead_reg (reg, output_p)
......@@ -1738,6 +1739,25 @@ wipe_dead_reg (reg, output_p)
{
register int regno = REGNO (reg);
/* If this insn has multiple results,
and the dead reg is used in one of the results,
extend its life to after this insn,
so it won't get allocated together with any other result of this insn. */
if (GET_CODE (PATTERN (this_insn)) == PARALLEL
&& !single_set (this_insn))
{
int i;
for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
{
rtx set = XVECEXP (PATTERN (this_insn), 0, i);
if (GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != REG
&& !rtx_equal_p (reg, SET_DEST (set))
&& reg_overlap_mentioned_p (reg, SET_DEST (set)))
output_p = 1;
}
}
if (regno < FIRST_PSEUDO_REGISTER)
{
mark_life (regno, GET_MODE (reg), 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment