aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-03-20 03:59:45 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-03-20 03:59:45 +0000
commite20e5153e2947ecd85323712b1bf35a7b2e6ccc3 (patch)
tree8970f20eac2ad2aaeb5016a190118c6ddbf2864a
parentec517cc92e1c4a6b84843d8bbaa91810e015f1c5 (diff)
PR optimization/14643
* tree-ssa-alias.c (group_aliases_into): Don't add a variable to its own may-alias set. (create_alias_map_for): New. (setup_pointers_and_addressables): Call it. Fix allocation of AI->ADDRESSABLE_VARS and AI->POINTERS. If there are no addressable variables and more than one dereferenced pointers, add type tags to the ADDRESSABLE_VARS array. (get_tmt_for): Add comment about using alias set equality when checking for existing tags. testsuite/ChangeLog.tree-ssa: * gcc.dg/tree-ssa/20040319-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@79728 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.tree-ssa16
-rw-r--r--gcc/testsuite/ChangeLog.tree-ssa5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c25
-rw-r--r--gcc/tree-ssa-alias.c83
4 files changed, 114 insertions, 15 deletions
diff --git a/gcc/ChangeLog.tree-ssa b/gcc/ChangeLog.tree-ssa
index 60fee4201ea..f897295969d 100644
--- a/gcc/ChangeLog.tree-ssa
+++ b/gcc/ChangeLog.tree-ssa
@@ -1,3 +1,17 @@
+2004-03-19 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14643
+ * tree-ssa-alias.c (group_aliases_into): Don't add a variable
+ to its own may-alias set.
+ (create_alias_map_for): New.
+ (setup_pointers_and_addressables): Call it.
+ Fix allocation of AI->ADDRESSABLE_VARS and AI->POINTERS.
+ If there are no addressable variables and more than one
+ dereferenced pointers, add type tags to the ADDRESSABLE_VARS
+ array.
+ (get_tmt_for): Add comment about using alias set equality when
+ checking for existing tags.
+
2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
* fold-const.c (fold_relational_const): Remove dead code.
@@ -9,7 +23,7 @@
2004-03-19 Jeff Law <law@redhat.com>
- * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Fix typo.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Fix typo.
Eliminate unnecessary test of VAL.
* tree-dfa.c (find_hidden_use_vars): Also look inside the
diff --git a/gcc/testsuite/ChangeLog.tree-ssa b/gcc/testsuite/ChangeLog.tree-ssa
index 8390e4c2af7..28dd2d37ece 100644
--- a/gcc/testsuite/ChangeLog.tree-ssa
+++ b/gcc/testsuite/ChangeLog.tree-ssa
@@ -1,3 +1,8 @@
+2004-03-19 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14643
+ * gcc.dg/tree-ssa/20040319-1.c: New test.
+
2004-03-19 Jeff Law <law@redhat.com>
* gcc.c-torture/execute/20040319-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c
new file mode 100644
index 00000000000..571c2aeabad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+/* Test derived from PR 14643. When a function has no addressable
+ variables but 2 or more pointers have conflicting memory tags, they
+ were not being processed by the type based alias analyzer,
+ resulting in optimizations removing a non-redundant load. */
+
+struct bar { int count; int *arr;};
+
+void foo (struct bar *b)
+{
+ b->count = 0;
+ *(b->arr) = 2;
+ if (b->count == 0) /* b->count can't be assumed to be 0 here. */
+ abort ();
+}
+
+main ()
+{
+ struct bar x;
+ x.arr = &x.count;
+ foo (&x);
+ return 0;
+}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2696256b1df..9ba570f394d 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -880,7 +880,12 @@ group_aliases_into (tree tag, sbitmap tag_aliases, struct alias_info *ai)
/* Make TAG the unique alias of VAR. */
ann->is_alias_tag = 0;
ann->may_aliases = NULL;
- add_may_alias (var, tag);
+
+ /* Note that VAR and TAG may be the same if the function has no
+ addressable variables (see the discussion at the end of
+ setup_pointers_and_addressables). */
+ if (var != tag)
+ add_may_alias (var, tag);
/* Reduce total number of virtual operands contributed
by TAG on behalf of VAR. Notice that the references to VAR
@@ -1071,6 +1076,23 @@ group_aliases (struct alias_info *ai)
}
+/* Create a new alias set entry for VAR in AI->ADDRESSABLE_VARS. */
+
+static void
+create_alias_map_for (tree var, struct alias_info *ai)
+{
+ struct alias_map_d *alias_map;
+ alias_map = xcalloc (1, sizeof (*alias_map));
+ alias_map->var = var;
+
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ alias_map->set = get_alias_set (TREE_TYPE (TREE_TYPE (var)));
+ else
+ alias_map->set = get_alias_set (var);
+ ai->addressable_vars[ai->num_addressable_vars++] = alias_map;
+}
+
+
/* Create memory tags for all the dereferenced pointers and build the
ADDRESSABLE_VARS and POINTERS arrays used for building the may-alias
sets. Based on the address escape and points-to information collected
@@ -1109,8 +1131,9 @@ setup_pointers_and_addressables (struct alias_info *ai)
because some TREE_ADDRESSABLE variables will be marked
non-addressable below and only pointers with unique type tags are
going to be added to POINTERS. */
- ai->addressable_vars = xcalloc (num_addressable_vars, sizeof (tree));
- ai->pointers = xcalloc (num_pointers, sizeof (tree));
+ ai->addressable_vars = xcalloc (num_addressable_vars,
+ sizeof (struct alias_map_d *));
+ ai->pointers = xcalloc (num_pointers, sizeof (struct alias_map_d *));
ai->num_addressable_vars = 0;
ai->num_pointers = 0;
@@ -1157,16 +1180,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
entry in ADDRESSABLE_VARS for VAR. */
if (may_be_aliased (var))
{
- /* Create a new alias set entry for VAR. */
- struct alias_map_d *alias_map;
- alias_map = xcalloc (1, sizeof (*alias_map));
- alias_map->var = var;
-
- if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
- alias_map->set = get_alias_set (TREE_TYPE (TREE_TYPE (var)));
- else
- alias_map->set = get_alias_set (var);
- ai->addressable_vars[ai->num_addressable_vars++] = alias_map;
+ create_alias_map_for (var, ai);
bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
}
@@ -1204,6 +1218,41 @@ setup_pointers_and_addressables (struct alias_info *ai)
ai->num_references[t_ann->uid] += ai->num_references[v_ann->uid];
}
}
+
+ /* If we found no addressable variables, but we have more than one
+ pointer, we will need to check for conflicts between the
+ pointers. Otherwise, we would miss alias relations as in
+ testsuite/gcc.dg/tree-ssa/20040319-1.c:
+
+ struct bar { int count; int *arr;};
+
+ void foo (struct bar *b)
+ {
+ b->count = 0;
+ *(b->arr) = 2;
+ if (b->count == 0)
+ abort ();
+ }
+
+ b->count and *(b->arr) could be aliased if b->arr == &b->count.
+ To do this, we add all the memory tags for the pointers in
+ AI->POINTERS to AI->ADDRESSABLE_VARS, so that
+ compute_flow_insensitive_aliasing will naturally compare every
+ pointer to every type tag. */
+ if (ai->num_addressable_vars == 0
+ && ai->num_pointers > 1)
+ {
+ free (ai->addressable_vars);
+ ai->addressable_vars = xcalloc (ai->num_pointers,
+ sizeof (struct alias_map_d *));
+ ai->num_addressable_vars = 0;
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ struct alias_map_d *p = ai->pointers[i];
+ tree tag = var_ann (p->var)->type_mem_tag;
+ create_alias_map_for (tag, ai);
+ }
+ }
}
@@ -1768,7 +1817,13 @@ get_tmt_for (tree ptr, struct alias_info *ai)
HOST_WIDE_INT tag_set = get_alias_set (tag_type);
/* To avoid creating unnecessary memory tags, only create one memory tag
- per alias set class. */
+ per alias set class. Note that it may be tempting to group
+ memory tags based on conflicting alias sets instead of
+ equivalence. That would be wrong because alias sets are not
+ necessarily transitive (as demonstrated by the libstdc++ test
+ 23_containers/vector/cons/4.cc). Given three alias sets A, B, C
+ such that conflicts (A, B) == true and conflicts (A, C) == true,
+ it does not necessarily follow that conflicts (B, C) == true. */
for (i = 0, tag = NULL_TREE; i < ai->num_pointers; i++)
{
struct alias_map_d *curr = ai->pointers[i];