diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-29 19:26:47 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-29 19:26:47 +0000 |
commit | c4aa078796bd9c7237e0ac5ea4ab7553106f199d (patch) | |
tree | 98a5e7f47a887d71b7ce051eac4583deee5a6dac /gcc/tree-ssa-structalias.c | |
parent | e34f5cd313173ac0144aeb70ab96e50fc36605ba (diff) | |
download | gcc-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.c | 132 |
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); } |