aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23382.c24
-rw-r--r--gcc/tree-dfa.c12
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-ssa-alias.c2
-rw-r--r--gcc/tree-ssa-structalias.c47
-rw-r--r--gcc/tree-ssa.c1
7 files changed, 103 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bd9a3e0..d6d939b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
index 0000000..eeeb0ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23382.c
@@ -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" } } */
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 9fc48d5..2ede8e6 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -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
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 389ec8f..b61b357 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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 */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 84c5225..5397894 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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 ();
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index aa912cb..67e872a 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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;
+ }
+}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index d78a944..15af7f3 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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)
{