Commit 941c63ac by Jeffrey A Law Committed by Jeff Law

rtlanal.c (multiple_sets): New function.

        * rtlanal.c (multiple_sets): New function.
        * rtl.h (multiple_sets): Declare it.
        * local-alloc.c (wipe_dead_reg): Use it.
        * global.c (global_conflicts): Likewise.
Should fix the m68k bootstrap problems.

From-SVN: r24283
parent 8d4c79be
Sat Dec 12 23:39:10 1998 Jeffrey A Law (law@cygnus.com)
* rtlanal.c (multiple_sets): New function.
* rtl.h (multiple_sets): Declare it.
* local-alloc.c (wipe_dead_reg): Use it.
* global.c (global_conflicts): Likewise.
Sat Dec 12 22:13:02 1998 Mark Mitchell <mark@markmitchell.com>
* global.c (record_conflicts): Don't use an array of shorts to
......
......@@ -739,9 +739,16 @@ global_conflicts ()
/* 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))
must conflict with the other outputs.
It is unsafe to use !single_set here since it will ignore an
unused output. Just because an output is unused does not mean
the compiler can assume the side effect will not occur.
Consider if REG appears in the address of an output and we
reload the output. If we allocate REG to the same hard
register as an unused output we could set the hard register
before the output reload insn. */
if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
{
......
......@@ -1876,9 +1876,16 @@ wipe_dead_reg (reg, output_p)
/* 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. */
so it won't get allocated together with any other result of this insn.
It is unsafe to use !single_set here since it will ignore an unused
output. Just because an output is unused does not mean the compiler
can assume the side effect will not occur. Consider if REG appears
in the address of an output and we reload the output. If we allocate
REG to the same hard register as an unused output we could set the hard
register before the output reload insn. */
if (GET_CODE (PATTERN (this_insn)) == PARALLEL
&& !single_set (this_insn))
&& multiple_sets (this_insn))
{
int i;
for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
......
......@@ -988,6 +988,7 @@ extern int no_labels_between_p PROTO((rtx, rtx));
extern int modified_in_p PROTO((rtx, rtx));
extern int reg_set_p PROTO((rtx, rtx));
extern rtx single_set PROTO((rtx));
extern rtx multiple_sets PROTO((rtx));
extern rtx find_last_value PROTO((rtx, rtx *, rtx));
extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
......
......@@ -690,6 +690,38 @@ single_set (insn)
return 0;
}
/* Given an INSN, return nonzero if it has more than one SET, else return
zero. */
rtx
multiple_sets (insn)
rtx insn;
{
rtx found;
int i;
/* INSN must be an insn. */
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
return 0;
/* Only a PARALLEL can have multiple SETs. */
if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
{
/* If we have already found a SET, then return now. */
if (found)
return 1;
else
found = 1;
}
}
/* Either zero or one SET. */
return 0;
}
/* Return the last thing that X was assigned from before *PINSN. Verify that
the object is not modified up to VALID_TO. If it was, if we hit
......
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