From 203084040858afd222f51667c307734d8375fc81 Mon Sep 17 00:00:00 2001 From: rguenth Date: Tue, 26 Feb 2008 14:05:42 +0000 Subject: 2008-02-26 Richard Guenther * tree-flow.h (uid_decl_map_hash, uid_decl_map_eq): Move ... * tree.h (uid_decl_map_hash, uid_decl_map_eq): ... here. (lookup_decl_from_uid): Declare. (remove_decl_from_map): Likewise. * tree-ssa.c (uid_decl_map_eq, uid_decl_map_hash): Move ... * tree.c (uid_decl_map_eq, uid_decl_map_hash): ... here. (decl_for_uid_map): New global hashtable mapping DECL_UID to the decl tree. (init_ttree): Allocate it. (insert_decl_to_uid_decl_map): New helper function. (make_node_stat): Insert new decls into the map. (copy_node_stat): Likewise. (lookup_decl_from_uid): New function. (remove_decl_from_map): Likewise. (print_decl_for_uid_map_statistics): New helper. (dump_tree_statistics): Call it. cp/ * decl.c (duplicate_decls): Remove decl from global mapping before ggc_freeing it. * tree-flow.h (struct gimple_df): Make referenced_vars a bitmap. (referenced_var_iterator): Adjust. (FOR_EACH_REFERENCED_VAR): Adjust. (FOR_EACH_REFERENCED_VAR_IN_BITMAP): New iterator. (num_referenced_vars): Adjust. * tree-flow-inline.h (gimple_referenced_vars): Adjust. (first_referenced_var): Remove. (end_referenced_vars_p): Likewise. (next_referenced_var): Likewise. (referenced_var_iterator_set): New helper function. * tree-dfa.c (referenced_var_lookup): Adjust. (referenced_var_check_and_insert): Likewise. (remove_referenced_var): Likewise. * tree-ssa.c (verify_flow_insensitive_alias_info): Use FOR_EACH_REFERENCED_VAR_IN_BITMAP. (verify_call_clobbering): Likewise. (verify_memory_partitions): Likewise. (init_tree_ssa): Allocate bitmap instead of hashtable for referenced_vars. (delete_tree_ssa): Adjust. * tree-ssa-alias.c (mark_aliases_call_clobbered): Use FOR_EACH_REFERENCED_VAR_IN_BITMAP. (compute_tag_properties): Likewise. (set_initial_properties): Likewise. (find_partition_for): Likewise. (update_reference_counts): Likewise. (dump_may_aliases_for): Likewise. * tree-ssa-operands.c (add_virtual_operand): Likewise. (add_call_clobber_ops): Likewise. (add_call_read_ops): Likewise. (get_asm_expr_operands): Likewise. * tree-into-ssa.c (dump_decl_set): Likewise. (update_ssa): Likewise. * tree-sra.c (scan_function): Likewise. (decide_instantiations): Likewise. (scalarize_parms): Likewise. * tree-ssa-alias-warnings.c (build_reference_table): Likewise. (dsa_named_for): Likewise. * tree-ssa-structalias.c (update_alias_info): Likewise. (merge_smts_into): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132676 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 60 ++++++++++++++++++++++++++++ gcc/cp/ChangeLog | 5 +++ gcc/cp/decl.c | 1 + gcc/tree-dfa.c | 41 +++++++------------ gcc/tree-flow-inline.h | 37 ++++++----------- gcc/tree-flow.h | 32 ++++++++------- gcc/tree-into-ssa.c | 15 ++++--- gcc/tree-sra.c | 23 +++++------ gcc/tree-ssa-alias-warnings.c | 29 ++++++-------- gcc/tree-ssa-alias.c | 58 +++++++++++---------------- gcc/tree-ssa-operands.c | 53 ++++++++++++------------- gcc/tree-ssa-structalias.c | 27 ++++++------- gcc/tree-ssa.c | 77 +++++++++++------------------------- gcc/tree.c | 92 +++++++++++++++++++++++++++++++++++++++++++ gcc/tree.h | 8 ++++ 15 files changed, 322 insertions(+), 236 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d11666e715..efca0338a40 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,63 @@ +2008-02-26 Richard Guenther + + * tree-flow.h (uid_decl_map_hash, uid_decl_map_eq): Move ... + * tree.h (uid_decl_map_hash, uid_decl_map_eq): ... here. + (lookup_decl_from_uid): Declare. + (remove_decl_from_map): Likewise. + * tree-ssa.c (uid_decl_map_eq, uid_decl_map_hash): Move ... + * tree.c (uid_decl_map_eq, uid_decl_map_hash): ... here. + (decl_for_uid_map): New global hashtable mapping DECL_UID + to the decl tree. + (init_ttree): Allocate it. + (insert_decl_to_uid_decl_map): New helper function. + (make_node_stat): Insert new decls into the map. + (copy_node_stat): Likewise. + (lookup_decl_from_uid): New function. + (remove_decl_from_map): Likewise. + (print_decl_for_uid_map_statistics): New helper. + (dump_tree_statistics): Call it. + + * tree-flow.h (struct gimple_df): Make referenced_vars a bitmap. + (referenced_var_iterator): Adjust. + (FOR_EACH_REFERENCED_VAR): Adjust. + (FOR_EACH_REFERENCED_VAR_IN_BITMAP): New iterator. + (num_referenced_vars): Adjust. + * tree-flow-inline.h (gimple_referenced_vars): Adjust. + (first_referenced_var): Remove. + (end_referenced_vars_p): Likewise. + (next_referenced_var): Likewise. + (referenced_var_iterator_set): New helper function. + * tree-dfa.c (referenced_var_lookup): Adjust. + (referenced_var_check_and_insert): Likewise. + (remove_referenced_var): Likewise. + * tree-ssa.c (verify_flow_insensitive_alias_info): Use + FOR_EACH_REFERENCED_VAR_IN_BITMAP. + (verify_call_clobbering): Likewise. + (verify_memory_partitions): Likewise. + (init_tree_ssa): Allocate bitmap instead of hashtable for + referenced_vars. + (delete_tree_ssa): Adjust. + * tree-ssa-alias.c (mark_aliases_call_clobbered): Use + FOR_EACH_REFERENCED_VAR_IN_BITMAP. + (compute_tag_properties): Likewise. + (set_initial_properties): Likewise. + (find_partition_for): Likewise. + (update_reference_counts): Likewise. + (dump_may_aliases_for): Likewise. + * tree-ssa-operands.c (add_virtual_operand): Likewise. + (add_call_clobber_ops): Likewise. + (add_call_read_ops): Likewise. + (get_asm_expr_operands): Likewise. + * tree-into-ssa.c (dump_decl_set): Likewise. + (update_ssa): Likewise. + * tree-sra.c (scan_function): Likewise. + (decide_instantiations): Likewise. + (scalarize_parms): Likewise. + * tree-ssa-alias-warnings.c (build_reference_table): Likewise. + (dsa_named_for): Likewise. + * tree-ssa-structalias.c (update_alias_info): Likewise. + (merge_smts_into): Likewise. + 2008-02-26 Manuel Lopez-Ibanez PR 34351 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index aa4bf07f4ea..198390fa1a9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-02-26 Richard Guenther + + * decl.c (duplicate_decls): Remove decl from global mapping + before ggc_freeing it. + 2008-02-26 Paolo Carlini PR c++/35323 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 82c55e0ec63..85186c97c24 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2154,6 +2154,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* The NEWDECL will no longer be needed. Because every out-of-class declaration of a member results in a call to duplicate_decls, freeing these nodes represents in a significant savings. */ + remove_decl_from_map (newdecl); ggc_free (newdecl); return olddecl; diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 346f6f3803c..f66a50c5a65 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -641,12 +641,16 @@ find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) tree referenced_var_lookup (unsigned int uid) { - tree h; - struct tree_decl_minimal in; - in.uid = uid; - h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid); - gcc_assert (h || uid == 0); - return h; + tree var; + + gcc_assert (bitmap_bit_p (gimple_referenced_vars (cfun), uid)); + + /* For now also assert that the variable is really referenced. + Otherwise callers need to deal with the result from this function + being NULL. */ + var = lookup_decl_from_uid (uid); + gcc_assert (var); + return var; } /* Check if TO is in the referenced_vars hash table and insert it if not. @@ -655,23 +659,13 @@ referenced_var_lookup (unsigned int uid) bool referenced_var_check_and_insert (tree to) { - tree h, *loc; - struct tree_decl_minimal in; unsigned int uid = DECL_UID (to); - in.uid = uid; - h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid); - if (h) - { - /* DECL_UID has already been entered in the table. Verify that it is - the same entry as TO. See PR 27793. */ - gcc_assert (h == to); - return false; - } + if (bitmap_bit_p (gimple_referenced_vars (cfun), uid)) + return false; + + bitmap_set_bit (gimple_referenced_vars (cfun), uid); - loc = (tree *) htab_find_slot_with_hash (gimple_referenced_vars (cfun), - &in, uid, INSERT); - *loc = to; return true; } @@ -761,8 +755,6 @@ void remove_referenced_var (tree var) { var_ann_t v_ann; - struct tree_decl_minimal in; - void **loc; unsigned int uid = DECL_UID (var); subvar_t sv; @@ -782,10 +774,7 @@ remove_referenced_var (tree var) ggc_free (v_ann); var->base.ann = NULL; gcc_assert (DECL_P (var)); - in.uid = uid; - loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun), &in, uid, - NO_INSERT); - htab_clear_slot (gimple_referenced_vars (cfun), loc); + bitmap_clear_bit (gimple_referenced_vars (cfun), uid); } diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 1afbd1a8fc7..8fcb77fd1ab 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -66,7 +66,7 @@ gimple_call_clobbered_vars (const struct function *fun) } /* Array of all variables referenced in the function. */ -static inline htab_t +static inline bitmap gimple_referenced_vars (const struct function *fun) { if (!fun->gimple_df) @@ -145,34 +145,23 @@ next_htab_element (htab_iterator *hti) return NULL; } -/* Initialize ITER to point to the first referenced variable in the - referenced_vars hashtable, and return that variable. */ - -static inline tree -first_referenced_var (referenced_var_iterator *iter) -{ - return (tree) first_htab_element (&iter->hti, - gimple_referenced_vars (cfun)); -} - -/* Return true if we have hit the end of the referenced variables ITER is - iterating through. */ +/* Helper for FOR_EACH_REFERENCED_VAR. Needed unless iterator + bodies deal with NULL elements. */ static inline bool -end_referenced_vars_p (const referenced_var_iterator *iter) +referenced_var_iterator_set (referenced_var_iterator *ri, tree *var) { - return end_htab_p (&iter->hti); + while (1) + { + if (!bmp_iter_set (&ri->bi, &ri->i)) + return false; + *var = lookup_decl_from_uid (ri->i); + if (*var) + return true; + bmp_iter_next (&ri->bi, &ri->i); + } } -/* Make ITER point to the next referenced_var in the referenced_var hashtable, - and return that variable. */ - -static inline tree -next_referenced_var (referenced_var_iterator *iter) -{ - return (tree) next_htab_element (&iter->hti); -} - /* Fill up VEC with the variables in the referenced vars hashtable. */ static inline void diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 286c60bce20..476f02e8a2e 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -138,8 +138,8 @@ struct mem_ref_stats_d GTY(()) fields should have gimple_set accessor. */ struct gimple_df GTY(()) { - /* Array of all variables referenced in the function. */ - htab_t GTY((param_is (union tree_node))) referenced_vars; + /* Bitmap of all variables referenced in the function. */ + bitmap referenced_vars; /* A list of all the noreturn calls passed to modify_stmt. cleanup_control_flow uses it to detect cases where a mid-block @@ -569,25 +569,29 @@ struct int_tree_map GTY(()) extern unsigned int int_tree_map_hash (const void *); extern int int_tree_map_eq (const void *, const void *); -extern unsigned int uid_decl_map_hash (const void *); -extern int uid_decl_map_eq (const void *, const void *); - typedef struct { - htab_iterator hti; + bitmap_iterator bi; + unsigned int i; } referenced_var_iterator; - /* This macro loops over all the referenced vars, one at a time, putting the - current var in VAR. Note: You are not allowed to add referenced variables - to the hashtable while using this macro. Doing so may cause it to behave - erratically. */ + current var in VAR. Note: It is undefined whether referenced variables + you add or remove during the iteration show up or not. */ #define FOR_EACH_REFERENCED_VAR(VAR, ITER) \ - for ((VAR) = first_referenced_var (&(ITER)); \ - !end_referenced_vars_p (&(ITER)); \ - (VAR) = next_referenced_var (&(ITER))) + for (bmp_iter_set_init (&(ITER).bi, gimple_referenced_vars (cfun), 0, &(ITER).i); \ + referenced_var_iterator_set (&(ITER), &(VAR)); \ + bmp_iter_next (&(ITER).bi, &(ITER).i)) + +/* Iterate over all variables whose UID is set in the bitmap BM, putting the + current var in VAR. Note: It is undefined whether variables you add or + remove during the iteration show up or not. */ +#define FOR_EACH_REFERENCED_VAR_IN_BITMAP(BM, VAR, ITER) \ + for (bmp_iter_set_init (&(ITER).bi, (BM), 0, &(ITER).i); \ + referenced_var_iterator_set (&(ITER), &(VAR)); \ + bmp_iter_next (&(ITER).bi, &(ITER).i)) typedef struct { @@ -609,7 +613,7 @@ typedef struct extern tree referenced_var_lookup (unsigned int); extern bool referenced_var_check_and_insert (tree); -#define num_referenced_vars htab_elements (gimple_referenced_vars (cfun)) +#define num_referenced_vars bitmap_count_bits (gimple_referenced_vars (cfun)) #define referenced_var(i) referenced_var_lookup (i) #define num_ssa_names (VEC_length (tree, cfun->gimple_df->ssa_names)) diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index c55f7363697..6a699ff4b6d 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1463,14 +1463,14 @@ dump_decl_set (FILE *file, bitmap set) { if (set) { - bitmap_iterator bi; - unsigned i; + referenced_var_iterator ri; + tree var; fprintf (file, "{ "); - EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (set, var, ri) { - print_generic_expr (file, referenced_var (i), 0); + print_generic_expr (file, var, 0); fprintf (file, " "); } @@ -3201,12 +3201,11 @@ update_ssa (unsigned update_flags) memory symbols into the set MEM_SYMS_TO_RENAME. */ if (!bitmap_empty_p (syms_to_rename)) { - unsigned i; - bitmap_iterator bi; + referenced_var_iterator ri; + tree sym; - EXECUTE_IF_SET_IN_BITMAP (syms_to_rename, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (syms_to_rename, sym, ri) { - tree sym = referenced_var (i); if (is_gimple_reg (sym)) bitmap_set_bit (regs_to_rename, i); else diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 26f1af4196a..ba1db90a996 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1162,18 +1162,17 @@ scan_function (void) static const struct sra_walk_fns fns = { scan_use, scan_copy, scan_init, scan_ldst, true }; - bitmap_iterator bi; sra_walk_function (&fns); if (dump_file && (dump_flags & TDF_DETAILS)) { - unsigned i; + referenced_var_iterator ri; + tree var; fputs ("\nScan results:\n", dump_file); - EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (sra_candidates, var, ri) { - tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); if (elt) scan_dump (elt); @@ -1950,19 +1949,18 @@ decide_block_copy (struct sra_elt *elt) static void decide_instantiations (void) { - unsigned int i; bool cleared_any; bitmap_head done_head; - bitmap_iterator bi; + referenced_var_iterator ri; + tree var; /* We cannot clear bits from a bitmap we're iterating over, so save up all the bits to clear until the end. */ bitmap_initialize (&done_head, &bitmap_default_obstack); cleared_any = false; - EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (sra_candidates, var, ri) { - tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); if (elt) { @@ -1972,7 +1970,7 @@ decide_instantiations (void) } if (!elt) { - bitmap_set_bit (&done_head, i); + bitmap_set_bit (&done_head, DECL_UID (var)); cleared_any = true; } } @@ -3532,12 +3530,11 @@ static void scalarize_parms (void) { tree list = NULL; - unsigned i; - bitmap_iterator bi; + referenced_var_iterator ri; + tree var; - EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (needs_copy_in, var, ri) { - tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); generate_copy_inout (elt, true, var, &list); } diff --git a/gcc/tree-ssa-alias-warnings.c b/gcc/tree-ssa-alias-warnings.c index 05d215c0f28..35117b35b20 100644 --- a/gcc/tree-ssa-alias-warnings.c +++ b/gcc/tree-ssa-alias-warnings.c @@ -452,14 +452,11 @@ build_reference_table (void) /* Add all aliased names to the interesting reference list. */ if (pi->pt_vars) { - unsigned ix; - bitmap_iterator bi; - - EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi) - { - tree alias = referenced_var (ix); - add_key (ref_table->objs, alias, references_pool); - } + referenced_var_iterator ri; + tree alias; + + FOR_EACH_REFERENCED_VAR_IN_BITMAP (pi->pt_vars, alias, ri) + add_key (ref_table->objs, alias, references_pool); } } } @@ -914,17 +911,13 @@ dsa_named_for (tree ptr) /* For all the variables it could be aliased to. */ if (pi->pt_vars) { - unsigned ix; - bitmap_iterator bi; - - EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi) - { - tree alias = referenced_var (ix); + referenced_var_iterator ri; + tree alias; - if (nonstandard_alias_p (ptr, alias, false)) - strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr), - ptr, true, alias, false, true); - } + FOR_EACH_REFERENCED_VAR_IN_BITMAP (pi->pt_vars, alias, ri) + if (nonstandard_alias_p (ptr, alias, false)) + strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr), + ptr, true, alias, false, true); } } } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 7ab2f6b5473..2166a7bb17d 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -390,8 +390,7 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, bitmap on_worklist, bitmap queued) { bitmap aliases; - bitmap_iterator bi; - unsigned int i; + referenced_var_iterator ri; tree entry; var_ann_t ta = var_ann (tag); @@ -401,9 +400,8 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, if (!aliases) return; - EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (aliases, entry, ri) { - entry = referenced_var (i); /* If you clobber one part of a structure, you clobber the entire thing. While this does not make the world a particularly nice place, it is necessary @@ -420,9 +418,9 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, } if (!bitmap_empty_p (queued)) { - EXECUTE_IF_SET_IN_BITMAP (queued, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (queued, entry, ri) { - subvar_t svars = get_subvars_for_var (referenced_var (i)); + subvar_t svars = get_subvars_for_var (entry); unsigned int i; tree subvar; @@ -484,8 +482,7 @@ compute_tag_properties (void) for (k = 0; VEC_iterate (tree, taglist, k, tag); k++) { bitmap ma; - bitmap_iterator bi; - unsigned int i; + referenced_var_iterator ri; tree entry; bool tagcc = is_call_clobbered (tag); bool tagglobal = MTAG_GLOBAL (tag); @@ -497,9 +494,8 @@ compute_tag_properties (void) if (!ma) continue; - EXECUTE_IF_SET_IN_BITMAP (ma, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (ma, entry, ri) { - entry = referenced_var (i); /* Call clobbered entries cause the tag to be marked call clobbered. */ if (!tagcc && is_call_clobbered (entry)) @@ -581,12 +577,10 @@ set_initial_properties (struct alias_info *ai) if (pi->pt_vars) { - bitmap_iterator bi; - unsigned int j; - EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi) + referenced_var_iterator ri; + tree alias; + FOR_EACH_REFERENCED_VAR_IN_BITMAP (pi->pt_vars, alias, ri) { - tree alias = referenced_var (j); - /* If you clobber one part of a structure, you clobber the entire thing. While this does not make the world a particularly nice place, it is necessary @@ -600,9 +594,9 @@ set_initial_properties (struct alias_info *ai) /* Process variables we need to clobber all parts of. */ if (!bitmap_empty_p (queued)) { - EXECUTE_IF_SET_IN_BITMAP (queued, 0, j, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (queued, alias, ri) { - subvar_t svars = get_subvars_for_var (referenced_var (j)); + subvar_t svars = get_subvars_for_var (alias); unsigned int i; tree subvar; @@ -1188,13 +1182,11 @@ find_partition_for (mem_sym_stats_t mp_p) static void rewrite_alias_set_for (tree tag, bitmap new_aliases) { - bitmap_iterator bi; - unsigned i; + referenced_var_iterator ri; tree mpt, sym; - EXECUTE_IF_SET_IN_BITMAP (MTAG_ALIASES (tag), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (MTAG_ALIASES (tag), sym, ri) { - sym = referenced_var (i); mpt = memory_partition (sym); if (mpt) bitmap_set_bit (new_aliases, DECL_UID (mpt)); @@ -1305,9 +1297,10 @@ estimate_vop_reduction (struct mem_ref_stats_d *mem_ref_stats, static void update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) { - unsigned i; - bitmap_iterator bi; + referenced_var_iterator ri; mem_sym_stats_t sym_stats; + unsigned int i; + tree sym; for (i = 1; i < num_ssa_names; i++) { @@ -1320,9 +1313,7 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL && pi->is_dereferenced) { - unsigned j; - bitmap_iterator bj; - tree tag; + tree tag, alias; mem_sym_stats_t ptr_stats, tag_stats; /* If PTR has flow-sensitive points-to information, use @@ -1348,9 +1339,8 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) TAG's alias set, add as many indirect references to ALIAS as direct references there are for TAG. */ if (MTAG_ALIASES (tag)) - EXECUTE_IF_SET_IN_BITMAP (MTAG_ALIASES (tag), 0, j, bj) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (MTAG_ALIASES (tag), alias, ri) { - tree alias = referenced_var (j); sym_stats = get_mem_sym_stats_for (alias); /* All the direct references to TAG are indirect references @@ -1370,9 +1360,8 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) /* Call-clobbered symbols are indirectly written at every call/asm site. */ - EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_call_clobbered_vars (cfun), sym, ri) { - tree sym = referenced_var (i); sym_stats = get_mem_sym_stats_for (sym); sym_stats->num_indirect_writes += mem_ref_stats->num_call_sites + mem_ref_stats->num_asm_sites; @@ -1381,9 +1370,8 @@ update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) /* Addressable symbols are indirectly written at some ASM sites. Since only ASM sites that clobber memory actually affect addressable symbols, this is an over-estimation. */ - EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_addressable_vars (cfun), sym, ri) { - tree sym = referenced_var (i); sym_stats = get_mem_sym_stats_for (sym); sym_stats->num_indirect_writes += mem_ref_stats->num_asm_sites; } @@ -3482,14 +3470,12 @@ dump_may_aliases_for (FILE *file, tree var) aliases = MTAG_ALIASES (var); if (aliases) { - bitmap_iterator bi; - unsigned int i; + referenced_var_iterator ri; tree al; fprintf (file, "{ "); - EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (aliases, al, ri) { - al = referenced_var (i); print_generic_expr (file, al, dump_flags); fprintf (file, " "); } diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index ceb18ba55a6..352dc9e67ce 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1469,7 +1469,9 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags, if (MTAG_P (var)) aliases = MTAG_ALIASES (var); - if (aliases == NULL) + if (aliases == NULL + /* ??? We should not have created an empty aliases bitmap. */ + || bitmap_empty_p (aliases)) { if (!gimple_aliases_computed_p (cfun) && (flags & opf_def)) @@ -1483,18 +1485,16 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags, } else { - bitmap_iterator bi; - unsigned int i; + referenced_var_iterator ri; bool none_added = true; + tree al; /* The variable is aliased. Add its aliases to the virtual operands. */ gcc_assert (!bitmap_empty_p (aliases)); - EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (aliases, al, ri) { - tree al = referenced_var (i); - /* For SFTs we have to consider all subvariables of the parent var if it is a potential points-to location. */ if (TREE_CODE (al) == STRUCT_FIELD_TAG @@ -1779,10 +1779,10 @@ get_tmr_operands (tree stmt, tree expr, int flags) static void add_call_clobber_ops (tree stmt, tree callee) { - unsigned u; - bitmap_iterator bi; + referenced_var_iterator ri; stmt_ann_t s_ann = stmt_ann (stmt); bitmap not_read_b, not_written_b; + tree var; /* If we created .GLOBAL_VAR earlier, just use it. */ if (gimple_global_var (cfun)) @@ -1796,17 +1796,18 @@ add_call_clobber_ops (tree stmt, tree callee) set for each static if the call being processed does not read or write that variable. */ not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; - not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL; + not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL; /* Add a VDEF operand for every call clobbered variable. */ - EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_call_clobbered_vars (cfun), var, ri) { - tree var = referenced_var_lookup (u); - unsigned int escape_mask = var_ann (var)->escape_mask; + unsigned int escape_mask; tree real_var = var; bool not_read; bool not_written; - + + escape_mask = var_ann (var)->escape_mask; + /* Not read and not written are computed on regular vars, not subvars, so look at the parent var if this is an SFT. */ if (TREE_CODE (var) == STRUCT_FIELD_TAG) @@ -1863,10 +1864,10 @@ add_call_clobber_ops (tree stmt, tree callee) static void add_call_read_ops (tree stmt, tree callee) { - unsigned u; - bitmap_iterator bi; + referenced_var_iterator ri; stmt_ann_t s_ann = stmt_ann (stmt); bitmap not_read_b; + tree var; /* if the function is not pure, it may reference memory. Add a VUSE for .GLOBAL_VAR if it has been created. See add_referenced_var @@ -1881,12 +1882,11 @@ add_call_read_ops (tree stmt, tree callee) not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; /* Add a VUSE for each call-clobbered variable. */ - EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_call_clobbered_vars (cfun), var, ri) { - tree var = referenced_var (u); tree real_var = var; bool not_read; - + clobber_stats.readonly_clobbers++; /* Not read and not written are computed on regular vars, not @@ -2008,21 +2008,18 @@ get_asm_expr_operands (tree stmt) for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link)) if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0) { - unsigned i; - bitmap_iterator bi; + referenced_var_iterator ri; + tree var; s_ann->references_memory = true; - EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi) - { - tree var = referenced_var (i); - add_stmt_operand (&var, s_ann, opf_def | opf_implicit); - } + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_call_clobbered_vars (cfun), + var, ri) + add_stmt_operand (&var, s_ann, opf_def | opf_implicit); - EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_addressable_vars (cfun), + var, ri) { - tree var = referenced_var (i); - /* Subvars are explicitly represented in this list, so we don't need the original to be added to the clobber ops, but the original *will* be in this list because we keep diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 70a9d3212c6..66f086c0c15 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3313,12 +3313,11 @@ update_alias_info (tree stmt, struct alias_info *ai) call-clobbered. */ if (stmt_escape_type != NO_ESCAPE) { - bitmap_iterator bi; - unsigned i; + referenced_var_iterator ri; + tree rvar; - EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (addr_taken, rvar, ri) { - tree rvar = referenced_var (i); if (!unmodifiable_var_p (rvar)) mark_call_clobbered (rvar, stmt_escape_type); } @@ -3476,8 +3475,8 @@ update_alias_info (tree stmt, struct alias_info *ai) memory reference stats for all memory symbols referenced by STMT. */ if (stmt_references_memory_p (stmt)) { - unsigned i; - bitmap_iterator bi; + referenced_var_iterator ri; + tree sym; mem_ref_stats->num_mem_stmts++; @@ -3504,9 +3503,8 @@ update_alias_info (tree stmt, struct alias_info *ai) memory symbols in its argument list, but these cases do not occur so frequently as to constitute a serious problem. */ if (STORED_SYMS (stmt)) - EXECUTE_IF_SET_IN_BITMAP (STORED_SYMS (stmt), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (STORED_SYMS (stmt), sym, ri) { - tree sym = referenced_var (i); pointer_set_insert (ai->written_vars, sym); if (!stmt_dereferences_ptr_p && stmt_escape_type != ESCAPE_TO_CALL @@ -3520,8 +3518,8 @@ update_alias_info (tree stmt, struct alias_info *ai) && stmt_escape_type != ESCAPE_TO_CALL && stmt_escape_type != ESCAPE_TO_PURE_CONST && stmt_escape_type != ESCAPE_TO_ASM) - EXECUTE_IF_SET_IN_BITMAP (LOADED_SYMS (stmt), 0, i, bi) - update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 1, 0); + FOR_EACH_REFERENCED_VAR_IN_BITMAP (LOADED_SYMS (stmt), sym, ri) + update_mem_sym_stats_from_stmt (sym, stmt, 1, 0); } } @@ -4881,8 +4879,6 @@ set_used_smts (void) static void merge_smts_into (tree p, bitmap solution) { - unsigned int i; - bitmap_iterator bi; tree smt; bitmap aliases; tree var = p; @@ -4894,18 +4890,19 @@ merge_smts_into (tree p, bitmap solution) if (smt) { alias_set_type smtset = get_alias_set (TREE_TYPE (smt)); + referenced_var_iterator ri; + tree newsmt; /* Need to set the SMT subsets first before this will work properly. */ bitmap_set_bit (solution, DECL_UID (smt)); - EXECUTE_IF_SET_IN_BITMAP (used_smts, 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (used_smts, newsmt, ri) { - tree newsmt = referenced_var (i); tree newsmttype = TREE_TYPE (newsmt); if (alias_set_subset_of (get_alias_set (newsmttype), smtset)) - bitmap_set_bit (solution, i); + bitmap_set_bit (solution, DECL_UID (newsmt)); } aliases = MTAG_ALIASES (smt); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 6c06df094b1..7b89e22ed6e 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -378,28 +378,23 @@ verify_flow_insensitive_alias_info (void) FOR_EACH_REFERENCED_VAR (var, rvi) { - unsigned int j; bitmap aliases; tree alias; - bitmap_iterator bi; + referenced_var_iterator ri; if (!MTAG_P (var) || !MTAG_ALIASES (var)) continue; aliases = MTAG_ALIASES (var); - EXECUTE_IF_SET_IN_BITMAP (aliases, 0, j, bi) - { - alias = referenced_var (j); - - if (TREE_CODE (alias) != MEMORY_PARTITION_TAG - && !may_be_aliased (alias)) - { - error ("non-addressable variable inside an alias set"); - debug_variable (alias); - goto err; - } - } + FOR_EACH_REFERENCED_VAR_IN_BITMAP (aliases, alias, ri) + if (TREE_CODE (alias) != MEMORY_PARTITION_TAG + && !may_be_aliased (alias)) + { + error ("non-addressable variable inside an alias set"); + debug_variable (alias); + goto err; + } } return; @@ -486,20 +481,17 @@ err: static void verify_call_clobbering (void) { - unsigned int i; - bitmap_iterator bi; - tree var; referenced_var_iterator rvi; + tree var; /* At all times, the result of the call_clobbered flag should match the result of the call_clobbered_vars bitmap. Verify both that everything in call_clobbered_vars is marked call_clobbered, and that everything marked call_clobbered is in call_clobbered_vars. */ - EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi) + FOR_EACH_REFERENCED_VAR_IN_BITMAP (gimple_call_clobbered_vars (cfun), + var, rvi) { - var = referenced_var (i); - if (memory_partition (var)) var = memory_partition (var); @@ -550,8 +542,8 @@ verify_memory_partitions (void) for (i = 0; VEC_iterate (tree, mpt_table, i, mpt); i++) { - unsigned j; - bitmap_iterator bj; + referenced_var_iterator ri; + tree var; if (MPT_SYMBOLS (mpt) == NULL) { @@ -560,17 +552,14 @@ verify_memory_partitions (void) goto err; } - EXECUTE_IF_SET_IN_BITMAP (MPT_SYMBOLS (mpt), 0, j, bj) - { - tree var = referenced_var (j); - if (pointer_set_insert (partitioned_syms, var)) - { - error ("Partitioned symbols should belong to exactly one " - "partition"); - debug_variable (var); - goto err; - } - } + FOR_EACH_REFERENCED_VAR_IN_BITMAP (MPT_SYMBOLS (mpt), var, ri) + if (pointer_set_insert (partitioned_syms, var)) + { + error ("Partitioned symbols should belong to exactly one " + "partition"); + debug_variable (var); + goto err; + } } pointer_set_destroy (partitioned_syms); @@ -774,24 +763,6 @@ int_tree_map_hash (const void *item) return ((const struct int_tree_map *)item)->uid; } -/* Return true if the DECL_UID in both trees are equal. */ - -int -uid_decl_map_eq (const void *va, const void *vb) -{ - const_tree a = (const_tree) va; - const_tree b = (const_tree) vb; - return (a->decl_minimal.uid == b->decl_minimal.uid); -} - -/* Hash a tree in a uid_decl_map. */ - -unsigned int -uid_decl_map_hash (const void *item) -{ - return ((const_tree)item)->decl_minimal.uid; -} - /* Return true if the uid in both int tree maps are equal. */ static int @@ -835,8 +806,7 @@ void init_tree_ssa (void) { cfun->gimple_df = GGC_CNEW (struct gimple_df); - cfun->gimple_df->referenced_vars = htab_create_ggc (20, uid_decl_map_hash, - uid_decl_map_eq, NULL); + cfun->gimple_df->referenced_vars = BITMAP_GGC_ALLOC (); cfun->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash, uid_ssaname_map_eq, NULL); cfun->gimple_df->var_anns = htab_create_ggc (20, var_ann_hash, @@ -893,7 +863,6 @@ delete_tree_ssa (void) ggc_free (var->base.ann); var->base.ann = NULL; } - htab_delete (gimple_referenced_vars (cfun)); cfun->gimple_df->referenced_vars = NULL; fini_ssanames (); diff --git a/gcc/tree.c b/gcc/tree.c index 043968cb95f..97c90ecf968 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -110,6 +110,12 @@ static GTY(()) int next_decl_uid; /* Unique id for next type created. */ static GTY(()) int next_type_uid = 1; +/* Mapping from unique DECL_UID to the decl tree node. */ +static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) + htab_t decl_for_uid_map; + +static void insert_decl_to_uid_decl_map (tree); + /* Since we cannot rehash a type after it is in the table, we have to keep the hash code. */ @@ -231,6 +237,9 @@ init_ttree (void) int_cst_node = make_node (INTEGER_CST); + decl_for_uid_map = htab_create_ggc (4093, uid_decl_map_hash, + uid_decl_map_eq, NULL); + tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON] = 1; tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_NON_COMMON] = 1; tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON] = 1; @@ -601,6 +610,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) } DECL_SOURCE_LOCATION (t) = input_location; DECL_UID (t) = next_decl_uid++; + insert_decl_to_uid_decl_map (t); break; @@ -704,6 +714,7 @@ copy_node_stat (tree node MEM_STAT_DECL) SET_DECL_RESTRICT_BASE (t, DECL_GET_RESTRICT_BASE (node)); DECL_BASED_ON_RESTRICT_P (t) = 1; } + insert_decl_to_uid_decl_map (t); } else if (TREE_CODE_CLASS (code) == tcc_type) { @@ -3325,6 +3336,86 @@ build_nt_call_list (tree fn, tree arglist) return t; } +/* Return true if the DECL_UID in both trees are equal. */ + +int +uid_decl_map_eq (const void *va, const void *vb) +{ + const_tree a = (const_tree) va; + const_tree b = (const_tree) vb; + return (a->decl_minimal.uid == b->decl_minimal.uid); +} + +/* Hash a tree in a uid_decl_map. */ + +unsigned int +uid_decl_map_hash (const void *item) +{ + return ((const_tree)item)->decl_minimal.uid; +} + +/* Insert the declaration NODE into the map mapping its unique uid + back to the tree. */ + +static void +insert_decl_to_uid_decl_map (tree node) +{ + void **slot; + struct tree_decl_minimal key; + + key.uid = DECL_UID (node); + slot = htab_find_slot_with_hash (decl_for_uid_map, + &key, DECL_UID (node), INSERT); + + /* We should never try to re-insert a decl with the same uid. + ??? The C++ frontend breaks this invariant. Hopefully in a + non-fatal way, so just overwrite the slot in this case. */ +#if 0 + gcc_assert (!*slot); +#endif + + *(tree *)slot = node; +} + +/* Lookup the declaration tree from its unique DECL_UID UID. Returns + the tree node with DECL_UID UID or NULL, if this node was collected. */ + +tree +lookup_decl_from_uid (int uid) +{ + struct tree_decl_minimal key; + + key.uid = uid; + return (tree) htab_find_with_hash (decl_for_uid_map, &key, uid); +} + +/* Remove the declaration tree DECL from the global UID to decl map. + This needs to be called if you ggc_free a decl tree, otherwise + garbage collection will take care of it. */ + +void +remove_decl_from_map (tree decl) +{ + struct tree_decl_minimal key; + + key.uid = DECL_UID (decl); +#if ENABLE_CHECKING + gcc_assert (decl == htab_find_with_hash (decl_for_uid_map, &key, key.uid)); +#endif + htab_remove_elt_with_hash (decl_for_uid_map, &key, key.uid); +} + +/* Print out the statistics for the decl_for_uid_map hash table. */ + +static void +print_decl_for_uid_map_statistics (void) +{ + fprintf (stderr, "DECL_FOR_UID_MAP hash: size %ld, %ld elements, %f collisions\n", + (long) htab_size (decl_for_uid_map), + (long) htab_elements (decl_for_uid_map), + htab_collisions (decl_for_uid_map)); +} + /* Create a DECL_... node of code CODE, name NAME and data type TYPE. We do NOT enter this node in any sort of symbol table. @@ -6654,6 +6745,7 @@ dump_tree_statistics (void) print_debug_expr_statistics (); print_value_expr_statistics (); print_restrict_base_statistics (); + print_decl_for_uid_map_statistics (); lang_hooks.print_statistics (); } diff --git a/gcc/tree.h b/gcc/tree.h index f98afe9be80..82723ea1bab 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5233,6 +5233,14 @@ struct tree_int_map GTY(()) #define tree_int_map_hash tree_map_base_hash #define tree_int_map_marked_p tree_map_base_marked_p +/* Map from a DECL_UID to the decl tree. */ + +extern unsigned int uid_decl_map_hash (const void *); +extern int uid_decl_map_eq (const void *, const void *); +extern tree lookup_decl_from_uid (int); +extern void remove_decl_from_map (tree); + + /* Map from a tree to initialization/finalization priorities. */ struct tree_priority_map GTY(()) -- cgit v1.2.1