In cselib, do not consider constants with different modes equivalent.
authorBernd Schmidt <bernds@redhat.co.uk>
Mon, 27 Nov 2000 11:43:32 +0000 (11:43 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Mon, 27 Nov 2000 11:43:32 +0000 (11:43 +0000)
From-SVN: r37792

gcc/ChangeLog
gcc/reload1.c
gcc/simplify-rtx.c

index 7d1d16ac20392b1d65df4dbff5ab7d4856e76a0a..9858a21fcb248c27201b83f9c75b1734e1c1ded8 100644 (file)
@@ -1,3 +1,17 @@
+2000-11-27  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       * reload1.c (reload_cse_simplify_set): Pass down mode to cselib_lookup.
+       (reload_cse_simplify_operands): Do nothing about operands where both
+       the operand and the match_operand fail to give us a mode.
+       * simplify-rtx.c (wrap_constant): New function.
+       (entry_and_rtx_equal_p): Except integer constants to come wrapped in a
+       CONST describing the proper mode.
+       (rtx_equal_for_cselib_p): Pass down modes to recursive calls of
+       cselib_lookup.
+       (cselib_lookup_mem): Call wrap_constant on the rtx that is passed to
+       htab_find_slot_with_hash.
+       (cselib_lookup): Likewise.
+
 2000-11-27  Alexandre Oliva  <aoliva@redhat.com>
 
        * configure.in (extra_objs): Enclose extra_headers in quotes.
index 60eac681ddf4f072e3bd96c04e5b150eeedf2756..44ff84ecaa538d4bfda8267009a9c7524f4249c5 100644 (file)
@@ -8093,7 +8093,7 @@ reload_cse_simplify_set (set, insn)
     /* ???   */
     old_cost = rtx_cost (src, SET);
 
-  val = cselib_lookup (src, VOIDmode, 0);
+  val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0);
   if (! val)
     return 0;
   for (l = val->locs; l; l = l->next)
@@ -8178,8 +8178,11 @@ reload_cse_simplify_operands (insn)
       CLEAR_HARD_REG_SET (equiv_regs[i]);
 
       /* cselib blows up on CODE_LABELs.  Trying to fix that doesn't seem
-        right, so avoid the problem here.  */
-      if (GET_CODE (recog_data.operand[i]) == CODE_LABEL)
+        right, so avoid the problem here.  Likewise if we have a constant
+         and the insn pattern doesn't tell us the mode we need.  */
+      if (GET_CODE (recog_data.operand[i]) == CODE_LABEL
+         || (CONSTANT_P (recog_data.operand[i])
+             && recog_data.operand_mode[i] == VOIDmode))
        continue;
 
       v = cselib_lookup (recog_data.operand[i], recog_data.operand_mode[i], 0);
index fcf0831479ab56fcf1df992ab24068f90d1e6cba..d7b43d1ac9171ccbfd81577a26eac3e20a0b836e 100644 (file)
@@ -115,6 +115,7 @@ static void clear_table                     PARAMS ((void));
 static int discard_useless_locs                PARAMS ((void **, void *));
 static int discard_useless_values      PARAMS ((void **, void *));
 static void remove_useless_values      PARAMS ((void));
+static rtx wrap_constant               PARAMS ((enum machine_mode, rtx));
 static unsigned int hash_rtx           PARAMS ((rtx, enum machine_mode, int));
 static cselib_val *new_cselib_val      PARAMS ((unsigned int,
                                                 enum machine_mode));
@@ -2221,7 +2222,9 @@ clear_table ()
 }
 
 /* The equality test for our hash table.  The first argument ENTRY is a table
-   element (i.e. a cselib_val), while the second arg X is an rtx.  */
+   element (i.e. a cselib_val), while the second arg X is an rtx.  We know
+   that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
+   CONST of an appropriate mode.  */
 
 static int
 entry_and_rtx_equal_p (entry, x_arg)
@@ -2230,7 +2233,20 @@ entry_and_rtx_equal_p (entry, x_arg)
   struct elt_loc_list *l;
   const cselib_val *v = (const cselib_val *) entry;
   rtx x = (rtx) x_arg;
+  enum machine_mode mode = GET_MODE (x);
 
