summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2025-10-24 22:05:37 -0700
committerVitaly Buka <vitalybuka@google.com>2025-10-24 22:05:37 -0700
commitf1d60a04d0b06844c12f9df58c6a9d6c8c8326ff (patch)
treef8c47ab33621eb99dc8c656bf2301c9bdde94133
parentc9a45d3fd777997f669ff6af9c1f27e60a0fa23f (diff)
parent4204d078f9c839f42a67ef4a4ded416f2c75a7fa (diff)
Created using spr 1.3.7
-rw-r--r--llvm/include/llvm/ADT/RadixTree.h1
-rw-r--r--llvm/include/llvm/Support/SpecialCaseList.h12
-rw-r--r--llvm/lib/Support/SpecialCaseList.cpp60
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>();