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
This commit is contained in:
Jeffrey A Law 1998-12-12 23:03:54 +00:00 committed by Jeff Law
parent 8d4c79be50
commit 941c63ac30
5 changed files with 58 additions and 4 deletions

View File

@ -1,3 +1,10 @@
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

View File

@ -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. */
must conflict with the other outputs.
if (GET_CODE (PATTERN (insn)) == PARALLEL && !single_set (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 (insn)) == PARALLEL && multiple_sets (insn))
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
{

View File

@ -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--)

View File

@ -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));

View File

@ -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