re PR tree-optimization/36345 (TBAA-pruning of points-to sets ineffective)
authorRichard Guenther <rguenther@suse.de>
Thu, 12 Jun 2008 10:21:45 +0000 (10:21 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 12 Jun 2008 10:21:45 +0000 (10:21 +0000)
2008-06-12  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/36345
* tree-flow.h (struct ptr_info_def): Align escape_mask,
add memory_tag_needed flag.
(may_alias_p): Declare.
* tree-ssa-alias.c (may_alias_p): Export.
(set_initial_properties): Use memory_tag_needed flag.
(update_reference_counts): Likewise.
(reset_alias_info): Reset memory_tag_needed flag.
(create_name_tags): Check memory_tag_needed flag.
(dump_points_to_info_for): Dump it.
* tree-ssa-structalias.c (struct variable_info): Remove
directly_dereferenced flag.
(new_var_info): Do not initialize it.
(process_constraint_1): Do not set it.
(update_alias_info): Set is_dereferenced flag.
(set_uids_in_ptset): Use may_alias_p.
(set_used_smts): Check memory_tag_needed flag.
(find_what_p_points_to): Likewise.  Pass is_dereferenced flag.
* tree-ssa-alias.c (verify_flow_sensitive_alias_info): Check
memory_tag_needed flag.
* tree-ssa-alias-warnings.c (dsa_named_for): Try to recover
from broken design.

* gcc.c-torture/execute/20020619-1.c: Remove broken part of
the testcase.

From-SVN: r136695

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20020619-1.c
gcc/tree-flow.h
gcc/tree-ssa-alias-warnings.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c

index e1c11b1a15fffb180ff43633f29a3bb6ad886526..eb6c434e6ff09353f3343dc8a7c21fa71b6ca5da 100644 (file)
@@ -1,3 +1,28 @@
+2008-06-12  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/36345
+       * tree-flow.h (struct ptr_info_def): Align escape_mask,
+       add memory_tag_needed flag.
+       (may_alias_p): Declare.
+       * tree-ssa-alias.c (may_alias_p): Export.
+       (set_initial_properties): Use memory_tag_needed flag.
+       (update_reference_counts): Likewise.
+       (reset_alias_info): Reset memory_tag_needed flag.
+       (create_name_tags): Check memory_tag_needed flag.
+       (dump_points_to_info_for): Dump it.
+       * tree-ssa-structalias.c (struct variable_info): Remove
+       directly_dereferenced flag.
+       (new_var_info): Do not initialize it.
+       (process_constraint_1): Do not set it.
+       (update_alias_info): Set is_dereferenced flag.
+       (set_uids_in_ptset): Use may_alias_p.
+       (set_used_smts): Check memory_tag_needed flag.
+       (find_what_p_points_to): Likewise.  Pass is_dereferenced flag.
+       * tree-ssa-alias.c (verify_flow_sensitive_alias_info): Check
+       memory_tag_needed flag.
+       * tree-ssa-alias-warnings.c (dsa_named_for): Try to recover
+       from broken design.
+
 2008-06-12  Kai Tietz  <kai.tietz@onevision.com>
 
        * config/i386/i386.c (ix86_compute_frame_layout): Disable red zone for
index dfbe10d872cc8a13443174de2adc91a83c8e47dc..7155d9124137be87702b1e7541abed272ea5be48 100644 (file)
@@ -1,3 +1,9 @@
+2008-06-12  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/36345
+       * gcc.c-torture/execute/20020619-1.c: Remove broken part of
+       the testcase.
+
 2008-06-11  Edmar Wienskoski  <edmar@freescale.com>
 
        PR target/36425
index 5ed4d00b01d0877ad5d27d10838db30d9ccf4c3c..6db1546e867c4d1b42675d1ad55c07d83592b383 100644 (file)
@@ -14,19 +14,11 @@ static int ref(void)
   return u.i;
 }
 
-#define MAX(a,b)  (a < b ? b : a)
-
-static int test(void)
-{
-  char c[MAX(5, sizeof(int))] __attribute__((aligned)) = { 1, 2, 3, 4 };
-  return *(int *)c;
-}
-
 int main()
 {
-  int a = test();
   int b = ref();
-  if (a != b)
+  if (b != 0x01020304
+      && b != 0x04030201)
     abort ();
   return 0;
 }
