summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-29 19:26:47 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-29 19:26:47 +0000
commitc4aa078796bd9c7237e0ac5ea4ab7553106f199d (patch)
tree98a5e7f47a887d71b7ce051eac4583deee5a6dac /gcc/tree-ssa-structalias.c
parente34f5cd313173ac0144aeb70ab96e50fc36605ba (diff)
downloadgcc-c4aa078796bd9c7237e0ac5ea4ab7553106f199d.tar.gz
2009-08-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151199 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c132
1 files changed, 80 insertions, 52 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a9eef0bc1ec..a9d31325b57 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -290,18 +290,39 @@ enum { nothing_id = 0, anything_id = 1, readonly_id = 2,
escaped_id = 3, nonlocal_id = 4, callused_id = 5,
storedanything_id = 6, integer_id = 7 };
+struct GTY(()) heapvar_map {
+ struct tree_map map;
+ unsigned HOST_WIDE_INT offset;
+};
+
+static int
+heapvar_map_eq (const void *p1, const void *p2)
+{
+ const struct heapvar_map *h1 = (const struct heapvar_map *)p1;
+ const struct heapvar_map *h2 = (const struct heapvar_map *)p2;
+ return (h1->map.base.from == h2->map.base.from
+ && h1->offset == h2->offset);
+}
+
+static unsigned int
+heapvar_map_hash (struct heapvar_map *h)
+{
+ return iterative_hash_host_wide_int (h->offset,
+ htab_hash_pointer (h->map.base.from));
+}
+
/* Lookup a heap var for FROM, and return it if we find one. */
static tree
-heapvar_lookup (tree from)
+heapvar_lookup (tree from, unsigned HOST_WIDE_INT offset)
{
- struct tree_map *h, in;
- in.base.from = from;
-
- h = (struct tree_map *) htab_find_with_hash (heapvar_for_stmt, &in,
- htab_hash_pointer (from));
+ struct heapvar_map *h, in;
+ in.map.base.from = from;
+ in.offset = offset;
+ h = (struct heapvar_map *) htab_find_with_hash (heapvar_for_stmt, &in,
+ heapvar_map_hash (&in));
if (h)
- return h->to;
+ return h->map.to;
return NULL_TREE;
}
@@ -309,17 +330,19 @@ heapvar_lookup (tree from)
hashtable. */
static void
-heapvar_insert (tree from, tree to)
+heapvar_insert (tree from, unsigned HOST_WIDE_INT offset, tree to)
{
- struct tree_map *h;
+ struct heapvar_map *h;
void **loc;
- h = GGC_NEW (struct tree_map);
- h->hash = htab_hash_pointer (from);
- h->base.from = from;
- h->to = to;
- loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->hash, INSERT);
- *(struct tree_map **) loc = h;
+ h = GGC_NEW (struct heapvar_map);
+ h->map.base.from = from;
+ h->offset = offset;
+ h->map.hash = heapvar_map_hash (h);
+ h->map.to = to;
+ loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->map.hash, INSERT);
+ gcc_assert (*loc == NULL);
+ *(struct heapvar_map **) loc = h;
}
/* Return a new variable info structure consisting for a variable
@@ -3365,7 +3388,7 @@ static varinfo_t
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
{
varinfo_t vi;
- tree heapvar = heapvar_lookup (lhs->decl);
+ tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
if (heapvar == NULL_TREE)
{
@@ -3373,7 +3396,7 @@ make_constraint_from_heapvar (varinfo_t lhs, const char *name)
heapvar = create_tmp_var_raw (ptr_type_node, name);
DECL_EXTERNAL (heapvar) = 1;
- heapvar_insert (lhs->decl, heapvar);
+ heapvar_insert (lhs->decl, lhs->offset, heapvar);
ann = get_var_ann (heapvar);
ann->is_heapvar = 1;
@@ -4496,6 +4519,13 @@ create_variable_info_for (tree decl, const char *name)
vi->size = fo->size;
vi->offset = fo->offset;
vi->may_have_pointers = fo->may_have_pointers;
+ if (vi->is_global_var
+ && (!flag_whole_program || !in_ipa_mode)
+ && vi->may_have_pointers)
+ {
+ if (fo->only_restrict_pointers)
+ make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
+ }
for (i = VEC_length (fieldoff_s, fieldstack) - 1;
i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
i--)
@@ -4518,13 +4548,13 @@ create_variable_info_for (tree decl, const char *name)
newvi->fullsize = vi->fullsize;
newvi->may_have_pointers = fo->may_have_pointers;
insert_into_field_list (vi, newvi);
- if (newvi->is_global_var
- && (!flag_whole_program || !in_ipa_mode)
+ if ((newvi->is_global_var || TREE_CODE (decl) == PARM_DECL)
&& newvi->may_have_pointers)
{
if (fo->only_restrict_pointers)
make_constraint_from_restrict (newvi, "GLOBAL_RESTRICT");
- make_copy_constraint (newvi, nonlocal_id);
+ if (newvi->is_global_var && !in_ipa_mode)
+ make_copy_constraint (newvi, nonlocal_id);
}
stats.total_vars++;
@@ -4588,43 +4618,41 @@ intra_create_variable_infos (void)
if (!could_have_pointers (t))
continue;
- /* If flag_argument_noalias is set, then function pointer
- arguments are guaranteed not to point to each other. In that
- case, create an artificial variable PARM_NOALIAS and the
- constraint ARG = &PARM_NOALIAS. */
- if (POINTER_TYPE_P (TREE_TYPE (t)) && flag_argument_noalias > 0)
+ /* For restrict qualified pointers to objects passed by
+ reference build a real representative for the pointed-to object. */
+ if (DECL_BY_REFERENCE (t)
+ && POINTER_TYPE_P (TREE_TYPE (t))
+ && TYPE_RESTRICT (TREE_TYPE (t)))
{
+ struct constraint_expr lhsc, rhsc;
varinfo_t vi;
- var_ann_t ann;
-
- vi = make_constraint_from_heapvar (get_vi_for_tree (t),
- "PARM_NOALIAS");
- ann = get_var_ann (vi->decl);
- if (flag_argument_noalias == 1)
- {
- ann->noalias_state = NO_ALIAS;
- make_copy_constraint (vi, nonlocal_id);
- }
- else if (flag_argument_noalias == 2)
- {
- ann->noalias_state = NO_ALIAS_GLOBAL;
- make_constraint_from (vi, vi->id);
- }
- else if (flag_argument_noalias == 3)
+ tree heapvar = heapvar_lookup (t, 0);
+ if (heapvar == NULL_TREE)
{
- ann->noalias_state = NO_ALIAS_ANYTHING;
- make_constraint_from (vi, vi->id);
+ var_ann_t ann;
+ heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)),
+ "PARM_NOALIAS");
+ DECL_EXTERNAL (heapvar) = 1;
+ heapvar_insert (t, 0, heapvar);
+ ann = get_var_ann (heapvar);
+ ann->is_heapvar = 1;
}
- else
- gcc_unreachable ();
+ if (gimple_referenced_vars (cfun))
+ add_referenced_var (heapvar);
+ lhsc.var = get_vi_for_tree (t)->id;
+ lhsc.type = SCALAR;
+ lhsc.offset = 0;
+ rhsc.var = (vi = get_vi_for_tree (heapvar))->id;
+ rhsc.type = ADDRESSOF;
+ rhsc.offset = 0;
+ process_constraint (new_constraint (lhsc, rhsc));
+ vi->is_restrict_var = 1;
+ continue;
}
- else
- {
- varinfo_t arg_vi = get_vi_for_tree (t);
- for (p = arg_vi; p; p = p->next)
- make_constraint_from (p, nonlocal_id);
- }
+ for (p = get_vi_for_tree (t); p; p = p->next)
+ if (p->may_have_pointers)
+ make_constraint_from (p, nonlocal_id);
if (POINTER_TYPE_P (TREE_TYPE (t))
&& TYPE_RESTRICT (TREE_TYPE (t)))
make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
@@ -5363,7 +5391,7 @@ static void
init_alias_heapvars (void)
{
if (!heapvar_for_stmt)
- heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
+ heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
NULL);
}