diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb741b5d41f..e8aaef5c576 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2006-10-20 Daniel Berlin + + * tree.h (DECL_PTA_ARTIFICIAL): Remove. + (tree_decl_with_vis): Remove artificial_pta_var flag. + * tree-flow.h (referenced_var_check_and_insert): Expose. + (nonlocal_all): New prototype. + * tree-ssa-structalias.c (nonlocal_for_type): Remove. + (nonlocal_all): Make global. + (nonlocal_lookup): Remove. + (nonlocal_insert): Ditto. + (create_nonlocal_var): Do not call nonlocal_insert. + (get_nonlocal_id_for_type): Remove. + (find_global_initializers): Mark new vars we find for renaming. + (intra_create_variable_infos): Only create one nonlocal. + (expand_nonlocal_solutions): Remove. + (compute_points_to_sets): Don't call it. + (ipa_pta_execute): Ditto. + (init_alias_heapvars): Don't create nonlocal_for_type. + (delete_alias_heapvars): Don't remove it. + * tree-ssa-operands.c (access_can_touch_variable): Don't prune + nonlocal_all. + 2006-10-19 Brooks Moses * doc/install.texi (Downloading GCC): Clarify mention of diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c index 302165608d5..a7e78a4dc70 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c @@ -14,5 +14,5 @@ main(void) } /* The V_*_DEF comes from the initial assignment and the asm. */ -/* { dg-final { scan-tree-dump-times "_DEF" 2 "alias1" } } */ +/* { dg-final { scan-tree-dump-times "_DEF" 3 "alias1" } } */ /* { dg-final { cleanup-tree-dump "alias1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c index 3f3ec1a3572..e500f1178a6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c @@ -17,5 +17,5 @@ void bar (void) malloc functions may clobber global memory. Only the function result does not alias any other pointer. Hence, we must have a VDEF for a before and after the call to foo(). */ -/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 1 "alias1"} } */ +/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 2 "alias1"} } */ /* { dg-final { cleanup-tree-dump "alias1" } } */ diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 088c45ab335..5ade6455d96 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -621,7 +621,7 @@ referenced_var_lookup (unsigned int uid) /* Check if TO is in the referenced_vars hash table and insert it if not. Return true if it required insertion. */ -static bool +bool referenced_var_check_and_insert (tree to) { struct int_tree_map *h, in; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index f70eb774f35..447b7328ffd 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -425,6 +425,7 @@ extern GTY((param_is (struct int_tree_map))) htab_t referenced_vars; extern GTY((param_is (struct int_tree_map))) htab_t default_defs; extern tree referenced_var_lookup (unsigned int); +extern bool referenced_var_check_and_insert (tree); #define num_referenced_vars htab_elements (referenced_vars) #define referenced_var(i) referenced_var_lookup (i) @@ -437,6 +438,10 @@ extern GTY(()) VEC(tree,gc) *ssa_names; /* Artificial variable used to model the effects of function calls. */ extern GTY(()) tree global_var; +/* Artificial variable used to model the effects of nonlocal + variables. */ +extern GTY(()) tree nonlocal_all; + /* Call clobbered variables in the function. If bit I is set, then REFERENCED_VARS (I) is call-clobbered. */ extern bitmap call_clobbered_vars; diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 0efbe0f3ae2..4fa876de39c 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1053,7 +1053,9 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset, if (alias == global_var) return true; - if (TREE_CODE (alias) == VAR_DECL && DECL_PTA_ARTIFICIAL (alias)) + /* We cannot prune nonlocal aliases because they are not type + specific. */ + if (alias == nonlocal_all) return true; /* If ALIAS is an SFT, it can't be touched if the offset diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index b1f125a8679..1c4a46e75ee 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -164,14 +164,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) htab_t heapvar_for_stmt; - -/* Represents nonlocals. */ -static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) -htab_t nonlocal_for_type; - -/* If strict aliasing is off, we only use one variable to represent - the nonlocal types. */ -static GTY (()) tree nonlocal_all; +/* One variable to represent all non-local accesses. */ +tree nonlocal_all; static bool use_field_sensitive = true; static int in_ipa_mode = 0; @@ -2516,40 +2510,6 @@ do_deref (VEC (ce_s, heap) **constraints) } } -/* Lookup a nonlocal variable for type FROM, and return it if we find - one. */ - -static tree -nonlocal_lookup (tree from) -{ - struct tree_map *h, in; - in.from = from; - - h = htab_find_with_hash (nonlocal_for_type, &in, - htab_hash_pointer (from)); - if (h) - return h->to; - return NULL_TREE; -} - -/* Insert a mapping FROM->TO in the nonlocal variable for type - hashtable. */ - -static void -nonlocal_insert (tree from, tree to) -{ - struct tree_map *h; - void **loc; - - h = ggc_alloc (sizeof (struct tree_map)); - h->hash = htab_hash_pointer (from); - h->from = from; - h->to = to; - loc = htab_find_slot_with_hash (nonlocal_for_type, h, h->hash, - INSERT); - *(struct tree_map **) loc = h; -} - /* Create a nonlocal variable of TYPE to represent nonlocals we can alias. */ @@ -2561,61 +2521,10 @@ create_nonlocal_var (tree type) if (referenced_vars) add_referenced_var (nonlocal); - DECL_PTA_ARTIFICIAL (nonlocal) = 1; DECL_EXTERNAL (nonlocal) = 1; - nonlocal_insert (type, nonlocal); return nonlocal; } -/* Get or create a nonlocal variable for TYPE, and return its - variable info id. */ - -static unsigned int -get_nonlocal_id_for_type (tree type) -{ - tree nonlocal; - unsigned int nonlocal_id; - varinfo_t nonlocal_vi; - - /* For strict aliasing, we have one variable per type. For - non-strict aliasing, we only need one variable. */ - if (flag_strict_aliasing != 0) - { - nonlocal = nonlocal_lookup (type); - } - else - { - if (!nonlocal_all) - { - nonlocal = create_nonlocal_var (void_type_node); - nonlocal_all = nonlocal; - } - else - nonlocal = nonlocal_all; - } - - if (nonlocal && lookup_id_for_tree (nonlocal, &nonlocal_id)) - return nonlocal_id; - - if (!nonlocal) - { - gcc_assert (flag_strict_aliasing != 0); - nonlocal = create_nonlocal_var (type); - } - - /* Create variable info for the nonlocal var if it does not - exist. */ - nonlocal_id = create_variable_info_for (nonlocal, - get_name (nonlocal)); - nonlocal_vi = get_varinfo (nonlocal_id); - nonlocal_vi->is_artificial_var = 1; - nonlocal_vi->is_heap_var = 1; - nonlocal_vi->is_unknown_size_var = 1; - nonlocal_vi->directly_dereferenced = true; - - return nonlocal_id; -} - /* Given a tree T, return the constraint expression for it. */ static void @@ -2756,7 +2665,6 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results) return; } break; - default: { temp.type = ADDRESSOF; @@ -4116,7 +4024,12 @@ find_global_initializers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, case VAR_DECL: /* We might not have walked this because we skip DECL_EXTERNALs during the initial scan. */ - add_referenced_var (t); + if (referenced_vars) + { + get_var_ann (t); + if (referenced_var_check_and_insert (t)) + mark_sym_for_renaming (t); + } break; default: break; @@ -4336,8 +4249,8 @@ intra_create_variable_infos (void) { tree t; struct constraint_expr lhs, rhs; - tree nonlocal; varinfo_t nonlocal_vi; + /* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a dummy variable if flag_argument_noalias > 2. */ for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t)) @@ -4393,14 +4306,12 @@ intra_create_variable_infos (void) make_constraint_from_escaped (p); } } - nonlocal = create_tmp_var_raw (void_type_node, "NONLOCAL_ALL"); - - DECL_EXTERNAL (nonlocal) = 1; + nonlocal_all = create_nonlocal_var (void_type_node); /* Create variable info for the nonlocal var if it does not exist. */ - nonlocal_vars_id = create_variable_info_for (nonlocal, - get_name (nonlocal)); + nonlocal_vars_id = create_variable_info_for (nonlocal_all, + get_name (nonlocal_all)); nonlocal_vi = get_varinfo (nonlocal_vars_id); nonlocal_vi->is_artificial_var = 1; nonlocal_vi->is_heap_var = 1; @@ -4860,61 +4771,6 @@ find_escape_constraints (tree stmt) VEC_free (ce_s, heap, rhsc); } -/* Expand the solutions that have nonlocal_id in them to include one - variable for each type that is pointed to by nonlocal and - dereferenced. */ - -static void -expand_nonlocal_solutions (void) -{ - int i; - varinfo_t v; - bitmap new_nonlocal_solution = BITMAP_ALLOC (&ptabitmap_obstack); - - /* We could do this faster by only checking non-collapsed nodes, - unless the node was collapsed to one we would normally ignore in the - rest of the loop. Logic already seems complicated enough, and - it wasn't a measurable speedup on any testcases i had. */ - for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++) - { - /* Where the solution for our variable is, since it may have - been collapsed to another varinfo. */ - varinfo_t solv = v; - - if (v->is_special_var - || v->id == nonlocal_vars_id - || v->id == escaped_vars_id - || !POINTER_TYPE_P (TREE_TYPE (v->decl))) - continue; - - if (v->node != v->id) - solv = get_varinfo (v->node); - if (bitmap_bit_p (solv->solution, nonlocal_vars_id)) - { - unsigned int new_nonlocal_id; - tree pttype = TREE_TYPE (TREE_TYPE (v->decl)); - - new_nonlocal_id = get_nonlocal_id_for_type (pttype); - bitmap_set_bit (new_nonlocal_solution, new_nonlocal_id); - } - } - - if (!bitmap_empty_p (new_nonlocal_solution)) - { - - for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++) - { - if (v->node != v->id) - continue; - if (bitmap_bit_p (v->solution, nonlocal_vars_id)) - { - bitmap_clear_bit (v->solution, nonlocal_vars_id); - bitmap_ior_into (v->solution, new_nonlocal_solution); - } - } - } -} - /* Create points-to sets for the current function. See the comments at the start of the file for an algorithmic overview. */ @@ -4983,8 +4839,6 @@ compute_points_to_sets (struct alias_info *ai) solve_graph (graph); - expand_nonlocal_solutions (); - if (dump_file) dump_sa_points_to_info (dump_file); @@ -5129,8 +4983,6 @@ ipa_pta_execute (void) solve_graph (graph); - expand_nonlocal_solutions (); - if (dump_file) dump_sa_points_to_info (dump_file); in_ipa_mode = 0; @@ -5162,8 +5014,6 @@ init_alias_heapvars (void) { heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq, NULL); - nonlocal_for_type = htab_create_ggc (11, tree_map_hash, tree_map_eq, - NULL); nonlocal_all = NULL_TREE; } @@ -5172,7 +5022,6 @@ delete_alias_heapvars (void) { nonlocal_all = NULL_TREE; htab_delete (heapvar_for_stmt); - htab_delete (nonlocal_for_type); } diff --git a/gcc/tree.h b/gcc/tree.h index dddd3863248..e6a861ca24a 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2858,10 +2858,6 @@ extern void decl_restrict_base_insert (tree, tree); multiple translation units should be merged. */ #define DECL_ONE_ONLY(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.one_only) -/* Internal to points-to analysis and operand scanning. Indicates - that this DECL is an artificial points-to variable. */ -#define DECL_PTA_ARTIFICIAL(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.artificial_pta_var) - struct tree_decl_with_vis GTY(()) { struct tree_decl_with_rtl common; @@ -2879,7 +2875,6 @@ struct tree_decl_with_vis GTY(()) unsigned based_on_restrict_p : 1; /* Used by C++. Might become a generic decl flag. */ unsigned shadowed_for_var_p : 1; - unsigned artificial_pta_var : 1; /* Don't belong to VAR_DECL exclusively. */ unsigned in_system_header_flag : 1; @@ -2894,7 +2889,7 @@ struct tree_decl_with_vis GTY(()) /* Belongs to VAR_DECL exclusively. */ ENUM_BITFIELD(tls_model) tls_model : 3; - /* 10 unused bits. */ + /* 11 unused bits. */ }; /* In a VAR_DECL that's static,