diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 6e2d4c10cfe..5010cefcd77 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -301,9 +301,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	// Allocate a node and construct an element within it.
 	template<typename... _Args>
-	  _Scoped_node(__hashtable_alloc* __h, _Args&&... __args)
+	  _Scoped_node(__hashtable_alloc* __h,
+		       __node_ptr __hint, _Args&&... __args)
 	  : _M_h(__h),
-	    _M_node(__h->_M_allocate_node(std::forward<_Args>(__args)...))
+	    _M_node(__h->_M_allocate_node(__hint,
+					  std::forward<_Args>(__args)...))
 	  { }
 
 	// Destroy element and deallocate node.
@@ -818,6 +820,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return nullptr;
 	}
 
+      // Gets a hint after which a node should be allocated given a bucket.
+      __node_ptr
+      _M_get_node_hint(size_type __bkt, __node_ptr __hint = nullptr) const
+      {
+	__node_base_ptr __node;
+	if (__node = _M_buckets[__bkt])
+	  return __node != &_M_before_begin
+	    ? static_cast<__node_ptr>(__node) : __hint;
+
+	return __hint;
+      }
+
       // Insert a node at the beginning of a bucket.
       void
       _M_insert_bucket_begin(size_type, __node_ptr);
@@ -846,26 +860,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename... _Args>
 	std::pair<iterator, bool>
-	_M_emplace(true_type __uks, _Args&&... __args);
+	_M_emplace_unique(const_iterator, _Args&&... __args);
 
       template<typename... _Args>
 	iterator
-	_M_emplace(false_type __uks, _Args&&... __args)
-	{ return _M_emplace(cend(), __uks, std::forward<_Args>(__args)...); }
+	_M_emplace_multi(const_iterator, _Args&&... __args);
+
+      template<typename... _Args>
+	std::pair<iterator, bool>
+	_M_emplace(true_type /*__uks*/, _Args&&... __args)
+	{ return _M_emplace_unique(cend(), std::forward<_Args>(__args)...); }
 
-      // Emplace with hint, useless when keys are unique.
       template<typename... _Args>
 	iterator
-	_M_emplace(const_iterator, true_type __uks, _Args&&... __args)
-	{ return _M_emplace(__uks, std::forward<_Args>(__args)...).first; }
+	_M_emplace(false_type /*__uks*/, _Args&&... __args)
+	{ return _M_emplace_multi(cend(), std::forward<_Args>(__args)...); }
 
       template<typename... _Args>
 	iterator
-	_M_emplace(const_iterator, false_type __uks, _Args&&... __args);
+	_M_emplace(const_iterator __hint, true_type /*__uks*/,
+		   _Args&&... __args)
+	{
+	  return _M_emplace_unique(__hint,
+				   std::forward<_Args>(__args)...).first;
+	}
+
+      template<typename... _Args>
+	iterator
+	_M_emplace(const_iterator __hint, false_type /*__uks*/,
+		   _Args&&... __args)
+	{ return _M_emplace_multi(__hint, std::forward<_Args>(__args)...); }
 
       template<typename _Kt, typename _Arg, typename _NodeGenerator>
 	std::pair<iterator, bool>
-	_M_insert_unique(_Kt&&, _Arg&&, const _NodeGenerator&);
+	_M_insert_unique(const_iterator, _Kt&&, _Arg&&, const _NodeGenerator&);
 
       template<typename _Kt>
 	static __conditional_t<
@@ -888,7 +916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
 		  true_type /* __uks */)
 	{
-	  return _M_insert_unique(
+	  return _M_insert_unique(cend(),
 	    _S_forward_key(_ExtractKey{}(std::forward<_Arg>(__arg))),
 	    std::forward<_Arg>(__arg), __node_gen);
 	}
@@ -902,14 +930,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			   __uks);
 	}
 
-      // Insert with hint, not used when keys are unique.
+      // Insert with hint when keys are unique.
       template<typename _Arg, typename _NodeGenerator>
 	iterator
