diff mbox series

[1/3] Support get_or_insert in ordered_hash_map

Message ID 20230731110346.174848-2-andrzej.turko@gmail.com
State New
Headers show
Series genmatch: Speed up recompilation after changes to match.pd | expand

Commit Message

Andrzej Turko July 31, 2023, 11:03 a.m. UTC
Get_or_insert method is already supported by the unordered hash map.
Adding it to the ordered map enables us to replace the unordered map
with the ordered one in cases where ordering may be useful.

Signed-off-by: Andrzej Turko <andrzej.turko@gmail.com>

gcc/ChangeLog:

	* ordered-hash-map.h: Add get_or_insert.
	* Makefile.in: Require the ordered map header for genmatch.o.
	* ordered-hash-map-tests.cc: Use get_or_insert in tests.

Signed-off-by: Andrzej Turko <andrzej.turko@gmail.com>
---
 gcc/Makefile.in               |  4 ++--
 gcc/ordered-hash-map-tests.cc | 19 +++++++++++++++----
 gcc/ordered-hash-map.h        | 26 ++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 6 deletions(-)

Comments

Richard Biener July 31, 2023, 1:38 p.m. UTC | #1
On Mon, Jul 31, 2023 at 1:06 PM Andrzej Turko via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Get_or_insert method is already supported by the unordered hash map.
> Adding it to the ordered map enables us to replace the unordered map
> with the ordered one in cases where ordering may be useful.

OK.  Note the Makefile.in change really belongs to another patch in
the series, without this
it could be pushed independently.

Thanks,
Richard.

