This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Fix PR tree-optimization/23382


This bug was where we kept adding may-defs for old heap-vars, even
though they were completely unused.

This turns out to be uglier to fix than i'd like, because we have no
easy way to just blow away a variable completely from the IR.  I tried
prettier things first, but they didn't fix the problem completely :(.

Basically, to get a variable out of the IR and the referenced vars
array, we have to mark it for renaming to get rid of it from the IR, and
then, the next time we go to delete the old heap variables, delete the
ones we renamed from the referenced vars array.  Sucky, but effective.

Bootstrapped and regtested on i686-pc-linux-gnu.  Committed to mainline.

--Dan
2005-11-08  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR tree-optimization/23382

	* tree-ssa-alias.c (compute_may_aliases): Call
	delete_old_heap_vars.
	* tree-dfa.c (referenced_var_remove): New function.
	* tree-ssa.c (delete_tree_ssa): Call delete_old_heap_vars.
	* tree-flow.h (referenced_var_remove): Add prototype.
	(delete_old_heap_vars): Ditto.
	* tree-ssa-structalias.c (heapvars): New variable.
	(oldheapvars): Ditto.
	(get_constraint_for): Put heap vars on heapvars list.
	(delete_old_heap_vars): New function.
	
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(revision 106592)
+++ tree-ssa-alias.c	(working copy)
@@ -252,6 +252,8 @@ compute_may_aliases (void)
   
   memset (&alias_stats, 0, sizeof (alias_stats));
 
+  delete_old_heap_vars ();
+
   /* Initialize aliasing information.  */
   ai = init_alias_info ();
 
Index: tree-dfa.c
===================================================================
--- tree-dfa.c	(revision 106592)
+++ tree-dfa.c	(working copy)
@@ -609,6 +609,18 @@ referenced_var_insert (unsigned int uid,
   *(struct int_tree_map **)  loc = h;
 }
 
+/* Remove the pair DECL_UID (TO), TO from the referenced vars
+   hashtable.  */
+
+void
+referenced_var_remove (tree to)
+{ 
+  struct int_tree_map in;
+  in.uid = DECL_UID (to);
+  in.to = to;
+  htab_remove_elt_with_hash (referenced_vars, &in, in.uid);
+}
+
 /* Add VAR to the list of dereferenced variables.
 
    WALK_STATE contains a hash table used to avoid adding the same
Index: tree-ssa.c
===================================================================
--- tree-ssa.c	(revision 106592)
+++ tree-ssa.c	(working copy)
@@ -848,6 +848,7 @@ delete_tree_ssa (void)
       set_phi_nodes (bb, NULL);
     }
 
+  delete_old_heap_vars ();
   /* Remove annotations from every referenced variable.  */
   FOR_EACH_REFERENCED_VAR (var, rvi)
     {
Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 106592)
+++ tree-flow.h	(working copy)
@@ -423,6 +423,7 @@ extern GTY((param_is (struct int_tree_ma
 
 extern tree referenced_var_lookup (unsigned int);
 extern tree referenced_var_lookup_if_exists (unsigned int);
+extern void referenced_var_remove (tree);
 #define num_referenced_vars htab_elements (referenced_vars)
 #define referenced_var(i) referenced_var_lookup (i)
 
@@ -891,6 +892,7 @@ int push_fields_onto_fieldstack (tree, V
 				 HOST_WIDE_INT, bool *);
 void sort_fieldstack (VEC(fieldoff_s,heap) *);
 
+void delete_old_heap_vars (void);
 #include "tree-flow-inline.h"
 
 #endif /* _TREE_FLOW_H  */
Index: tree-ssa-structalias.c
===================================================================
--- tree-ssa-structalias.c	(revision 106592)
+++ tree-ssa-structalias.c	(working copy)
@@ -159,6 +159,9 @@ Foundation, Inc., 51 Franklin Street, Fi
   TODO: We could handle unions, but to be honest, it's probably not
   worth the pain or slowdown.  */
 
+static VEC(tree, heap) *heapvars = NULL;
+static VEC(tree, heap) *oldheapvars = NULL;
+
 static bool use_field_sensitive = true;
 static unsigned int create_variable_info_for (tree, const char *);
 static struct constraint_expr get_constraint_for (tree, bool *);
@@ -2213,6 +2216,7 @@ get_constraint_for (tree t, bool *need_a
 		tree heapvar;
 		
 		heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
+		VEC_safe_push (tree, heap, heapvars, heapvar);
 		DECL_EXTERNAL (heapvar) = 1;
 		add_referenced_tmp_var (heapvar);
 		temp.var = create_variable_info_for (heapvar,
@@ -3763,3 +3767,46 @@ delete_points_to_sets (void)
 
   have_alias_info = false;
 }
+
+/* Delete old heap vars, since nothing else will remove them for
+   us.  */
+void
+delete_old_heap_vars (void)
+{
+  if (!in_ssa_p)
+    {
+      VEC_free (tree, heap, heapvars);
+      VEC_free (tree, heap, oldheapvars);
+      heapvars = NULL;
+      oldheapvars = NULL;
+    }
+  /* Why is this complicated?
+     We can't remove the heapvars from the referenced var array until
+     they go away from the ssa form, and we can't remove them from the
+     ssa form until we've renamed it.  We can't renamed it if it's not
+     in the referenced vars array. 
+     Thus, we have to first mark it for renaming, and then the *next*
+     time after that we call this function, we can remove it from
+     referenced vars.  */
+
+  if (!VEC_empty (tree, heapvars))
+    {
+      int i;
+      tree heapvar;
+      for (i = 0; VEC_iterate (tree, heapvars, i, heapvar); i++)
+	{
+	  if (in_ssa_p)
+	    mark_sym_for_renaming (heapvar);
+	  DECL_EXTERNAL (heapvar) = false;
+	  bitmap_clear_bit (call_clobbered_vars, DECL_UID (heapvar));
+	}
+      if (!VEC_empty (tree, oldheapvars))
+	{
+	  for (i = 0; VEC_iterate (tree, oldheapvars, i, heapvar); i++)
+	    referenced_var_remove (heapvar);
+	}
+      VEC_free (tree, heap, oldheapvars);
+      oldheapvars = heapvars;
+      heapvars = NULL;
+    }
+}
Index: testsuite/gcc.dg/tree-ssa/pr23382.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/pr23382.c	(revision 0)
+++ testsuite/gcc.dg/tree-ssa/pr23382.c	(revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */ 
+/* { dg-options "-O2 -fdump-tree-alias-vops" } */
+struct a
+{
+  int length;
+  int a1[256];
+};
+
+void *malloc(long size) __attribute__((malloc));
+
+void f(void)
+{
+   struct a *a = malloc(sizeof(struct a));
+}
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF <HEAP" 1 "alias1"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF <HEAP" 1 "alias2"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF <HEAP" 1 "alias3"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF <HEAP" 1 "alias4"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF <HEAP" 1 "alias5"} } */
+/* { dg-final { cleanup-tree-dump "alias1" } } */
+/* { dg-final { cleanup-tree-dump "alias2" } } */
+/* { dg-final { cleanup-tree-dump "alias3" } } */
+/* { dg-final { cleanup-tree-dump "alias4" } } */
+/* { dg-final { cleanup-tree-dump "alias5" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]