-	_M_insert(const_iterator, _Arg&& __arg,
+	_M_insert(const_iterator __hint, _Arg&& __arg,
 		  const _NodeGenerator& __node_gen, true_type __uks)
 	{
-	  return
-	    _M_insert(std::forward<_Arg>(__arg), __node_gen, __uks).first;
+	  return _M_insert_unique(__hint,
+	    _S_forward_key(_ExtractKey{}(std::forward<_Arg>(__arg))),
+	    std::forward<_Arg>(__arg), __node_gen).first;
 	}
 
       // Insert with hint when keys are not unique.
@@ -973,7 +1002,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus > 201402L
       /// Re-insert an extracted node into a container with unique keys.
       insert_return_type
-      _M_reinsert_node(node_type&& __nh)
+      _M_reinsert_node(const_iterator __hint, node_type&& __nh)
       {
 	insert_return_type __ret;
 	if (__nh.empty())
@@ -983,6 +1012,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    __glibcxx_assert(get_allocator() == __nh.get_allocator());
 
 	    const key_type& __k = __nh._M_key();
+	    if (__hint._M_cur && this->_M_equals(__k, *__hint._M_cur))
+	      {
+		__ret.node = std::move(__nh);
+		__ret.position = iterator(__hint._M_cur);
+		__ret.inserted = false;
+	      }
+	    else
+	      {
 		__hash_code __code = this->_M_hash_code(__k);
 		size_type __bkt = _M_bucket_index(__code);
 		if (__node_ptr __n = _M_find_node(__bkt, __k, __code))
@@ -999,6 +1036,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		    __ret.inserted = true;
 		  }
 	      }
+	  }
 	return __ret;
       }
 
@@ -1012,7 +1050,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__glibcxx_assert(get_allocator() == __nh.get_allocator());
 
 	const key_type& __k = __nh._M_key();
-	auto __code = this->_M_hash_code(__k);
+	__hash_code __code;
+	if (__hint._M_cur && this->_M_equals(__k, *__hint._M_cur))
+	  __code = this->_M_hash_code(*__hint._M_cur);
+	else
+	  __code = this->_M_hash_code(__k);
 	auto __ret
 	  = _M_insert_multi_node(__hint._M_cur, __code, __nh._M_ptr);
 	__nh._M_ptr = nullptr;
