]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/25737 (ACATS c974001 c974013 hang with struct aliasing)
authorAdam Nemet <anemet@caviumnetworks.com>
Wed, 20 Jun 2007 18:19:10 +0000 (18:19 +0000)
committerAdam Nemet <nemet@gcc.gnu.org>
Wed, 20 Jun 2007 18:19:10 +0000 (18:19 +0000)
PR tree-optimization/25737
* tree.h (struct tree_struct_field_tag): Add new field alias_set.
(SFT_NONADDRESSABLE_P, SFT_ALIAS_SET): New macros.
* tree-flow.h (struct fieldoff): Add new field alias_set.
* tree-ssa-structalias.c (push_fields_onto_fieldstack): Add new
argument addressable_type.  Set alias_set of fieldoff.
* tree-ssa-alias.c (create_sft): Add new argument alias_set.
(create_overlap_variables_for): Pass alias_set from fieldoff to
create_sft.
* alias.c (get_alias_set): Use alias_set from SFT if set.

From-SVN: r125890

gcc/ChangeLog
gcc/alias.c
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c
gcc/tree.h

index 1b76b90002191a107715c154f16f10b4bbb3d240..95789e56955d14611381f6387841373a5ed90e72 100644 (file)
@@ -1,3 +1,16 @@
+2007-06-20  Adam Nemet  <anemet@caviumnetworks.com>
+
+       PR tree-optimization/25737
+       * tree.h (struct tree_struct_field_tag): Add new field alias_set.
+       (SFT_NONADDRESSABLE_P, SFT_ALIAS_SET): New macros.
+       * tree-flow.h (struct fieldoff): Add new field alias_set.
+       * tree-ssa-structalias.c (push_fields_onto_fieldstack): Add new
+       argument addressable_type.  Set alias_set of fieldoff.
+       * tree-ssa-alias.c (create_sft): Add new argument alias_set.
+       (create_overlap_variables_for): Pass alias_set from fieldoff to
+       create_sft.
+       * alias.c (get_alias_set): Use alias_set from SFT if set.
+
 2007-06-20  Hui-May Chang  <hm.chang@apple.com>
 
        * config/i386/darwin.h (ASM_OUTPUT_COMMON): Print the size
index c03ff03ce6207dfc8ecd8f872501bec94a389c59..8064b8e087a44a275afc35971bec4b985a176b22 100644 (file)
@@ -586,6 +586,13 @@ get_alias_set (tree t)
            return 0;
        }
 
+      /* For non-addressable fields we return the alias set of the
+        outermost object that could have its address taken.  If this
+        is an SFT use the precomputed value.  */
+      if (TREE_CODE (t) == STRUCT_FIELD_TAG
+         && SFT_NONADDRESSABLE_P (t))
+       return SFT_ALIAS_SET (t);
+
       /* Otherwise, pick up the outermost object that we could have a pointer
         to, processing conversions as above.  */
       while (component_uses_parent_alias_set (t))
index c23a094707a22b68a817507803576429612f0d57..0af3bdc39559b80bc170b70d16d66c5258b104bb 100644 (file)
@@ -1158,13 +1158,14 @@ struct fieldoff
   tree size;
   tree decl;
   HOST_WIDE_INT offset;  
+  HOST_WIDE_INT alias_set;
 };
 typedef struct fieldoff fieldoff_s;
 
 DEF_VEC_O(fieldoff_s);
 DEF_VEC_ALLOC_O(fieldoff_s,heap);
 int push_fields_onto_fieldstack (tree, VEC(fieldoff_s,heap) **,
-                                HOST_WIDE_INT, bool *);
+                                HOST_WIDE_INT, bool *, tree);
 void sort_fieldstack (VEC(fieldoff_s,heap) *);
 
 void init_alias_heapvars (void);
index 31911e68ef4f0b3484c95a50e5ac45b63e9b63d9..46c17ea68b177465106999fcbe1fde6e724d27d7 100644 (file)
@@ -3646,11 +3646,13 @@ get_or_create_used_part_for (size_t uid)
 
 
 /* Create and return a structure sub-variable for field type FIELD at
-   offset OFFSET, with size SIZE, of variable VAR.  */
+   offset OFFSET, with size SIZE, of variable VAR.  If ALIAS_SET not
+   -1 this field is non-addressable and we should use this alias set
+   with this field.  */
 
 static tree
 create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
-           unsigned HOST_WIDE_INT size)
+           unsigned HOST_WIDE_INT size, HOST_WIDE_INT alias_set)
 {
   tree subvar = create_tag_raw (STRUCT_FIELD_TAG, field, "SFT");
 
@@ -3669,6 +3671,7 @@ create_sft (tree var, tree field, unsigned HOST_WIDE_INT offset,
   SFT_PARENT_VAR (subvar) = var;
   SFT_OFFSET (subvar) = offset;
   SFT_SIZE (subvar) = size;
+  SFT_ALIAS_SET (subvar) = alias_set;
   return subvar;
 }
 
@@ -3688,7 +3691,8 @@ create_overlap_variables_for (tree var)
       || up->write_only)
     return;
 
