summaryrefslogtreecommitdiff
path: root/absl/container/internal/raw_hash_set.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2022-03-28 13:12:19 -0700
committerGravatar rogeeff <rogeeff@google.com>2022-03-29 10:08:46 -0400
commit3204cc0625230e9876f0310a6dea0014210ab325 (patch)
tree7b9193fc4b720bc8e767912b8a38f82c11e19569 /absl/container/internal/raw_hash_set.h
parent0c6302fe427963ec5c471d3ee660120682ab15f7 (diff)
Export of internal Abseil changes
-- 291f7ef542f73e4801ab5108014bc02344ef31df by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 437835981 Change-Id: I42fd92e74903894533ac9984d7f622e3ba20f468 -- 2e8caf1a57c50b518e05b4bca48e4fe1bb19af82 by Andy Getzendanner <durandal@google.com>: Internal change PiperOrigin-RevId: 437832673 Change-Id: I61b35089418d01a54cecf161b254b68252bebff3 -- b927482ccc399f7e337b60582988b914d9946e4e by Derek Mauro <dmauro@google.com>: Simplify endian intrinsics for modern compilers All modern compilers have either __builtin_bswapN (gcc, clang) or _byteswap_TYPE (MSVC). The other intrinsic definitions are no longer necessary. PiperOrigin-RevId: 437772295 Change-Id: Ifb3d88ba24b9097f87ceb202272b36d2f5e5117f -- b6782a2247a16d5c14706a74ec577c19963d9f97 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 437373174 Change-Id: I0f77e1780dee90d7a3c32a08d96c4aeb624a57b4 -- a53e0c724e37b0b01515a99bd25394b8e21ffdfc by Derek Mauro <dmauro@google.com>: Unify detection of SSE2 and SSSE3 instruction sets and include the proper headers Fix the intrinsic implementation of FastHexToBufferZeroPad16 in numbers.h which only relies on SSSE3, not SSE 4.2. https://godbolt.org/z/Pf5bn1Yv9 Closes #639 PiperOrigin-RevId: 437286940 Change-Id: Ic97948399b61b91e9c0bccd09313b795b904d714 -- f173f597cb2a75ef2a989f45a496334b85e6f40d by Abseil Team <absl-team@google.com>: Change assertion function to enable clearer error messages. PiperOrigin-RevId: 437227057 Change-Id: If420d2f63b51feef6648762f344d5be012cd9c85 GitOrigin-RevId: 291f7ef542f73e4801ab5108014bc02344ef31df
Diffstat (limited to 'absl/container/internal/raw_hash_set.h')
-rw-r--r--absl/container/internal/raw_hash_set.h51
1 files changed, 34 insertions, 17 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index a05bebf6..6a6525e2 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -176,6 +176,18 @@
#ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
#define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
#include <algorithm>
#include <cmath>
#include <cstdint>
@@ -187,6 +199,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
@@ -196,7 +209,6 @@
#include "absl/container/internal/hash_policy_traits.h"
#include "absl/container/internal/hashtable_debug_hooks.h"
#include "absl/container/internal/hashtablez_sampler.h"
-#include "absl/container/internal/have_sse.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
@@ -461,7 +473,7 @@ inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); }
inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; }
inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; }
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
// Quick reference guide for intrinsics used below:
//
// * __m128i: An XMM (128-bit) word.
@@ -522,7 +534,7 @@ struct GroupSse2Impl {
// Returns a bitmask representing the positions of empty slots.
BitMask<uint32_t, kWidth> MatchEmpty() const {
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
// This only works because ctrl_t::kEmpty is -128.
return BitMask<uint32_t, kWidth>(
static_cast<uint32_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
@@ -548,7 +560,7 @@ struct GroupSse2Impl {
void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
auto msbs = _mm_set1_epi8(static_cast<char>(-128));
auto x126 = _mm_set1_epi8(126);
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs);
#else
auto zero = _mm_setzero_si128();
@@ -614,7 +626,7 @@ struct GroupPortableImpl {
uint64_t ctrl;
};
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
using Group = GroupSse2Impl;
#else
using Group = GroupPortableImpl;
@@ -700,13 +712,8 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last,
return 0;
}
-inline void AssertIsFull(ctrl_t* ctrl) {
- ABSL_HARDENING_ASSERT(
- (ctrl != nullptr && IsFull(*ctrl)) &&
- "Invalid operation on iterator. The element might have "
- "been erased, the table might have rehashed, or this may "
- "be an end() iterator.");
-}
+#define ABSL_INTERNAL_ASSERT_IS_FULL(ctrl, msg) \
+ ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && msg);
inline void AssertIsValid(ctrl_t* ctrl) {
ABSL_HARDENING_ASSERT(
@@ -942,16 +949,22 @@ class raw_hash_set {
// PRECONDITION: not an end() iterator.
reference operator*() const {
- AssertIsFull(ctrl_);
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+ "operator*() called on invalid iterator.");
return PolicyTraits::element(slot_);
}
// PRECONDITION: not an end() iterator.
- pointer operator->() const { return &operator*(); }
+ pointer operator->() const {
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+ "operator-> called on invalid iterator.");
+ return &operator*();
+ }
// PRECONDITION: not an end() iterator.
iterator& operator++() {
- AssertIsFull(ctrl_);
+ ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+ "operator++ called on invalid iterator.");
++ctrl_;
++slot_;
skip_empty_or_deleted();
@@ -1500,7 +1513,8 @@ class raw_hash_set {
// This overload is necessary because otherwise erase<K>(const K&) would be
// a better match if non-const iterator is passed as an argument.
void erase(iterator it) {
- AssertIsFull(it.ctrl_);
+ ABSL_INTERNAL_ASSERT_IS_FULL(it.ctrl_,
+ "erase() called on invalid iterator.")
PolicyTraits::destroy(&alloc_ref(), it.slot_);
erase_meta_only(it);
}
@@ -1534,7 +1548,8 @@ class raw_hash_set {
}
node_type extract(const_iterator position) {
- AssertIsFull(position.inner_.ctrl_);
+ ABSL_INTERNAL_ASSERT_IS_FULL(position.inner_.ctrl_,
+ "extract() called on invalid iterator.")
auto node =
CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
erase_meta_only(position);
@@ -2263,4 +2278,6 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
ABSL_NAMESPACE_END
} // namespace absl
+#undef ABSL_INTERNAL_ASSERT_IS_FULL
+
#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_