summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authordberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-24 01:26:26 +0000
committerdberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-24 01:26:26 +0000
commit44a2bb4a172e461a7bd99e12eef4d0d0d2f829cf (patch)
tree86bb8592c5decd4b23398697a4d2fa1efb913559 /gcc/tree-ssa-alias.c
parent4642aba62183c5518d84d248171736f1487a41b0 (diff)
downloadgcc-44a2bb4a172e461a7bd99e12eef4d0d0d2f829cf.tar.gz
2006-11-23 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-alias.c (tree_pointer_compare): New function. (compact_name_tags): New function. (group_aliases): Call compact_name_tags. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119142 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 275c2449a0d..a12dca28025 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1436,6 +1436,73 @@ group_aliases_into (tree tag, bitmap tag_aliases, struct alias_info *ai)
tag_ann->may_aliases = NULL;
}
+/* Simple comparison function for qsort that sorts based on pointer
+ address. */
+
+static int
+tree_pointer_compare (const void *pa, const void *pb)
+{
+ const tree a = *((const tree *)pa);
+ const tree b = *((const tree *)pb);
+
+ return b - a;
+}
+
+
+/* Replacing may aliases in name tags during grouping can up with the
+ same SMT multiple times in the may_alias list. It's quicker to
+ just remove them post-hoc than it is to avoid them during
+ replacement. Thus, this routine sorts the may-alias list and
+ removes duplicates. */
+
+static void
+compact_name_tags (void)
+{
+ referenced_var_iterator rvi;
+ tree var;
+
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ {
+ if (TREE_CODE (var) == NAME_MEMORY_TAG)
+ {
+ VEC(tree, gc) *aliases, *new_aliases;
+ tree alias, last_alias;
+ int i;
+
+ last_alias = NULL;
+ aliases = var_ann (var)->may_aliases;
+ new_aliases = NULL;
+
+ if (VEC_length (tree, aliases) > 1)
+ {
+ bool changed = false;
+ qsort (VEC_address (tree, aliases), VEC_length (tree, aliases),
+ sizeof (tree), tree_pointer_compare);
+
+ for (i = 0; VEC_iterate (tree, aliases, i, alias); i++)
+ {
+ if (alias == last_alias)
+ {
+ changed = true;
+ continue;
+ }
+
+ VEC_safe_push (tree, gc, new_aliases, alias);
+ last_alias = alias;
+ }
+
+ /* Only replace the array if something has changed. */
+ if (changed)
+ {
+ VEC_free (tree, gc, aliases);
+ var_ann (var)->may_aliases = new_aliases;
+ }
+ else
+ VEC_free (tree, gc, new_aliases);
+ }
+ }
+ }
+}
/* Group may-aliases sets to reduce the number of virtual operands due
to aliasing.
@@ -1597,6 +1664,8 @@ group_aliases (struct alias_info *ai)
}
}
+ compact_name_tags ();
+
if (dump_file)
fprintf (dump_file,
"%s: Total number of aliased vops after grouping: %ld%s\n",