index 45711ae3f124580c2455da120883d57b7e8c082a..855f0807951028874775287e55d1ee498020d38e 100644 (file)
@@ -227,6 +227,9 @@ typedef struct
 /* Aliasing information for SSA_NAMEs representing pointer variables.  */
 struct ptr_info_def GTY(())
 {
+  /* Mask of reasons this pointer's value escapes the function.  */
+  ENUM_BITFIELD (escape_type) escape_mask : 9;
+
   /* Nonzero if points-to analysis couldn't determine where this pointer
      is pointing to.  */
   unsigned int pt_anything : 1;
@@ -234,7 +237,11 @@ struct ptr_info_def GTY(())
   /* Nonzero if the value of this pointer escapes the current function.  */
   unsigned int value_escapes_p : 1;
 
-  /* Nonzero if this pointer is dereferenced.  */
+  /* Nonzero if a memory tag is needed for this pointer.  This is
+     true if this pointer is eventually dereferenced.  */
+  unsigned int memory_tag_needed : 1;
+
+  /* Nonzero if this pointer is really dereferenced.  */
   unsigned int is_dereferenced : 1;
 
   /* Nonzero if this pointer points to a global variable.  */
@@ -243,9 +250,6 @@ struct ptr_info_def GTY(())
   /* Nonzero if this pointer points to NULL.  */
   unsigned int pt_null : 1;
 
-  /* Mask of reasons this pointer's value escapes the function  */
-  ENUM_BITFIELD (escape_type) escape_mask : 9;
-
   /* Set of variables that this pointer may point to.  */
   bitmap pt_vars;
 
@@ -852,6 +856,7 @@ extern void debug_points_to_info (void);
 extern void dump_points_to_info_for (FILE *, tree);
 extern void debug_points_to_info_for (tree);
 extern bool may_be_aliased (tree);
+extern bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
 extern struct ptr_info_def *get_ptr_info (tree);
 extern bool may_point_to_global_var (tree);
 extern void new_type_alias (tree, tree, tree);
index bf95258ed288f8fe83e22bb62a166d22ac6e3464..be26cb37d494d95b664d9ef8627d85ea06f53d66 100644 (file)
@@ -914,6 +914,7 @@ dsa_named_for (tree ptr)
        {
          unsigned ix;
          bitmap_iterator bi;
+         bool any = false;
 
          EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
            {
@@ -922,7 +923,16 @@ dsa_named_for (tree ptr)
              if (nonstandard_alias_p (ptr, alias, false))
                strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr),
                                      ptr, true, alias, false, true);
+             else
+               any = true;
            }
+
+         /* If there was no object in the points-to set that the pointer
+            may alias, unconditionally warn.  */
+         if (!any)
+           warning (OPT_Wstrict_aliasing,
+                    "dereferencing type-punned pointer %D will "
+                    "break strict-aliasing rules", SSA_NAME_VAR (ptr));
        }
     }
 }
index e89e73b9f5981b5650e552906d7273bc70cbef30..0e5071994de691cdcc12315e67ae75bf82350a8e 100644 (file)
@@ -197,7 +197,6 @@ static bitmap_obstack alias_bitmap_obstack;
 /* Local functions.  */
 static void compute_flow_insensitive_aliasing (struct alias_info *);
 static void dump_alias_stats (FILE *);
-static bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
 static tree create_memory_tag (tree type, bool is_type_tag);
 static tree get_smt_for (tree, struct alias_info *);
 static tree get_nmt_for (tree);
