[wpiutil] Replace LLVM StringMap impl with std::map

As string_view operations on std::map<std::string> won't be integrated
until C++26, placeholder implementations are used which are less efficient
in a couple of situations (e.g. insert with hint).
This commit is contained in:
Peter Johnson
2024-10-23 21:33:12 -07:00
parent 5f3cf517d3
commit f620141e0d
34 changed files with 944 additions and 2031 deletions

View File

@@ -8,8 +8,6 @@ Subject: [PATCH 01/38] Remove StringRef, ArrayRef, and Optional
llvm/include/llvm/ADT/SmallSet.h | 2 +-
llvm/include/llvm/ADT/SmallString.h | 103 ++++++++++--------
llvm/include/llvm/ADT/SmallVector.h | 7 +-
llvm/include/llvm/ADT/StringMap.h | 38 +++----
llvm/include/llvm/ADT/StringMapEntry.h | 20 ++--
llvm/include/llvm/Support/Chrono.h | 10 +-
llvm/include/llvm/Support/Compiler.h | 2 +-
llvm/include/llvm/Support/ConvertUTF.h | 31 +++---
@@ -22,7 +20,6 @@ Subject: [PATCH 01/38] Remove StringRef, ArrayRef, and Optional
llvm/lib/Support/ConvertUTFWrapper.cpp | 38 +++----
llvm/lib/Support/ErrorHandling.cpp | 13 +--
llvm/lib/Support/SmallVector.cpp | 5 +-
llvm/lib/Support/StringMap.cpp | 12 +-
llvm/lib/Support/raw_ostream.cpp | 25 ++---
llvm/lib/Support/xxhash.cpp | 10 +-
llvm/unittests/ADT/DenseMapTest.cpp | 29 +----
@@ -31,7 +28,6 @@ Subject: [PATCH 01/38] Remove StringRef, ArrayRef, and Optional
llvm/unittests/ADT/SmallPtrSetTest.cpp | 1 -
llvm/unittests/ADT/SmallStringTest.cpp | 50 ++++-----
llvm/unittests/ADT/SmallVectorTest.cpp | 30 +----
llvm/unittests/ADT/StringMapTest.cpp | 32 +++---
llvm/unittests/Support/ConvertUTFTest.cpp | 41 ++++---
llvm/unittests/Support/xxhashTest.cpp | 4 +-
30 files changed, 282 insertions(+), 323 deletions(-)
@@ -372,230 +368,6 @@ index 09676d792dfebd88e5c8eace666b3ab0044a962e..c96fd0e4956ee6d586f85dc79623de13
this->append(A.begin(), A.end());
}
diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
index 466f95254d102e98343290b211f317f749d7692b..34dfbf83c681f4e81a9dadd9382ddca6ef8d6c1d 100644
--- a/llvm/include/llvm/ADT/StringMap.h
+++ b/llvm/include/llvm/ADT/StringMap.h
@@ -60,12 +60,12 @@ protected:
/// specified bucket will be non-null. Otherwise, it will be null. In either
/// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string.
- unsigned LookupBucketFor(StringRef Key);
+ unsigned LookupBucketFor(std::string_view Key);
/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key. Otherwise return -1.
/// This does not modify the map.
- int FindKey(StringRef Key) const;
+ int FindKey(std::string_view Key) const;
/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
/// delete it. This aborts if the value isn't in the table.
@@ -73,7 +73,7 @@ protected:
/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null.
- StringMapEntryBase *RemoveKey(StringRef Key);
+ StringMapEntryBase *RemoveKey(std::string_view Key);
/// Allocate the table with the specified number of buckets and otherwise
/// setup the map as empty.
@@ -127,7 +127,7 @@ public:
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
AllocTy(A) {}
- StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
+ StringMap(std::initializer_list<std::pair<std::string_view, ValueTy>> List)
: StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
insert(List);
}
@@ -215,14 +215,14 @@ public:
StringMapKeyIterator<ValueTy>(end()));
}
- iterator find(StringRef Key) {
+ iterator find(std::string_view Key) {
int Bucket = FindKey(Key);
if (Bucket == -1)
return end();
return iterator(TheTable + Bucket, true);
}
- const_iterator find(StringRef Key) const {
+ const_iterator find(std::string_view Key) const {
int Bucket = FindKey(Key);
if (Bucket == -1)
return end();
@@ -231,7 +231,7 @@ public:
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
- ValueTy lookup(StringRef Key) const {
+ ValueTy lookup(std::string_view Key) const {
const_iterator Iter = find(Key);
if (Iter != end())
return Iter->second;
@@ -240,7 +240,7 @@ public:
/// at - Return the entry for the specified key, or abort if no such
/// entry exists.
- const ValueTy &at(StringRef Val) const {
+ const ValueTy &at(std::string_view Val) const {
auto Iter = this->find(std::move(Val));
assert(Iter != this->end() && "StringMap::at failed due to a missing key");
return Iter->second;
@@ -248,13 +248,13 @@ public:
/// Lookup the ValueTy for the \p Key, or create a default constructed value
/// if the key is not in the map.
- ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
+ ValueTy &operator[](std::string_view Key) { return try_emplace(Key).first->second; }
/// contains - Return true if the element is in the map, false otherwise.
- bool contains(StringRef Key) const { return find(Key) != end(); }
+ bool contains(std::string_view Key) const { return find(Key) != end(); }
/// count - Return 1 if the element is in the map, 0 otherwise.
- size_type count(StringRef Key) const { return contains(Key) ? 1 : 0; }
+ size_type count(std::string_view Key) const { return contains(Key) ? 1 : 0; }
template <typename InputTy>
size_type count(const StringMapEntry<InputTy> &MapEntry) const {
@@ -304,7 +304,7 @@ public:
/// isn't already in the map. The bool component of the returned pair is true
/// if and only if the insertion takes place, and the iterator component of
/// the pair points to the element with key equivalent to the key of the pair.
- std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
+ std::pair<iterator, bool> insert(std::pair<std::string_view, ValueTy> KV) {
return try_emplace(KV.first, std::move(KV.second));
}
@@ -319,14 +319,14 @@ public:
/// Inserts elements from initializer list ilist. If multiple elements in
/// the range have keys that compare equivalent, it is unspecified which
/// element is inserted
- void insert(std::initializer_list<std::pair<StringRef, ValueTy>> List) {
+ void insert(std::initializer_list<std::pair<std::string_view, ValueTy>> List) {
insert(List.begin(), List.end());
}
/// Inserts an element or assigns to the current element if the key already
/// exists. The return type is the same as try_emplace.
template <typename V>
- std::pair<iterator, bool> insert_or_assign(StringRef Key, V &&Val) {
+ std::pair<iterator, bool> insert_or_assign(std::string_view Key, V &&Val) {
auto Ret = try_emplace(Key, std::forward<V>(Val));
if (!Ret.second)
Ret.first->second = std::forward<V>(Val);
@@ -338,7 +338,7 @@ public:
/// if and only if the insertion takes place, and the iterator component of
/// the pair points to the element with key equivalent to the key of the pair.
template <typename... ArgsTy>
- std::pair<iterator, bool> try_emplace(StringRef Key, ArgsTy &&...Args) {
+ std::pair<iterator, bool> try_emplace(std::string_view Key, ArgsTy &&...Args) {
unsigned BucketNo = LookupBucketFor(Key);
StringMapEntryBase *&Bucket = TheTable[BucketNo];
if (Bucket && Bucket != getTombstoneVal())
@@ -385,7 +385,7 @@ public:
V.Destroy(getAllocator());
}
- bool erase(StringRef Key) {
+ bool erase(std::string_view Key) {
iterator I = find(Key);
if (I == end())
return false;
@@ -482,17 +482,17 @@ template <typename ValueTy>
class StringMapKeyIterator
: public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
StringMapConstIterator<ValueTy>,
- std::forward_iterator_tag, StringRef> {
+ std::forward_iterator_tag, std::string_view> {
using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
StringMapConstIterator<ValueTy>,
- std::forward_iterator_tag, StringRef>;
+ std::forward_iterator_tag, std::string_view>;
public:
StringMapKeyIterator() = default;
explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
: base(std::move(Iter)) {}
- StringRef operator*() const { return this->wrapped()->getKey(); }
+ std::string_view operator*() const { return this->wrapped()->getKey(); }
};
} // end namespace llvm
diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
index 98b51cc1aebd59eba20076e6d8a4eebc0eebb982..388e81c361642113937f7d5680de73a50635b07d 100644
--- a/llvm/include/llvm/ADT/StringMapEntry.h
+++ b/llvm/include/llvm/ADT/StringMapEntry.h
@@ -16,8 +16,8 @@
#ifndef LLVM_ADT_STRINGMAPENTRY_H
#define LLVM_ADT_STRINGMAPENTRY_H
-#include "llvm/ADT/StringRef.h"
#include <optional>
+#include <string_view>
namespace llvm {
@@ -36,13 +36,13 @@ protected:
/// type-erase the allocator and put it in a source file.
template <typename AllocatorTy>
static void *allocateWithKey(size_t EntrySize, size_t EntryAlign,
- StringRef Key, AllocatorTy &Allocator);
+ std::string_view Key, AllocatorTy &Allocator);
};
// Define out-of-line to dissuade inlining.
template <typename AllocatorTy>
void *StringMapEntryBase::allocateWithKey(size_t EntrySize, size_t EntryAlign,
- StringRef Key,
+ std::string_view Key,
AllocatorTy &Allocator) {
size_t KeyLength = Key.size();
@@ -105,8 +105,8 @@ public:
using ValueType = ValueTy;
- StringRef getKey() const {
- return StringRef(getKeyData(), this->getKeyLength());
+ std::string_view getKey() const {
+ return std::string_view(getKeyData(), this->getKeyLength());
}
/// getKeyData - Return the start of the string data that is the key for this
@@ -116,15 +116,15 @@ public:
return reinterpret_cast<const char *>(this + 1);
}
- StringRef first() const {
- return StringRef(getKeyData(), this->getKeyLength());
+ std::string_view first() const {
+ return std::string_view(getKeyData(), this->getKeyLength());
}
/// Create a StringMapEntry for the specified key construct the value using
/// \p InitiVals.
template <typename AllocatorTy, typename... InitTy>
- static StringMapEntry *create(StringRef key, AllocatorTy &allocator,
- InitTy &&...initVals) {
+ static StringMapEntry *create(std::string_view key, AllocatorTy &allocator,
+ InitTy &&... initVals) {
return new (StringMapEntryBase::allocateWithKey(
sizeof(StringMapEntry), alignof(StringMapEntry), key, allocator))
StringMapEntry(key.size(), std::forward<InitTy>(initVals)...);
@@ -167,7 +167,7 @@ struct tuple_size<llvm::StringMapEntry<ValueTy>>
template <std::size_t I, typename ValueTy>
struct tuple_element<I, llvm::StringMapEntry<ValueTy>>
- : std::conditional<I == 0, llvm::StringRef, ValueTy> {};
+ : std::conditional<I == 0, std::string_view, ValueTy> {};
} // namespace std
#endif // LLVM_ADT_STRINGMAPENTRY_H
diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h
index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702c61f4326 100644
--- a/llvm/include/llvm/Support/Chrono.h
@@ -1228,63 +1000,6 @@ index b6ce37842040b36fc79770ca0296255f2bb42a1a..4f6fee18b659adcbfd79822832f91417
#endif
}
diff --git a/llvm/lib/Support/StringMap.cpp b/llvm/lib/Support/StringMap.cpp
index 67c05a87959cf0c243d17646ae2f28f6c9f0d708..7be219323f6d76f32a9a841115f2f146141cdbab 100644
--- a/llvm/lib/Support/StringMap.cpp
+++ b/llvm/lib/Support/StringMap.cpp
@@ -81,7 +81,7 @@ void StringMapImpl::init(unsigned InitSize) {
/// specified bucket will be non-null. Otherwise, it will be null. In either
/// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string.
-unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
+unsigned StringMapImpl::LookupBucketFor(std::string_view Name) {
// Hash table unallocated so far?
if (NumBuckets == 0)
init(16);
@@ -121,7 +121,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
// Do the comparison like this because Name isn't necessarily
// null-terminated!
char *ItemStr = (char *)BucketItem + ItemSize;
- if (Name == StringRef(ItemStr, BucketItem->getKeyLength())) {
+ if (Name == std::string_view(ItemStr, BucketItem->getKeyLength())) {
// We found a match!
return BucketNo;
}
@@ -139,7 +139,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key. Otherwise return -1.
/// This does not modify the map.
-int StringMapImpl::FindKey(StringRef Key) const {
+int StringMapImpl::FindKey(std::string_view Key) const {
if (NumBuckets == 0)
return -1; // Really empty table?
unsigned FullHashValue = xxh3_64bits(Key);
@@ -166,7 +166,7 @@ int StringMapImpl::FindKey(StringRef Key) const {
// Do the comparison like this because NameStart isn't necessarily
// null-terminated!
char *ItemStr = (char *)BucketItem + ItemSize;
- if (Key == StringRef(ItemStr, BucketItem->getKeyLength())) {
+ if (Key == std::string_view(ItemStr, BucketItem->getKeyLength())) {
// We found a match!
return BucketNo;
}
@@ -185,14 +185,14 @@ int StringMapImpl::FindKey(StringRef Key) const {
/// delete it. This aborts if the value isn't in the table.
void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
const char *VStr = (char *)V + ItemSize;
- StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength()));
+ StringMapEntryBase *V2 = RemoveKey(std::string_view(VStr, V->getKeyLength()));
(void)V2;
assert(V == V2 && "Didn't find key?");
}
/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null.
-StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
+StringMapEntryBase *StringMapImpl::RemoveKey(std::string_view Key) {
int Bucket = FindKey(Key);
if (Bucket == -1)
return nullptr;
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 3d3a564af51d120786b358b96a3c90e2b7fbf9f3..220d850b9bc69f8fc2fba7cd23629eca487cde23 100644
--- a/llvm/lib/Support/raw_ostream.cpp
@@ -1746,132 +1461,6 @@ index 137dd43b473068eae34b39edc4b9b8b9633bab95..7029038d18d433cef987bedbfa4fda26
{
llvm::SmallVector<To> Vector(Array);
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index f9b138e9a472137139397d9cae76823711594211..7f10b3d7d3a8894b1ab0ac660268d94a8b89e082 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -7,8 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include "gtest/gtest.h"
#include <limits>
@@ -43,10 +41,10 @@ protected:
// Lookup tests
EXPECT_FALSE(testMap.contains(testKey));
EXPECT_EQ(0u, testMap.count(testKey));
- EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
+ EXPECT_EQ(0u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
EXPECT_EQ(0u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.end());
- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
+ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
testMap.end());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
}
@@ -67,10 +65,10 @@ protected:
// Lookup tests
EXPECT_TRUE(testMap.contains(testKey));
EXPECT_EQ(1u, testMap.count(testKey));
- EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
+ EXPECT_EQ(1u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
EXPECT_EQ(1u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
+ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
testMap.begin());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
}
@@ -108,10 +106,10 @@ TEST_F(StringMapTest, ConstEmptyMapTest) {
// Lookup tests
EXPECT_EQ(0u, constTestMap.count(testKey));
- EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
+ EXPECT_EQ(0u, constTestMap.count(std::string_view(testKeyFirst, testKeyLength)));
EXPECT_EQ(0u, constTestMap.count(testKeyStr));
EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
- EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
+ EXPECT_TRUE(constTestMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
constTestMap.end());
EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
}
@@ -251,7 +249,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
MallocAllocator Allocator;
StringMap<uint32_t>::value_type *entry =
StringMap<uint32_t>::value_type::create(
- StringRef(testKeyFirst, testKeyLength), Allocator, 1u);
+ std::string_view(testKeyFirst, testKeyLength), Allocator, 1u);
EXPECT_STREQ(testKey, entry->first().data());
EXPECT_EQ(1u, entry->second);
entry->Destroy(Allocator);
@@ -261,7 +259,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
TEST_F(StringMapTest, InsertTest) {
SCOPED_TRACE("InsertTest");
testMap.insert(StringMap<uint32_t>::value_type::create(
- StringRef(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u));
+ std::string_view(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u));
assertSingleItemMap();
}
@@ -330,10 +328,10 @@ TEST_F(StringMapTest, IterMapKeysVector) {
Map["C"] = 3;
Map["D"] = 3;
- std::vector<StringRef> Keys{Map.keys().begin(), Map.keys().end()};
+ std::vector<std::string_view> Keys{Map.keys().begin(), Map.keys().end()};
llvm::sort(Keys);
- std::vector<StringRef> Expected{{"A", "B", "C", "D"}};
+ std::vector<std::string_view> Expected{{"A", "B", "C", "D"}};
EXPECT_EQ(Expected, Keys);
}
@@ -347,7 +345,7 @@ TEST_F(StringMapTest, IterMapKeysSmallVector) {
auto Keys = to_vector<4>(Map.keys());
llvm::sort(Keys);
- SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
+ SmallVector<std::string_view, 4> Expected = {"A", "B", "C", "D"};
EXPECT_EQ(Expected, Keys);
}
@@ -389,13 +387,13 @@ private:
TEST_F(StringMapTest, MoveOnly) {
StringMap<MoveOnly> t;
t.insert(std::make_pair("Test", MoveOnly(42)));
- StringRef Key = "Test";
+ std::string_view Key = "Test";
StringMapEntry<MoveOnly>::create(Key, t.getAllocator(), MoveOnly(42))
->Destroy(t.getAllocator());
}
TEST_F(StringMapTest, CtorArg) {
- StringRef Key = "Test";
+ std::string_view Key = "Test";
MallocAllocator Allocator;
StringMapEntry<MoveOnly>::create(Key, Allocator, Immovable())
->Destroy(Allocator);
@@ -580,7 +578,7 @@ TEST(StringMapCustomTest, InitialSizeTest) {
CountCtorCopyAndMove::Copy = 0;
for (int i = 0; i < Size; ++i)
Map.insert(std::pair<std::string, CountCtorCopyAndMove>(
- std::piecewise_construct, std::forward_as_tuple(Twine(i).str()),
+ std::piecewise_construct, std::forward_as_tuple(std::to_string(i)),
std::forward_as_tuple(i)));
// After the initial move, the map will move the Elts in the Entry.
EXPECT_EQ((unsigned)Size * 2, CountCtorCopyAndMove::Move);
@@ -649,7 +647,7 @@ TEST(StringMapCustomTest, StringMapEntrySize) {
else
LargeValue = std::numeric_limits<unsigned>::max() + 1ULL;
StringMapEntry<int> LargeEntry(LargeValue);
- StringRef Key = LargeEntry.getKey();
+ std::string_view Key = LargeEntry.getKey();
EXPECT_EQ(LargeValue, Key.size());
// Test that the entry can hold at least max size_t.
diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b8a4fa472 100644
--- a/llvm/unittests/Support/ConvertUTFTest.cpp

View File

@@ -8,7 +8,6 @@ Subject: [PATCH 06/38] Explicitly use std::
llvm/lib/Support/ErrorHandling.cpp | 2 +-
llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 +-
llvm/unittests/ADT/SmallSetTest.cpp | 10 +++++-----
llvm/unittests/ADT/StringMapTest.cpp | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h
@@ -100,16 +99,3 @@ index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574
EXPECT_EQ(4u, s1.size());
EXPECT_EQ("str 0", V[0]);
EXPECT_EQ("str 1", V[1]);
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index 7f10b3d7d3a8894b1ab0ac660268d94a8b89e082..acd8b566f9c7a6efc2c9204624c01104dd34daf6 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -343,7 +343,7 @@ TEST_F(StringMapTest, IterMapKeysSmallVector) {
Map["D"] = 3;
auto Keys = to_vector<4>(Map.keys());
- llvm::sort(Keys);
+ std::sort(Keys.begin(), Keys.end());
SmallVector<std::string_view, 4> Expected = {"A", "B", "C", "D"};
EXPECT_EQ(Expected, Keys);

View File

@@ -4,143 +4,9 @@ Date: Tue, 3 May 2022 22:16:10 -0400
Subject: [PATCH 12/38] Extra collections features
---
llvm/include/llvm/ADT/StringMap.h | 103 +++++++++++++++++++++++++++++-
llvm/lib/Support/raw_ostream.cpp | 8 +++
2 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
index 34dfbf83c681f4e81a9dadd9382ddca6ef8d6c1d..c133e84f9b2e3a225cdac782c011fadbf07adab2 100644
--- a/llvm/include/llvm/ADT/StringMap.h
+++ b/llvm/include/llvm/ADT/StringMap.h
@@ -42,7 +42,7 @@ protected:
protected:
explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {}
- StringMapImpl(StringMapImpl &&RHS)
+ StringMapImpl(StringMapImpl &&RHS) noexcept
: TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
ItemSize(RHS.ItemSize) {
@@ -432,11 +432,27 @@ public:
return Tmp;
}
+ DerivedTy &operator--() { // Predecrement
+ --Ptr;
+ ReversePastEmptyBuckets();
+ return static_cast<DerivedTy &>(*this);
+ }
+
+ DerivedTy operator--(int) { // Post-decrement
+ DerivedTy Tmp(Ptr);
+ --*this;
+ return Tmp;
+ }
+
private:
void AdvancePastEmptyBuckets() {
while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
++Ptr;
}
+ void ReversePastEmptyBuckets() {
+ while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
+ --Ptr;
+ }
};
template <typename ValueTy>
@@ -495,6 +511,91 @@ public:
std::string_view operator*() const { return this->wrapped()->getKey(); }
};
+template <typename ValueTy>
+bool operator==(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
+ // same instance?
+ if (&lhs == &rhs) return true;
+
+ // first check that sizes are identical
+ if (lhs.size() != rhs.size()) return false;
+
+ // copy into vectors and sort by key
+ SmallVector<StringMapConstIterator<ValueTy>, 16> lhs_items;
+ lhs_items.reserve(lhs.size());
+ for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
+ lhs_items.push_back(i);
+ std::sort(lhs_items.begin(), lhs_items.end(),
+ [](const StringMapConstIterator<ValueTy>& a,
+ const StringMapConstIterator<ValueTy>& b) {
+ return a->getKey() < b->getKey();
+ });
+
+ SmallVector<StringMapConstIterator<ValueTy>, 16> rhs_items;
+ rhs_items.reserve(rhs.size());
+ for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
+ rhs_items.push_back(i);
+ std::sort(rhs_items.begin(), rhs_items.end(),
+ [](const StringMapConstIterator<ValueTy>& a,
+ const StringMapConstIterator<ValueTy>& b) {
+ return a->getKey() < b->getKey();
+ });
+
+ // compare vector keys and values
+ for (auto a = lhs_items.begin(), b = rhs_items.begin(),
+ aend = lhs_items.end(), bend = rhs_items.end();
+ a != aend && b != bend; ++a, ++b) {
+ if ((*a)->first() != (*b)->first() || (*a)->second != (*b)->second)
+ return false;
+ }
+ return true;
+}
+
+template <typename ValueTy>
+inline bool operator!=(const StringMap<ValueTy>& lhs,
+ const StringMap<ValueTy>& rhs) {
+ return !(lhs == rhs);
+}
+
+template <typename ValueTy>
+bool operator<(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
+ // same instance?
+ if (&lhs == &rhs) return false;
+
+ // copy into vectors and sort by key
+ SmallVector<std::string_view, 16> lhs_keys;
+ lhs_keys.reserve(lhs.size());
+ for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
+ lhs_keys.push_back(i->getKey());
+ std::sort(lhs_keys.begin(), lhs_keys.end());
+
+ SmallVector<std::string_view, 16> rhs_keys;
+ rhs_keys.reserve(rhs.size());
+ for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
+ rhs_keys.push_back(i->getKey());
+ std::sort(rhs_keys.begin(), rhs_keys.end());
+
+ // use std::vector comparison
+ return lhs_keys < rhs_keys;
+}
+
+template <typename ValueTy>
+inline bool operator<=(const StringMap<ValueTy>& lhs,
+ const StringMap<ValueTy>& rhs) {
+ return !(rhs < lhs);
+}
+
+template <typename ValueTy>
+inline bool operator>(const StringMap<ValueTy>& lhs,
+ const StringMap<ValueTy>& rhs) {
+ return !(lhs <= rhs);
+}
+
+template <typename ValueTy>
+inline bool operator>=(const StringMap<ValueTy>& lhs,
+ const StringMap<ValueTy>& rhs) {
+ return !(lhs < rhs);
+}
+
} // end namespace llvm
#endif // LLVM_ADT_STRINGMAP_H
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 57d3091fd5cc5b416e814f9f33811f0fa7afe9cf..5bec803ccc76ce287b7ff3ea037d5e490a7af20c 100644
--- a/llvm/lib/Support/raw_ostream.cpp

View File

@@ -4,48 +4,15 @@ Date: Sun, 8 May 2022 16:38:11 -0400
Subject: [PATCH 16/38] Fixup includes
---
llvm/include/llvm/ADT/StringMap.h | 4 ++++
llvm/include/llvm/ADT/StringMapEntry.h | 4 ++++
llvm/include/llvm/Support/PointerLikeTypeTraits.h | 1 +
llvm/lib/Support/ConvertUTFWrapper.cpp | 1 +
llvm/lib/Support/ErrorHandling.cpp | 7 +++----
llvm/lib/Support/raw_ostream.cpp | 11 ++++++-----
llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 ++
llvm/unittests/ADT/SmallVectorTest.cpp | 1 +
llvm/unittests/ADT/StringMapTest.cpp | 1 +
llvm/unittests/Support/ConvertUTFTest.cpp | 2 ++
10 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
index c133e84f9b2e3a225cdac782c011fadbf07adab2..2173a4159111e7fea70325de82dbfce628ae3ea8 100644
--- a/llvm/include/llvm/ADT/StringMap.h
+++ b/llvm/include/llvm/ADT/StringMap.h
@@ -17,6 +17,10 @@
#include "llvm/ADT/StringMapEntry.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/AllocatorBase.h"
+#include "llvm/Support/MemAlloc.h"
+#include "llvm/Support/SmallVector.h"
+#include "llvm/Support/iterator.h"
+#include "llvm/Support/iterator_range.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <initializer_list>
#include <iterator>
diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
index 388e81c361642113937f7d5680de73a50635b07d..011806f5fd89ff738ed805a82b3ddbc6fc9b08ce 100644
--- a/llvm/include/llvm/ADT/StringMapEntry.h
+++ b/llvm/include/llvm/ADT/StringMapEntry.h
@@ -16,6 +16,10 @@
#ifndef LLVM_ADT_STRINGMAPENTRY_H
#define LLVM_ADT_STRINGMAPENTRY_H
+#include "wpi/MemAlloc.h"
+
+#include <cassert>
+#include <cstring>
#include <optional>
#include <string_view>
diff --git a/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/llvm/include/llvm/Support/PointerLikeTypeTraits.h
index 1b15f930bd87d97d51824af5e62ea5f222a6b4c9..acadd5e89a1651cfbad67a5b1b0933d1f288d094 100644
--- a/llvm/include/llvm/Support/PointerLikeTypeTraits.h
@@ -153,18 +120,6 @@ index f8c37820ef9fdfe0af067f5aa8d2297ed15e73bc..5e91f71bc9ac0e499a64dd1591e581d0
#include <list>
#include <span>
#include <stdarg.h>
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index acd8b566f9c7a6efc2c9204624c01104dd34daf6..6b6cf564909f329c220eb225f3b7af6c35301029 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
#include "gtest/gtest.h"
+#include <algorithm>
#include <limits>
#include <tuple>
using namespace llvm;
diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
index 3b07d344f15a555f11ad5f8177a0a65b8a4fa472..77e70a46d3621ecfaed923d87256184addfda721 100644
--- a/llvm/unittests/Support/ConvertUTFTest.cpp

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Wed, 10 Aug 2022 22:35:00 -0700
Subject: [PATCH 27/38] Remove StringMap test for llvm::sort()
---
llvm/unittests/ADT/StringMapTest.cpp | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index 6b6cf564909f329c220eb225f3b7af6c35301029..0d83669a580408e925ec6308410ebe7c01b48b12 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -322,20 +322,6 @@ TEST_F(StringMapTest, InsertOrAssignTest) {
EXPECT_EQ(0, try1.first->second.copy);
}
-TEST_F(StringMapTest, IterMapKeysVector) {
- StringMap<int> Map;
- Map["A"] = 1;
- Map["B"] = 2;
- Map["C"] = 3;
- Map["D"] = 3;
-
- std::vector<std::string_view> Keys{Map.keys().begin(), Map.keys().end()};
- llvm::sort(Keys);
-
- std::vector<std::string_view> Expected{{"A", "B", "C", "D"}};
- EXPECT_EQ(Expected, Keys);
-}
-
TEST_F(StringMapTest, IterMapKeysSmallVector) {
StringMap<int> Map;
Map["A"] = 1;

View File

@@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ryan Blue <ryanzblue@gmail.com>
Date: Tue, 24 Sep 2024 23:36:16 -0400
Subject: [PATCH 38/38] StringMap: fix structured bindings with move-only types
---
llvm/include/llvm/ADT/StringMapEntry.h | 12 +++++++++++-
llvm/unittests/ADT/StringMapTest.cpp | 10 ++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
index 011806f5fd89ff738ed805a82b3ddbc6fc9b08ce..5b8eeb167c53c7ab15d05b0c71b75cd7f5b496c5 100644
--- a/llvm/include/llvm/ADT/StringMapEntry.h
+++ b/llvm/include/llvm/ADT/StringMapEntry.h
@@ -159,7 +159,17 @@ decltype(auto) get(const StringMapEntry<ValueTy> &E) {
if constexpr (Index == 0)
return E.first();
else
- return E.second;
+ return (E.second);
+}
+
+// Allow structured bindings on StringMapEntry.
+template <std::size_t Index, typename ValueTy>
+decltype(auto) get(StringMapEntry<ValueTy> &E) {
+ static_assert(Index < 2);
+ if constexpr (Index == 0)
+ return E.first();
+ else
+ return (E.second);
}
} // end namespace llvm
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index 0d83669a580408e925ec6308410ebe7c01b48b12..f1834bec65afec6be4365e52c4e21aa61cbb1d12 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -526,6 +526,16 @@ TEST_F(StringMapTest, StructuredBindings) {
}
}
+TEST_F(StringMapTest, StructuredBindingsMoveOnly) {
+ StringMap<MoveOnly> A;
+ A.insert(std::make_pair("a", MoveOnly(42)));
+
+ for (auto &&[Key, Value] : A) {
+ EXPECT_EQ("a", Key);
+ EXPECT_EQ(42, Value.i);
+ }
+}
+
namespace {
// Simple class that counts how many moves and copy happens when growing a map
struct CountCtorCopyAndMove {