From: bonzini Date: Tue, 6 Feb 2007 14:34:51 +0000 (+0000) Subject: 2006-02-06 Paolo Bonzini X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=b30a87157955484be66baebfecc08c680d721d93 2006-02-06 Paolo Bonzini * Makefile.in (tree-ssa-loop-ivopts.o): Add pointer-set.h dependency. (tree-ssa-reassoc.o): Add pointer-set.h dependency. (tree-cfg.o): Remove hashtab.h dependency. * tree-ssa-loop-ivopts.c: Include pointer-set.h. (struct ivopts_data): Change niters to pointer_map_t. (struct nfe_cache_elt, nfe_hash, nfe_eq): Delete. (niter_for_exit): Create pointer_map on demand. Change for pointer_map API. (tree_ssa_iv_optimize_init): Initialize data->niters to NULL. (free_loop_data): Destroy data->niters if created and reset field. (tree_ssa_iv_optimize_finalize): Don't delete data->niters here. (tree_ssa_iv_optimize_loop): Check for presence of stale data. * tree-ssa-reassoc.c: Include pointer-set.h. (bb_rank): Change to long *. (operand_rank): Change to pointer_map_t. (find_operand_rank): Return long, -1 if not found. Declare as inline. (insert_operand_rank): Accept long. (operand_entry_hash, operand_entry_eq): Remove. (get_rank): Return long. Adjust for changes above. (init_reassoc): Change rank type to long. Adjust creation of bb_rank and operand_rank. (fini_reassoc): Delete operand_rank with pointer_map_destroy. * tree-ssa-structalias.c (vi_for_tree): Change to pointer_map. (struct tree_vi, tree_vi_t, tree_vi_hash, tree_vi_eq): Delete. (insert_vi_for_tree): Rewrite for pointer_map API. Assert argument is not NULL. (lookup_vi_for_tree): Rewrite for pointer_map API. Return varinfo_t directly since it cannot be NULL. (get_vi_for_tree): Rewrite for pointer_map API. (find_what_p_points_to): Adjust for change to lookup_vi_for_tree. (init_alias_vars): Create vi_for_tree as pointer_map. (delete_points_to_sets): Delete vi_for_tree using pointer_map_destroy. * tree-cfg.c: Don't include hashtab.h. (edge_to_cases): Declare as pointer_map. (struct edge_to_cases_elt, edge_to_cases_hash, edge_to_cases_eq): Delete. (edge_to_cases_cleanup): Rewrite as pointer_map_traverse callback. (start_recording_case_labels): Create edge_to_cases as pointer_map. (end_recoding_case_labels): Cleanup edge_to_cases manually before destroying it. (record_switch_edge): Delete. (get_cases_for_edge): Adjust for pointer_map API, inline record_switch_edge (rewritten for new API), remove goto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121648 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3b07b0b172..f915a021713 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,74 @@ +2006-02-06 Paolo Bonzini + + * Makefile.in (tree-ssa-loop-ivopts.o): Add pointer-set.h dependency. + (tree-ssa-reassoc.o): Add pointer-set.h dependency. + (tree-cfg.o): Remove hashtab.h dependency. + + * tree-ssa-loop-ivopts.c: Include pointer-set.h. + (struct ivopts_data): Change niters to pointer_map_t. + (struct nfe_cache_elt, nfe_hash, nfe_eq): Delete. + (niter_for_exit): Create pointer_map on demand. Change for + pointer_map API. + (tree_ssa_iv_optimize_init): Initialize data->niters to NULL. + (free_loop_data): Destroy data->niters if created and reset field. + (tree_ssa_iv_optimize_finalize): Don't delete data->niters here. + (tree_ssa_iv_optimize_loop): Check for presence of stale data. + + * tree-ssa-reassoc.c: Include pointer-set.h. + (bb_rank): Change to long *. + (operand_rank): Change to pointer_map_t. + (find_operand_rank): Return long, -1 if not found. Declare as inline. + (insert_operand_rank): Accept long. + (operand_entry_hash, operand_entry_eq): Remove. + (get_rank): Return long. Adjust for changes above. + (init_reassoc): Change rank type to long. Adjust creation of bb_rank + and operand_rank. + (fini_reassoc): Delete operand_rank with pointer_map_destroy. + + * tree-ssa-structalias.c (vi_for_tree): Change to pointer_map. + (struct tree_vi, tree_vi_t, tree_vi_hash, tree_vi_eq): Delete. + (insert_vi_for_tree): Rewrite for pointer_map API. Assert argument + is not NULL. + (lookup_vi_for_tree): Rewrite for pointer_map API. Return varinfo_t + directly since it cannot be NULL. + (get_vi_for_tree): Rewrite for pointer_map API. + (find_what_p_points_to): Adjust for change to lookup_vi_for_tree. + (init_alias_vars): Create vi_for_tree as pointer_map. + (delete_points_to_sets): Delete vi_for_tree using pointer_map_destroy. + + * tree-cfg.c: Don't include hashtab.h. + (edge_to_cases): Declare as pointer_map. + (struct edge_to_cases_elt, edge_to_cases_hash, edge_to_cases_eq): + Delete. + (edge_to_cases_cleanup): Rewrite as pointer_map_traverse callback. + (start_recording_case_labels): Create edge_to_cases as pointer_map. + (end_recoding_case_labels): Cleanup edge_to_cases manually before + destroying it. + (record_switch_edge): Delete. + (get_cases_for_edge): Adjust for pointer_map API, inline + record_switch_edge (rewritten for new API), remove goto. + +2006-02-06 Paolo Bonzini + + * Makefile.in (tree-nested.o): Add pointer-set.h dependency. + * tree-nested.c: Include pointer-set.h. + (var_map_elt, var_map_eq, var_map_hash): Delete. + (struct nesting_info): Remove GTY marker. Change the two htab_t's + to pointer_map_t's. + (nesting_info_bitmap_obstack): New. + (lookup_field_for_decl): Adjust for pointer_map API. + (lookup_tramp_for_decl): Adjust for pointer_map API. + (get_nonlocal_debug_decl): Adjust for pointer_map API. + (get_local_debug_decl): Adjust for pointer_map API. + (convert_nl_goto_reference): Adjust for pointer_map API. + (convert_nl_goto_receiver): Adjust for pointer_map API. + (create_nesting_tree): Create outside GGC space. Create bitmap on + the new obstack. Create field_map and var_map as pointer_maps. + (free_nesting_tree): Adjust for changes to create_nesting_tree. + (root): Delete. + (lower_nested_functions): Move root here, no need to NULL it. + Initialize and release the obstack. + 2007-02-06 Paolo Bonzini * tree.c (tree_int_map_hash, tree_int_map_eq, tree_int_map_marked_p): diff --git a/gcc/Makefile.in b/gcc/Makefile.in index f22407f8f79..689122d1490 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2055,7 +2055,7 @@ tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ $(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \ - $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) toplev.h \ + $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h toplev.h \ tree-ssa-propagate.h tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \ @@ -2078,7 +2078,7 @@ tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \ $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(TREE_DUMP_H) $(TREE_INLINE_H) \ tree-iterator.h $(TREE_GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \ - $(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) + $(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ $(CFGLOOP_H) $(RTL_H) $(C_COMMON_H) tree-chrec.h $(TREE_DATA_REF_H) \ @@ -2140,7 +2140,7 @@ tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \ output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \ $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \ - tree-chrec.h $(VARRAY_H) tree-affine.h + tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) \ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \ output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) @@ -2167,7 +2167,7 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\ $(BASIC_BLOCK_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) vec.h \ - alloc-pool.h + alloc-pool.h pointer-set.h tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6f492052501..d9794592cf6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -44,7 +44,6 @@ Boston, MA 02110-1301, USA. */ #include "except.h" #include "cfgloop.h" #include "cfglayout.h" -#include "hashtab.h" #include "tree-ssa-propagate.h" #include "value-prof.h" #include "pointer-set.h" @@ -70,19 +69,7 @@ static const int initial_cfg_capacity = 20; more persistent. The key is getting notification of changes to the CFG (particularly edge removal, creation and redirection). */ -struct edge_to_cases_elt -{ - /* The edge itself. Necessary for hashing and equality tests. */ - edge e; - - /* The case labels associated with this edge. We link these up via - their TREE_CHAIN field, then we wipe out the TREE_CHAIN fields - when we destroy the hash table. This prevents problems when copying - SWITCH_EXPRs. */ - tree case_labels; -}; - -static htab_t edge_to_cases; +static struct pointer_map_t *edge_to_cases; /* CFG statistics. */ struct cfg_stats_d @@ -619,28 +606,6 @@ make_cond_expr_edges (basic_block bb) } } -/* Hashing routine for EDGE_TO_CASES. */ - -static hashval_t -edge_to_cases_hash (const void *p) -{ - edge e = ((struct edge_to_cases_elt *)p)->e; - - /* Hash on the edge itself (which is a pointer). */ - return htab_hash_pointer (e); -} - -/* Equality routine for EDGE_TO_CASES, edges are unique, so testing - for equality is just a pointer comparison. */ - -static int -edge_to_cases_eq (const void *p1, const void *p2) -{ - edge e1 = ((struct edge_to_cases_elt *)p1)->e; - edge e2 = ((struct edge_to_cases_elt *)p2)->e; - - return e1 == e2; -} /* Called for each element in the hash table (P) as we delete the edge to cases hash table. @@ -649,18 +614,20 @@ edge_to_cases_eq (const void *p1, const void *p2) SWITCH_EXPRs and structure sharing rules, then free the hash table element. */ -static void -edge_to_cases_cleanup (void *p) +static bool +edge_to_cases_cleanup (void *key ATTRIBUTE_UNUSED, void **value, + void *data ATTRIBUTE_UNUSED) { - struct edge_to_cases_elt *elt = (struct edge_to_cases_elt *) p; tree t, next; - for (t = elt->case_labels; t; t = next) + for (t = (tree) *value; t; t = next) { next = TREE_CHAIN (t); TREE_CHAIN (t) = NULL; } - free (p); + + *value = NULL; + return false; } /* Start recording information mapping edges to case labels. */ @@ -669,11 +636,7 @@ void start_recording_case_labels (void) { gcc_assert (edge_to_cases == NULL); - - edge_to_cases = htab_create (37, - edge_to_cases_hash, - edge_to_cases_eq, - edge_to_cases_cleanup); + edge_to_cases = pointer_map_create (); } /* Return nonzero if we are recording information for case labels. */ @@ -689,46 +652,11 @@ recording_case_labels_p (void) void end_recording_case_labels (void) { - htab_delete (edge_to_cases); + pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL); + pointer_map_destroy (edge_to_cases); edge_to_cases = NULL; } -/* Record that CASE_LABEL (a CASE_LABEL_EXPR) references edge E. */ - -static void -record_switch_edge (edge e, tree case_label) -{ - struct edge_to_cases_elt *elt; - void **slot; - - /* Build a hash table element so we can see if E is already - in the table. */ - elt = XNEW (struct edge_to_cases_elt); - elt->e = e; - elt->case_labels = case_label; - - slot = htab_find_slot (edge_to_cases, elt, INSERT); - - if (*slot == NULL) - { - /* E was not in the hash table. Install E into the hash table. */ - *slot = (void *)elt; - } - else - { - /* E was already in the hash table. Free ELT as we do not need it - anymore. */ - free (elt); - - /* Get the entry stored in the hash table. */ - elt = (struct edge_to_cases_elt *) *slot; - - /* Add it to the chain of CASE_LABEL_EXPRs referencing E. */ - TREE_CHAIN (case_label) = elt->case_labels; - elt->case_labels = case_label; - } -} - /* If we are inside a {start,end}_recording_cases block, then return a chain of CASE_LABEL_EXPRs from T which reference E. @@ -737,7 +665,6 @@ record_switch_edge (edge e, tree case_label) static tree get_cases_for_edge (edge e, tree t) { - struct edge_to_cases_elt elt, *elt_p; void **slot; size_t i, n; tree vec; @@ -747,16 +674,9 @@ get_cases_for_edge (edge e, tree t) if (!recording_case_labels_p ()) return NULL; -restart: - elt.e = e; - elt.case_labels = NULL; - slot = htab_find_slot (edge_to_cases, &elt, NO_INSERT); - + slot = pointer_map_contains (edge_to_cases, e); if (slot) - { - elt_p = (struct edge_to_cases_elt *)*slot; - return elt_p->case_labels; - } + return (tree) *slot; /* If we did not find E in the hash table, then this must be the first time we have been queried for information about E & T. Add all the @@ -766,11 +686,19 @@ restart: n = TREE_VEC_LENGTH (vec); for (i = 0; i < n; i++) { - tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i)); + tree elt = TREE_VEC_ELT (vec, i); + tree lab = CASE_LABEL (elt); basic_block label_bb = label_to_block (lab); - record_switch_edge (find_edge (e->src, label_bb), TREE_VEC_ELT (vec, i)); + edge this_edge = find_edge (e->src, label_bb); + + /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create + a new chain. */ + slot = pointer_map_insert (edge_to_cases, this_edge); + TREE_CHAIN (elt) = (tree) *slot; + *slot = elt; } - goto restart; + + return (tree) *pointer_map_contains (edge_to_cases, e); } /* Create the edges for a SWITCH_EXPR starting at block BB. diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index fdf39cc4623..a3ea11432d0 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -34,6 +34,7 @@ #include "cgraph.h" #include "expr.h" #include "langhooks.h" +#include "pointer-set.h" #include "ggc.h" @@ -77,20 +78,14 @@ been written as independent functions without change. */ -struct var_map_elt GTY(()) -{ - tree old; - tree new; -}; - -struct nesting_info GTY ((chain_next ("%h.next"))) +struct nesting_info { struct nesting_info *outer; struct nesting_info *inner; struct nesting_info *next; - htab_t GTY ((param_is (struct var_map_elt))) field_map; - htab_t GTY ((param_is (struct var_map_elt))) var_map; + struct pointer_map_t *field_map; + struct pointer_map_t *var_map; bitmap suppress_expansion; tree context; @@ -108,22 +103,9 @@ struct nesting_info GTY ((chain_next ("%h.next"))) }; -/* Hashing and equality functions for nesting_info->var_map. */ +/* Obstack used for the bitmaps in the struct above. */ +static struct bitmap_obstack nesting_info_bitmap_obstack; -static hashval_t -var_map_hash (const void *x) -{ - const struct var_map_elt *a = (const struct var_map_elt *) x; - return htab_hash_pointer (a->old); -} - -static int -var_map_eq (const void *x, const void *y) -{ - const struct var_map_elt *a = (const struct var_map_elt *) x; - const struct var_map_elt *b = (const struct var_map_elt *) y; - return a->old == b->old; -} /* We're working in so many different function contexts simultaneously, that create_tmp_var is dangerous. Prevent mishap. */ @@ -268,22 +250,18 @@ static tree lookup_field_for_decl (struct nesting_info *info, tree decl, enum insert_option insert) { - struct var_map_elt *elt, dummy; void **slot; - tree field; - dummy.old = decl; - slot = htab_find_slot (info->field_map, &dummy, insert); - if (!slot) + if (insert == NO_INSERT) { - gcc_assert (insert != INSERT); - return NULL; + slot = pointer_map_contains (info->field_map, decl); + return slot ? *slot : NULL; } - elt = (struct var_map_elt *) *slot; - if (!elt && insert == INSERT) + slot = pointer_map_insert (info->field_map, decl); + if (!*slot) { - field = make_node (FIELD_DECL); + tree field = make_node (FIELD_DECL); DECL_NAME (field) = DECL_NAME (decl); if (use_pointer_in_frame (decl)) @@ -304,19 +282,13 @@ lookup_field_for_decl (struct nesting_info *info, tree decl, } insert_field_into_struct (get_frame_type (info), field); - - elt = GGC_NEW (struct var_map_elt); - elt->old = decl; - elt->new = field; - *slot = elt; + *slot = field; if (TREE_CODE (decl) == PARM_DECL) info->any_parm_remapped = true; } - else - field = elt ? elt->new : NULL; - return field; + return *slot; } /* Build or return the variable that holds the static chain within @@ -469,39 +441,29 @@ static tree lookup_tramp_for_decl (struct nesting_info *info, tree decl, enum insert_option insert) { - struct var_map_elt *elt, dummy; void **slot; - tree field; - dummy.old = decl; - slot = htab_find_slot (info->var_map, &dummy, insert); - if (!slot) + if (insert == NO_INSERT) { - gcc_assert (insert != INSERT); - return NULL; + slot = pointer_map_contains (info->var_map, decl); + return slot ? *slot : NULL; } - elt = (struct var_map_elt *) *slot; - if (!elt && insert == INSERT) + slot = pointer_map_insert (info->var_map, decl); + if (!*slot) { - field = make_node (FIELD_DECL); + tree field = make_node (FIELD_DECL); DECL_NAME (field) = DECL_NAME (decl); TREE_TYPE (field) = get_trampoline_type (); TREE_ADDRESSABLE (field) = 1; insert_field_into_struct (get_frame_type (info), field); - - elt = GGC_NEW (struct var_map_elt); - elt->old = decl; - elt->new = field; - *slot = elt; + *slot = field; info->any_tramp_created = true; } - else - field = elt ? elt->new : NULL; - return field; + return *slot; } /* Build or return the field within the non-local frame state that holds @@ -767,10 +729,10 @@ check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl) static struct nesting_info * create_nesting_tree (struct cgraph_node *cgn) { - struct nesting_info *info = GGC_CNEW (struct nesting_info); - info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free); - info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free); - info->suppress_expansion = BITMAP_GGC_ALLOC (); + struct nesting_info *info = XCNEW (struct nesting_info); + info->field_map = pointer_map_create (); + info->var_map = pointer_map_create (); + info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack); info->context = cgn->decl; for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) @@ -865,18 +827,15 @@ get_frame_field (struct nesting_info *info, tree target_context, static tree get_nonlocal_debug_decl (struct nesting_info *info, tree decl) { - struct var_map_elt *elt, dummy; tree target_context; struct nesting_info *i; tree x, field, new_decl; void **slot; - dummy.old = decl; - slot = htab_find_slot (info->var_map, &dummy, INSERT); - elt = *slot; + slot = pointer_map_insert (info->var_map, decl); - if (elt) - return elt->new; + if (*slot) + return *slot; target_context = decl_function_context (decl); @@ -920,11 +879,7 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl) SET_DECL_VALUE_EXPR (new_decl, x); DECL_HAS_VALUE_EXPR_P (new_decl) = 1; - elt = ggc_alloc (sizeof (*elt)); - elt->old = decl; - elt->new = new_decl; - *slot = elt; - + *slot = new_decl; TREE_CHAIN (new_decl) = info->debug_var_chain; info->debug_var_chain = new_decl; @@ -1198,16 +1153,12 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) static tree get_local_debug_decl (struct nesting_info *info, tree decl, tree field) { - struct var_map_elt *elt, dummy; tree x, new_decl; void **slot; - dummy.old = decl; - slot = htab_find_slot (info->var_map, &dummy, INSERT); - elt = *slot; - - if (elt) - return elt->new; + slot = pointer_map_insert (info->var_map, decl); + if (*slot) + return *slot; /* Make sure frame_decl gets created. */ (void) get_frame_type (info); @@ -1227,11 +1178,7 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field) SET_DECL_VALUE_EXPR (new_decl, x); DECL_HAS_VALUE_EXPR_P (new_decl) = 1; - - elt = ggc_alloc (sizeof (*elt)); - elt->old = decl; - elt->new = new_decl; - *slot = elt; + *slot = new_decl; TREE_CHAIN (new_decl) = info->debug_var_chain; info->debug_var_chain = new_decl; @@ -1491,7 +1438,6 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data) struct walk_stmt_info *wi = (struct walk_stmt_info *) data; struct nesting_info *info = wi->info, *i; tree t = *tp, label, new_label, target_context, x, arg, field; - struct var_map_elt *elt, dummy; void **slot; *walk_subtrees = 0; @@ -1514,21 +1460,15 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data) (hairy target-specific) non-local goto receiver code to be generated when we expand rtl. Enter this association into var_map so that we can insert the new label into the IL during a second pass. */ - dummy.old = label; - slot = htab_find_slot (i->var_map, &dummy, INSERT); - elt = (struct var_map_elt *) *slot; - if (elt == NULL) + slot = pointer_map_insert (i->var_map, label); + if (*slot == NULL) { new_label = create_artificial_label (); DECL_NONLOCAL (new_label) = 1; - - elt = GGC_NEW (struct var_map_elt); - elt->old = label; - elt->new = new_label; - *slot = elt; + *slot = new_label; } else - new_label = elt->new; + new_label = *slot; /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */ field = get_nl_goto_field (i); @@ -1559,19 +1499,17 @@ convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data) struct walk_stmt_info *wi = (struct walk_stmt_info *) data; struct nesting_info *info = wi->info; tree t = *tp, label, new_label, x; - struct var_map_elt *elt, dummy; tree_stmt_iterator tmp_tsi; + void **slot; *walk_subtrees = 0; if (TREE_CODE (t) != LABEL_EXPR) return NULL_TREE; label = LABEL_EXPR_LABEL (t); - dummy.old = label; - elt = (struct var_map_elt *) htab_find (info->var_map, &dummy); - if (!elt) + slot = pointer_map_contains (info->var_map, label); + if (!slot) return NULL_TREE; - new_label = elt->new; /* If there's any possibility that the previous statement falls through, then we must branch around the new non-local label. */ @@ -1582,6 +1520,8 @@ convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data) x = build1 (GOTO_EXPR, void_type_node, label); tsi_link_before (&wi->tsi, x, TSI_SAME_STMT); } + + new_label = (tree) *slot; x = build1 (LABEL_EXPR, void_type_node, new_label); tsi_link_before (&wi->tsi, x, TSI_SAME_STMT); @@ -1953,16 +1893,15 @@ free_nesting_tree (struct nesting_info *root) { if (root->inner) free_nesting_tree (root->inner); - htab_delete (root->var_map); + pointer_map_destroy (root->var_map); + pointer_map_destroy (root->field_map); next = root->next; - ggc_free (root); + free (root); root = next; } while (root); } -static GTY(()) struct nesting_info *root; - /* Main entry point for this pass. Process FNDECL and all of its nested subroutines and turn them into something less tightly bound. */ @@ -1970,12 +1909,14 @@ void lower_nested_functions (tree fndecl) { struct cgraph_node *cgn; + struct nesting_info *root; /* If there are no nested functions, there's nothing to do. */ cgn = cgraph_node (fndecl); if (!cgn->nested) return; + bitmap_obstack_initialize (&nesting_info_bitmap_obstack); root = create_nesting_tree (cgn); walk_all_functions (convert_nonlocal_reference, root); walk_all_functions (convert_local_reference, root); @@ -1985,7 +1926,7 @@ lower_nested_functions (tree fndecl) finalize_nesting_tree (root); unnest_nesting_tree (root); free_nesting_tree (root); - root = NULL; + bitmap_obstack_release (&nesting_info_bitmap_obstack); } #include "gt-tree-nested.h" diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 65f1b84df14..5982b3d3f62 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -83,6 +83,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "ggc.h" #include "insn-config.h" #include "recog.h" +#include "pointer-set.h" #include "hashtab.h" #include "tree-chrec.h" #include "tree-scalar-evolution.h" @@ -208,7 +209,7 @@ struct ivopts_data unsigned regs_used; /* Numbers of iterations for all exits of the current loop. */ - htab_t niters; + struct pointer_map_t *niters; /* The size of version_info array allocated. */ unsigned version_info_size; @@ -673,58 +674,26 @@ contains_abnormal_ssa_name_p (tree expr) return false; } -/* Element of the table in that we cache the numbers of iterations obtained - from exits of the loop. */ - -struct nfe_cache_elt -{ - /* The edge for that the number of iterations is cached. */ - edge exit; - - /* Number of iterations corresponding to this exit, or NULL if it cannot be - determined. */ - tree niter; -}; - -/* Hash function for nfe_cache_elt E. */ - -static hashval_t -nfe_hash (const void *e) -{ - const struct nfe_cache_elt *elt = e; - - return htab_hash_pointer (elt->exit); -} - -/* Equality function for nfe_cache_elt E1 and edge E2. */ - -static int -nfe_eq (const void *e1, const void *e2) -{ - const struct nfe_cache_elt *elt1 = e1; - - return elt1->exit == e2; -} - /* Returns tree describing number of iterations determined from EXIT of DATA->current_loop, or NULL if something goes wrong. */ static tree niter_for_exit (struct ivopts_data *data, edge exit) { - struct nfe_cache_elt *nfe_desc; struct tree_niter_desc desc; - PTR *slot; - - slot = htab_find_slot_with_hash (data->niters, exit, - htab_hash_pointer (exit), - INSERT); + tree niter; + void **slot; - if (!*slot) + if (!data->niters) { - nfe_desc = xmalloc (sizeof (struct nfe_cache_elt)); - nfe_desc->exit = exit; + data->niters = pointer_map_create (); + slot = NULL; + } + else + slot = pointer_map_contains (data->niters, exit); + if (!slot) + { /* Try to determine number of iterations. We must know it unconditionally (i.e., without possibility of # of iterations being zero). Also, we cannot safely work with ssa names that @@ -734,14 +703,16 @@ niter_for_exit (struct ivopts_data *data, edge exit) exit, &desc, true) && integer_zerop (desc.may_be_zero) && !contains_abnormal_ssa_name_p (desc.niter)) - nfe_desc->niter = desc.niter; + niter = desc.niter; else - nfe_desc->niter = NULL_TREE; + niter = NULL_TREE; + + *pointer_map_insert (data->niters, exit) = niter; } else - nfe_desc = *slot; + niter = *slot; - return nfe_desc->niter; + return niter; } /* Returns tree describing number of iterations determined from @@ -770,7 +741,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data) data->relevant = BITMAP_ALLOC (NULL); data->important_candidates = BITMAP_ALLOC (NULL); data->max_inv_id = 0; - data->niters = htab_create (10, nfe_hash, nfe_eq, free); + data->niters = NULL; data->iv_uses = VEC_alloc (iv_use_p, heap, 20); data->iv_candidates = VEC_alloc (iv_cand_p, heap, 20); decl_rtl_to_reset = VEC_alloc (tree, heap, 20); @@ -5236,7 +5207,11 @@ free_loop_data (struct ivopts_data *data) bitmap_iterator bi; tree obj; - htab_empty (data->niters); + if (data->niters) + { + pointer_map_destroy (data->niters); + data->niters = NULL; + } EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, i, bi) { @@ -5304,7 +5279,6 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data) free (data->version_info); BITMAP_FREE (data->relevant); BITMAP_FREE (data->important_candidates); - htab_delete (data->niters); VEC_free (tree, heap, decl_rtl_to_reset); VEC_free (iv_use_p, heap, data->iv_uses); @@ -5320,6 +5294,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop) struct iv_ca *iv_ca; edge exit; + gcc_assert (!data->niters); data->current_loop = loop; if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 5e782615072..e216f996637 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA. */ #include "alloc-pool.h" #include "vec.h" #include "langhooks.h" +#include "pointer-set.h" /* This is a simple global reassociation pass. It is, in part, based on the LLVM pass of the same name (They do some things more/less @@ -179,68 +180,38 @@ static alloc_pool operand_entry_pool; /* Starting rank number for a given basic block, so that we can rank operations using unmovable instructions in that BB based on the bb depth. */ -static unsigned int *bb_rank; +static long *bb_rank; /* Operand->rank hashtable. */ -static htab_t operand_rank; +static struct pointer_map_t *operand_rank; /* Look up the operand rank structure for expression E. */ -static operand_entry_t +static inline long find_operand_rank (tree e) { - void **slot; - struct operand_entry vrd; - - vrd.op = e; - slot = htab_find_slot (operand_rank, &vrd, NO_INSERT); - if (!slot) - return NULL; - return ((operand_entry_t) *slot); + void **slot = pointer_map_contains (operand_rank, e); + return slot ? (long) *slot : -1; } /* Insert {E,RANK} into the operand rank hashtable. */ -static void -insert_operand_rank (tree e, unsigned int rank) +static inline void +insert_operand_rank (tree e, long rank) { void **slot; - operand_entry_t new_pair = pool_alloc (operand_entry_pool); - - new_pair->op = e; - new_pair->rank = rank; - slot = htab_find_slot (operand_rank, new_pair, INSERT); - gcc_assert (*slot == NULL); - *slot = new_pair; -} - -/* Return the hash value for a operand rank structure */ - -static hashval_t -operand_entry_hash (const void *p) -{ - const operand_entry_t vr = (operand_entry_t) p; - return iterative_hash_expr (vr->op, 0); -} - -/* Return true if two operand rank structures are equal. */ - -static int -operand_entry_eq (const void *p1, const void *p2) -{ - const operand_entry_t vr1 = (operand_entry_t) p1; - const operand_entry_t vr2 = (operand_entry_t) p2; - return vr1->op == vr2->op; + gcc_assert (rank > 0); + slot = pointer_map_insert (operand_rank, e); + gcc_assert (!*slot); + *slot = (void *) rank; } /* Given an expression E, return the rank of the expression. */ -static unsigned int +static long get_rank (tree e) { - operand_entry_t vr; - /* Constants have rank 0. */ if (is_gimple_min_invariant (e)) return 0; @@ -260,12 +231,12 @@ get_rank (tree e) { tree stmt; tree rhs; - unsigned int rank, maxrank; + long rank, maxrank; int i; if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL && SSA_NAME_IS_DEFAULT_DEF (e)) - return find_operand_rank (e)->rank; + return find_operand_rank (e); stmt = SSA_NAME_DEF_STMT (e); if (bb_for_stmt (stmt) == NULL) @@ -276,9 +247,9 @@ get_rank (tree e) return bb_rank[bb_for_stmt (stmt)->index]; /* If we already have a rank for this expression, use that. */ - vr = find_operand_rank (e); - if (vr) - return vr->rank; + rank = find_operand_rank (e); + if (rank != -1) + return rank; /* Otherwise, find the maximum rank for the operands, or the bb rank, whichever is less. */ @@ -301,7 +272,7 @@ get_rank (tree e) { fprintf (dump_file, "Rank for "); print_generic_expr (dump_file, e, 0); - fprintf (dump_file, " is %d\n", (rank + 1)); + fprintf (dump_file, " is %ld\n", (rank + 1)); } /* Note the rank in the hashtable so we don't recompute it. */ @@ -1417,7 +1388,7 @@ static void init_reassoc (void) { int i; - unsigned int rank = 2; + long rank = 2; tree param; int *bbs = XNEWVEC (int, last_basic_block + 1); @@ -1429,10 +1400,8 @@ init_reassoc (void) /* Reverse RPO (Reverse Post Order) will give us something where deeper loops come later. */ pre_and_rev_post_order_compute (NULL, bbs, false); - bb_rank = XCNEWVEC (unsigned int, last_basic_block + 1); - - operand_rank = htab_create (511, operand_entry_hash, - operand_entry_eq, 0); + bb_rank = XCNEWVEC (long, last_basic_block + 1); + operand_rank = pointer_map_create (); /* Give each argument a distinct rank. */ for (param = DECL_ARGUMENTS (current_function_decl); @@ -1483,8 +1452,8 @@ fini_reassoc (void) fprintf (dump_file, "Statements rewritten: %d\n", reassociate_stats.rewritten); } - htab_delete (operand_rank); + pointer_map_destroy (operand_rank); free_alloc_pool (operand_entry_pool); free (bb_rank); VEC_free (tree, heap, broken_up_subtracts); diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 576ae1b78bb..238e7f487c1 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2138,67 +2138,31 @@ solve_graph (constraint_graph_t graph) } /* Map from trees to variable infos. */ -static htab_t vi_for_tree; +static struct pointer_map_t *vi_for_tree; -typedef struct tree_vi -{ - tree t; - varinfo_t vi; -} *tree_vi_t; - -/* Hash a tree id structure. */ - -static hashval_t -tree_vi_hash (const void *p) -{ - const tree_vi_t ta = (tree_vi_t) p; - return htab_hash_pointer (ta->t); -} - -/* Return true if the tree in P1 and the tree in P2 are the same. */ - -static int -tree_vi_eq (const void *p1, const void *p2) -{ - const tree_vi_t ta1 = (tree_vi_t) p1; - const tree_vi_t ta2 = (tree_vi_t) p2; - return ta1->t == ta2->t; -} -/* Insert ID as the variable id for tree T in the hashtable. */ +/* Insert ID as the variable id for tree T in the vi_for_tree map. */ static void insert_vi_for_tree (tree t, varinfo_t vi) { - void **slot; - struct tree_vi finder; - tree_vi_t new_pair; - - finder.t = t; - slot = htab_find_slot (vi_for_tree, &finder, INSERT); + void **slot = pointer_map_insert (vi_for_tree, t); + gcc_assert (vi); gcc_assert (*slot == NULL); - new_pair = XNEW (struct tree_vi); - new_pair->t = t; - new_pair->vi = vi; - *slot = (void *)new_pair; + *slot = vi; } /* Find the variable info for tree T in VI_FOR_TREE. If T does not - exist in the hash table, return false, otherwise, return true and - set *VI to the varinfo we found. */ + exist in the map, return NULL, otherwise, return the varinfo we found. */ -static bool -lookup_vi_for_tree (tree t, varinfo_t *vi) +static varinfo_t +lookup_vi_for_tree (tree t) { - tree_vi_t pair; - struct tree_vi finder; + void **slot = pointer_map_contains (vi_for_tree, t); + if (slot == NULL) + return NULL; - finder.t = t; - pair = htab_find (vi_for_tree, &finder); - if (pair == NULL) - return false; - *vi = pair->vi; - return true; + return (varinfo_t) *slot; } /* Return a printable name for DECL */ @@ -2235,21 +2199,17 @@ alias_get_name (tree decl) return res; } -/* Find the variable id for tree T in the hashtable. - If T doesn't exist in the hash table, create an entry for it. */ +/* Find the variable id for tree T in the map. + If T doesn't exist in the map, create an entry for it and return it. */ static varinfo_t get_vi_for_tree (tree t) { - tree_vi_t pair; - struct tree_vi finder; - - finder.t = t; - pair = htab_find (vi_for_tree, &finder); - if (pair == NULL) + void **slot = pointer_map_contains (vi_for_tree, t); + if (slot == NULL) return get_varinfo (create_variable_info_for (t, alias_get_name (t))); - return pair->vi; + return (varinfo_t) *slot; } /* Get a constraint expression from an SSA_VAR_P node. */ @@ -4383,9 +4343,9 @@ find_what_p_points_to (tree p) && SSA_NAME_IS_DEFAULT_DEF (p)) lookup_p = SSA_NAME_VAR (p); - if (lookup_vi_for_tree (lookup_p, &vi)) + vi = lookup_vi_for_tree (lookup_p); + if (vi) { - if (vi->is_artificial_var) return false; @@ -4633,7 +4593,7 @@ init_alias_vars (void) sizeof (struct variable_info), 30); constraints = VEC_alloc (constraint_t, heap, 8); varmap = VEC_alloc (varinfo_t, heap, 8); - vi_for_tree = htab_create (10, tree_vi_hash, tree_vi_eq, free); + vi_for_tree = pointer_map_create (); memset (&stats, 0, sizeof (stats)); @@ -4774,7 +4734,7 @@ delete_points_to_sets (void) fprintf (dump_file, "Points to sets created:%d\n", stats.points_to_sets_created); - htab_delete (vi_for_tree); + pointer_map_destroy (vi_for_tree); bitmap_obstack_release (&pta_obstack); VEC_free (constraint_t, heap, constraints);