aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-09-23 06:11:30 +0000
committerRichard Stallman <rms@gnu.org>1993-09-23 06:11:30 +0000
commitef026f9101328fcfbf79b3ed5280135230afefc2 (patch)
treec0bdf84e967cb652316c1401252cf15a8710c448 /gcc
parent9f5cad058274f4fdb14939db3470c89a94c21a24 (diff)
downloadgcc-ef026f9101328fcfbf79b3ed5280135230afefc2.zip
gcc-ef026f9101328fcfbf79b3ed5280135230afefc2.tar.gz
gcc-ef026f9101328fcfbf79b3ed5280135230afefc2.tar.bz2
(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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/combine.c98
1 files changed, 61 insertions, 37 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 59d7cda..8251b2e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -368,6 +368,7 @@ static struct undobuf undobuf;
static int n_occurrences;
+static void init_reg_last_arrays PROTO(());
static void setup_incoming_promotions PROTO(());
static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx));
static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
@@ -438,6 +439,13 @@ combine_instructions (f, 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_set = (rtx *) alloca (nregs * sizeof (rtx));
reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
@@ -451,21 +459,7 @@ combine_instructions (f, nregs)
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));
-
- 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_reg_last_arrays ();
init_recog_no_volatile ();
@@ -523,13 +517,7 @@ combine_instructions (f, nregs)
label_tick = 1;
last_call_cuid = 0;
mem_last_set = 0;
- 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));
-
+ init_reg_last_arrays ();
setup_incoming_promotions ();
for (insn = f; insn; insn = next ? next : NEXT_INSN (insn))
@@ -640,6 +628,24 @@ combine_instructions (f, nregs)
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. */
@@ -5554,25 +5560,34 @@ force_to_mode (x, mode, mask, reg)
rtx reg;
{
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;
/* 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
in MODE. */
- enum machine_mode op_mode
- = ((code_to_optab[(int) code] != 0
- && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
- != CODE_FOR_nothing))
- ? mode : GET_MODE (x));
+ op_mode = ((code_to_optab[(int) code] != 0
+ && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
+ != CODE_FOR_nothing))
+ ? 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
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. */
- unsigned HOST_WIDE_INT fuller_mask
- = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
- ? GET_MODE_MASK (op_mode)
- : ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1);
+ if (op_mode)
+ fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
+ ? GET_MODE_MASK (op_mode)
+ : ((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 ((nonzero & mask) == 0)
@@ -9188,13 +9203,17 @@ record_value_for_reg (reg, insn, value)
}
/* 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
- the death of the register. */
+ we don't know about its bitwise content, that its value has been
+ updated, and that we don't know the location of the death of the
+ register. */
for (i = regno; i < endregno; i ++)
{
if (insn)
reg_last_set[i] = insn;
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;
}
@@ -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
INSN in the combiner loop.
- We update reg_last_set, reg_last_set_value, reg_last_death, 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). */
+ We update reg_last_set, reg_last_set_value, reg_last_set_mode,
+ reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
+ 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
record_dead_and_set_regs (insn)
@@ -9316,6 +9337,9 @@ record_dead_and_set_regs (insn)
if (call_used_regs[i])
{
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;
}