summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2018-11-01 14:00:22 -0700
committerGravatar Matt Calabrese <calabrese@x.team>2018-11-02 12:35:09 -0400
commitf95179062eb65ce40895cc76f1398cce25394369 (patch)
tree9506d0c91321ddc6c4d487d130676b444fe5b88f
parentcc8dcd307b76a575d2e3e0958a4fe4c7193c2f68 (diff)
Export of internal Abseil changes.
-- 4e224c85c3730398919fc5195cb1fc7a752e6e4f by Mark Barolak <mbar@google.com>: Update some references to "StringPiece" to say "string_view" instead. PiperOrigin-RevId: 219693697 -- 6bdc925a3db5e97f1f8a404bdfda2e47e48f7b9a by Abseil Team <absl-team@google.com>: Disable weak symbols for the Windows backend of LLVM, since they are currently buggy. See https://bugs.llvm.org/show_bug.cgi?id=37598 for more information. PiperOrigin-RevId: 219676493 -- 5823f495036181191f435efa4c45d60ca3160145 by Derek Mauro <dmauro@google.com>: Don't use the SSE2 implementation of container_internal::Group with -funsigned-char under GCC. This is a workaround for https://github.com/abseil/abseil-cpp/issues/209. _mm_cmpgt_epi8 is broken under GCC with -funsigned-char. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 PiperOrigin-RevId: 219666066 GitOrigin-RevId: 4e224c85c3730398919fc5195cb1fc7a752e6e4f Change-Id: I2f115d0256576cf476ae73a9464c21d4106a2a56
-rw-r--r--absl/base/attributes.h13
-rw-r--r--absl/container/internal/raw_hash_set.h28
-rw-r--r--absl/container/internal/raw_hash_set_test.cc67
-rw-r--r--absl/strings/str_cat.cc2
-rw-r--r--absl/strings/str_split_benchmark.cc8
5 files changed, 71 insertions, 47 deletions
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index e8500224..c44b8828 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -155,7 +155,12 @@
// ABSL_ATTRIBUTE_WEAK
//
// Tags a function as weak for the purposes of compilation and linking.
-#if ABSL_HAVE_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__))
+// Weak attributes currently do not work properly in LLVM's Windows backend,
+// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
+// for futher information.
+#if (ABSL_HAVE_ATTRIBUTE(weak) || \
+ (defined(__GNUC__) && !defined(__clang__))) && \
+ !(defined(__llvm__) && defined(_WIN32))
#undef ABSL_ATTRIBUTE_WEAK
#define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
#define ABSL_HAVE_ATTRIBUTE_WEAK 1
@@ -296,13 +301,13 @@
// ABSL_HAVE_ATTRIBUTE_SECTION
//
-// Indicates whether labeled sections are supported. Labeled sections are not
-// supported on Darwin/iOS.
+// Indicates whether labeled sections are supported. Weak symbol support is
+// a prerequisite. Labeled sections are not supported on Darwin/iOS.
#ifdef ABSL_HAVE_ATTRIBUTE_SECTION
#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set
#elif (ABSL_HAVE_ATTRIBUTE(section) || \
(defined(__GNUC__) && !defined(__clang__))) && \
- !defined(__APPLE__)
+ !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK
#define ABSL_HAVE_ATTRIBUTE_SECTION 1
// ABSL_ATTRIBUTE_SECTION
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index aa423b25..78382a35 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -337,10 +337,10 @@ inline bool IsDeleted(ctrl_t c) { return c == kDeleted; }
inline bool IsEmptyOrDeleted(ctrl_t c) { return c < kSentinel; }
#if SWISSTABLE_HAVE_SSE2
-struct Group {
+struct GroupSse2Impl {
static constexpr size_t kWidth = 16; // the number of slots per group
- explicit Group(const ctrl_t* pos) {
+ explicit GroupSse2Impl(const ctrl_t* pos) {
ctrl = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pos));
}
@@ -390,11 +390,13 @@ struct Group {
__m128i ctrl;
};
-#else
-struct Group {
+#endif // SWISSTABLE_HAVE_SSE2
+
+struct GroupPortableImpl {
static constexpr size_t kWidth = 8;
- explicit Group(const ctrl_t* pos) : ctrl(little_endian::Load64(pos)) {}
+ explicit GroupPortableImpl(const ctrl_t* pos)
+ : ctrl(little_endian::Load64(pos)) {}
BitMask<uint64_t, kWidth, 3> Match(h2_t hash) const {
// For the technique, see:
@@ -441,12 +443,24 @@ struct Group {
uint64_t ctrl;
};
-#endif // SWISSTABLE_HAVE_SSE2
+
+#if SWISSTABLE_HAVE_SSE2 && defined(__GNUC__) && !defined(__clang__)
+// https://github.com/abseil/abseil-cpp/issues/209
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853
+// _mm_cmpgt_epi8 is broken under GCC with -funsigned-char
+// Work around this by using the portable implementation of Group
+// when using -funsigned-char under GCC.
+using Group = std::conditional<std::is_signed<char>::value, GroupSse2Impl,
+ GroupPortableImpl>::type;
+#elif SWISSTABLE_HAVE_SSE2
+using Group = GroupSse2Impl;
+#else
+using Group = GroupPortableImpl;
+#endif
template <class Policy, class Hash, class Eq, class Alloc>
class raw_hash_set;
-
inline bool IsValidCapacity(size_t n) {
return ((n + 1) & n) == 0 && n >= Group::kWidth - 1;
}
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index f48578eb..b66a8f16 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -130,45 +130,50 @@ TEST(Group, EmptyGroup) {
for (h2_t h = 0; h != 128; ++h) EXPECT_FALSE(Group{EmptyGroup()}.Match(h));
}
-#if SWISSTABLE_HAVE_SSE2
TEST(Group, Match) {
- ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
- 7, 5, 3, 1, 1, 1, 1, 1};
- EXPECT_THAT(Group{group}.Match(0), ElementsAre());
- EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15));
- EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10));
- EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9));
- EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8));
+ if (Group::kWidth == 16) {
+ ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
+ 7, 5, 3, 1, 1, 1, 1, 1};
+ EXPECT_THAT(Group{group}.Match(0), ElementsAre());
+ EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15));
+ EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10));
+ EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9));
+ EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8));
+ } else if (Group::kWidth == 8) {
+ ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
+ EXPECT_THAT(Group{group}.Match(0), ElementsAre());
+ EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7));
+ EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4));
+ } else {
+ FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
+ }
}
TEST(Group, MatchEmpty) {
- ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
- 7, 5, 3, 1, 1, 1, 1, 1};
- EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4));
-}
-
-TEST(Group, MatchEmptyOrDeleted) {
- ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
- 7, 5, 3, 1, 1, 1, 1, 1};
- EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4));
-}
-#else
-TEST(Group, Match) {
- ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
- EXPECT_THAT(Group{group}.Match(0), ElementsAre());
- EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7));
- EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4));
-}
-TEST(Group, MatchEmpty) {
- ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
- EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0));
+ if (Group::kWidth == 16) {
+ ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
+ 7, 5, 3, 1, 1, 1, 1, 1};
+ EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4));
+ } else if (Group::kWidth == 8) {
+ ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
+ EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0));
+ } else {
+ FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
+ }
}
TEST(Group, MatchEmptyOrDeleted) {
- ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
- EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3));
+ if (Group::kWidth == 16) {
+ ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7,
+ 7, 5, 3, 1, 1, 1, 1, 1};
+ EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4));
+ } else if (Group::kWidth == 8) {
+ ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1};
+ EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3));
+ } else {
+ FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth;
+ }
}
-#endif
TEST(Batch, DropDeletes) {
constexpr size_t kCapacity = 63;
diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc
index efa4fd73..b14d571f 100644
--- a/absl/strings/str_cat.cc
+++ b/absl/strings/str_cat.cc
@@ -80,7 +80,7 @@ AlphaNum::AlphaNum(Dec dec) {
// StrCat()
// This merges the given strings or integers, with no delimiter. This
// is designed to be the fastest possible way to construct a string out
-// of a mix of raw C strings, StringPieces, strings, and integer values.
+// of a mix of raw C strings, string_views, strings, and integer values.
// ----------------------------------------------------------------------
// Append is merely a version of memcpy that returns the address of the byte
diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc
index 326ff744..0ac297c8 100644
--- a/absl/strings/str_split_benchmark.cc
+++ b/absl/strings/str_split_benchmark.cc
@@ -35,16 +35,16 @@ std::string MakeTestString(int desired_length) {
return test;
}
-void BM_Split2StringPiece(benchmark::State& state) {
+void BM_Split2StringView(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
for (auto _ : state) {
std::vector<absl::string_view> result = absl::StrSplit(test, ';');
benchmark::DoNotOptimize(result);
}
}
-BENCHMARK_RANGE(BM_Split2StringPiece, 0, 1 << 20);
+BENCHMARK_RANGE(BM_Split2StringView, 0, 1 << 20);
-void BM_Split2StringPieceLifted(benchmark::State& state) {
+void BM_Split2StringViewLifted(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
std::vector<absl::string_view> result;
for (auto _ : state) {
@@ -52,7 +52,7 @@ void BM_Split2StringPieceLifted(benchmark::State& state) {
}
benchmark::DoNotOptimize(result);
}
-BENCHMARK_RANGE(BM_Split2StringPieceLifted, 0, 1 << 20);
+BENCHMARK_RANGE(BM_Split2StringViewLifted, 0, 1 << 20);
void BM_Split2String(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));