+  if (GET_CODE (x) == CONST_INT
+      || (mode == VOIDmode && GET_CODE (x) == CONST_DOUBLE))
+    abort ();
+  if (mode != GET_MODE (v->u.val_rtx))
+    return 0;
+
+  /* Unwrap X if necessary.  */
+  if (GET_CODE (x) == CONST
+      && (GET_CODE (XEXP (x, 0)) == CONST_INT
+         || GET_CODE (XEXP (x, 0)) == CONST_DOUBLE))
+    x = XEXP (x, 0);
+  
   /* We don't guarantee that distinct rtx's have different hash values,
      so we need to do a comparison.  */
   for (l = v->locs; l; l = l->next)
@@ -2366,7 +2382,7 @@ rtx_equal_for_cselib_p (x, y)
   
   if (GET_CODE (x) == REG || GET_CODE (x) == MEM)
     {
-      cselib_val *e = cselib_lookup (x, VOIDmode, 0);
+      cselib_val *e = cselib_lookup (x, GET_MODE (x), 0);
 
       if (e)
        x = e->u.val_rtx;
@@ -2374,7 +2390,7 @@ rtx_equal_for_cselib_p (x, y)
 
   if (GET_CODE (y) == REG || GET_CODE (y) == MEM)
     {
-      cselib_val *e = cselib_lookup (y, VOIDmode, 0);
+      cselib_val *e = cselib_lookup (y, GET_MODE (y), 0);
 
       if (e)
        y = e->u.val_rtx;
@@ -2492,6 +2508,22 @@ rtx_equal_for_cselib_p (x, y)
   return 1;
 }
 
+/* We need to pass down the mode of constants through the hash table
+   functions.  For that purpose, wrap them in a CONST of the appropriate
+   mode.  */
+static rtx
+wrap_constant (mode, x)
+     enum machine_mode mode;
+     rtx x;
+{
+  if (GET_CODE (x) != CONST_INT
+      && (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode))
+    return x;
+  if (mode == VOIDmode)
+    abort ();
+  return gen_rtx_CONST (mode, x);
+}
+
 /* Hash an rtx.  Return 0 if we couldn't hash the rtx.
    For registers and memory locations, we look up their cselib_val structure
    and return its VALUE element.
@@ -2690,31 +2722,33 @@ cselib_lookup_mem (x, create)
      rtx x;
      int create;
 {
+  enum machine_mode mode = GET_MODE (x);
   void **slot;
   cselib_val *addr;
   cselib_val *mem_elt;
   struct elt_list *l;
 
-  if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode
-      || (FLOAT_MODE_P (GET_MODE (x)) && flag_float_store))
+  if (MEM_VOLATILE_P (x) || mode == BLKmode
+      || (FLOAT_MODE_P (mode) && flag_float_store))
     return 0;
 
   /* Look up the value for the address.  */
-  addr = cselib_lookup (XEXP (x, 0), GET_MODE (x), create);
+  addr = cselib_lookup (XEXP (x, 0), mode, create);
   if (! addr)
     return 0;
 
   /* Find a value that describes a value of our mode at that address.  */
   for (l = addr->addr_list; l; l = l->next)
-    if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
+    if (GET_MODE (l->elt->u.val_rtx) == mode)
       return l->elt;
 
   if (! create)
     return 0;
 
-  mem_elt = new_cselib_val (++next_unknown_value, GET_MODE (x));
+  mem_elt = new_cselib_val (++next_unknown_value, mode);
   add_mem_for_addr (addr, mem_elt, x);
-  slot = htab_find_slot_with_hash (hash_table, x, mem_elt->value, INSERT);
+  slot = htab_find_slot_with_hash (hash_table, wrap_constant (mode, x),
+                                  mem_elt->value, INSERT);
   *slot = mem_elt;
   return mem_elt;
 }
@@ -2847,8 +2881,8 @@ cselib_lookup (x, mode, create)
   if (! hashval)
     return 0;
 
-  slot = htab_find_slot_with_hash (hash_table, x, hashval,
-                                  create ? INSERT : NO_INSERT);
+  slot = htab_find_slot_with_hash (hash_table, wrap_constant (mode, x),
+                                  hashval, create ? INSERT : NO_INSERT);
   if (slot == 0)
     return 0;