Include hard-reg-set.h.

(reg_nonzero_bits): Should be unsigned.
(reg_last_set_{mode,nonzero_bits,sign_bit_copies}): New variables.
(combine_instructions): Allocate and initialized them.
(nonzero_bits, num_sign_bit_copies, case REG): Use new variables to get
information on regs we've seen before.
(record_value_for_reg): Set new variables for register being modified.
(record_dead_and_set_regs): Invalidate regs clobbered by CALL_INSN.

From-SVN: r4051
This commit is contained in:
Richard Kenner 1993-04-08 21:44:57 -04:00
parent f67850266f
commit 55310dadb0
1 changed files with 67 additions and 11 deletions

View File

@ -78,6 +78,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rtl.h" #include "rtl.h"
#include "flags.h" #include "flags.h"
#include "regs.h" #include "regs.h"
#include "hard-reg-set.h"
#include "expr.h" #include "expr.h"
#include "basic-block.h" #include "basic-block.h"
#include "insn-config.h" #include "insn-config.h"
@ -262,7 +263,7 @@ static short label_tick;
If an entry is zero, it means that we don't know anything special. */ If an entry is zero, it means that we don't know anything special. */
static HOST_WIDE_INT *reg_nonzero_bits; static unsigned HOST_WIDE_INT *reg_nonzero_bits;
/* Mode used to compute significance in reg_nonzero_bits. It is the largest /* Mode used to compute significance in reg_nonzero_bits. It is the largest
integer mode that can fit in HOST_BITS_PER_WIDE_INT. */ integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
@ -280,6 +281,15 @@ static char *reg_sign_bit_copies;
which can be incorrect if a variable is modified in a loop. */ 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.
@ -417,7 +427,15 @@ combine_instructions (f, nregs)
reg_last_set_table_tick = (short *) alloca (nregs * sizeof (short)); reg_last_set_table_tick = (short *) alloca (nregs * sizeof (short));
reg_last_set_label = (short *) alloca (nregs * sizeof (short)); reg_last_set_label = (short *) alloca (nregs * sizeof (short));
reg_last_set_invalid = (char *) alloca (nregs * sizeof (char)); reg_last_set_invalid = (char *) alloca (nregs * sizeof (char));
reg_nonzero_bits = (HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT)); reg_last_set_mode
= (enum machine_mode *) alloca (nregs * sizeof (enum machine_mode));
reg_last_set_nonzero_bits
= (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
reg_last_set_sign_bit_copies
= (char *) alloca (nregs * sizeof (char));
reg_nonzero_bits
= (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char)); reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char));
bzero (reg_last_death, nregs * sizeof (rtx)); bzero (reg_last_death, nregs * sizeof (rtx));
@ -426,6 +444,9 @@ combine_instructions (f, nregs)
bzero (reg_last_set_table_tick, nregs * sizeof (short)); bzero (reg_last_set_table_tick, nregs * sizeof (short));
bzero (reg_last_set_label, nregs * sizeof (short)); bzero (reg_last_set_label, nregs * sizeof (short));
bzero (reg_last_set_invalid, nregs * sizeof (char)); bzero (reg_last_set_invalid, nregs * sizeof (char));
bzero (reg_last_set_mode, nregs * sizeof (enum machine_mode));
bzero (reg_last_set_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
bzero (reg_last_set_sign_bit_copies, nregs * sizeof (char));
bzero (reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); bzero (reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
bzero (reg_sign_bit_copies, nregs * sizeof (char)); bzero (reg_sign_bit_copies, nregs * sizeof (char));
@ -6144,9 +6165,17 @@ nonzero_bits (x, mode)
} }
#endif #endif
/* If X is a register whose value we can find, use that value. /* If X is a register whose nonzero bits value is current, use it.
Otherwise, use the previously-computed nonzero bits for this Otherwise, if X is a register whose value we can find, use that
register. */ value. Otherwise, use the previously-computed global nonzero bits
for this register. */
if (reg_last_set_value[REGNO (x)] != 0
&& reg_last_set_mode[REGNO (x)] == mode
&& (reg_n_sets[REGNO (x)] == 1
|| reg_last_set_label[REGNO (x)] == label_tick)
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
return reg_last_set_nonzero_bits[REGNO (x)];
tem = get_last_value (x); tem = get_last_value (x);
if (tem) if (tem)
@ -6425,12 +6454,20 @@ num_sign_bit_copies (x, mode)
switch (code) switch (code)
{ {
case REG: case REG:
if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0)
return reg_sign_bit_copies[REGNO (x)]; if (reg_last_set_value[REGNO (x)] != 0
&& reg_last_set_mode[REGNO (x)] == mode
&& (reg_n_sets[REGNO (x)] == 1
|| reg_last_set_label[REGNO (x)] == label_tick)
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
return reg_last_set_sign_bit_copies[REGNO (x)];
tem = get_last_value (x); tem = get_last_value (x);
if (tem != 0) if (tem != 0)
return num_sign_bit_copies (tem, mode); return num_sign_bit_copies (tem, mode);
if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0)
return reg_sign_bit_copies[REGNO (x)];
break; break;
#ifdef BYTE_LOADS_SIGN_EXTEND #ifdef BYTE_LOADS_SIGN_EXTEND
@ -8856,9 +8893,18 @@ record_value_for_reg (reg, insn, value)
value = 0; value = 0;
} }
/* For the main register being modified, update the value. */ /* For the main register being modified, update the value, the mode, the
nonzero bits, and the number of sign bit copies. */
reg_last_set_value[regno] = value; reg_last_set_value[regno] = value;
if (value)
{
reg_last_set_mode[regno] = GET_MODE (reg);
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg));
reg_last_set_sign_bit_copies[regno]
= num_sign_bit_copies (value, GET_MODE (reg));
}
} }
/* Used for communication between the following two routines. */ /* Used for communication between the following two routines. */
@ -8907,6 +8953,8 @@ record_dead_and_set_regs (insn)
rtx insn; rtx insn;
{ {
register rtx link; register rtx link;
int i;
for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{ {
if (REG_NOTE_KIND (link) == REG_DEAD if (REG_NOTE_KIND (link) == REG_DEAD
@ -8917,7 +8965,6 @@ record_dead_and_set_regs (insn)
= regno + (regno < FIRST_PSEUDO_REGISTER = regno + (regno < FIRST_PSEUDO_REGISTER
? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0))) ? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
: 1); : 1);
int i;
for (i = regno; i < endregno; i++) for (i = regno; i < endregno; i++)
reg_last_death[i] = insn; reg_last_death[i] = insn;
@ -8927,7 +8974,16 @@ record_dead_and_set_regs (insn)
} }
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
last_call_cuid = mem_last_set = INSN_CUID (insn); {
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (call_used_regs[i])
{
reg_last_set_value[i] = 0;
reg_last_death[i] = 0;
}
last_call_cuid = mem_last_set = INSN_CUID (insn);
}
record_dead_insn = insn; record_dead_insn = insn;
note_stores (PATTERN (insn), record_dead_and_set_regs_1); note_stores (PATTERN (insn), record_dead_and_set_regs_1);
@ -9018,7 +9074,7 @@ get_last_value (x)
if (value == 0 if (value == 0
|| (reg_n_sets[regno] != 1 || (reg_n_sets[regno] != 1
&& (reg_last_set_label[regno] != label_tick))) && reg_last_set_label[regno] != label_tick))
return 0; return 0;
/* If the value was set in a later insn that the ones we are processing, /* If the value was set in a later insn that the ones we are processing,