-  push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL);
+  push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL,
+                              TREE_TYPE (var));
   if (VEC_length (fieldoff_s, fieldstack) != 0)
     {
       subvar_t *subvars;
@@ -3780,7 +3784,8 @@ create_overlap_variables_for (tree var)
            continue;
          sv = GGC_NEW (struct subvar);
          sv->next = *subvars;
-         sv->var = create_sft (var, fo->type, fo->offset, fosize);
+         sv->var =
+           create_sft (var, fo->type, fo->offset, fosize, fo->alias_set);
 
          if (dump_file)
            {
index 663dff0b1cbeba9014c4e0b26fa01f15f250cf05..ddd7de3eb6c06bb826f704b65d8d3a99961ca27e 100644 (file)
@@ -3695,11 +3695,13 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
    than just the immediately containing structure.  Returns the number
    of fields pushed.
    HAS_UNION is set to true if we find a union type as a field of
-   TYPE.  */
+   TYPE.  ADDRESSABLE_TYPE is the type of the outermost object that could have
+   its address taken.  */
 
 int
 push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
-                            HOST_WIDE_INT offset, bool *has_union)
+                            HOST_WIDE_INT offset, bool *has_union,
+                            tree addressable_type)
 {
   tree field;
   int count = 0;
@@ -3712,12 +3714,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
       real_part->size = TYPE_SIZE (TREE_TYPE (type));
       real_part->offset = offset;
       real_part->decl = NULL_TREE;
+      real_part->alias_set = -1;
 
       img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
       img_part->type = TREE_TYPE (type);
       img_part->size = TYPE_SIZE (TREE_TYPE (type));
       img_part->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type)));
       img_part->decl = NULL_TREE;
+      img_part->alias_set = -1;
 
       return 2;
     }
@@ -3755,7 +3759,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
            push = true;
          else if (!(pushed = push_fields_onto_fieldstack
                     (TREE_TYPE (type), fieldstack,
-                     offset + i * TREE_INT_CST_LOW (elsz), has_union)))
+                     offset + i * TREE_INT_CST_LOW (elsz), has_union,
+                     TREE_TYPE (type))))
            /* Empty structures may have actual size, like in C++. So
               see if we didn't push any subfields and the size is
               nonzero, push the field onto the stack */
@@ -3770,6 +3775,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
              pair->size = elsz;
              pair->decl = NULL_TREE;
              pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
+             pair->alias_set = -1;
              count++;
            }
          else
@@ -3794,7 +3800,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
          push = true;
        else if (!(pushed = push_fields_onto_fieldstack
                   (TREE_TYPE (field), fieldstack,
-                   offset + bitpos_of_field (field), has_union))
+                   offset + bitpos_of_field (field), has_union,
+                   (DECL_NONADDRESSABLE_P (field)
+                    ? addressable_type
+                    : TREE_TYPE (field))))
                 && DECL_SIZE (field)
                 && !integer_zerop (DECL_SIZE (field)))
          /* Empty structures may have actual size, like in C++. So
@@ -3811,6 +3820,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
            pair->size = DECL_SIZE (field);
            pair->decl = field;
            pair->offset = offset + bitpos_of_field (field);
+           if (DECL_NONADDRESSABLE_P (field))
+             pair->alias_set = get_alias_set (addressable_type);
+           else
+             pair->alias_set = -1;
            count++;
          }
        else
@@ -4009,7 +4022,8 @@ create_variable_info_for (tree decl, const char *name)
             || TREE_CODE (decltype) == QUAL_UNION_TYPE;
   if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
     {
-      push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
+      push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion,
+                                  decltype);
       if (hasunion)
        {
          VEC_free (fieldoff_s, heap, fieldstack);
index ab6d5ff60f0863e853e5ec4d7cb3975a07818f5d..e6f1cee3c9fc7eae3da9b7dee4f9c1cb73eacf0d 100644 (file)
@@ -2516,10 +2516,15 @@ struct tree_struct_field_tag GTY(())
   /* Size of the field.  */
   unsigned HOST_WIDE_INT size;
 
+  /* Alias set for a DECL_NONADDRESSABLE_P field.  Otherwise -1.  */
+  HOST_WIDE_INT alias_set;
 };
 #define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.parent_var)
 #define SFT_OFFSET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.offset)
 #define SFT_SIZE(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.size)
+#define SFT_NONADDRESSABLE_P(NODE) \
+  (STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set != -1)
+#define SFT_ALIAS_SET(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->sft.alias_set)
 
 /* Memory Partition Tags (MPTs) group memory symbols under one
    common name for the purposes of placing memory PHI nodes.  */