Skip to content

Commit 301d008

Browse files
vitalybukajurahul
andauthored
[SpecialCaseList] Support early return from matching (llvm#163279)
On average it saves half positive of Glob matching. However, in real build most SpecialCaseList unmatched, this change should not affect this case. To be able to do so without breaking behavior, we need to re-order matches according precedence. Usually it's LineNo, and it's already ordered, but Diagnostic requires reordering by rule length. Co-authored-by: Rahul Joshi <[email protected]>
1 parent 645745f commit 301d008

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

clang/lib/Basic/Diagnostic.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,8 @@ std::unique_ptr<WarningsSpecialCaseList>
525525
WarningsSpecialCaseList::create(const llvm::MemoryBuffer &Input,
526526
std::string &Err) {
527527
auto WarningSuppressionList = std::make_unique<WarningsSpecialCaseList>();
528-
if (!WarningSuppressionList->createInternal(&Input, Err))
528+
if (!WarningSuppressionList->createInternal(&Input, Err,
529+
/*OrderBySize=*/true))
529530
return nullptr;
530531
return WarningSuppressionList;
531532
}

llvm/include/llvm/Support/SpecialCaseList.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ class SpecialCaseList {
115115
// classes.
116116
LLVM_ABI bool createInternal(const std::vector<std::string> &Paths,
117117
vfs::FileSystem &VFS, std::string &Error);
118-
LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error);
118+
LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error,
119+
bool OrderBySize = false);
119120

120121
SpecialCaseList() = default;
121122
SpecialCaseList(SpecialCaseList const &) = delete;
@@ -126,6 +127,8 @@ class SpecialCaseList {
126127
class RegexMatcher {
127128
public:
128129
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
130+
LLVM_ABI void preprocess(bool BySize);
131+
129132
LLVM_ABI void
130133
match(StringRef Query,
131134
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
@@ -144,6 +147,8 @@ class SpecialCaseList {
144147
class GlobMatcher {
145148
public:
146149
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
150+
LLVM_ABI void preprocess(bool BySize);
151+
147152
LLVM_ABI void
148153
match(StringRef Query,
149154
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
@@ -165,6 +170,7 @@ class SpecialCaseList {
165170
LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash);
166171

167172
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
173+
LLVM_ABI void preprocess(bool BySize);
168174

169175
LLVM_ABI void
170176
match(StringRef Query,
@@ -206,6 +212,8 @@ class SpecialCaseList {
206212
StringRef Category) const;
207213

208214
private:
215+
friend class SpecialCaseList;
216+
LLVM_ABI void preprocess(bool OrderBySize);
209217
LLVM_ABI const SpecialCaseList::Matcher *
210218
findMatcher(StringRef Prefix, StringRef Category) const;
211219
};
@@ -222,7 +230,7 @@ class SpecialCaseList {
222230

223231
/// Parses just-constructed SpecialCaseList entries from a memory buffer.
224232
LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB,
225-
std::string &Error);
233+
std::string &Error, bool OrderBySize);
226234
};
227235

228236
} // namespace llvm

llvm/lib/Support/SpecialCaseList.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,20 @@ Error SpecialCaseList::RegexMatcher::insert(StringRef Pattern,
5555
return Error::success();
5656
}
5757

58+
void SpecialCaseList::RegexMatcher::preprocess(bool BySize) {
59+
if (BySize) {
60+
llvm::stable_sort(RegExes, [](const Reg &A, const Reg &B) {
61+
return A.Name.size() < B.Name.size();
62+
});
63+
}
64+
}
65+
5866
void SpecialCaseList::RegexMatcher::match(
5967
StringRef Query,
6068
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
6169
for (const auto &R : reverse(RegExes))
6270
if (R.Rg.match(Query))
63-
Cb(R.Name, R.LineNo);
71+
return Cb(R.Name, R.LineNo);
6472
}
6573

6674
Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
@@ -75,12 +83,20 @@ Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
7583
return Error::success();
7684
}
7785

86+
void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
87+
if (BySize) {
88+
llvm::stable_sort(Globs, [](const Glob &A, const Glob &B) {
89+
return A.Name.size() < B.Name.size();
90+
});
91+
}
92+
}
93+
7894
void SpecialCaseList::GlobMatcher::match(
7995
StringRef Query,
8096
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
8197
for (const auto &G : reverse(Globs))
8298
if (G.Pattern.match(Query))
83-
Cb(G.Name, G.LineNo);
99+
return Cb(G.Name, G.LineNo);
84100
}
85101

86102
SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
@@ -91,6 +107,14 @@ SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
91107
M.emplace<RegexMatcher>();
92108
}
93109

110+
Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) {
111+
return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M);
112+
}
113+
114+
LLVM_ABI void SpecialCaseList::Matcher::preprocess(bool BySize) {
115+
return std::visit([&](auto &V) { return V.preprocess(BySize); }, M);
116+
}
117+
94118
void SpecialCaseList::Matcher::match(
95119
StringRef Query,
96120
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
@@ -99,10 +123,6 @@ void SpecialCaseList::Matcher::match(
99123
return std::visit([&](auto &V) { return V.match(Query, Cb); }, M);
100124
}
101125

102-
Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) {
103-
return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M);
104-
}
105-
106126
// TODO: Refactor this to return Expected<...>
107127
std::unique_ptr<SpecialCaseList>
108128
SpecialCaseList::create(const std::vector<std::string> &Paths,
@@ -141,17 +161,17 @@ bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
141161
return false;
142162
}
143163
std::string ParseError;
144-
if (!parse(i, FileOrErr.get().get(), ParseError)) {
164+
if (!parse(i, FileOrErr.get().get(), ParseError, /*OrderBySize=*/false)) {
145165
Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
146166
return false;
147167
}
148168
}
149169
return true;
150170
}
151171

152-
bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
153-
std::string &Error) {
154-
if (!parse(0, MB, Error))
172+
bool SpecialCaseList::createInternal(const MemoryBuffer *MB, std::string &Error,
173+
bool OrderBySize) {
174+
if (!parse(0, MB, Error, OrderBySize))
155175
return false;
156176
return true;
157177
}
@@ -174,7 +194,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
174194
}
175195

176196
bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
177-
std::string &Error) {
197+
std::string &Error, bool OrderBySize) {
178198
unsigned long long Version = 2;
179199

180200
StringRef Header = MB->getBuffer();
@@ -246,6 +266,10 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
246266
return false;
247267
}
248268
}
269+
270+
for (Section &S : Sections)
271+
S.preprocess(OrderBySize);
272+
249273
return true;
250274
}
251275

@@ -283,6 +307,13 @@ SpecialCaseList::Section::findMatcher(StringRef Prefix,
283307
return &II->second;
284308
}
285309

310+
LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) {
311+
SectionMatcher.preprocess(false);
312+
for (auto &[K1, E] : Entries)
313+
for (auto &[K2, M] : E)
314+
M.preprocess(OrderBySize);
315+
}
316+
286317
unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix,
287318
StringRef Query,
288319
StringRef Category) const {

0 commit comments

Comments
 (0)