@@ -588,14 +587,14 @@ set_initial_properties (struct alias_info *ai)
          So removing this code and fixing all the bugs would be nice.
          It is the cause of a bunch of clobbering.  */
       if ((pi->pt_global_mem || pi->pt_anything) 
-         && pi->is_dereferenced && pi->name_mem_tag)
+         && pi->memory_tag_needed && pi->name_mem_tag)
        {
          mark_call_clobbered (pi->name_mem_tag, ESCAPE_IS_GLOBAL);
          MTAG_GLOBAL (pi->name_mem_tag) = true;
        }
       
       if ((pi->pt_global_mem || pi->pt_anything) 
-         && pi->is_dereferenced
+         && pi->memory_tag_needed
          && tag)
        {
          mark_call_clobbered (tag, ESCAPE_IS_GLOBAL);
@@ -1278,7 +1277,7 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats)
       if (ptr
          && POINTER_TYPE_P (TREE_TYPE (ptr))
          && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
-         && pi->is_dereferenced)
+         && pi->memory_tag_needed)
        {
          unsigned j;
          bitmap_iterator bj;
@@ -2027,6 +2026,7 @@ reset_alias_info (void)
          pi->pt_anything = 0;
          pi->pt_null = 0;
          pi->value_escapes_p = 0;
+         pi->memory_tag_needed = 0;
          pi->is_dereferenced = 0;
          if (pi->pt_vars)
            bitmap_clear (pi->pt_vars);
@@ -2170,7 +2170,7 @@ create_name_tags (void)
 
       pi = SSA_NAME_PTR_INFO (ptr);
 
-      if (pi->pt_anything || !pi->is_dereferenced)
+      if (pi->pt_anything || !pi->memory_tag_needed)
        {
          /* No name tags for pointers that have not been
             dereferenced or point to an arbitrary location.  */
@@ -2649,7 +2649,7 @@ maybe_create_global_var (void)
    
    VAR_ALIAS_SET is the alias set for VAR.  */
 
-static bool
+bool
 may_alias_p (tree ptr, alias_set_type mem_alias_set,
             tree var, alias_set_type var_alias_set,
             bool alias_set_only)
@@ -3231,6 +3231,8 @@ dump_points_to_info_for (FILE *file, tree ptr)
 
       if (pi->is_dereferenced)
        fprintf (file, ", is dereferenced");
+      else if (pi->memory_tag_needed)
+       fprintf (file, ", is dereferenced in call");
 
       if (pi->value_escapes_p)
        fprintf (file, ", its value escapes");
index d66a4a82239682432f0b6715f31227c3f79cdfe1..338e190d4c8fb6c6d8554c4b4a0dc7a88d76628f 100644 (file)
@@ -227,11 +227,6 @@ struct variable_info
   /* A link to the variable for the next field in this structure.  */
   struct variable_info *next;
 
-  /* True if the variable is directly the target of a dereference.
-     This is used to track which variables are *actually* dereferenced
-     so we can prune their points to listed. */
-  unsigned int directly_dereferenced:1;
-
   /* True if this is a variable created by the constraint analysis, such as
      heap variables and constraints we had to break up.  */
   unsigned int is_artificial_var:1;
@@ -364,7 +359,6 @@ new_var_info (tree t, unsigned int id, const char *name)
   ret->id = id;
   ret->name = name;
   ret->decl = t;
-  ret->directly_dereferenced = false;
   ret->is_artificial_var = false;
   ret->is_heap_var = false;
   ret->is_special_var = false;
@@ -2520,14 +2514,6 @@ process_constraint_1 (constraint_t t, bool from_call)
   gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
   gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
 
-  if (!from_call)
-    {
-      if (lhs.type == DEREF)
-       get_varinfo (lhs.var)->directly_dereferenced = true;
-      if (rhs.type == DEREF)
-       get_varinfo (rhs.var)->directly_dereferenced = true;
-    }
-
   if (!use_field_sensitive)
     {
       t->rhs.offset = 0;
@@ -3369,6 +3355,12 @@ update_alias_info (tree stmt, struct alias_info *ai)
         is an escape point, whether OP escapes.  */
       count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores);
 
+      /* For directly dereferenced pointers we can apply
+        TBAA-pruning to their points-to set.  We may not count the
+        implicit dereferences &PTR->FLD here.  */
+      if (num_loads + num_stores > 0)
+       pi->is_dereferenced = 1;
+
       /* Handle a corner case involving address expressions of the
         form '&PTR->FLD'.  The problem with these expressions is that
         they do not represent a dereference of PTR.  However, if some
@@ -3409,7 +3401,10 @@ update_alias_info (tree stmt, struct alias_info *ai)
             dereferenced pointers that point to a set of
             variables will be assigned a name tag to alias
             all the variables OP points to.  */
-         pi->is_dereferenced = 1;
+         pi->memory_tag_needed = 1;
+
+         /* ???  For always executed direct dereferences we can
+            apply TBAA-pruning to their escape set.  */
 
          /* If this is a store operation, mark OP as being
             dereferenced to store, otherwise mark it as being
@@ -3443,7 +3438,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
              || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
            {
              pointer_set_insert (ai->dereferenced_ptrs_store, var);
-             pi->is_dereferenced = 1;
+             pi->memory_tag_needed = 1;
            }
        }
     }
@@ -4653,10 +4648,11 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
            bitmap_set_bit (into, DECL_UID (vi->decl));
          else
            {
-             alias_set_type var_alias_set, ptr_alias_set;
+             alias_set_type var_alias_set, mem_alias_set;
              var_alias_set = get_alias_set (vi->decl);
-             ptr_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
-             if (alias_sets_conflict_p (ptr_alias_set, var_alias_set))
+             mem_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
+             if (may_alias_p (SSA_NAME_VAR (ptr), mem_alias_set,
+                              vi->decl, var_alias_set, true))
                bitmap_set_bit (into, DECL_UID (vi->decl));
            }
        }
@@ -4703,7 +4699,7 @@ set_used_smts (void)
       /* Skip the special variables and those that can't be aliased.  */
       if (vi->is_special_var
          || !SSA_VAR_P (var)
-         || (pi && !pi->is_dereferenced)
+         || (pi && !pi->memory_tag_needed)
          || (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var))
          || !POINTER_TYPE_P (TREE_TYPE (var)))
        continue;
@@ -4771,7 +4767,7 @@ find_what_p_points_to (tree p)
          bitmap finished_solution;
          bitmap result;
 
-         if (!pi->is_dereferenced)
+         if (!pi->memory_tag_needed)
            return false;
 
          /* This variable may have been collapsed, let's get the real
@@ -4815,7 +4811,7 @@ find_what_p_points_to (tree p)
          stats.points_to_sets_created++;
 
          set_uids_in_ptset (p, finished_solution, vi->solution,
-                            vi->directly_dereferenced,
+                            pi->is_dereferenced,
                             vi->no_tbaa_pruning);
          result = shared_bitmap_lookup (finished_solution);
 
index 8e6ea4cff7a960ff61bf6cc7778b50a29e0429e4..52b17d4f9721a933489e910daa7e8a60b833f15a 100644 (file)
@@ -559,7 +559,7 @@ verify_flow_sensitive_alias_info (void)
        continue;
 
       ann = var_ann (var);
-      if (pi->is_dereferenced && !pi->name_mem_tag && !ann->symbol_mem_tag)
+      if (pi->memory_tag_needed && !pi->name_mem_tag && !ann->symbol_mem_tag)
        {
          error ("dereferenced pointers should have a name or a symbol tag");
          goto err;