> Signed-off-by: Andrzej Turko <andrzej.turko@gmail.com>
>
> gcc/ChangeLog:
>
>         * ordered-hash-map.h: Add get_or_insert.
>         * Makefile.in: Require the ordered map header for genmatch.o.
>         * ordered-hash-map-tests.cc: Use get_or_insert in tests.
>
> Signed-off-by: Andrzej Turko <andrzej.turko@gmail.com>
> ---
>  gcc/Makefile.in               |  4 ++--
>  gcc/ordered-hash-map-tests.cc | 19 +++++++++++++++----
>  gcc/ordered-hash-map.h        | 26 ++++++++++++++++++++++++++
>  3 files changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index e99628cec07..2429128cbf2 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -3004,8 +3004,8 @@ build/genhooks.o : genhooks.cc $(TARGET_DEF) $(C_TARGET_DEF)              \
>    $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(BCONFIG_H) $(SYSTEM_H) errors.h
>  build/genmddump.o : genmddump.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)        \
>    $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)
> -build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) \
> -  $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h \
> +build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \
> +  errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h ordered-hash-map.h \
>    tree.def builtins.def internal-fn.def case-cfn-macros.h $(CPPLIB_H)
>  build/gencfn-macros.o : gencfn-macros.cc $(BCONFIG_H) $(SYSTEM_H)      \
>    $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-set.h builtins.def      \
> diff --git a/gcc/ordered-hash-map-tests.cc b/gcc/ordered-hash-map-tests.cc
> index 1c26bbfa979..55894c25fa0 100644
> --- a/gcc/ordered-hash-map-tests.cc
> +++ b/gcc/ordered-hash-map-tests.cc
> @@ -58,6 +58,7 @@ static void
>  test_map_of_strings_to_int ()
>  {
>    ordered_hash_map <const char *, int> m;
> +  bool existed;
>
>    const char *ostrich = "ostrich";
>    const char *elephant = "elephant";
> @@ -74,17 +75,23 @@ test_map_of_strings_to_int ()
>    ASSERT_EQ (false, m.put (ostrich, 2));
>    ASSERT_EQ (false, m.put (elephant, 4));
>    ASSERT_EQ (false, m.put (ant, 6));
> -  ASSERT_EQ (false, m.put (spider, 8));
> +  existed = true;
> +  int &value = m.get_or_insert (spider, &existed);
> +  value = 8;
> +  ASSERT_EQ (false, existed);
>    ASSERT_EQ (false, m.put (millipede, 750));
>    ASSERT_EQ (false, m.put (eric, 3));
>
> +
>    /* Verify that we can recover the stored values.  */
>    ASSERT_EQ (6, m.elements ());
>    ASSERT_EQ (2, *m.get (ostrich));
>    ASSERT_EQ (4, *m.get (elephant));
>    ASSERT_EQ (6, *m.get (ant));
>    ASSERT_EQ (8, *m.get (spider));
> -  ASSERT_EQ (750, *m.get (millipede));
> +  existed = false;
> +  ASSERT_EQ (750, m.get_or_insert (millipede, &existed));
> +  ASSERT_EQ (true, existed);
>    ASSERT_EQ (3, *m.get (eric));
>
>    /* Verify that the order of insertion is preserved.  */
> @@ -113,6 +120,7 @@ test_map_of_int_to_strings ()
>  {
>    const int EMPTY = -1;
>    const int DELETED = -2;
> +  bool existed;
>    typedef int_hash <int, EMPTY, DELETED> int_hash_t;
>    ordered_hash_map <int_hash_t, const char *> m;
>
> @@ -131,7 +139,9 @@ test_map_of_int_to_strings ()
>    ASSERT_EQ (false, m.put (2, ostrich));
>    ASSERT_EQ (false, m.put (4, elephant));
>    ASSERT_EQ (false, m.put (6, ant));
> -  ASSERT_EQ (false, m.put (8, spider));
> +  const char* &value = m.get_or_insert (8, &existed);
> +  value = spider;
> +  ASSERT_EQ (false, existed);
>    ASSERT_EQ (false, m.put (750, millipede));
>    ASSERT_EQ (false, m.put (3, eric));
>
> @@ -141,7 +151,8 @@ test_map_of_int_to_strings ()
>    ASSERT_EQ (*m.get (4), elephant);
>    ASSERT_EQ (*m.get (6), ant);
>    ASSERT_EQ (*m.get (8), spider);
> -  ASSERT_EQ (*m.get (750), millipede);
> +  ASSERT_EQ (m.get_or_insert (750, &existed), millipede);
> +  ASSERT_EQ (existed, TRUE);
>    ASSERT_EQ (*m.get (3), eric);
>
>    /* Verify that the order of insertion is preserved.  */
> diff --git a/gcc/ordered-hash-map.h b/gcc/ordered-hash-map.h
> index 6b68cc96305..9fc875182e1 100644
> --- a/gcc/ordered-hash-map.h
> +++ b/gcc/ordered-hash-map.h
> @@ -76,6 +76,32 @@ public:
>      return m_map.get (k);
>    }
>
> +  /* Return a reference to the value for the passed in key, creating the entry
> +    if it doesn't already exist.  If existed is not NULL then it is set to
> +    false if the key was not previously in the map, and true otherwise.  */
> +
> +  Value &get_or_insert (const Key &k, bool *existed = NULL)
> +  {
> +    bool _existed;
> +    Value &ret = m_map.get_or_insert (k, &_existed);
> +
> +    if (!_existed)
> +      {
> +       bool key_present;
> +       int &slot = m_key_index.get_or_insert (k, &key_present);
> +       if (!key_present)
> +         {
> +           slot = m_keys.length ();
> +           m_keys.safe_push (k);
> +         }
> +      }
> +
> +    if (existed)
> +      *existed = _existed;
> +
> +    return ret;
> +  }
> +
>    /* Removing a key removes it from the map, but retains the insertion
>       order.  */
>
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index e99628cec07..2429128cbf2 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3004,8 +3004,8 @@  build/genhooks.o : genhooks.cc $(TARGET_DEF) $(C_TARGET_DEF)		\
   $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(BCONFIG_H) $(SYSTEM_H) errors.h
 build/genmddump.o : genmddump.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)
-build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) \
-  $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h \
+build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \
+  errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h ordered-hash-map.h \
   tree.def builtins.def internal-fn.def case-cfn-macros.h $(CPPLIB_H)
 build/gencfn-macros.o : gencfn-macros.cc $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-set.h builtins.def	\
