2008-02-26 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2008 14:05:42 +0000 (14:05 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2008 14:05:42 +0000 (14:05 +0000)
* 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

15 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/tree-dfa.c
gcc/tree-flow-inline.h
gcc/tree-flow.h
gcc/tree-into-ssa.c
gcc/tree-sra.c
gcc/tree-ssa-alias-warnings.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-operands.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c
gcc/tree.c
gcc/tree.h

index 4d11666..efca033 100644 (file)
@@ -1,3 +1,63 @@
+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
index aa4bf07..198390f 100644 (file)
@@ -1,3 +1,8 @@
+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
index 82c55e0..85186c9 100644 (file)
@@ -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;
index 346f6f3..f66a50c 100644 (file)
@@ -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);
 }
 
 
index 1afbd1a..8fcb77f 100644 (file)
@@ -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
index 286c60b..476f02e 100644 (file)
@@ -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))
index c55f736..6a699ff 100644 (file)
@@ -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
index 26f1af4..ba1db90 100644 (file)
@@ -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);
     }
index 05d215c..35117b3 100644 (file)
@@ -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);
        }
     }
 }
index 7ab2f6b..2166a7b 100644 (file)
@@ -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, " ");
        }
index ceb18ba..352dc9e 100644 (file)
@@ -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
index 70a9d32..66f086c 100644 (file)
@@ -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);
index 6c06df0..7b89e22 100644 (file)
@@ -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 ();
index 043968c..97c90ec 100644 (file)
@@ -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;
 }
 \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.
 
@@ -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 ();
 }
 \f
index f98afe9..82723ea 100644 (file)
@@ -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(())