From 42e7e81b8afa02b97d0c6589315c557b2d66ab1d Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 31 Aug 2025 22:14:20 -0700 Subject: [PATCH] [ADT] Simplify StringMapIterBase (NFC) In open-adressing hash tables, begin() needs to advance to the first valid element. We don't need to do the same for any other operations like end(), find(), and try_emplace(). The problem is that the constructor of StringMapIterBase says: bool NoAdvance = false This increases the burden on the callers because most places need to pass true for NoAdvance, defeating the benefit of the default parameter. This patch fixes the problem by changing the name and default to: bool Advance = false and adjusting callers. Again, begin() is the only caller that specifies this parameter. This patch fixes a "latent bug" where try_emplace() was requesting advancing even on a successful insertion. I say "latent" because the request is a no-op on success. --- llvm/include/llvm/ADT/StringMap.h | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h index ac66444968f8e..2c146fbf08df1 100644 --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -220,14 +220,12 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap using const_iterator = StringMapIterBase; using iterator = StringMapIterBase; - iterator begin() { return iterator(TheTable, NumBuckets == 0); } - iterator end() { return iterator(TheTable + NumBuckets, true); } + iterator begin() { return iterator(TheTable, NumBuckets != 0); } + iterator end() { return iterator(TheTable + NumBuckets); } const_iterator begin() const { - return const_iterator(TheTable, NumBuckets == 0); - } - const_iterator end() const { - return const_iterator(TheTable + NumBuckets, true); + return const_iterator(TheTable, NumBuckets != 0); } + const_iterator end() const { return const_iterator(TheTable + NumBuckets); } iterator_range> keys() const { return make_range(StringMapKeyIterator(begin()), @@ -240,7 +238,7 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap int Bucket = FindKey(Key, FullHashValue); if (Bucket == -1) return end(); - return iterator(TheTable + Bucket, true); + return iterator(TheTable + Bucket); } const_iterator find(StringRef Key) const { return find(Key, hash(Key)); } @@ -249,7 +247,7 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap int Bucket = FindKey(Key, FullHashValue); if (Bucket == -1) return end(); - return const_iterator(TheTable + Bucket, true); + return const_iterator(TheTable + Bucket); } /// lookup - Return the entry for the specified key, or a default @@ -380,8 +378,7 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap unsigned BucketNo = LookupBucketFor(Key, FullHashValue); StringMapEntryBase *&Bucket = TheTable[BucketNo]; if (Bucket && Bucket != getTombstoneVal()) - return {iterator(TheTable + BucketNo, false), - false}; // Already exists in map. + return {iterator(TheTable + BucketNo), false}; // Already exists in map. if (Bucket == getTombstoneVal()) --NumTombstones; @@ -391,7 +388,7 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap assert(NumItems + NumTombstones <= NumBuckets); BucketNo = RehashTable(BucketNo); - return {iterator(TheTable + BucketNo, false), true}; + return {iterator(TheTable + BucketNo), true}; } // clear - Empties out the StringMap @@ -444,10 +441,9 @@ template class StringMapIterBase { StringMapIterBase() = default; - explicit StringMapIterBase(StringMapEntryBase **Bucket, - bool NoAdvance = false) + explicit StringMapIterBase(StringMapEntryBase **Bucket, bool Advance = false) : Ptr(Bucket) { - if (!NoAdvance) + if (Advance) AdvancePastEmptyBuckets(); } @@ -469,7 +465,7 @@ template class StringMapIterBase { template ::type> operator StringMapIterBase() const { - return StringMapIterBase(Ptr, true); + return StringMapIterBase(Ptr); } friend bool operator==(const StringMapIterBase &LHS,