c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs and ARRAY_TYPEs.
authorMark Mitchell <mark@markmitchell.com>
Mon, 28 Sep 1998 07:44:12 +0000 (07:44 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 28 Sep 1998 07:44:12 +0000 (07:44 +0000)
* c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs
and ARRAY_TYPEs.  Tidy up.  Improve support for type-punning.
* expr.c (store_field): Add alias_set parameter.  Set the
MEM_ALIAS_SET accordingly, if the target is a MEM.
(expand_assignment): Use it.
(store_constructor_field): Pass 0.
(expand_expr): Likewise.

From-SVN: r22620

gcc/ChangeLog
gcc/c-common.c
gcc/expr.c

index 5a01f5a65caa974d0fa7717507a6a2eac7258139..154165c3c78297227b662a513c4be86840d55ae3 100644 (file)
@@ -1,3 +1,13 @@
+Mon Sep 28 07:43:34 1998  Mark Mitchell  <mark@markmitchell.com>
+
+       * c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs
+       and ARRAY_TYPEs.  Tidy up.  Improve support for type-punning. 
+       * expr.c (store_field): Add alias_set parameter.  Set the
+       MEM_ALIAS_SET accordingly, if the target is a MEM.
+       (expand_assignment): Use it.
+       (store_constructor_field): Pass 0.
+       (expand_expr): Likewise.
+
 Mon Sep 28 07:54:03 1998  Catherine Moore  <clm@cygnus.com>
  
         * flags.h:  Add flag_data_sections.
index a79d9d2f2b3d0bf88656d40adb6a5554baa185ae..4d2e7a090a8b0b42098990360e0f84e2159362a6 100644 (file)
@@ -2990,14 +2990,13 @@ c_get_alias_set (t)
     return 0;
 
   type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
-    ? t :  TREE_TYPE (t);
+    ? t : TREE_TYPE (t);
 
   if (type == error_mark_node)
     return 0;
 
-  if (TYPE_ALIAS_SET_KNOWN_P (type))
-    /* If we've already calculated the value, just return it.  */
-    return TYPE_ALIAS_SET (type);
+  /* Deal with special cases first; for certain kinds of references
+     we're interested in more than just the type.  */
 
   if (TREE_CODE (t) == BIT_FIELD_REF)
     /* Perhaps reads and writes to this piece of data alias fields
@@ -3005,6 +3004,7 @@ c_get_alias_set (t)
        let's just assume that bitfields can alias everything, which is
        the conservative assumption.  */
     return 0;
+
   if (TREE_CODE (t) == COMPONENT_REF
       && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
     /* Permit type-punning when accessing a union, provided the
@@ -3014,13 +3014,16 @@ c_get_alias_set (t)
        GCC extension, albeit a common and useful one; the C standard
        says that such accesses have implementation-defined behavior.  */ 
     return 0;
+
+  /* From here on, only the type matters.  */
+
+  if (TYPE_ALIAS_SET_KNOWN_P (type))
+    /* If we've already calculated the value, just return it.  */
+    return TYPE_ALIAS_SET (type);
   else if (TYPE_MAIN_VARIANT (type) != type)
-    {
-      /* The C standard specifically allows aliasing between
-        cv-qualified variants of types.  */
-      TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
-      return TYPE_ALIAS_SET (type);
-    }
+    /* The C standard specifically allows aliasing between
+       cv-qualified variants of types.  */
+    TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
   else if (TREE_CODE (type) == INTEGER_TYPE)
     {
       tree signed_variant;
@@ -3031,34 +3034,37 @@ c_get_alias_set (t)
       signed_variant = signed_type (type);
 
       if (signed_variant != type)
-       {
-         TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
-         return TYPE_ALIAS_SET (type);
-       }
+       TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
       else if (signed_variant == signed_char_type_node)
        /* The C standard guarantess that any object may be accessed
           via an lvalue that has character type.  We don't have to
           check for unsigned_char_type_node or char_type_node because
           we are specifically looking at the signed variant.  */
-       {
-         TYPE_ALIAS_SET (type) = 0;
-         return TYPE_ALIAS_SET (type);
-       }
+       TYPE_ALIAS_SET (type) = 0;
     }
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    /* Anything that can alias one of the array elements can alias
+       the entire array as well.  */
+    TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type));
+  else if (TREE_CODE (type) == FUNCTION_TYPE)
+    /* There are no objects of FUNCTION_TYPE, so there's no point in
+       using up an alias set for them.  (There are, of course,
+       pointers and references to functions, but that's 
+       different.)  */
+    TYPE_ALIAS_SET (type) = 0;
   else if (TREE_CODE (type) == RECORD_TYPE
           || TREE_CODE (type) == UNION_TYPE)
