From b377855627f22cdef5712621e89e68048a94a164 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Thu, 12 Jun 2008 10:21:45 +0000
Subject: [PATCH] re PR tree-optimization/36345 (TBAA-pruning of points-to sets
 ineffective)

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                                 | 25 ++++++++++++
 gcc/testsuite/ChangeLog                       |  6 +++
 .../gcc.c-torture/execute/20020619-1.c        | 12 +-----
 gcc/tree-flow.h                               | 13 ++++--
 gcc/tree-ssa-alias-warnings.c                 | 10 +++++
 gcc/tree-ssa-alias.c                          | 14 ++++---
 gcc/tree-ssa-structalias.c                    | 40 +++++++++----------
 gcc/tree-ssa.c                                |  2 +-
 8 files changed, 79 insertions(+), 43 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e1c11b1a15ff..eb6c434e6ff0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dfbe10d872cc..7155d9124137 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
index 5ed4d00b01d0..6db1546e867c 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
@@ -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;
 }
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 45711ae3f124..855f08079510 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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);
diff --git a/gcc/tree-ssa-alias-warnings.c b/gcc/tree-ssa-alias-warnings.c
index bf95258ed288..be26cb37d494 100644
--- a/gcc/tree-ssa-alias-warnings.c
+++ b/gcc/tree-ssa-alias-warnings.c
@@ -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));
 	}
     }
 }
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index e89e73b9f598..0e5071994de6 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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");
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index d66a4a822396..338e190d4c8f 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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);
 
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 8e6ea4cff7a9..52b17d4f9721 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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;
-- 
GitLab