Commit ef026f91 by Richard Stallman

(init_reg_last_arrays): New function.

(combine_instructions): Use it.
(force_to_mode): Narrow mask to fit mode (except VOIDmode).
(record_value_for_reg): When zeroing reg_last_set_value, also
zero reg_last_set_{mode,nonzero_bits,sign_bit_copies}.
(record_dead_and_set_regs): Likewise.

From-SVN: r5430
parent 9f5cad05
...@@ -368,6 +368,7 @@ static struct undobuf undobuf; ...@@ -368,6 +368,7 @@ static struct undobuf undobuf;
static int n_occurrences; static int n_occurrences;
static void init_reg_last_arrays PROTO(());
static void setup_incoming_promotions PROTO(()); static void setup_incoming_promotions PROTO(());
static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx)); static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx));
static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *)); static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
...@@ -438,6 +439,13 @@ combine_instructions (f, nregs) ...@@ -438,6 +439,13 @@ combine_instructions (f, nregs)
combine_max_regno = nregs; combine_max_regno = nregs;
reg_nonzero_bits
= (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char));
bzero (reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
bzero (reg_sign_bit_copies, nregs * sizeof (char));
reg_last_death = (rtx *) alloca (nregs * sizeof (rtx)); reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
reg_last_set = (rtx *) alloca (nregs * sizeof (rtx)); reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx)); reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
...@@ -451,21 +459,7 @@ combine_instructions (f, nregs) ...@@ -451,21 +459,7 @@ combine_instructions (f, nregs)
reg_last_set_sign_bit_copies reg_last_set_sign_bit_copies
= (char *) alloca (nregs * sizeof (char)); = (char *) alloca (nregs * sizeof (char));
reg_nonzero_bits init_reg_last_arrays ();
= (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char));
bzero (reg_last_death, nregs * sizeof (rtx));
bzero (reg_last_set, nregs * sizeof (rtx));
bzero (reg_last_set_value, nregs * sizeof (rtx));
bzero (reg_last_set_table_tick, nregs * sizeof (int));
bzero (reg_last_set_label, nregs * sizeof (int));
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_sign_bit_copies, nregs * sizeof (char));
init_recog_no_volatile (); init_recog_no_volatile ();
...@@ -523,13 +517,7 @@ combine_instructions (f, nregs) ...@@ -523,13 +517,7 @@ combine_instructions (f, nregs)
label_tick = 1; label_tick = 1;
last_call_cuid = 0; last_call_cuid = 0;
mem_last_set = 0; mem_last_set = 0;
bzero (reg_last_death, nregs * sizeof (rtx)); init_reg_last_arrays ();
bzero (reg_last_set, nregs * sizeof (rtx));
bzero (reg_last_set_value, nregs * sizeof (rtx));
bzero (reg_last_set_table_tick, nregs * sizeof (int));
bzero (reg_last_set_label, nregs * sizeof (int));
bzero (reg_last_set_invalid, nregs * sizeof (char));
setup_incoming_promotions (); setup_incoming_promotions ();
for (insn = f; insn; insn = next ? next : NEXT_INSN (insn)) for (insn = f; insn; insn = next ? next : NEXT_INSN (insn))
...@@ -640,6 +628,24 @@ combine_instructions (f, nregs) ...@@ -640,6 +628,24 @@ combine_instructions (f, nregs)
nonzero_sign_valid = 0; nonzero_sign_valid = 0;
} }
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
static void
init_reg_last_arrays ()
{
int nregs = combine_max_regno;
bzero (reg_last_death, nregs * sizeof (rtx));
bzero (reg_last_set, nregs * sizeof (rtx));
bzero (reg_last_set_value, nregs * sizeof (rtx));
bzero (reg_last_set_table_tick, nregs * sizeof (int));
bzero (reg_last_set_label, nregs * sizeof (int));
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));
}
/* Set up any promoted values for incoming argument registers. */ /* Set up any promoted values for incoming argument registers. */
...@@ -5554,25 +5560,34 @@ force_to_mode (x, mode, mask, reg) ...@@ -5554,25 +5560,34 @@ force_to_mode (x, mode, mask, reg)
rtx reg; rtx reg;
{ {
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
unsigned HOST_WIDE_INT nonzero = nonzero_bits (x, mode); enum machine_mode op_mode;
unsigned HOST_WIDE_INT fuller_mask, nonzero;
rtx op0, op1, temp; rtx op0, op1, temp;
/* We want to perform the operation is its present mode unless we know /* We want to perform the operation is its present mode unless we know
that the operation is valid in MODE, in which case we do the operation that the operation is valid in MODE, in which case we do the operation
in MODE. */ in MODE. */
enum machine_mode op_mode op_mode = ((code_to_optab[(int) code] != 0
= ((code_to_optab[(int) code] != 0 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
&& (code_to_optab[(int) code]->handlers[(int) mode].insn_code != CODE_FOR_nothing))
!= CODE_FOR_nothing)) ? mode : GET_MODE (x));
? mode : GET_MODE (x));
/* Truncate MASK to fit OP_MODE. */
if (op_mode)
mask &= GET_MODE_MASK (op_mode);
/* When we have an arithmetic operation, or a shift whose count we /* When we have an arithmetic operation, or a shift whose count we
do not know, we need to assume that all bit the up to the highest-order do not know, we need to assume that all bit the up to the highest-order
bit in MASK will be needed. This is how we form such a mask. */ bit in MASK will be needed. This is how we form such a mask. */
unsigned HOST_WIDE_INT fuller_mask if (op_mode)
= (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
? GET_MODE_MASK (op_mode) ? GET_MODE_MASK (op_mode)
: ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1); : ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1);
else
fuller_mask = ~ (HOST_WIDE_INT) 0;
/* Determine what bits of X are guaranteed to be (non)zero. */
nonzero = nonzero_bits (x, mode);
/* If none of the bits in X are needed, return a zero. */ /* If none of the bits in X are needed, return a zero. */
if ((nonzero & mask) == 0) if ((nonzero & mask) == 0)
...@@ -9188,13 +9203,17 @@ record_value_for_reg (reg, insn, value) ...@@ -9188,13 +9203,17 @@ record_value_for_reg (reg, insn, value)
} }
/* For each register modified, show we don't know its value, that /* For each register modified, show we don't know its value, that
its value has been updated, and that we don't know the location of we don't know about its bitwise content, that its value has been
the death of the register. */ updated, and that we don't know the location of the death of the
register. */
for (i = regno; i < endregno; i ++) for (i = regno; i < endregno; i ++)
{ {
if (insn) if (insn)
reg_last_set[i] = insn; reg_last_set[i] = insn;
reg_last_set_value[i] = 0; reg_last_set_value[i] = 0;
reg_last_set_mode[i] = 0;
reg_last_set_nonzero_bits[i] = 0;
reg_last_set_sign_bit_copies[i] = 0;
reg_last_death[i] = 0; reg_last_death[i] = 0;
} }
...@@ -9281,9 +9300,11 @@ record_dead_and_set_regs_1 (dest, setter) ...@@ -9281,9 +9300,11 @@ record_dead_and_set_regs_1 (dest, setter)
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_death, and also the We update reg_last_set, reg_last_set_value, reg_last_set_mode,
similar information mem_last_set (which insn most recently modified memory) reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
and last_call_cuid (which insn was the most recent subroutine call). */ and also the similar information mem_last_set (which insn most recently
modified memory) and last_call_cuid (which insn was the most recent
subroutine call). */
static void static void
record_dead_and_set_regs (insn) record_dead_and_set_regs (insn)
...@@ -9316,6 +9337,9 @@ record_dead_and_set_regs (insn) ...@@ -9316,6 +9337,9 @@ record_dead_and_set_regs (insn)
if (call_used_regs[i]) if (call_used_regs[i])
{ {
reg_last_set_value[i] = 0; reg_last_set_value[i] = 0;
reg_last_set_mode[i] = 0;
reg_last_set_nonzero_bits[i] = 0;
reg_last_set_sign_bit_copies[i] = 0;
reg_last_death[i] = 0; reg_last_death[i] = 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