-    {
-      /* If TYPE is a struct or union type then we're reading or
-        writing an entire struct.  Thus, we don't know anything about
-        aliasing.  (In theory, such an access can only alias objects
-        whose type is the same as one of the fields, recursively, but
-        we don't yet make any use of that information.)  */
-      TYPE_ALIAS_SET (type) = 0;
-      return TYPE_ALIAS_SET (type);
-    }
+    /* If TYPE is a struct or union type then we're reading or
+       writing an entire struct.  Thus, we don't know anything about
+       aliasing.  (In theory, such an access can only alias objects
+       whose type is the same as one of the fields, recursively, but
+       we don't yet make any use of that information.)  */
+    TYPE_ALIAS_SET (type) = 0;
+
+  if (!TYPE_ALIAS_SET_KNOWN_P (type)) 
+    /* TYPE is something we haven't seen before.  Put it in a new
+       alias set.  */
+    TYPE_ALIAS_SET (type) = new_alias_set ();
 
-  /* TYPE is something we haven't seen before.  Put it in a new alias
-     set.  */
-  TYPE_ALIAS_SET (type) = new_alias_set ();
   return TYPE_ALIAS_SET (type);
 }
index 2c82924d2208e2be38883821119efd03e3b293bb..19885880efcd049f4207eb8c4498b7567c3472ed 100644 (file)
@@ -168,7 +168,8 @@ static void store_constructor_field PROTO((rtx, int, int, enum machine_mode,
                                           tree, tree, int));
 static void store_constructor  PROTO((tree, rtx, int));
 static rtx store_field         PROTO((rtx, int, int, enum machine_mode, tree,
-                                      enum machine_mode, int, int, int));
+                                      enum machine_mode, int, int,
+                                      int, int));
 static enum memory_use_mode
   get_memory_usage_from_modifier PROTO((enum expand_modifier));
 static tree save_noncopied_parts PROTO((tree, tree));
@@ -3223,7 +3224,8 @@ expand_assignment (to, from, want_value, suggest_reg)
                            unsignedp,
                            /* Required alignment of containing datum.  */
                            alignment,
-                           int_size_in_bytes (TREE_TYPE (tem)));
+                           int_size_in_bytes (TREE_TYPE (tem)),
+                           get_alias_set (to));
       preserve_temp_slots (result);
       free_temp_slots ();
       pop_temp_slots ();
@@ -3805,7 +3807,7 @@ store_constructor_field (target, bitsize, bitpos,
   else
     store_field (target, bitsize, bitpos, mode, exp,
                 VOIDmode, 0, TYPE_ALIGN (type) / BITS_PER_UNIT,
-                int_size_in_bytes (type));
+                int_size_in_bytes (type), 0);
 }
 
 /* Store the value of constructor EXP into the rtx TARGET.
@@ -4385,11 +4387,15 @@ store_constructor (exp, target, cleared)
    In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
 
    ALIGN is the alignment that TARGET is known to have, measured in bytes.
-   TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.  */
+   TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.  
+
+   ALIAS_SET is the alias set for the destination.  This value will
+   (in general) be different from that for TARGET, since TARGET is a
+   reference to the containing structure.  */
 
 static rtx
 store_field (target, bitsize, bitpos, mode, exp, value_mode,
-            unsignedp, align, total_size)
+            unsignedp, align, total_size, alias_set)
      rtx target;
      int bitsize, bitpos;
      enum machine_mode mode;
@@ -4398,6 +4404,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
      int unsignedp;
      int align;
      int total_size;
+     int alias_set;
 {
   HOST_WIDE_INT width_mask = 0;
 
@@ -4433,7 +4440,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
        emit_move_insn (object, target);
 
       store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
-                  align, total_size);
+                  align, total_size, alias_set);
 
       /* Even though we aren't returning target, we need to
         give it the updated value.  */
@@ -4548,6 +4555,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
                                                        (bitpos
                                                         / BITS_PER_UNIT))));
       MEM_IN_STRUCT_P (to_rtx) = 1;
+      MEM_ALIAS_SET (to_rtx) = alias_set;
 
       return store_expr (exp, to_rtx, value_mode != VOIDmode);
     }
@@ -6614,7 +6622,8 @@ expand_expr (exp, target, tmode, modifier)
            store_field (target, GET_MODE_BITSIZE (TYPE_MODE (valtype)), 0,
                         TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
                         VOIDmode, 0, 1,
-                        int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))));
+                        int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))),
+                        0);
          else
            abort ();