+2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * 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 <manu@gcc.gnu.org>
PR 34351
+2008-02-26 Richard Guenther <rguenther@suse.de>
+
+ * decl.c (duplicate_decls): Remove decl from global mapping
+ before ggc_freeing it.
+
2008-02-26 Paolo Carlini <pcarlini@suse.de>
PR c++/35323
/* 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;
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.
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;
}
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;
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);
}
}
/* 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)
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
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
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
{
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))
{
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, " ");
}
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
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);
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)
{
}
if (!elt)
{
- bitmap_set_bit (&done_head, i);
+ bitmap_set_bit (&done_head, DECL_UID (var));
cleared_any = true;
}
}
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);
}
/* 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);
}
}
}
/* 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);
}
}
}
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);
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
}
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;
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);
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))
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
/* 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;
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));
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++)
{
&& (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
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
/* 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;
/* 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;
}
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, " ");
}
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))
}
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
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))
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)
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
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
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
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);
}
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++;
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
&& 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);
}
}
static void
merge_smts_into (tree p, bitmap solution)
{
- unsigned int i;
- bitmap_iterator bi;
tree smt;
bitmap aliases;
tree var = p;
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);
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;
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);
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)
{
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);
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
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,
ggc_free (var->base.ann);
var->base.ann = NULL;
}
- htab_delete (gimple_referenced_vars (cfun));
cfun->gimple_df->referenced_vars = NULL;
fini_ssanames ();
/* 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. */
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;
}
DECL_SOURCE_LOCATION (t) = input_location;
DECL_UID (t) = next_decl_uid++;
+ insert_decl_to_uid_decl_map (t);
break;
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)
{
return t;
}
\f
+/* 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.
print_debug_expr_statistics ();
print_value_expr_statistics ();
print_restrict_base_statistics ();
+ print_decl_for_uid_map_statistics ();
lang_hooks.print_statistics ();
}
\f
#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(())