[llvm] [NFC][Support] Add RadixTree (PR #164524)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 23 21:06:55 PDT 2025


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/164524

>From 1e6377ab554f06c533a0e2b30d29794e5d0100f6 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 21 Oct 2025 17:55:10 -0700
Subject: [PATCH 01/11] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
 =?UTF-8?q?changes=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7

[skip ci]
---
 llvm/include/llvm/Support/GlobPattern.h    | 22 ++++---
 llvm/lib/Support/GlobPattern.cpp           | 67 +++++++++++++++++++---
 llvm/unittests/Support/GlobPatternTest.cpp | 66 +++++++++++++++++++++
 3 files changed, 140 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/Support/GlobPattern.h b/llvm/include/llvm/Support/GlobPattern.h
index c1b44849b9794..8b8ac89304e31 100644
--- a/llvm/include/llvm/Support/GlobPattern.h
+++ b/llvm/include/llvm/Support/GlobPattern.h
@@ -63,22 +63,30 @@ class GlobPattern {
   // Returns true for glob pattern "*". Can be used to avoid expensive
   // preparation/acquisition of the input for match().
   bool isTrivialMatchAll() const {
-    if (!Prefix.empty())
+    if (PrefixSize)
       return false;
-    if (!Suffix.empty())
+    if (SuffixSize)
       return false;
     if (SubGlobs.size() != 1)
       return false;
     return SubGlobs[0].getPat() == "*";
   }
 
-  StringRef prefix() const { return Prefix; }
-  StringRef suffix() const { return Suffix; }
+  // The following functions are just shortcuts for faster matching. They are
+  // conservative to simplify implementations.
 
-private:
-  StringRef Prefix;
-  StringRef Suffix;
+  // Returns plain prefix of the pattern.
+  StringRef prefix() const { return Pattern.take_front(PrefixSize); }
+  // Returns plain suffix of the pattern.
+  StringRef suffix() const { return Pattern.take_back(SuffixSize); }
+  // Returns the longest plain substring of the pattern between prefix and
+  // suffix.
+  StringRef longest_substr() const;
 
+private:
+  StringRef Pattern;
+  size_t PrefixSize = 0;
+  size_t SuffixSize = 0;
   struct SubGlobPattern {
     /// \param Pat the pattern to match against
     LLVM_ABI static Expected<SubGlobPattern> create(StringRef Pat);
diff --git a/llvm/lib/Support/GlobPattern.cpp b/llvm/lib/Support/GlobPattern.cpp
index 0ecf47dc1d3d1..2715229c65be1 100644
--- a/llvm/lib/Support/GlobPattern.cpp
+++ b/llvm/lib/Support/GlobPattern.cpp
@@ -132,24 +132,70 @@ parseBraceExpansions(StringRef S, std::optional<size_t> MaxSubPatterns) {
   return std::move(SubPatterns);
 }
 
+static StringRef maxPlainSubstring(StringRef S) {
+  StringRef Best;
+  while (!S.empty()) {
+    size_t PrefixSize = S.find_first_of("?*[{\\");
+    if (PrefixSize == std::string::npos)
+      PrefixSize = S.size();
+
+    if (Best.size() < PrefixSize)
+      Best = S.take_front(PrefixSize);
+
+    S = S.drop_front(PrefixSize);
+
+    // It's impossible, as the first and last characters of the input string
+    // must be Glob special characters, otherwise they would be parts of
+    // the prefix or the suffix.
+    assert(!S.empty());
+
+    switch (S.front()) {
+    case '\\':
+      S = S.drop_front(2);
+      break;
+    case '[': {
+      // Drop '[' and the first character which can be ']'.
+      S = S.drop_front(2);
+      size_t EndBracket = S.find_first_of("]");
+      // Should not be possible, SubGlobPattern::create should fail on invalid
+      // pattern before we get here.
+      assert(EndBracket != std::string::npos);
+      S = S.drop_front(EndBracket + 1);
+      break;
+    }
+    case '{':
+      // TODO: implement.
+      // Fallback to whatever is best for now.
+      return Best;
+    default:
+      S = S.drop_front(1);
+    }
+  }
+
+  return Best;
+}
+
 Expected<GlobPattern>
 GlobPattern::create(StringRef S, std::optional<size_t> MaxSubPatterns) {
   GlobPattern Pat;
+  Pat.Pattern = S;
 
   // Store the prefix that does not contain any metacharacter.
-  size_t PrefixSize = S.find_first_of("?*[{\\");
-  Pat.Prefix = S.substr(0, PrefixSize);
-  if (PrefixSize == std::string::npos)
+  Pat.PrefixSize = S.find_first_of("?*[{\\");
+  if (Pat.PrefixSize == std::string::npos) {
+    Pat.PrefixSize = S.size();
     return Pat;
-  S = S.substr(PrefixSize);
+  }
+  S = S.substr(Pat.PrefixSize);
 
   // Just in case we stop on unmatched opening brackets.
   size_t SuffixStart = S.find_last_of("?*[]{}\\");
   assert(SuffixStart != std::string::npos);
   if (S[SuffixStart] == '\\')
     ++SuffixStart;
-  ++SuffixStart;
-  Pat.Suffix = S.substr(SuffixStart);
+  if (SuffixStart < S.size())
+    ++SuffixStart;
+  Pat.SuffixSize = S.size() - SuffixStart;
   S = S.substr(0, SuffixStart);
 
   SmallVector<std::string, 1> SubPats;
@@ -199,10 +245,15 @@ GlobPattern::SubGlobPattern::create(StringRef S) {
   return Pat;
 }
 
+StringRef GlobPattern::longest_substr() const {
+  return maxPlainSubstring(
+      Pattern.drop_front(PrefixSize).drop_back(SuffixSize));
+}
+
 bool GlobPattern::match(StringRef S) const {
-  if (!S.consume_front(Prefix))
+  if (!S.consume_front(prefix()))
     return false;
-  if (!S.consume_back(Suffix))
+  if (!S.consume_back(suffix()))
     return false;
   if (SubGlobs.empty() && S.empty())
     return true;
diff --git a/llvm/unittests/Support/GlobPatternTest.cpp b/llvm/unittests/Support/GlobPatternTest.cpp
index 58fd7678131c6..872a21e948d7a 100644
--- a/llvm/unittests/Support/GlobPatternTest.cpp
+++ b/llvm/unittests/Support/GlobPatternTest.cpp
@@ -329,6 +329,72 @@ TEST_F(GlobPatternTest, PrefixSuffix) {
   EXPECT_EQ("cd", Pat->suffix());
 }
 
+TEST_F(GlobPatternTest, Substr) {
+  auto Pat = GlobPattern::create("");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("", Pat->longest_substr());
+
+  Pat = GlobPattern::create("abcd");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcd");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("", Pat->longest_substr());
+
+  Pat = GlobPattern::create("*abcd");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("", Pat->longest_substr());
+
+  Pat = GlobPattern::create("abcd*");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bc*d");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bc", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bc*def*g");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("def", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcd*ef*g");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcd", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcd*efg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcd", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcd[ef]g*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcd", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bc[d]efg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("efg", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bc[]]efg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("efg", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcde\\fg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcde", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcde\\[fg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcde", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcde?fg*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcde", Pat->longest_substr());
+
+  Pat = GlobPattern::create("a*bcdef{g}*h");
+  ASSERT_TRUE((bool)Pat);
+  EXPECT_EQ("bcdef", Pat->longest_substr());
+}
+
 TEST_F(GlobPatternTest, Pathological) {
   std::string P, S(40, 'a');
   StringRef Pieces[] = {"a*", "[ba]*", "{b*,a*}*"};

>From 40ba10a6096b7183ab90cee58486ef41de096e85 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 21 Oct 2025 18:03:03 -0700
Subject: [PATCH 02/11] spelling

Created using spr 1.3.7
---
 llvm/include/llvm/Support/RadixTree.h | 28 +++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/Support/RadixTree.h b/llvm/include/llvm/Support/RadixTree.h
index c9bed5ca6ba1b..05697fc267628 100644
--- a/llvm/include/llvm/Support/RadixTree.h
+++ b/llvm/include/llvm/Support/RadixTree.h
@@ -65,8 +65,8 @@ namespace llvm {
 /// The `RadixTree` takes ownership of the `KeyType` and `T` objects
 /// inserted into it. When an element is removed or the tree is destroyed,
 /// these objects will be destructed.
-/// However, if `KeyType` is a reference-like type, e.g. StrignRef or range,
-/// User must guaranty that destination has lifetime longer than the tree.
+/// However, if `KeyType` is a reference-like type, e.g. StringRef or range,
+/// User must guarantee that destination has lifetime longer than the tree.
 template <typename KeyType, typename T> class RadixTree {
 public:
   using key_type = KeyType;
@@ -81,7 +81,7 @@ template <typename KeyType, typename T> class RadixTree {
       remove_cvref_t<decltype(*adl_begin(std::declval<key_type &>()))>;
   using ContainerType = std::list<value_type>;
 
-  /// Represents a internal node in the Radix Tree.
+  /// Represents an internal node in the Radix Tree.
   struct Node {
     KeyConstIteratorRangeType Key = {KeyConstIteratorType{},
                                      KeyConstIteratorType{}};
@@ -110,12 +110,12 @@ template <typename KeyType, typename T> class RadixTree {
     Node &operator=(const Node &) = delete;
 
     const Node *findChild(const KeyConstIteratorRangeType &Key) const {
-      if (!Key.empty()) {
-        for (const auto &Child : Children) {
-          assert(!Child.Key.empty()); // Only root can be empty.
-          if (Child.KeyFront == *Key.begin())
-            return &Child;
-        }
+      if (Key.empty())
+        return nullptr;
+      for (const auto &Child : Children) {
+        assert(!Child.Key.empty()); // Only root can be empty.
+        if (Child.KeyFront == *Key.begin())
+          return &Child;
       }
       return nullptr;
     }
@@ -167,12 +167,12 @@ template <typename KeyType, typename T> class RadixTree {
       Key = make_range(I1, Key.end());
 
       if (I2 != Curr->Key.end()) {
-        // Match is partial. Either query is too short, or there is missmatching
+        // Match is partial. Either query is too short, or there is mismatching
         // character. Split either way, and put new node in between of the
         // current and its children.
         Curr->split(I2);
 
-        // Split was caused by mismatch, we can't 'findChild' will fail.
+        // Split was caused by mismatch, so `findChild` will fail.
         break;
       }
 
@@ -196,7 +196,7 @@ template <typename KeyType, typename T> class RadixTree {
   }
 
   ///
-  /// An iterator for traversing prefixes searche results.
+  /// An iterator for traversing prefixes search results.
   ///
   /// This iterator is used by `find_prefixes` to traverse the tree and find
   /// elements that are prefixes to the given key. It's a forward iterator.
@@ -278,7 +278,7 @@ template <typename KeyType, typename T> class RadixTree {
 
   /// Returns the number of nodes in the tree.
   ///
-  /// This function counts all internal in the tree. It can be useful for
+  /// This function counts all internal nodes in the tree. It can be useful for
   /// understanding the memory footprint or complexity of the tree structure.
   size_t countNodes() const { return Root.countNodes(); }
 
@@ -322,7 +322,7 @@ template <typename KeyType, typename T> class RadixTree {
   ///
   /// This function returns an iterator range over all elements in the tree
   /// whose keys are prefixes of the provided `Key`. For example, if the tree
-  /// contains "abcde", "abc", "abcdefgh, and `Key` is "abcde", this function
+  /// contains "abcde", "abc", "abcdefgh", and `Key` is "abcde", this function
   /// would return iterators to "abcde" and "abc".
   ///
   /// \param Key The key to search for prefixes of.

>From 5d58018daf347ca9496a29bc236e63e15f904a44 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 00:32:32 -0700
Subject: [PATCH 03/11] rebase

Created using spr 1.3.7
---
 llvm/docs/ProgrammersManual.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst
index 9cdac9c59fa9b..26865e4f671d7 100644
--- a/llvm/docs/ProgrammersManual.rst
+++ b/llvm/docs/ProgrammersManual.rst
@@ -2161,6 +2161,16 @@ that are not simple pointers (use :ref:`SmallPtrSet <dss_smallptrset>` for
 pointers).  Note that ``DenseSet`` has the same requirements for the value type that
 :ref:`DenseMap <dss_densemap>` has.
 
+.. _dss_radixtree:
+
+llvm/ADT/RadixTree.h
+^^^^^^^^^^^^^^^^^^^^
+
+``RadixTree`` is a trie-based data structure that stores range like keys and
+their associated values. It is particularly efficient for storing keys that
+share common prefixes, as it can compress these prefixes to save memory. It
+supports efficient search of matching prefixes.
+
 .. _dss_sparseset:
 
 llvm/ADT/SparseSet.h

>From 1840fe0b4c3569907b020cad55a67b299e0e9bf4 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:03:44 -0700
Subject: [PATCH 04/11] Update llvm/docs/ProgrammersManual.rst

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/docs/ProgrammersManual.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst
index 26865e4f671d7..d99b5843c2133 100644
--- a/llvm/docs/ProgrammersManual.rst
+++ b/llvm/docs/ProgrammersManual.rst
@@ -2166,7 +2166,7 @@ pointers).  Note that ``DenseSet`` has the same requirements for the value type
 llvm/ADT/RadixTree.h
 ^^^^^^^^^^^^^^^^^^^^
 
-``RadixTree`` is a trie-based data structure that stores range like keys and
+``RadixTree`` is a trie-based data structure that stores range-like keys and
 their associated values. It is particularly efficient for storing keys that
 share common prefixes, as it can compress these prefixes to save memory. It
 supports efficient search of matching prefixes.

>From b24b6ddc6d1811d31b006fb14e8c872c2060a0b7 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:03:58 -0700
Subject: [PATCH 05/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 5dd3f0c4d1b4e..8e8506d095383 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -172,7 +172,7 @@ template <typename KeyType, typename T> class RadixTree {
         // current and its children.
         Curr->split(I2);
 
-        // Split was caused by mismatch, so `findChild` will fail.
+        // Split was caused by mismatch, so `findChild` would fail.
         break;
       }
 

>From f97c94ba9e83616cd25400efaa137ff7fc946688 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:04:14 -0700
Subject: [PATCH 06/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 8e8506d095383..dd8655244c44d 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -189,7 +189,7 @@ template <typename KeyType, typename T> class RadixTree {
       return *Curr;
     }
 
-    // `Key` a suffix of original `Key` unmatched by path from the `Root` to the
+    // `Key` is a suffix of original `Key` unmatched by path from the `Root` to the
     // `Curr`, and we have no candidate in the children to match more. Create a
     // new one.
     return Curr->Children.emplace_back(Key);

>From 2a13ceacd91203a133783a8336261e89046b606b Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:05:22 -0700
Subject: [PATCH 07/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index dd8655244c44d..b80633e419d74 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -85,7 +85,7 @@ template <typename KeyType, typename T> class RadixTree {
   struct Node {
     KeyConstIteratorRangeType Key = {KeyConstIteratorType{},
                                      KeyConstIteratorType{}};
-    std::vector<Node> Children;
+    SmallVector<Node, 0> Children;
 
     /// An iterator to the value associated with this node.
     ///

>From 8e62249c96a64ba14f9a7a9b9913745230236f70 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:05:36 -0700
Subject: [PATCH 08/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index b80633e419d74..87a353609399a 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -112,7 +112,7 @@ template <typename KeyType, typename T> class RadixTree {
     const Node *findChild(const KeyConstIteratorRangeType &Key) const {
       if (Key.empty())
         return nullptr;
-      for (const auto &Child : Children) {
+      for (const Node &Child : Children) {
         assert(!Child.Key.empty()); // Only root can be empty.
         if (Child.KeyFront == *Key.begin())
           return &Child;

>From c1dafd2bf242c2cb02337ac34536e64bf8d9e762 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:06:10 -0700
Subject: [PATCH 09/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 87a353609399a..8014ea9de868a 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -209,7 +209,7 @@ template <typename KeyType, typename T> class RadixTree {
       : public iterator_facade_base<IteratorImpl<MappedType>,
                                     std::forward_iterator_tag, MappedType> {
     const Node *Curr = nullptr;
-    KeyConstIteratorRangeType Query;
+    KeyConstIteratorRangeType Query{};
 
     void findNextValid() {
       while (Curr && Curr->Value == typename ContainerType::iterator())

>From 058bd72c546958c9be8fc84317cd6bd082e0f85b Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:06:27 -0700
Subject: [PATCH 10/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 8014ea9de868a..64b9fa18a0d02 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -154,7 +154,7 @@ template <typename KeyType, typename T> class RadixTree {
   };
 
   Node Root; // Root is always for empty range.
-  ContainerType Values;
+  ContainerType KeyValuePairs;
 
   /// Finds or creates a new tail or leaf node corresponding to the `Key`.
   Node &findOrCreate(KeyConstIteratorRangeType Key) {

>From f80e076b745812c1bb3c5e9f69c1793b724a7bc6 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 23 Oct 2025 21:06:42 -0700
Subject: [PATCH 11/11] Update llvm/include/llvm/ADT/RadixTree.h

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/include/llvm/ADT/RadixTree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 64b9fa18a0d02..00a76302f814a 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -292,7 +292,7 @@ template <typename KeyType, typename T> class RadixTree {
 
   /// Constructs and inserts a new element into the tree.
   ///
-  /// This function constructs an element in-place within the tree. If an
+  /// This function constructs an element in place within the tree. If an
   /// element with the same key already exists, the insertion fails and the
   /// function returns an iterator to the existing element along with `false`.
   /// Otherwise, the new element is inserted and the function returns an



More information about the llvm-commits mailing list