(init_reg_last_arrays): New function.
authorRichard Stallman <rms@gnu.org>
Thu, 23 Sep 1993 06:11:30 +0000 (06:11 +0000)
committerRichard Stallman <rms@gnu.org>
Thu, 23 Sep 1993 06:11:30 +0000 (06:11 +0000)
(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

gcc/combine.c

index 59d7cda450dca114df78d16b25eed0e9a346fddb..8251b2e5f087bbd205a0b770b0bd5e1de396e0fb 100644 (file)
@@ -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));
+}
 \f
 /* 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;
          }