From: Trevor Saunders <tsaund...@mozilla.com>

Hi,

The only user of this is splay_tree.  We only have a couple splay trees in ggc
memory, and it wasn't clear to me any of them were tree based instead of hash
based for performance reasons, so I chose to just convert them to hash_map
rather than writing a templated splay tree.

bootstrapped + regtested x86_64-unknown-linux-gnu, ok?

trev

gcc/

        * hash-map.h (hash_map::iterator): New class.
        (hash_map::begin): New method.
        (hash_map::end): Likewise.
        * alias.c, config/alpha/alpha.c, dwarf2asm.c, omp-low.c, tree.h:
        replace splay_tree with hash_map.


diff --git a/gcc/alias.c b/gcc/alias.c
index aa6ae41..fe27ce8 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "cselib.h"
 #include "splay-tree.h"
+#include "hash-map.h"
 #include "langhooks.h"
 #include "timevar.h"
 #include "dumpfile.h"
@@ -139,6 +140,32 @@ along with GCC; see the file COPYING3.  If not see
    However, this is no actual entry for alias set zero.  It is an
    error to attempt to explicitly construct a subset of zero.  */
 
+struct alias_set_traits : default_hashmap_traits
+{
+  template<typename T>
+  static bool
+  is_empty (T &e)
+  {
+    return e.m_key == INT_MIN;
+  }
+
+  template<typename  T>
+  static bool
+  is_deleted (T &e)
+  {
+    return e.m_key == (INT_MIN + 1);
+  }
+
+  template<typename T> static void mark_empty (T &e) { e.m_key = INT_MIN; }
+
+  template<typename T>
+  static void
+  mark_deleted (T &e)
+  {
+    e.m_key = INT_MIN + 1;
+  }
+};
+
 struct GTY(()) alias_set_entry_d {
   /* The alias set number, as stored in MEM_ALIAS_SET.  */
   alias_set_type alias_set;
@@ -154,7 +181,7 @@ struct GTY(()) alias_set_entry_d {
 
      continuing our example above, the children here will be all of
      `int', `double', `float', and `struct S'.  */
-  splay_tree GTY((param1_is (int), param2_is (int))) children;
+  hash_map<int, int, alias_set_traits> *children;
 };
 typedef struct alias_set_entry_d *alias_set_entry;
 
@@ -165,7 +192,6 @@ static int base_alias_check (rtx, rtx, rtx, rtx, 
machine_mode,
                             machine_mode);
 static rtx find_base_value (rtx);
 static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx);
-static int insert_subset_children (splay_tree_node, void*);
 static alias_set_entry get_alias_set_entry (alias_set_type);
 static tree decl_for_component_ref (tree);
 static int write_dependence_p (const_rtx,
@@ -405,17 +431,6 @@ mems_in_disjoint_alias_sets_p (const_rtx mem1, const_rtx 
mem2)
   return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2));
 }
 
-/* Insert the NODE into the splay tree given by DATA.  Used by
-   record_alias_subset via splay_tree_foreach.  */
-
-static int
-insert_subset_children (splay_tree_node node, void *data)
-{
-  splay_tree_insert ((splay_tree) data, node->key, node->value);
-
-  return 0;
-}
-
 /* Return true if the first alias set is a subset of the second.  */
 
 bool
@@ -431,8 +446,7 @@ alias_set_subset_of (alias_set_type set1, alias_set_type 
set2)
   ase = get_alias_set_entry (set2);
   if (ase != 0
       && (ase->has_zero_child
-         || splay_tree_lookup (ase->children,
-                               (splay_tree_key) set1)))
+         || ase->children->get (set1)))
     return true;
   return false;
 }
@@ -452,16 +466,14 @@ alias_sets_conflict_p (alias_set_type set1, 
alias_set_type set2)
   ase = get_alias_set_entry (set1);
   if (ase != 0
       && (ase->has_zero_child
-         || splay_tree_lookup (ase->children,
-                               (splay_tree_key) set2)))
+         || ase->children->get (set2)))
     return 1;
 
   /* Now do the same, but with the alias sets reversed.  */
   ase = get_alias_set_entry (set2);
   if (ase != 0
       && (ase->has_zero_child
-         || splay_tree_lookup (ase->children,
-                               (splay_tree_key) set1)))
+         || ase->children->get (set1)))
     return 1;
 
   /* The two alias sets are distinct and neither one is the
@@ -956,9 +968,7 @@ record_alias_subset (alias_set_type superset, 
alias_set_type subset)
       superset_entry = ggc_cleared_alloc<alias_set_entry_d> ();
       superset_entry->alias_set = superset;
       superset_entry->children
-       = splay_tree_new_ggc (splay_tree_compare_ints,
-                             ggc_alloc_splay_tree_scalar_scalar_splay_tree_s,
-                             
ggc_alloc_splay_tree_scalar_scalar_splay_tree_node_s);
+       = hash_map<int, int, alias_set_traits>::create_ggc (64);
       superset_entry->has_zero_child = 0;
       (*alias_sets)[superset] = superset_entry;
     }
@@ -975,13 +985,14 @@ record_alias_subset (alias_set_type superset, 
alias_set_type subset)
          if (subset_entry->has_zero_child)
            superset_entry->has_zero_child = 1;
 
-         splay_tree_foreach (subset_entry->children, insert_subset_children,
-                             superset_entry->children);
+         hash_map<int, int, alias_set_traits>::iterator iter
+           = subset_entry->children->begin ();
+         for (; iter != subset_entry->children->end (); ++iter)
+           superset_entry->children->put ((*iter).first, (*iter).second);
        }
 
       /* Enter the SUBSET itself as a child of the SUPERSET.  */
-      splay_tree_insert (superset_entry->children,
-                        (splay_tree_key) subset, 0);
+      superset_entry->children->put (subset, 0);
     }
 }
 
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 05db3dc..33ff717 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "debug.h"
 #include "langhooks.h"
 #include "splay-tree.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "predict.h"
 #include "dominance.h"
@@ -4860,6 +4861,14 @@ alpha_multipass_dfa_lookahead (void)
 
 struct GTY(()) alpha_links;
 
+struct string_traits : default_hashmap_traits
+{
+  static bool equal_keys (const char *const &a, const char *const &b)
+  {
+    return strcmp (a, b) == 0;
+  }
+};
+
 struct GTY(()) machine_function
 {
   /* For flag_reorder_blocks_and_partition.  */
@@ -4869,8 +4878,7 @@ struct GTY(()) machine_function
   bool uses_condition_handler;
 
   /* Linkage entries.  */
-  splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
-    links;
+  hash_map<const char *, alpha_links *, string_traits> *links;
 };
 
 /* How to allocate a 'struct machine_function'.  */
@@ -9642,18 +9650,14 @@ alpha_use_linkage (rtx func, bool lflag, bool rflag)
 
   if (cfun->machine->links)
     {
-      splay_tree_node lnode;
-
       /* Is this name already defined?  */
-      lnode = splay_tree_lookup (cfun->machine->links, (splay_tree_key) name);
-      if (lnode)
-       al = (struct alpha_links *) lnode->value;
+      alpha_links *slot = cfun->machine->links->get (name);
+      if (slot)
+       al = *slot;
     }
   else
-    cfun->machine->links = splay_tree_new_ggc
-      ((splay_tree_compare_fn) strcmp,
-       ggc_alloc_splay_tree_str_alpha_links_splay_tree_s,
-       ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s);
+    cfun->machine->links
+      = hash_map<const char *, alpha_links *, string_traits>::create_ggc (64);
 
   if (al == NULL)
     {
@@ -9681,9 +9685,7 @@ alpha_use_linkage (rtx func, bool lflag, bool rflag)
       al->func = func;
       al->linkage = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (linksym));
 
-      splay_tree_insert (cfun->machine->links,
-                         (splay_tree_key) ggc_strdup (name),
-                        (splay_tree_value) al);
+      cfun->machine->links->put (ggc_strdup (name), al);
     }
 
   al->rkind = rflag ? KIND_CODEADDR : KIND_LINKAGE;
@@ -9695,12 +9697,8 @@ alpha_use_linkage (rtx func, bool lflag, bool rflag)
 }
 
 static int
-alpha_write_one_linkage (splay_tree_node node, void *data)
+alpha_write_one_linkage (const char *name, alpha_links *link, FILE *steam)
 {
-  const char *const name = (const char *) node->key;
-  struct alpha_links *link = (struct alpha_links *) node->value;
-  FILE *stream = (FILE *) data;
-
   ASM_OUTPUT_INTERNAL_LABEL (stream, XSTR (link->linkage, 0));
   if (link->rkind == KIND_CODEADDR)
     {
@@ -9750,8 +9748,10 @@ alpha_write_linkage (FILE *stream, const char *funname)
 
   if (cfun->machine->links)
     {
-      splay_tree_foreach (cfun->machine->links, alpha_write_one_linkage, 
stream);
-      /* splay_tree_delete (func->links); */
+      hash_map<const char *, alpha_links *, string_traits>::iterator iter
+       = cfun->machine->links->begin ();
+      for (; iter != cfun->machine->links->end (); ++iter)
+       alpha_write_one_linkage ((*iter).first, (*iter).second, stream);
     }
 }
 
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index b437005..3eba5ca 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2asm.h"
 #include "dwarf2.h"
 #include "splay-tree.h"
+#include "hash-map.h"
 #include "ggc.h"
 #include "tm_p.h"
 
@@ -790,9 +791,7 @@ dw2_asm_output_delta_sleb128 (const char *lab1 
ATTRIBUTE_UNUSED,
 }
 #endif /* 0 */
 
-static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
-
-static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
+static GTY(()) hash_map<const char *, tree> *indirect_pool;
 
 static GTY(()) int dw2_const_labelno;
 
@@ -808,10 +807,10 @@ static GTY(()) int dw2_const_labelno;
    K2, respectively.  */
 
 static int
-splay_tree_compare_strings (splay_tree_key k1, splay_tree_key k2)
+compare_strings (const void *a, const void *b)
 {
-  const char *s1 = (const char *)k1;
-  const char *s2 = (const char *)k2;
+  const char *s1 = ((const std::pair<const char *, tree> *) a)->first;
+  const char *s2 = ((const std::pair<const char *, tree> *) b)->first;
   int ret;
 
   if (s1 == s2)
@@ -836,23 +835,18 @@ splay_tree_compare_strings (splay_tree_key k1, 
splay_tree_key k2)
 rtx
 dw2_force_const_mem (rtx x, bool is_public)
 {
-  splay_tree_node node;
   const char *key;
   tree decl_id;
 
   if (! indirect_pool)
-    /* We use strcmp, rather than just comparing pointers, so that the
-       sort order will not depend on the host system.  */
-    indirect_pool = splay_tree_new_ggc (splay_tree_compare_strings,
-                                       
ggc_alloc_splay_tree_str_tree_node_splay_tree_s,
-                                       
ggc_alloc_splay_tree_str_tree_node_splay_tree_node_s);
+    indirect_pool = hash_map<const char *, tree>::create_ggc (64);
 
   gcc_assert (GET_CODE (x) == SYMBOL_REF);
 
   key = XSTR (x, 0);
-  node = splay_tree_lookup (indirect_pool, (splay_tree_key) key);
-  if (node)
-    decl_id = (tree) node->value;
+  tree *slot = indirect_pool->get (key);
+  if (slot)
+    decl_id = *slot;
   else
     {
       tree id;
@@ -881,8 +875,7 @@ dw2_force_const_mem (rtx x, bool is_public)
       if (id)
        TREE_SYMBOL_REFERENCED (id) = 1;
 
-      splay_tree_insert (indirect_pool, (splay_tree_key) key,
-                        (splay_tree_value) decl_id);
+      indirect_pool->put (key, decl_id);
     }
 
   return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
@@ -892,15 +885,10 @@ dw2_force_const_mem (rtx x, bool is_public)
    splay_tree_foreach.  Emit one queued constant to memory.  */
 
 static int
-dw2_output_indirect_constant_1 (splay_tree_node node,
-                               void *data ATTRIBUTE_UNUSED)
+dw2_output_indirect_constant_1 (const char *sym, tree id)
 {
-  const char *sym;
   rtx sym_ref;
-  tree id, decl;
-
-  sym = (const char *) node->key;
-  id = (tree) node->value;
+  tree decl;
 
   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
   SET_DECL_ASSEMBLER_NAME (decl, id);
@@ -930,8 +918,18 @@ dw2_output_indirect_constant_1 (splay_tree_node node,
 void
 dw2_output_indirect_constants (void)
 {
-  if (indirect_pool)
-    splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
+  if (!indirect_pool)
+    return;
+
+  auto_vec<std::pair<const char *, tree> > temp (indirect_pool->elements ());
+  for (hash_map<const char *, tree>::iterator iter = indirect_pool->begin ();
+       iter != indirect_pool->end (); ++iter)
+    temp.quick_push (*iter);
+
+    temp.qsort (compare_strings);
+
+    for (unsigned int i = 0; i < temp.length (); i++)
+    dw2_output_indirect_constant_1 (temp[i].first, temp[i].second);
 }
 
 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index a5816dc..f6fdc1c 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 #define hash_map_h
 
 #include <new>
+#include <utility>
 #include "hash-table.h"
 
 /* implement default behavior for traits when types allow it.  */
@@ -266,6 +267,39 @@ public:
 
   size_t elements () const { return m_table.elements (); }
 
+  class iterator
+  {
+  public:
+    explicit iterator (const typename hash_table<hash_entry>::iterator &iter) :
+      m_iter (iter) {}
+
+    iterator &operator++ ()
+    {
+      ++m_iter;
+      return *this;
+    }
+
+    std::pair<Key, Value> operator* ()
+    {
+      hash_entry &e = *m_iter;
+      return std::pair<Key, Value> (e.m_key, e.m_value);
+    }
+
+    bool
+    operator != (const iterator &other) const
+    {
+      return m_iter != other.m_iter;
+    }
+
+  private:
+    typename hash_table<hash_entry>::iterator m_iter;
+  };
+
+  /* Standard iterator retrieval methods.  */
+
+  iterator  begin () const { return iterator (m_table.begin ()); }
+  iterator end () const { return iterator (m_table.end ()); }
+
 private:
 
   template<typename T, typename U, typename V> friend void gt_ggc_mx 
(hash_map<T, U, V> *);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b59d069..b151430 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -9243,8 +9243,7 @@ lower_omp_ordered (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
    requires that languages coordinate a symbol name.  It is therefore
    best put here in common code.  */
 
-static GTY((param1_is (tree), param2_is (tree)))
-  splay_tree critical_name_mutexes;
+static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
 
 static void
 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
@@ -9259,15 +9258,11 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
   if (name)
     {
       tree decl;
-      splay_tree_node n;
 
       if (!critical_name_mutexes)
-       critical_name_mutexes
-         = splay_tree_new_ggc (splay_tree_compare_pointers,
-                               
ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
-                               
ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
+       critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
 
-      n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
+      tree *n = critical_name_mutexes->get (name);
       if (n == NULL)
        {
          char *new_str;
@@ -9284,11 +9279,10 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
          DECL_IGNORED_P (decl) = 1;
          varpool_node::finalize_decl (decl);
 
-         splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
-                            (splay_tree_value) decl);
+         critical_name_mutexes->put (name, decl);
        }
       else
-       decl = (tree) n->value;
+       decl = *n;
 
       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, 
decl));
diff --git a/gcc/tree.h b/gcc/tree.h
index 9875a50..7bff405 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4862,4 +4862,9 @@ int_bit_position (const_tree field)
   return (wi::lshift (wi::to_offset (DECL_FIELD_OFFSET (field)), 
BITS_PER_UNIT_LOG)
          + wi::to_offset (DECL_FIELD_BIT_OFFSET (field))).to_shwi ();
 }
+
+extern void gt_ggc_mx (tree &);
+extern void gt_pch_nx (tree &);
+extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
+
 #endif  /* GCC_TREE_H  */
-- 
2.1.3

Reply via email to