diff options
| author | Jordan Rupprecht <rupprecht@google.com> | 2025-10-24 22:05:37 -0700 |
|---|---|---|
| committer | Vitaly Buka <vitalybuka@google.com> | 2025-10-24 22:05:37 -0700 |
| commit | f1d60a04d0b06844c12f9df58c6a9d6c8c8326ff (patch) | |
| tree | f8c47ab33621eb99dc8c656bf2301c9bdde94133 | |
| parent | c9a45d3fd777997f669ff6af9c1f27e60a0fa23f (diff) | |
| parent | 4204d078f9c839f42a67ef4a4ded416f2c75a7fa (diff) | |
[𝘀𝗽𝗿] initial versionusers/vitalybuka/spr/adtnfc-add-missing-include-vector-165068
Created using spr 1.3.7
| -rw-r--r-- | llvm/include/llvm/ADT/RadixTree.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/Support/SpecialCaseList.h | 12 | ||||
| -rw-r--r-- | llvm/lib/Support/SpecialCaseList.cpp | 60 |
3 files changed, 69 insertions, 4 deletions
diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h index d3c44e4e6345..a65acddf186b 100644 --- a/llvm/include/llvm/ADT/RadixTree.h +++ b/llvm/include/llvm/ADT/RadixTree.h @@ -22,6 +22,7 @@ #include <limits> #include <list> #include <utility> +#include <vector> namespace llvm { diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index ead765562504..3e7592f153c2 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -13,7 +13,10 @@ #define LLVM_SUPPORT_SPECIALCASELIST_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/RadixTree.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/GlobPattern.h" @@ -162,6 +165,15 @@ private: }; std::vector<GlobMatcher::Glob> Globs; + + RadixTree<iterator_range<StringRef::const_reverse_iterator>, + RadixTree<iterator_range<StringRef::const_iterator>, + SmallVector<const GlobMatcher::Glob *, 1>>> + SuffixPrefixToGlob; + + RadixTree<iterator_range<StringRef::const_iterator>, + SmallVector<const GlobMatcher::Glob *, 1>> + SubstrToGlob; }; /// Represents a set of patterns and their line numbers diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index f74e52a3a7fa..1e303ebbfd3f 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -89,17 +89,69 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) { return A.Name.size() < B.Name.size(); }); } + + for (const auto &G : Globs) { + StringRef Prefix = G.Pattern.prefix(); + StringRef Suffix = G.Pattern.suffix(); + + if (Suffix.empty() && Prefix.empty()) { + // If both prefix and suffix are empty put into special tree to search by + // substring in a middle. + StringRef Substr = G.Pattern.longest_substr(); + if (!Substr.empty()) { + // But only if substring is not empty. Searching this tree is more + // expensive. + auto &V = SubstrToGlob.emplace(Substr).first->second; + V.emplace_back(&G); + continue; + } + } + + auto &PToGlob = SuffixPrefixToGlob.emplace(reverse(Suffix)).first->second; + auto &V = PToGlob.emplace(Prefix).first->second; + V.emplace_back(&G); + } } void SpecialCaseList::GlobMatcher::match( StringRef Query, llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const { - for (const auto &G : reverse(Globs)) - if (G.Pattern.match(Query)) - return Cb(G.Name, G.LineNo); + if (!SuffixPrefixToGlob.empty()) { + for (const auto &[_, PToGlob] : + SuffixPrefixToGlob.find_prefixes(reverse(Query))) { + for (const auto &[_, V] : PToGlob.find_prefixes(Query)) { + for (const auto *G : V) { + // Each value of the map is a vector of globs ordered from the best to + // the worst. + if (G->Pattern.match(Query)) { + Cb(G->Name, G->LineNo); + // As soon as we find a match in the vector we can break for the + // vector, still we can't return, and need to continue for others + // values in the map, as they may contain a better match. + break; + } + } + } + } + } + + if (!SubstrToGlob.empty()) { + // As we don't know when substring exactly starts, we will try all + // possibilities. In most cases search will fail on first characters. + for (StringRef Q = Query; !Q.empty(); Q = Q.drop_front()) { + for (const auto &[_, V] : SubstrToGlob.find_prefixes(Q)) { + for (const auto *G : reverse(V)) { + if (G->Pattern.match(Query)) { + Cb(G->Name, G->LineNo); + break; + } + } + } + } + } } -SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) + SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) : RemoveDotSlash(RemoveDotSlash) { if (UseGlobs) M.emplace<GlobMatcher>(); |