diff --git a/gcc/ordered-hash-map-tests.cc b/gcc/ordered-hash-map-tests.cc
index 1c26bbfa979..55894c25fa0 100644
--- a/gcc/ordered-hash-map-tests.cc
+++ b/gcc/ordered-hash-map-tests.cc
@@ -58,6 +58,7 @@  static void
 test_map_of_strings_to_int ()
 {
   ordered_hash_map <const char *, int> m;
+  bool existed;
 
   const char *ostrich = "ostrich";
   const char *elephant = "elephant";
@@ -74,17 +75,23 @@  test_map_of_strings_to_int ()
   ASSERT_EQ (false, m.put (ostrich, 2));
   ASSERT_EQ (false, m.put (elephant, 4));
   ASSERT_EQ (false, m.put (ant, 6));
-  ASSERT_EQ (false, m.put (spider, 8));
+  existed = true;
+  int &value = m.get_or_insert (spider, &existed);
+  value = 8;
+  ASSERT_EQ (false, existed);
   ASSERT_EQ (false, m.put (millipede, 750));
   ASSERT_EQ (false, m.put (eric, 3));
 
+
   /* Verify that we can recover the stored values.  */
   ASSERT_EQ (6, m.elements ());
   ASSERT_EQ (2, *m.get (ostrich));
   ASSERT_EQ (4, *m.get (elephant));
   ASSERT_EQ (6, *m.get (ant));
   ASSERT_EQ (8, *m.get (spider));
-  ASSERT_EQ (750, *m.get (millipede));
+  existed = false;
+  ASSERT_EQ (750, m.get_or_insert (millipede, &existed));
+  ASSERT_EQ (true, existed);
   ASSERT_EQ (3, *m.get (eric));
 
   /* Verify that the order of insertion is preserved.  */
@@ -113,6 +120,7 @@  test_map_of_int_to_strings ()
 {
   const int EMPTY = -1;
   const int DELETED = -2;
+  bool existed;
   typedef int_hash <int, EMPTY, DELETED> int_hash_t;
   ordered_hash_map <int_hash_t, const char *> m;
 
@@ -131,7 +139,9 @@  test_map_of_int_to_strings ()
   ASSERT_EQ (false, m.put (2, ostrich));
   ASSERT_EQ (false, m.put (4, elephant));
   ASSERT_EQ (false, m.put (6, ant));
-  ASSERT_EQ (false, m.put (8, spider));
+  const char* &value = m.get_or_insert (8, &existed);
+  value = spider;
+  ASSERT_EQ (false, existed);
   ASSERT_EQ (false, m.put (750, millipede));
   ASSERT_EQ (false, m.put (3, eric));
 
@@ -141,7 +151,8 @@  test_map_of_int_to_strings ()
   ASSERT_EQ (*m.get (4), elephant);
   ASSERT_EQ (*m.get (6), ant);
   ASSERT_EQ (*m.get (8), spider);
-  ASSERT_EQ (*m.get (750), millipede);
+  ASSERT_EQ (m.get_or_insert (750, &existed), millipede);
+  ASSERT_EQ (existed, TRUE);
   ASSERT_EQ (*m.get (3), eric);
 
   /* Verify that the order of insertion is preserved.  */
diff --git a/gcc/ordered-hash-map.h b/gcc/ordered-hash-map.h
index 6b68cc96305..9fc875182e1 100644
--- a/gcc/ordered-hash-map.h
+++ b/gcc/ordered-hash-map.h
@@ -76,6 +76,32 @@  public:
     return m_map.get (k);
   }
 
+  /* Return a reference to the value for the passed in key, creating the entry
+    if it doesn't already exist.  If existed is not NULL then it is set to
+    false if the key was not previously in the map, and true otherwise.  */
+
+  Value &get_or_insert (const Key &k, bool *existed = NULL)
+  {
+    bool _existed;
+    Value &ret = m_map.get_or_insert (k, &_existed);
+
+    if (!_existed)
+      {
+	bool key_present;
+	int &slot = m_key_index.get_or_insert (k, &key_present);
+	if (!key_present)
+	  {
+	    slot = m_keys.length ();
+	    m_keys.safe_push (k);
+	  }
+      }
+
+    if (existed)
+      *existed = _existed;
+
+    return ret;
+  }
+
   /* Removing a key removes it from the map, but retains the insertion
      order.  */