re PR tree-optimization/23382 (Does not remove the old HEAP virtual variables in...
authorDaniel Berlin <dberlin@dberlin.org>
Tue, 8 Nov 2005 16:34:48 +0000 (16:34 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Tue, 8 Nov 2005 16:34:48 +0000 (16:34 +0000)
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.

From-SVN: r106643

gcc/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr23382.c [new file with mode: 0644]
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c

index bd9a3e0450441f3f2de2b53a0625d64933ae2b5a..d6d939ba0d296a802ebdfba34881aca73e8d8d32 100644 (file)
@@ -1,3 +1,18 @@
+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.
+       
 2005-11-08  Jason Merrill  <jason@redhat.com>
 
        * tree.h (CALL_FROM_THUNK_P): Add CALL_EXPR_CHECK.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23382.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23382.c
new file mode 100644 (file)
index 0000000..eeeb0ff
--- /dev/null
@@ -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 9fc48d5cbe8c8fdb77941a46917763acb7aaf55f..2ede8e6365bbbffdc9c1becea90cd77b17bad2df 100644 (file)
@@ -609,6 +609,18 @@ referenced_var_insert (unsigned int uid, tree to)
   *(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 389ec8f94d0d435fa6432c558686f3ba952b00ca..b61b3575dd2fb4819c136646a90da5d7ca8ae058 100644 (file)
@@ -423,6 +423,7 @@ extern GTY((param_is (struct int_tree_map))) htab_t referenced_vars;
 
 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, VEC(fieldoff_s,heap) **,
                                 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 84c522554b21c5147efdce1f0f34ab9e72f7851c..539789491b3b8cd5bd22585e9f81c3507baff626 100644 (file)
@@ -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 aa912cb7bd0f94414c476cfdbe2a9732ce95f659..67e872af9d3347dee14bd23029486e95a2fe0d51 100644 (file)
@@ -159,6 +159,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   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_anyoffset)
                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 d78a944209e12843b065ae46967ba7e51df75e40..15af7f37210e206b57ac8c8fd9a0a3b13a916403 100644 (file)
@@ -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)
     {