mirror of git://gcc.gnu.org/git/gcc.git
Replace several arrays with a struct of arrays.
2004-05-12 Paolo Bonzini <bonzini@gnu.org> Replace several arrays with a struct of arrays. * combine.c (struct reg_stat): New. (init_reg_last_arrays): Renamed to... (init_reg_last): ...this. Callers adjusted. (reg_stat): New. (combine_instructions): Allocate it and use it. (reg_last_death, reg_last_set, reg_last_set_value, reg_last_set_label, reg_last_set_table_tick, reg_last_set_invalid, reg_nonzero_bits, reg_sign_bit_copies, reg_last_set_mode, reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies): Replace throughout with items of reg_stat. From-SVN: r81740
This commit is contained in:
parent
f5657d6742
commit
5eaad4813d
|
@ -1,3 +1,18 @@
|
||||||
|
2004-05-12 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
Replace several arrays with a struct of arrays.
|
||||||
|
* combine.c (struct reg_stat): New.
|
||||||
|
(init_reg_last_arrays): Renamed to...
|
||||||
|
(init_reg_last): ...this. Callers adjusted.
|
||||||
|
(reg_stat): New.
|
||||||
|
(combine_instructions): Allocate it and use it.
|
||||||
|
(reg_last_death, reg_last_set, reg_last_set_value,
|
||||||
|
reg_last_set_label, reg_last_set_table_tick,
|
||||||
|
reg_last_set_invalid, reg_nonzero_bits, reg_sign_bit_copies,
|
||||||
|
reg_last_set_mode, reg_last_set_nonzero_bits,
|
||||||
|
reg_last_set_sign_bit_copies): Replace throughout
|
||||||
|
with items of reg_stat.
|
||||||
|
|
||||||
2004-05-11 Kaz Kojima <kkojima@gcc.gnu.org>
|
2004-05-11 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||||
|
|
||||||
PR optimization/15100
|
PR optimization/15100
|
||||||
|
|
424
gcc/combine.c
424
gcc/combine.c
|
@ -143,13 +143,103 @@ static int max_uid_cuid;
|
||||||
|
|
||||||
static unsigned int combine_max_regno;
|
static unsigned int combine_max_regno;
|
||||||
|
|
||||||
/* Record last point of death of (hard or pseudo) register n. */
|
struct reg_stat {
|
||||||
|
/* Record last point of death of (hard or pseudo) register n. */
|
||||||
|
rtx last_death;
|
||||||
|
|
||||||
static rtx *reg_last_death;
|
/* Record last point of modification of (hard or pseudo) register n. */
|
||||||
|
rtx last_set;
|
||||||
|
|
||||||
/* Record last point of modification of (hard or pseudo) register n. */
|
/* The next group of fields allows the recording of the last value assigned
|
||||||
|
to (hard or pseudo) register n. We use this information to see if an
|
||||||
|
operation being processed is redundant given a prior operation performed
|
||||||
|
on the register. For example, an `and' with a constant is redundant if
|
||||||
|
all the zero bits are already known to be turned off.
|
||||||
|
|
||||||
static rtx *reg_last_set;
|
We use an approach similar to that used by cse, but change it in the
|
||||||
|
following ways:
|
||||||
|
|
||||||
|
(1) We do not want to reinitialize at each label.
|
||||||
|
(2) It is useful, but not critical, to know the actual value assigned
|
||||||
|
to a register. Often just its form is helpful.
|
||||||
|
|
||||||
|
Therefore, we maintain the following fields:
|
||||||
|
|
||||||
|
last_set_value the last value assigned
|
||||||
|
last_set_label records the value of label_tick when the
|
||||||
|
register was assigned
|
||||||
|
last_set_table_tick records the value of label_tick when a
|
||||||
|
value using the register is assigned
|
||||||
|
last_set_invalid set to nonzero when it is not valid
|
||||||
|
to use the value of this register in some
|
||||||
|
register's value
|
||||||
|
|
||||||
|
To understand the usage of these tables, it is important to understand
|
||||||
|
the distinction between the value in last_set_value being valid and
|
||||||
|
the register being validly contained in some other expression in the
|
||||||
|
table.
|
||||||
|
|
||||||
|
(The next two parameters are out of date).
|
||||||
|
|
||||||
|
reg_stat[i].last_set_value is valid if it is nonzero, and either
|
||||||
|
reg_n_sets[i] is 1 or reg_stat[i].last_set_label == label_tick.
|
||||||
|
|
||||||
|
Register I may validly appear in any expression returned for the value
|
||||||
|
of another register if reg_n_sets[i] is 1. It may also appear in the
|
||||||
|
value for register J if reg_stat[j].last_set_invalid is zero, or
|
||||||
|
reg_stat[i].last_set_label < reg_stat[j].last_set_label.
|
||||||
|
|
||||||
|
If an expression is found in the table containing a register which may
|
||||||
|
not validly appear in an expression, the register is replaced by
|
||||||
|
something that won't match, (clobber (const_int 0)). */
|
||||||
|
|
||||||
|
/* Record last value assigned to (hard or pseudo) register n. */
|
||||||
|
|
||||||
|
rtx last_set_value;
|
||||||
|
|
||||||
|
/* Record the value of label_tick when an expression involving register n
|
||||||
|
is placed in last_set_value. */
|
||||||
|
|
||||||
|
int last_set_table_tick;
|
||||||
|
|
||||||
|
/* Record the value of label_tick when the value for register n is placed in
|
||||||
|
last_set_value. */
|
||||||
|
|
||||||
|
int last_set_label;
|
||||||
|
|
||||||
|
/* These fields are maintained in parallel with last_set_value and are
|
||||||
|
used to store the mode in which the register was last set, te bits
|
||||||
|
that were known to be zero when it was last set, and the number of
|
||||||
|
sign bits copies it was known to have when it was last set. */
|
||||||
|
|
||||||
|
unsigned HOST_WIDE_INT last_set_nonzero_bits;
|
||||||
|
char last_set_sign_bit_copies;
|
||||||
|
ENUM_BITFIELD(machine_mode) last_set_mode : 8;
|
||||||
|
|
||||||
|
/* Set nonzero if references to register n in expressions should not be
|
||||||
|
used. last_set_invalid is set nonzero when this register is being
|
||||||
|
assigned to and last_set_table_tick == label_tick. */
|
||||||
|
|
||||||
|
char last_set_invalid;
|
||||||
|
|
||||||
|
/* Some registers that are set more than once and used in more than one
|
||||||
|
basic block are nevertheless always set in similar ways. For example,
|
||||||
|
a QImode register may be loaded from memory in two places on a machine
|
||||||
|
where byte loads zero extend.
|
||||||
|
|
||||||
|
We record in the following fields if a register has some leading bits
|
||||||
|
that are always equal to the sign bit, and what we know about the
|
||||||
|
nonzero bits of a register, specifically which bits are known to be
|
||||||
|
zero.
|
||||||
|
|
||||||
|
If an entry is zero, it means that we don't know anything special. */
|
||||||
|
|
||||||
|
unsigned char sign_bit_copies;
|
||||||
|
|
||||||
|
unsigned HOST_WIDE_INT nonzero_bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct reg_stat *reg_stat;
|
||||||
|
|
||||||
/* Record the cuid of the last insn that invalidated memory
|
/* Record the cuid of the last insn that invalidated memory
|
||||||
(anything that writes memory, and subroutine calls, but not pushes). */
|
(anything that writes memory, and subroutine calls, but not pushes). */
|
||||||
|
@ -197,110 +287,23 @@ static basic_block this_basic_block;
|
||||||
those blocks as starting points. */
|
those blocks as starting points. */
|
||||||
static sbitmap refresh_blocks;
|
static sbitmap refresh_blocks;
|
||||||
|
|
||||||
/* The next group of arrays allows the recording of the last value assigned
|
|
||||||
to (hard or pseudo) register n. We use this information to see if an
|
|
||||||
operation being processed is redundant given a prior operation performed
|
|
||||||
on the register. For example, an `and' with a constant is redundant if
|
|
||||||
all the zero bits are already known to be turned off.
|
|
||||||
|
|
||||||
We use an approach similar to that used by cse, but change it in the
|
|
||||||
following ways:
|
|
||||||
|
|
||||||
(1) We do not want to reinitialize at each label.
|
|
||||||
(2) It is useful, but not critical, to know the actual value assigned
|
|
||||||
to a register. Often just its form is helpful.
|
|
||||||
|
|
||||||
Therefore, we maintain the following arrays:
|
|
||||||
|
|
||||||
reg_last_set_value the last value assigned
|
|
||||||
reg_last_set_label records the value of label_tick when the
|
|
||||||
register was assigned
|
|
||||||
reg_last_set_table_tick records the value of label_tick when a
|
|
||||||
value using the register is assigned
|
|
||||||
reg_last_set_invalid set to nonzero when it is not valid
|
|
||||||
to use the value of this register in some
|
|
||||||
register's value
|
|
||||||
|
|
||||||
To understand the usage of these tables, it is important to understand
|
|
||||||
the distinction between the value in reg_last_set_value being valid
|
|
||||||
and the register being validly contained in some other expression in the
|
|
||||||
table.
|
|
||||||
|
|
||||||
Entry I in reg_last_set_value is valid if it is nonzero, and either
|
|
||||||
reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick.
|
|
||||||
|
|
||||||
Register I may validly appear in any expression returned for the value
|
|
||||||
of another register if reg_n_sets[i] is 1. It may also appear in the
|
|
||||||
value for register J if reg_last_set_label[i] < reg_last_set_label[j] or
|
|
||||||
reg_last_set_invalid[j] is zero.
|
|
||||||
|
|
||||||
If an expression is found in the table containing a register which may
|
|
||||||
not validly appear in an expression, the register is replaced by
|
|
||||||
something that won't match, (clobber (const_int 0)).
|
|
||||||
|
|
||||||
reg_last_set_invalid[i] is set nonzero when register I is being assigned
|
|
||||||
to and reg_last_set_table_tick[i] == label_tick. */
|
|
||||||
|
|
||||||
/* Record last value assigned to (hard or pseudo) register n. */
|
|
||||||
|
|
||||||
static rtx *reg_last_set_value;
|
|
||||||
|
|
||||||
/* Record the value of label_tick when the value for register n is placed in
|
|
||||||
reg_last_set_value[n]. */
|
|
||||||
|
|
||||||
static int *reg_last_set_label;
|
|
||||||
|
|
||||||
/* Record the value of label_tick when an expression involving register n
|
|
||||||
is placed in reg_last_set_value. */
|
|
||||||
|
|
||||||
static int *reg_last_set_table_tick;
|
|
||||||
|
|
||||||
/* Set nonzero if references to register n in expressions should not be
|
|
||||||
used. */
|
|
||||||
|
|
||||||
static char *reg_last_set_invalid;
|
|
||||||
|
|
||||||
/* Incremented for each label. */
|
/* Incremented for each label. */
|
||||||
|
|
||||||
static int label_tick;
|
static int label_tick;
|
||||||
|
|
||||||
/* Some registers that are set more than once and used in more than one
|
/* Mode used to compute significance in reg_stat[].nonzero_bits. It is the
|
||||||
basic block are nevertheless always set in similar ways. For example,
|
largest integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
|
||||||
a QImode register may be loaded from memory in two places on a machine
|
|
||||||
where byte loads zero extend.
|
|
||||||
|
|
||||||
We record in the following array what we know about the nonzero
|
|
||||||
bits of a register, specifically which bits are known to be zero.
|
|
||||||
|
|
||||||
If an entry is zero, it means that we don't know anything special. */
|
|
||||||
|
|
||||||
static unsigned HOST_WIDE_INT *reg_nonzero_bits;
|
|
||||||
|
|
||||||
/* Mode used to compute significance in reg_nonzero_bits. It is the largest
|
|
||||||
integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
|
|
||||||
|
|
||||||
static enum machine_mode nonzero_bits_mode;
|
static enum machine_mode nonzero_bits_mode;
|
||||||
|
|
||||||
/* Nonzero if we know that a register has some leading bits that are always
|
/* Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can
|
||||||
equal to the sign bit. */
|
be safely used. It is zero while computing them and after combine has
|
||||||
|
completed. This former test prevents propagating values based on
|
||||||
static unsigned char *reg_sign_bit_copies;
|
previously set values, which can be incorrect if a variable is modified
|
||||||
|
in a loop. */
|
||||||
/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used.
|
|
||||||
It is zero while computing them and after combine has completed. This
|
|
||||||
former test prevents propagating values based on previously set values,
|
|
||||||
which can be incorrect if a variable is modified in a loop. */
|
|
||||||
|
|
||||||
static int nonzero_sign_valid;
|
static int nonzero_sign_valid;
|
||||||
|
|
||||||
/* These arrays are maintained in parallel with reg_last_set_value
|
|
||||||
and are used to store the mode in which the register was last set,
|
|
||||||
the bits that were known to be zero when it was last set, and the
|
|
||||||
number of sign bits copies it was known to have when it was last set. */
|
|
||||||
|
|
||||||
static enum machine_mode *reg_last_set_mode;
|
|
||||||
static unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits;
|
|
||||||
static char *reg_last_set_sign_bit_copies;
|
|
||||||
|
|
||||||
/* Record one modification to rtl structure
|
/* Record one modification to rtl structure
|
||||||
to be undone by storing old_contents into *where.
|
to be undone by storing old_contents into *where.
|
||||||
|
@ -336,7 +339,7 @@ static int n_occurrences;
|
||||||
|
|
||||||
static void do_SUBST (rtx *, rtx);
|
static void do_SUBST (rtx *, rtx);
|
||||||
static void do_SUBST_INT (int *, int);
|
static void do_SUBST_INT (int *, int);
|
||||||
static void init_reg_last_arrays (void);
|
static void init_reg_last (void);
|
||||||
static void setup_incoming_promotions (void);
|
static void setup_incoming_promotions (void);
|
||||||
static void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
|
static void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
|
||||||
static int cant_combine_insn_p (rtx);
|
static int cant_combine_insn_p (rtx);
|
||||||
|
@ -523,20 +526,7 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||||
See comments in gen_lowpart_for_combine. */
|
See comments in gen_lowpart_for_combine. */
|
||||||
gen_lowpart = gen_lowpart_for_combine;
|
gen_lowpart = gen_lowpart_for_combine;
|
||||||
|
|
||||||
reg_nonzero_bits = xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT));
|
reg_stat = xcalloc (nregs, sizeof (struct reg_stat));
|
||||||
reg_sign_bit_copies = xcalloc (nregs, sizeof (unsigned char));
|
|
||||||
|
|
||||||
reg_last_death = xmalloc (nregs * sizeof (rtx));
|
|
||||||
reg_last_set = xmalloc (nregs * sizeof (rtx));
|
|
||||||
reg_last_set_value = xmalloc (nregs * sizeof (rtx));
|
|
||||||
reg_last_set_table_tick = xmalloc (nregs * sizeof (int));
|
|
||||||
reg_last_set_label = xmalloc (nregs * sizeof (int));
|
|
||||||
reg_last_set_invalid = xmalloc (nregs * sizeof (char));
|
|
||||||
reg_last_set_mode = xmalloc (nregs * sizeof (enum machine_mode));
|
|
||||||
reg_last_set_nonzero_bits = xmalloc (nregs * sizeof (HOST_WIDE_INT));
|
|
||||||
reg_last_set_sign_bit_copies = xmalloc (nregs * sizeof (char));
|
|
||||||
|
|
||||||
init_reg_last_arrays ();
|
|
||||||
|
|
||||||
init_recog_no_volatile ();
|
init_recog_no_volatile ();
|
||||||
|
|
||||||
|
@ -551,8 +541,8 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||||
|
|
||||||
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
|
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
|
||||||
|
|
||||||
/* Don't use reg_nonzero_bits when computing it. This can cause problems
|
/* Don't use reg_stat[].nonzero_bits when computing it. This can cause
|
||||||
when, for example, we have j <<= 1 in a loop. */
|
problems when, for example, we have j <<= 1 in a loop. */
|
||||||
|
|
||||||
nonzero_sign_valid = 0;
|
nonzero_sign_valid = 0;
|
||||||
|
|
||||||
|
@ -605,7 +595,7 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||||
label_tick = 1;
|
label_tick = 1;
|
||||||
last_call_cuid = 0;
|
last_call_cuid = 0;
|
||||||
mem_last_set = 0;
|
mem_last_set = 0;
|
||||||
init_reg_last_arrays ();
|
init_reg_last ();
|
||||||
setup_incoming_promotions ();
|
setup_incoming_promotions ();
|
||||||
|
|
||||||
FOR_EACH_BB (this_basic_block)
|
FOR_EACH_BB (this_basic_block)
|
||||||
|
@ -768,17 +758,7 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
sbitmap_free (refresh_blocks);
|
sbitmap_free (refresh_blocks);
|
||||||
free (reg_nonzero_bits);
|
free (reg_stat);
|
||||||
free (reg_sign_bit_copies);
|
|
||||||
free (reg_last_death);
|
|
||||||
free (reg_last_set);
|
|
||||||
free (reg_last_set_value);
|
|
||||||
free (reg_last_set_table_tick);
|
|
||||||
free (reg_last_set_label);
|
|
||||||
free (reg_last_set_invalid);
|
|
||||||
free (reg_last_set_mode);
|
|
||||||
free (reg_last_set_nonzero_bits);
|
|
||||||
free (reg_last_set_sign_bit_copies);
|
|
||||||
free (uid_cuid);
|
free (uid_cuid);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -805,22 +785,14 @@ combine_instructions (rtx f, unsigned int nregs)
|
||||||
return new_direct_jump_p;
|
return new_direct_jump_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
|
/* Wipe the last_xxx fields of reg_stat in preparation for another pass. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_reg_last_arrays (void)
|
init_reg_last (void)
|
||||||
{
|
{
|
||||||
unsigned int nregs = combine_max_regno;
|
unsigned int i;
|
||||||
|
for (i = 0; i < combine_max_regno; i++)
|
||||||
memset (reg_last_death, 0, nregs * sizeof (rtx));
|
memset (reg_stat + i, 0, offsetof (struct reg_stat, sign_bit_copies));
|
||||||
memset (reg_last_set, 0, nregs * sizeof (rtx));
|
|
||||||
memset (reg_last_set_value, 0, nregs * sizeof (rtx));
|
|
||||||
memset (reg_last_set_table_tick, 0, nregs * sizeof (int));
|
|
||||||
memset (reg_last_set_label, 0, nregs * sizeof (int));
|
|
||||||
memset (reg_last_set_invalid, 0, nregs * sizeof (char));
|
|
||||||
memset (reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
|
|
||||||
memset (reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
|
|
||||||
memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up any promoted values for incoming argument registers. */
|
/* Set up any promoted values for incoming argument registers. */
|
||||||
|
@ -878,8 +850,8 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
|
||||||
{
|
{
|
||||||
if (set == 0 || GET_CODE (set) == CLOBBER)
|
if (set == 0 || GET_CODE (set) == CLOBBER)
|
||||||
{
|
{
|
||||||
reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
|
reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
|
||||||
reg_sign_bit_copies[REGNO (x)] = 1;
|
reg_stat[REGNO (x)].sign_bit_copies = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +873,7 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
|
||||||
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
|
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
|
||||||
/* If X is narrower than a word and SRC is a non-negative
|
/* If X is narrower than a word and SRC is a non-negative
|
||||||
constant that would appear negative in the mode of X,
|
constant that would appear negative in the mode of X,
|
||||||
sign-extend it for use in reg_nonzero_bits because some
|
sign-extend it for use in reg_stat[].nonzero_bits because some
|
||||||
machines (maybe most) will actually do the sign-extension
|
machines (maybe most) will actually do the sign-extension
|
||||||
and this is the conservative approach.
|
and this is the conservative approach.
|
||||||
|
|
||||||
|
@ -920,18 +892,18 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Don't call nonzero_bits if it cannot change anything. */
|
/* Don't call nonzero_bits if it cannot change anything. */
|
||||||
if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
|
if (reg_stat[REGNO (x)].nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
|
||||||
reg_nonzero_bits[REGNO (x)]
|
reg_stat[REGNO (x)].nonzero_bits
|
||||||
|= nonzero_bits (src, nonzero_bits_mode);
|
|= nonzero_bits (src, nonzero_bits_mode);
|
||||||
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
|
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
|
||||||
if (reg_sign_bit_copies[REGNO (x)] == 0
|
if (reg_stat[REGNO (x)].sign_bit_copies == 0
|
||||||
|| reg_sign_bit_copies[REGNO (x)] > num)
|
|| reg_stat[REGNO (x)].sign_bit_copies > num)
|
||||||
reg_sign_bit_copies[REGNO (x)] = num;
|
reg_stat[REGNO (x)].sign_bit_copies = num;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
|
reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
|
||||||
reg_sign_bit_copies[REGNO (x)] = 1;
|
reg_stat[REGNO (x)].sign_bit_copies = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1073,7 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
|
||||||
does not use any registers whose values alter in between. However,
|
does not use any registers whose values alter in between. However,
|
||||||
If the insns are adjacent, a use can't cross a set even though we
|
If the insns are adjacent, a use can't cross a set even though we
|
||||||
think it might (this can happen for a sequence of insns each setting
|
think it might (this can happen for a sequence of insns each setting
|
||||||
the same destination; reg_last_set of that register might point to
|
the same destination; last_set of that register might point to
|
||||||
a NOTE). If INSN has a REG_EQUIV note, the register is always
|
a NOTE). If INSN has a REG_EQUIV note, the register is always
|
||||||
equivalent to the memory so the substitution is valid even if there
|
equivalent to the memory so the substitution is valid even if there
|
||||||
are intervening stores. Also, don't move a volatile asm or
|
are intervening stores. Also, don't move a volatile asm or
|
||||||
|
@ -2331,18 +2303,18 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
||||||
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
|
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
|
||||||
&& ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
|
&& ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
|
||||||
(GET_CODE (temp) == REG
|
(GET_CODE (temp) == REG
|
||||||
&& reg_nonzero_bits[REGNO (temp)] != 0
|
&& reg_stat[REGNO (temp)].nonzero_bits != 0
|
||||||
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
|
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
|
||||||
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
|
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
|
||||||
&& (reg_nonzero_bits[REGNO (temp)]
|
&& (reg_stat[REGNO (temp)].nonzero_bits
|
||||||
!= GET_MODE_MASK (word_mode))))
|
!= GET_MODE_MASK (word_mode))))
|
||||||
&& ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
|
&& ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
|
||||||
&& (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
|
&& (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
|
||||||
(GET_CODE (temp) == REG
|
(GET_CODE (temp) == REG
|
||||||
&& reg_nonzero_bits[REGNO (temp)] != 0
|
&& reg_stat[REGNO (temp)].nonzero_bits != 0
|
||||||
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
|
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
|
||||||
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
|
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
|
||||||
&& (reg_nonzero_bits[REGNO (temp)]
|
&& (reg_stat[REGNO (temp)].nonzero_bits
|
||||||
!= GET_MODE_MASK (word_mode)))))
|
!= GET_MODE_MASK (word_mode)))))
|
||||||
&& ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
|
&& ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
|
||||||
SET_SRC (XVECEXP (newpat, 0, 1)))
|
SET_SRC (XVECEXP (newpat, 0, 1)))
|
||||||
|
@ -2783,9 +2755,10 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|
||||||
REG_N_SETS (regno)--;
|
REG_N_SETS (regno)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update reg_nonzero_bits et al for any changes that may have been made
|
/* Update reg_stat[].nonzero_bits et al for any changes that may have
|
||||||
to this insn. The order of set_nonzero_bits_and_sign_copies() is
|
been made to this insn. The order of
|
||||||
important. Because newi2pat can affect nonzero_bits of newpat */
|
set_nonzero_bits_and_sign_copies() is important. Because newi2pat
|
||||||
|
can affect nonzero_bits of newpat */
|
||||||
if (newi2pat)
|
if (newi2pat)
|
||||||
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
|
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
|
||||||
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
|
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
|
||||||
|
@ -8171,17 +8144,17 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
|
||||||
value. Otherwise, use the previously-computed global nonzero bits
|
value. Otherwise, use the previously-computed global nonzero bits
|
||||||
for this register. */
|
for this register. */
|
||||||
|
|
||||||
if (reg_last_set_value[REGNO (x)] != 0
|
if (reg_stat[REGNO (x)].last_set_value != 0
|
||||||
&& (reg_last_set_mode[REGNO (x)] == mode
|
&& (reg_stat[REGNO (x)].last_set_mode == mode
|
||||||
|| (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
|
|| (GET_MODE_CLASS (reg_stat[REGNO (x)].last_set_mode) == MODE_INT
|
||||||
&& GET_MODE_CLASS (mode) == MODE_INT))
|
&& GET_MODE_CLASS (mode) == MODE_INT))
|
||||||
&& (reg_last_set_label[REGNO (x)] == label_tick
|
&& (reg_stat[REGNO (x)].last_set_label == label_tick
|
||||||
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||||
&& REG_N_SETS (REGNO (x)) == 1
|
&& REG_N_SETS (REGNO (x)) == 1
|
||||||
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
|
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
|
||||||
REGNO (x))))
|
REGNO (x))))
|
||||||
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
|
&& INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
|
||||||
return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
|
return reg_stat[REGNO (x)].last_set_nonzero_bits & nonzero;
|
||||||
|
|
||||||
tem = get_last_value (x);
|
tem = get_last_value (x);
|
||||||
|
|
||||||
|
@ -8190,8 +8163,8 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
|
||||||
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
|
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
|
||||||
/* If X is narrower than MODE and TEM is a non-negative
|
/* If X is narrower than MODE and TEM is a non-negative
|
||||||
constant that would appear negative in the mode of X,
|
constant that would appear negative in the mode of X,
|
||||||
sign-extend it for use in reg_nonzero_bits because some
|
sign-extend it for use in reg_stat[].nonzero_bits because
|
||||||
machines (maybe most) will actually do the sign-extension
|
some machines (maybe most) will actually do the sign-extension
|
||||||
and this is the conservative approach.
|
and this is the conservative approach.
|
||||||
|
|
||||||
??? For 2.5, try to tighten up the MD files in this regard
|
??? For 2.5, try to tighten up the MD files in this regard
|
||||||
|
@ -8209,9 +8182,9 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
|
||||||
#endif
|
#endif
|
||||||
return nonzero_bits_with_known (tem, mode) & nonzero;
|
return nonzero_bits_with_known (tem, mode) & nonzero;
|
||||||
}
|
}
|
||||||
else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
|
else if (nonzero_sign_valid && reg_stat[REGNO (x)].nonzero_bits)
|
||||||
{
|
{
|
||||||
unsigned HOST_WIDE_INT mask = reg_nonzero_bits[REGNO (x)];
|
unsigned HOST_WIDE_INT mask = reg_stat[REGNO (x)].nonzero_bits;
|
||||||
|
|
||||||
if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width)
|
if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width)
|
||||||
/* We don't know anything about the upper bits. */
|
/* We don't know anything about the upper bits. */
|
||||||
|
@ -8667,23 +8640,23 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
|
||||||
return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
|
return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (reg_last_set_value[REGNO (x)] != 0
|
if (reg_stat[REGNO (x)].last_set_value != 0
|
||||||
&& reg_last_set_mode[REGNO (x)] == mode
|
&& reg_stat[REGNO (x)].last_set_mode == mode
|
||||||
&& (reg_last_set_label[REGNO (x)] == label_tick
|
&& (reg_stat[REGNO (x)].last_set_label == label_tick
|
||||||
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||||
&& REG_N_SETS (REGNO (x)) == 1
|
&& REG_N_SETS (REGNO (x)) == 1
|
||||||
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
|
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
|
||||||
REGNO (x))))
|
REGNO (x))))
|
||||||
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
|
&& INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
|
||||||
return reg_last_set_sign_bit_copies[REGNO (x)];
|
return reg_stat[REGNO (x)].last_set_sign_bit_copies;
|
||||||
|
|
||||||
tem = get_last_value (x);
|
tem = get_last_value (x);
|
||||||
if (tem != 0)
|
if (tem != 0)
|
||||||
return num_sign_bit_copies_with_known (tem, mode);
|
return num_sign_bit_copies_with_known (tem, mode);
|
||||||
|
|
||||||
if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
|
if (nonzero_sign_valid && reg_stat[REGNO (x)].sign_bit_copies != 0
|
||||||
&& GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
|
&& GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
|
||||||
return reg_sign_bit_copies[REGNO (x)];
|
return reg_stat[REGNO (x)].sign_bit_copies;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM:
|
case MEM:
|
||||||
|
@ -11367,7 +11340,7 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utility function for following routine. Called when X is part of a value
|
/* Utility function for following routine. Called when X is part of a value
|
||||||
being stored into reg_last_set_value. Sets reg_last_set_table_tick
|
being stored into last_set_value. Sets last_set_table_tick
|
||||||
for each register mentioned. Similar to mention_regs in cse.c */
|
for each register mentioned. Similar to mention_regs in cse.c */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -11386,7 +11359,7 @@ update_table_tick (rtx x)
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
|
|
||||||
for (r = regno; r < endregno; r++)
|
for (r = regno; r < endregno; r++)
|
||||||
reg_last_set_table_tick[r] = label_tick;
|
reg_stat[r].last_set_table_tick = label_tick;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -11434,8 +11407,9 @@ update_table_tick (rtx x)
|
||||||
|
|
||||||
/* Record that REG is set to VALUE in insn INSN. If VALUE is zero, we
|
/* Record that REG is set to VALUE in insn INSN. If VALUE is zero, we
|
||||||
are saying that the register is clobbered and we no longer know its
|
are saying that the register is clobbered and we no longer know its
|
||||||
value. If INSN is zero, don't update reg_last_set; this is only permitted
|
value. If INSN is zero, don't update reg_stat[].last_set; this is
|
||||||
with VALUE also zero and is used to invalidate the register. */
|
only permitted with VALUE also zero and is used to invalidate the
|
||||||
|
register. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
record_value_for_reg (rtx reg, rtx insn, rtx value)
|
record_value_for_reg (rtx reg, rtx insn, rtx value)
|
||||||
|
@ -11479,13 +11453,13 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
|
||||||
for (i = regno; i < endregno; i++)
|
for (i = regno; i < endregno; i++)
|
||||||
{
|
{
|
||||||
if (insn)
|
if (insn)
|
||||||
reg_last_set[i] = insn;
|
reg_stat[i].last_set = insn;
|
||||||
|
|
||||||
reg_last_set_value[i] = 0;
|
reg_stat[i].last_set_value = 0;
|
||||||
reg_last_set_mode[i] = 0;
|
reg_stat[i].last_set_mode = 0;
|
||||||
reg_last_set_nonzero_bits[i] = 0;
|
reg_stat[i].last_set_nonzero_bits = 0;
|
||||||
reg_last_set_sign_bit_copies[i] = 0;
|
reg_stat[i].last_set_sign_bit_copies = 0;
|
||||||
reg_last_death[i] = 0;
|
reg_stat[i].last_death = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark registers that are being referenced in this value. */
|
/* Mark registers that are being referenced in this value. */
|
||||||
|
@ -11501,40 +11475,40 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
|
||||||
|
|
||||||
for (i = regno; i < endregno; i++)
|
for (i = regno; i < endregno; i++)
|
||||||
{
|
{
|
||||||
reg_last_set_label[i] = label_tick;
|
reg_stat[i].last_set_label = label_tick;
|
||||||
if (value && reg_last_set_table_tick[i] == label_tick)
|
if (value && reg_stat[i].last_set_table_tick == label_tick)
|
||||||
reg_last_set_invalid[i] = 1;
|
reg_stat[i].last_set_invalid = 1;
|
||||||
else
|
else
|
||||||
reg_last_set_invalid[i] = 0;
|
reg_stat[i].last_set_invalid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The value being assigned might refer to X (like in "x++;"). In that
|
/* The value being assigned might refer to X (like in "x++;"). In that
|
||||||
case, we must replace it with (clobber (const_int 0)) to prevent
|
case, we must replace it with (clobber (const_int 0)) to prevent
|
||||||
infinite loops. */
|
infinite loops. */
|
||||||
if (value && ! get_last_value_validate (&value, insn,
|
if (value && ! get_last_value_validate (&value, insn,
|
||||||
reg_last_set_label[regno], 0))
|
reg_stat[regno].last_set_label, 0))
|
||||||
{
|
{
|
||||||
value = copy_rtx (value);
|
value = copy_rtx (value);
|
||||||
if (! get_last_value_validate (&value, insn,
|
if (! get_last_value_validate (&value, insn,
|
||||||
reg_last_set_label[regno], 1))
|
reg_stat[regno].last_set_label, 1))
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the main register being modified, update the value, the mode, the
|
/* For the main register being modified, update the value, the mode, the
|
||||||
nonzero bits, and the number of sign bit copies. */
|
nonzero bits, and the number of sign bit copies. */
|
||||||
|
|
||||||
reg_last_set_value[regno] = value;
|
reg_stat[regno].last_set_value = value;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
enum machine_mode mode = GET_MODE (reg);
|
enum machine_mode mode = GET_MODE (reg);
|
||||||
subst_low_cuid = INSN_CUID (insn);
|
subst_low_cuid = INSN_CUID (insn);
|
||||||
reg_last_set_mode[regno] = mode;
|
reg_stat[regno].last_set_mode = mode;
|
||||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
||||||
mode = nonzero_bits_mode;
|
mode = nonzero_bits_mode;
|
||||||
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
|
reg_stat[regno].last_set_nonzero_bits = nonzero_bits (value, mode);
|
||||||
reg_last_set_sign_bit_copies[regno]
|
reg_stat[regno].last_set_sign_bit_copies
|
||||||
= num_sign_bit_copies (value, GET_MODE (reg));
|
= num_sign_bit_copies (value, GET_MODE (reg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11579,11 +11553,11 @@ record_dead_and_set_regs_1 (rtx dest, rtx setter, void *data)
|
||||||
for the things done by INSN. This is the last thing done in processing
|
for the things done by INSN. This is the last thing done in processing
|
||||||
INSN in the combiner loop.
|
INSN in the combiner loop.
|
||||||
|
|
||||||
We update reg_last_set, reg_last_set_value, reg_last_set_mode,
|
We update reg_stat[], in particular fields last_set, last_set_value,
|
||||||
reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
|
last_set_mode, last_set_nonzero_bits, last_set_sign_bit_copies,
|
||||||
and also the similar information mem_last_set (which insn most recently
|
last_death, and also the similar information mem_last_set (which insn
|
||||||
modified memory) and last_call_cuid (which insn was the most recent
|
most recently modified memory) and last_call_cuid (which insn was the
|
||||||
subroutine call). */
|
most recent subroutine call). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
record_dead_and_set_regs (rtx insn)
|
record_dead_and_set_regs (rtx insn)
|
||||||
|
@ -11603,7 +11577,7 @@ record_dead_and_set_regs (rtx insn)
|
||||||
: 1);
|
: 1);
|
||||||
|
|
||||||
for (i = regno; i < endregno; i++)
|
for (i = regno; i < endregno; i++)
|
||||||
reg_last_death[i] = insn;
|
reg_stat[i].last_death = insn;
|
||||||
}
|
}
|
||||||
else if (REG_NOTE_KIND (link) == REG_INC)
|
else if (REG_NOTE_KIND (link) == REG_INC)
|
||||||
record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
|
record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
|
||||||
|
@ -11614,11 +11588,11 @@ record_dead_and_set_regs (rtx insn)
|
||||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||||
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
|
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
|
||||||
{
|
{
|
||||||
reg_last_set_value[i] = 0;
|
reg_stat[i].last_set_value = 0;
|
||||||
reg_last_set_mode[i] = 0;
|
reg_stat[i].last_set_mode = 0;
|
||||||
reg_last_set_nonzero_bits[i] = 0;
|
reg_stat[i].last_set_nonzero_bits = 0;
|
||||||
reg_last_set_sign_bit_copies[i] = 0;
|
reg_stat[i].last_set_sign_bit_copies = 0;
|
||||||
reg_last_death[i] = 0;
|
reg_stat[i].last_death = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_call_cuid = mem_last_set = INSN_CUID (insn);
|
last_call_cuid = mem_last_set = INSN_CUID (insn);
|
||||||
|
@ -11666,10 +11640,10 @@ record_promoted_value (rtx insn, rtx subreg)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg_last_set[regno] == insn)
|
if (reg_stat[regno].last_set == insn)
|
||||||
{
|
{
|
||||||
if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
|
if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
|
||||||
reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode);
|
reg_stat[regno].last_set_nonzero_bits &= GET_MODE_MASK (mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GET_CODE (SET_SRC (set)) == REG)
|
if (GET_CODE (SET_SRC (set)) == REG)
|
||||||
|
@ -11739,14 +11713,14 @@ get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
for (j = regno; j < endregno; j++)
|
for (j = regno; j < endregno; j++)
|
||||||
if (reg_last_set_invalid[j]
|
if (reg_stat[j].last_set_invalid
|
||||||
/* If this is a pseudo-register that was only set once and not
|
/* If this is a pseudo-register that was only set once and not
|
||||||
live at the beginning of the function, it is always valid. */
|
live at the beginning of the function, it is always valid. */
|
||||||
|| (! (regno >= FIRST_PSEUDO_REGISTER
|
|| (! (regno >= FIRST_PSEUDO_REGISTER
|
||||||
&& REG_N_SETS (regno) == 1
|
&& REG_N_SETS (regno) == 1
|
||||||
&& (! REGNO_REG_SET_P
|
&& (! REGNO_REG_SET_P
|
||||||
(ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
|
(ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
|
||||||
&& reg_last_set_label[j] > tick))
|
&& reg_stat[j].last_set_label > tick))
|
||||||
{
|
{
|
||||||
if (replace)
|
if (replace)
|
||||||
*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
|
*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
|
||||||
|
@ -11838,7 +11812,7 @@ get_last_value (rtx x)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
regno = REGNO (x);
|
regno = REGNO (x);
|
||||||
value = reg_last_set_value[regno];
|
value = reg_stat[regno].last_set_value;
|
||||||
|
|
||||||
/* If we don't have a value, or if it isn't for this basic block and
|
/* If we don't have a value, or if it isn't for this basic block and
|
||||||
it's either a hard register, set more than once, or it's a live
|
it's either a hard register, set more than once, or it's a live
|
||||||
|
@ -11851,7 +11825,7 @@ get_last_value (rtx x)
|
||||||
block. */
|
block. */
|
||||||
|
|
||||||
if (value == 0
|
if (value == 0
|
||||||
|| (reg_last_set_label[regno] != label_tick
|
|| (reg_stat[regno].last_set_label != label_tick
|
||||||
&& (regno < FIRST_PSEUDO_REGISTER
|
&& (regno < FIRST_PSEUDO_REGISTER
|
||||||
|| REG_N_SETS (regno) != 1
|
|| REG_N_SETS (regno) != 1
|
||||||
|| (REGNO_REG_SET_P
|
|| (REGNO_REG_SET_P
|
||||||
|
@ -11860,20 +11834,20 @@ get_last_value (rtx x)
|
||||||
|
|
||||||
/* If the value was set in a later insn than the ones we are processing,
|
/* If the value was set in a later insn than the ones we are processing,
|
||||||
we can't use it even if the register was only set once. */
|
we can't use it even if the register was only set once. */
|
||||||
if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
|
if (INSN_CUID (reg_stat[regno].last_set) >= subst_low_cuid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the value has all its registers valid, return it. */
|
/* If the value has all its registers valid, return it. */
|
||||||
if (get_last_value_validate (&value, reg_last_set[regno],
|
if (get_last_value_validate (&value, reg_stat[regno].last_set,
|
||||||
reg_last_set_label[regno], 0))
|
reg_stat[regno].last_set_label, 0))
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
/* Otherwise, make a copy and replace any invalid register with
|
/* Otherwise, make a copy and replace any invalid register with
|
||||||
(clobber (const_int 0)). If that fails for some reason, return 0. */
|
(clobber (const_int 0)). If that fails for some reason, return 0. */
|
||||||
|
|
||||||
value = copy_rtx (value);
|
value = copy_rtx (value);
|
||||||
if (get_last_value_validate (&value, reg_last_set[regno],
|
if (get_last_value_validate (&value, reg_stat[regno].last_set,
|
||||||
reg_last_set_label[regno], 1))
|
reg_stat[regno].last_set_label, 1))
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -11902,8 +11876,8 @@ use_crosses_set_p (rtx x, int from_cuid)
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
for (; regno < endreg; regno++)
|
for (; regno < endreg; regno++)
|
||||||
if (reg_last_set[regno]
|
if (reg_stat[regno].last_set
|
||||||
&& INSN_CUID (reg_last_set[regno]) > from_cuid)
|
&& INSN_CUID (reg_stat[regno].last_set) > from_cuid)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12163,7 +12137,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
|
||||||
if (code == REG)
|
if (code == REG)
|
||||||
{
|
{
|
||||||
unsigned int regno = REGNO (x);
|
unsigned int regno = REGNO (x);
|
||||||
rtx where_dead = reg_last_death[regno];
|
rtx where_dead = reg_stat[regno].last_death;
|
||||||
rtx before_dead, after_dead;
|
rtx before_dead, after_dead;
|
||||||
|
|
||||||
/* Don't move the register if it gets killed in between from and to. */
|
/* Don't move the register if it gets killed in between from and to. */
|
||||||
|
@ -12190,7 +12164,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
|
||||||
rtx note = remove_death (regno, where_dead);
|
rtx note = remove_death (regno, where_dead);
|
||||||
|
|
||||||
/* It is possible for the call above to return 0. This can occur
|
/* It is possible for the call above to return 0. This can occur
|
||||||
when reg_last_death points to I2 or I1 that we combined with.
|
when last_death points to I2 or I1 that we combined with.
|
||||||
In that case make a new note.
|
In that case make a new note.
|
||||||
|
|
||||||
We must also check for the case where X is a hard register
|
We must also check for the case where X is a hard register
|
||||||
|
@ -12803,14 +12777,14 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|
||||||
|| reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
|
|| reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
|
||||||
{
|
{
|
||||||
/* Unless the register previously died in PLACE, clear
|
/* Unless the register previously died in PLACE, clear
|
||||||
reg_last_death. [I no longer understand why this is
|
last_death. [I no longer understand why this is
|
||||||
being done.] */
|
being done.] */
|
||||||
if (reg_last_death[regno] != place)
|
if (reg_stat[regno].last_death != place)
|
||||||
reg_last_death[regno] = 0;
|
reg_stat[regno].last_death = 0;
|
||||||
place = 0;
|
place = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
reg_last_death[regno] = place;
|
reg_stat[regno].last_death = place;
|
||||||
|
|
||||||
/* If this is a death note for a hard reg that is occupying
|
/* If this is a death note for a hard reg that is occupying
|
||||||
multiple registers, ensure that we are still using all
|
multiple registers, ensure that we are still using all
|
||||||
|
|
Loading…
Reference in New Issue