@@ -1105,8 +1147,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  for (auto __i = __src.cbegin(), __end = __src.cend(); __i != __end;)
 	    {
 	      auto __pos = __i++;
-	      __hash_code __code
-		= this->_M_hash_code(__src.hash_function(), *__pos._M_cur);
+	      const key_type& __k = _ExtractKey{}(*__pos);
+	      __hash_code __code;
+	      if (__hint && this->_M_equals(__k, *__hint))
+		__code = this->_M_hash_code(*__hint);
+	      else
+		__code = this->_M_hash_code(__src.hash_function(), *__pos._M_cur);
 	      auto __nh = __src.extract(__pos);
 	      __hint = _M_insert_multi_node(__hint, __code, __nh._M_ptr)._M_cur;
 	      __nh._M_ptr = nullptr;
@@ -1332,7 +1378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    // _M_before_begin.
 	    __node_ptr __ht_n = __ht._M_begin();
 	    __node_ptr __this_n
-	      = __node_gen(__fwd_value_for<_Ht>(__ht_n->_M_v()));
+	      = __node_gen(nullptr, __fwd_value_for<_Ht>(__ht_n->_M_v()));
 	    this->_M_copy_code(*__this_n, *__ht_n);
 	    _M_update_bbegin(__this_n);
 
@@ -1340,7 +1386,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    __node_ptr __prev_n = __this_n;
 	    for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
 	      {
-		__this_n = __node_gen(__fwd_value_for<_Ht>(__ht_n->_M_v()));
+		__this_n
+		  = __node_gen(__prev_n, __fwd_value_for<_Ht>(__ht_n->_M_v()));
 		__prev_n->_M_nxt = __this_n;
 		this->_M_copy_code(*__this_n, *__ht_n);
 		size_type __bkt = _M_bucket_index(*__this_n);
@@ -1732,10 +1779,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// All equivalent values are next to each other, if we find a
 	// non-equivalent value after an equivalent one it means that we won't
 	// find any new equivalent value.
+	const key_type& __nk = _ExtractKey{}(__n->_M_v());
 	iterator __it(__n);
 	size_type __result = 1;
 	for (++__it;
-	     __it._M_cur && this->_M_equals_tr(__k, __code, *__it._M_cur);
+	     __it._M_cur && this->_M_equals(__nk, __code, *__it._M_cur);
 	     ++__it)
 	  ++__result;
 
@@ -1819,8 +1867,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// All equivalent values are next to each other, if we find a
 	// non-equivalent value after an equivalent one it means that we won't
 	// find any new equivalent value.
+	const key_type& __nk = _ExtractKey{}(__n->_M_v());
 	auto __beg = __ite++;
-	while (__ite._M_cur && this->_M_equals_tr(__k, __code, *__ite._M_cur))
+	while (__ite._M_cur && this->_M_equals(__nk, __code, *__ite._M_cur))
 	  ++__ite;
 
 	return { __beg, __ite };
@@ -1847,8 +1896,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// All equivalent values are next to each other, if we find a
 	// non-equivalent value after an equivalent one it means that we won't
 	// find any new equivalent value.
+	const key_type& __nk = _ExtractKey{}(__n->_M_v());
 	auto __beg = __ite++;
-	while (__ite._M_cur && this->_M_equals_tr(__k, __code, *__ite._M_cur))
+	while (__ite._M_cur && this->_M_equals(__nk, __code, *__ite._M_cur))
 	  ++__ite;
 
 	return { __beg, __ite };
@@ -1997,17 +2047,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       auto
       _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
 		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
-      _M_emplace(true_type /* __uks */, _Args&&... __args)
+      _M_emplace_unique(const_iterator __hint, _Args&&... __args)
       -> pair<iterator, bool>
       {
 	// First build the node to get access to the hash code
-	_Scoped_node __node { this, std::forward<_Args>(__args)...  };
+	_Scoped_node __node { this, __hint._M_cur, std::forward<_Args>(__args)...  };
 	const key_type& __k = _ExtractKey{}(__node._M_node->_M_v());
+	if (__hint._M_cur && this->_M_equals(__k, *__hint._M_cur))
+	  return { iterator(__hint._M_cur), false };
+
 	__hash_code __code = this->_M_hash_code(__k);
 	size_type __bkt = _M_bucket_index(__code);
 	if (__node_ptr __p = _M_find_node(__bkt, __k, __code))
 	  // There is already an equivalent node, no insertion
-	  return std::make_pair(iterator(__p), false);
+	  return { iterator(__p), false };
 
 	// Insert the node
 	auto __pos = _M_insert_unique_node(__bkt, __code, __node._M_node);
@@ -2023,15 +2076,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       auto
       _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
 		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
-      _M_emplace(const_iterator __hint, false_type /* __uks */,
-		 _Args&&... __args)
+      _M_emplace_multi(const_iterator __hint, _Args&&... __args)
       -> iterator
       {
 	// First build the node to get its hash code.
-	_Scoped_node __node { this, std::forward<_Args>(__args)...  };
+	_Scoped_node __node
+	{ this, __hint._M_cur, std::forward<_Args>(__args)...  };
+
 	const key_type& __k = _ExtractKey{}(__node._M_node->_M_v());
+	__hash_code __code;
+	if (__hint._M_cur && this->_M_equals(__k, *__hint._M_cur))
+	  __code = this->_M_hash_code(*__hint._M_cur);
+	else
+	  __code = this->_M_hash_code(__k);
 
-	__hash_code __code = this->_M_hash_code(__k);
 	auto __pos
 	  = _M_insert_multi_node(__hint._M_cur, __code, __node._M_node);
 	__node._M_node = nullptr;
@@ -2132,10 +2190,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       auto
       _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
 		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
-      _M_insert_unique(_Kt&& __k, _Arg&& __v,
+      _M_insert_unique(const_iterator __hint,
+		       _Kt&& __k, _Arg&& __v,
 		       const _NodeGenerator& __node_gen)
       -> pair<iterator, bool>
       {
+	if (__hint._M_cur && this->_M_equals_tr(__k, *__hint._M_cur))
+	  return { iterator(__hint._M_cur), false };
+
 	__hash_code __code = this->_M_hash_code_tr(__k);
 	size_type __bkt = _M_bucket_index(__code);
 
@@ -2143,11 +2205,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return { iterator(__node), false };
 
 	_Scoped_node __node {
-	  __node_builder_t::_S_build(std::forward<_Kt>(__k),
+	  __node_builder_t::_S_build(_M_get_node_hint(__bkt, __hint._M_cur),
+				     std::forward<_Kt>(__k),
 				     std::forward<_Arg>(__v),
 				     __node_gen),
 	  this
 	};
+
 	auto __pos
 	  = _M_insert_unique_node(__bkt, __code, __node._M_node);
 	__node._M_node = nullptr;
@@ -2169,11 +2233,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       -> iterator
       {
 	// First allocate new node so that we don't do anything if it throws.
-	_Scoped_node __node{ __node_gen(std::forward<_Arg>(__v)), this };
+	_Scoped_node __node
+	{ __node_gen(__hint._M_cur, std::forward<_Arg>(__v)), this };
 
 	// Second compute the hash code so that we don't rehash if it throws.
-	__hash_code __code
-	  = this->_M_hash_code(_ExtractKey{}(__node._M_node->_M_v()));
+	const auto& __k = _ExtractKey{}(__node._M_node->_M_v());
+	__hash_code __code;
+	if (__hint._M_cur && this->_M_equals(__k, *__hint._M_cur))
+	  __code = this->_M_hash_code(*__hint._M_cur);
+	else
+	  __code = this->_M_hash_code(__k);
 
 	auto __pos
 	  = _M_insert_multi_node(__hint._M_cur, __code, __node._M_node);
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 0b5443fc187..7b9e0476159 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -115,12 +115,14 @@ namespace __detail
   template<>
     struct _NodeBuilder<_Select1st>
     {
-      template<typename _Kt, typename _Arg, typename _NodeGenerator>
-	static auto
-	_S_build(_Kt&& __k, _Arg&& __arg, const _NodeGenerator& __node_gen)
-	-> typename _NodeGenerator::__node_type*
-	{
-	  return __node_gen(std::forward<_Kt>(__k),
+      template<typename _NodePtr,
+	       typename _Kt, typename _Arg, typename _NodeGenerator>
+	static _NodePtr
+	_S_build(_NodePtr __hint,
+		 _Kt&& __k, _Arg&& __arg, const _NodeGenerator& __node_gen)
+	{
+	  return __node_gen(__hint,
+			    std::forward<_Kt>(__k),
 			    std::forward<_Arg>(__arg).second);
 	}
     };
@@ -128,11 +130,12 @@ namespace __detail
   template<>
     struct _NodeBuilder<_Identity>
     {
-      template<typename _Kt, typename _Arg, typename _NodeGenerator>
-	static auto
-	_S_build(_Kt&& __k, _Arg&&, const _NodeGenerator& __node_gen)
-	-> typename _NodeGenerator::__node_type*
-	{ return __node_gen(std::forward<_Kt>(__k)); }
+      template<typename _NodePtr,
+	       typename _Kt, typename _Arg, typename _NodeGenerator>
+	static _NodePtr
+	_S_build(_NodePtr __hint,
+		 _Kt&& __k, _Arg&&, const _NodeGenerator& __node_gen)
+	{ return __node_gen(__hint, std::forward<_Kt>(__k)); }
     };
 
   template<typename _NodeAlloc>
@@ -150,22 +153,23 @@ namespace __detail
 	typename __hashtable_alloc::__node_alloc_traits;
 
     public:
-      using __node_type = typename __hashtable_alloc::__node_type;
+      using __node_ptr = typename __hashtable_alloc::__node_ptr;
 
-      _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
+      _ReuseOrAllocNode(__node_ptr __nodes, __hashtable_alloc& __h)
       : _M_nodes(__nodes), _M_h(__h) { }
+
       _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete;
 
       ~_ReuseOrAllocNode()
       { _M_h._M_deallocate_nodes(_M_nodes); }
 
       template<typename... _Args>
-	__node_type*
-	operator()(_Args&&... __args) const
+	__node_ptr
+	operator()(__node_ptr __hint, _Args&&... __args) const
 	{
 	  if (_M_nodes)
 	    {
-	      __node_type* __node = _M_nodes;
+	      __node_ptr __node = _M_nodes;
 	      _M_nodes = _M_nodes->_M_next();
 	      __node->_M_nxt = nullptr;
 	      auto& __a = _M_h._M_node_allocator();
@@ -180,13 +184,15 @@ namespace __detail
 		  _M_h._M_deallocate_node_ptr(__node);
 		  __throw_exception_again;
 		}
+
 	      return __node;
 	    }
-	  return _M_h._M_allocate_node(std::forward<_Args>(__args)...);
+
+	  return _M_h._M_allocate_node(__hint, std::forward<_Args>(__args)...);
 	}
 
     private:
-      mutable __node_type* _M_nodes;
+      mutable __node_ptr _M_nodes;
       __hashtable_alloc& _M_h;
     };
 
@@ -199,15 +205,15 @@ namespace __detail
       using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
 
     public:
-      using __node_type = typename __hashtable_alloc::__node_type;
+      using __node_ptr = typename __hashtable_alloc::__node_ptr;
 
       _AllocNode(__hashtable_alloc& __h)
       : _M_h(__h) { }
 
       template<typename... _Args>
-	__node_type*
-	operator()(_Args&&... __args) const
-	{ return _M_h._M_allocate_node(std::forward<_Args>(__args)...); }
+	__node_ptr
+	operator()(__node_ptr __hint, _Args&&... __args) const
+	{ return _M_h._M_allocate_node(__hint, std::forward<_Args>(__args)...); }
 
     private:
       __hashtable_alloc& _M_h;
@@ -761,6 +767,7 @@ namespace __detail
 
       typename __hashtable::_Scoped_node __node {
 	__h,
+	__h->_M_get_node_hint(__bkt),
 	std::piecewise_construct,
 	std::tuple<const key_type&>(__k),
 	std::tuple<>()
@@ -788,6 +795,7 @@ namespace __detail
 
       typename __hashtable::_Scoped_node __node {
 	__h,
+	__h->_M_get_node_hint(__bkt),
 	std::piecewise_construct,
 	std::forward_as_tuple(std::move(__k)),
 	std::tuple<>()
@@ -876,7 +884,7 @@ namespace __detail
 
       template<typename _KType, typename... _Args>
 	std::pair<iterator, bool>
-	try_emplace(const_iterator, _KType&& __k, _Args&&... __args)
+	try_emplace(const_iterator __hint, _KType&& __k, _Args&&... __args)
 	{
 	  __hashtable& __h = _M_conjure_hashtable();
 	  auto __code = __h._M_hash_code(__k);
@@ -885,7 +893,7 @@ namespace __detail
 	    return { iterator(__node), false };
 
 	  typename __hashtable::_Scoped_node __node {
-	    &__h,
+	    &__h, __hint._M_cur,
 	    std::piecewise_construct,
 	    std::forward_as_tuple(std::forward<_KType>(__k)),
 	    std::forward_as_tuple(std::forward<_Args>(__args)...)
@@ -1250,6 +1258,14 @@ namespace __detail
 	  return _M_hash()(__k);
 	}
 
+      __hash_code
+      _M_hash_code(const _Hash_node_value<_Value, true>& __n) const
+      { return __n._M_hash_code; }
+
+      __hash_code
+      _M_hash_code(const _Hash_node_value<_Value, false>& __n) const
+      { return _M_hash_code(_ExtractKey{}(__n._M_v())); }
+
       __hash_code
       _M_hash_code(const _Hash&,
 		   const _Hash_node_value<_Value, true>& __n) const
@@ -1641,18 +1657,23 @@ namespace __detail
       { }
 
       bool
-      _M_equals(const _Key& __k, __hash_code __c,
+      _M_equals(const _Key& __k,
 		const _Hash_node_value<_Value, __hash_cached::value>& __n) const
       {
 	static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
 	  "key equality predicate must be invocable with two arguments of "
 	  "key type");
-	return _S_equals(__c, __n) && _M_eq()(__k, _ExtractKey{}(__n._M_v()));
+	return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
       }
 
+      bool
+      _M_equals(const _Key& __k, __hash_code __c,
+		const _Hash_node_value<_Value, __hash_cached::value>& __n) const
+      { return _S_equals(__c, __n) && _M_equals(__k, __n); }
+
       template<typename _Kt>
 	bool
-	_M_equals_tr(const _Kt& __k, __hash_code __c,
+	_M_equals_tr(const _Kt& __k,
 		     const _Hash_node_value<_Value,
 					    __hash_cached::value>& __n) const
 	{
@@ -1660,9 +1681,16 @@ namespace __detail
 	    __is_invocable<const _Equal&, const _Kt&, const _Key&>{},
 	    "key equality predicate must be invocable with two arguments of "
 	    "key type");
-	  return _S_equals(__c, __n) && _M_eq()(__k, _ExtractKey{}(__n._M_v()));
+	  return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
 	}
 
+      template<typename _Kt>
+	bool
+	_M_equals_tr(const _Kt& __k, __hash_code __c,
+		     const _Hash_node_value<_Value,
+					    __hash_cached::value>& __n) const
+	{ return _S_equals(__c, __n) && _M_equals_tr(__k, __n); }
+
       bool
       _M_node_equals(
 	const _Hash_node_value<_Value, __hash_cached::value>& __lhn,
@@ -1880,7 +1908,7 @@ namespace __detail
       // Allocate a node and construct an element within it.
       template<typename... _Args>
 	__node_ptr
-	_M_allocate_node(_Args&&... __args);
+	_M_allocate_node(__node_ptr __hint, _Args&&... __args);
 
       // Destroy the element within a node and deallocate the node.
       void
@@ -1907,22 +1935,32 @@ namespace __detail
   template<typename _NodeAlloc>
     template<typename... _Args>
       auto
-      _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
+      _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(__node_ptr __hint,
+						     _Args&&... __args)
       -> __node_ptr
       {
-	auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
+	auto& __alloc = _M_node_allocator();
+	typename __node_alloc_traits::pointer __nptr;
+	if (__hint)
+	  {
+	    typedef typename __node_alloc_traits::const_pointer _CPtr;
+	    auto __hptr = std::pointer_traits<_CPtr>::pointer_to(*__hint);
+	    __nptr = __node_alloc_traits::allocate(__alloc, 1, __hptr);
+	  }
+	else
+	  __nptr = __node_alloc_traits::allocate(__alloc, 1);
+
 	__node_ptr __n = std::__to_address(__nptr);
 	__try
 	  {
 	    ::new ((void*)__n) __node_type;
-	    __node_alloc_traits::construct(_M_node_allocator(),
-					   __n->_M_valptr(),
+	    __node_alloc_traits::construct(__alloc, __n->_M_valptr(),
 					   std::forward<_Args>(__args)...);
 	    return __n;
 	  }
 	__catch(...)
 	  {
-	    __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
+	    __node_alloc_traits::deallocate(__alloc, __nptr, 1);
 	    __throw_exception_again;
 	  }
       }
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index 2261e6685ea..9f621cdbaeb 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -436,12 +436,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /// Re-insert an extracted node.
       insert_return_type
       insert(node_type&& __nh)
-      { return _M_h._M_reinsert_node(std::move(__nh)); }
+      { return _M_h._M_reinsert_node(cend(), std::move(__nh)); }
 
       /// Re-insert an extracted node.
       iterator
-      insert(const_iterator, node_type&& __nh)
-      { return _M_h._M_reinsert_node(std::move(__nh)).position; }
+      insert(const_iterator __hint, node_type&& __nh)
+      { return _M_h._M_reinsert_node(__hint, std::move(__nh)).position; }
 
 #define __cpp_lib_unordered_map_try_emplace 201411
       /**
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index ac4a890d25a..10d81905acb 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -497,12 +497,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /// Re-insert an extracted node.
       insert_return_type
       insert(node_type&& __nh)
-      { return _M_h._M_reinsert_node(std::move(__nh)); }
+      { return _M_h._M_reinsert_node(cend(), std::move(__nh)); }
 
       /// Re-insert an extracted node.
       iterator
-      insert(const_iterator, node_type&& __nh)
-      { return _M_h._M_reinsert_node(std::move(__nh)).position; }
+      insert(const_iterator __hint, node_type&& __nh)
+      { return _M_h._M_reinsert_node(__hint, std::move(__nh)).position; }
 #endif // C++17
 
       ///@{
