diff options
author | serge-sans-paille <sguelton@mozilla.com> | 2022-12-04 09:33:14 +0100 |
---|---|---|
committer | serge-sans-paille <sguelton@mozilla.com> | 2022-12-07 16:32:37 +0100 |
commit | bdfa3100dc3ea9e9ce4d3d4100ea6bb4c3fa2b81 (patch) | |
tree | 7bf3586904eb870c194b5ee7de9c3630b2766aef /llvm/lib/Option/OptTable.cpp | |
parent | 7d40baa82b1f272f68de63f3c4f68d970bdcd6ed (diff) | |
download | llvm-bdfa3100dc3ea9e9ce4d3d4100ea6bb4c3fa2b81.zip llvm-bdfa3100dc3ea9e9ce4d3d4100ea6bb4c3fa2b81.tar.gz llvm-bdfa3100dc3ea9e9ce4d3d4100ea6bb4c3fa2b81.tar.bz2 |
Store OptTable::Info::Name as a StringRef
This is a recommit of 8ae18303f97d5dcfaecc90b4d87effb2011ed82e,
with a few cleanups.
This avoids implicit conversion to StringRef at several points, which in
turns avoid redundant calls to strlen.
As a side effect, this greatly simplifies the implementation of
StrCmpOptionNameIgnoreCase.
It also eventually gives a consistent, humble speedup in compilation
time (timing updated since original commit).
https://llvm-compile-time-tracker.com/compare.php?from=76fcfea283472a80356d87c89270b0e2d106b54c&to=b70eb1f347f22fe4d2977360c4ed701eabc43994&stat=instructions:u
Differential Revision: https://reviews.llvm.org/D139274
Diffstat (limited to 'llvm/lib/Option/OptTable.cpp')
-rw-r--r-- | llvm/lib/Option/OptTable.cpp | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index ef4873e..06ed6b7 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -36,31 +36,23 @@ namespace opt { // Ordering on Info. The ordering is *almost* case-insensitive lexicographic, // with an exception. '\0' comes at the end of the alphabet instead of the // beginning (thus options precede any other options which prefix them). -static int StrCmpOptionNameIgnoreCase(const char *A, const char *B) { - const char *X = A, *Y = B; - char a = tolower(*A), b = tolower(*B); - while (a == b) { - if (a == '\0') - return 0; - - a = tolower(*++X); - b = tolower(*++Y); - } +static int StrCmpOptionNameIgnoreCase(StringRef A, StringRef B) { + size_t MinSize = std::min(A.size(), B.size()); + if (int Res = A.substr(0, MinSize).compare_insensitive(B.substr(0, MinSize))) + return Res; - if (a == '\0') // A is a prefix of B. - return 1; - if (b == '\0') // B is a prefix of A. - return -1; + if (A.size() == B.size()) + return 0; - // Otherwise lexicographic. - return (a < b) ? -1 : 1; + return (A.size() == MinSize) ? 1 /* A is a prefix of B. */ + : -1 /* B is a prefix of A */; } #ifndef NDEBUG -static int StrCmpOptionName(const char *A, const char *B) { +static int StrCmpOptionName(StringRef A, StringRef B) { if (int N = StrCmpOptionNameIgnoreCase(A, B)) return N; - return strcmp(A, B); + return A.compare(B); } static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { @@ -86,7 +78,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { #endif // Support lower_bound between info and an option name. -static inline bool operator<(const OptTable::Info &I, const char *Name) { +static inline bool operator<(const OptTable::Info &I, StringRef Name) { return StrCmpOptionNameIgnoreCase(I.Name, Name) < 0; } @@ -186,7 +178,7 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str, bool Matched = IgnoreCase ? Rest.startswith_insensitive(I->Name) : Rest.startswith(I->Name); if (Matched) - return Prefix.size() + StringRef(I->Name).size(); + return Prefix.size() + I->Name.size(); } } return 0; @@ -321,7 +313,7 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString, return BestDistance; } -bool OptTable::addValues(const char *Option, const char *Values) { +bool OptTable::addValues(StringRef Option, const char *Values) { for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) { Info &In = OptionInfos[I]; if (optionMatches(In, Option)) { @@ -347,8 +339,8 @@ std::unique_ptr<Arg> OptTable::parseOneArgGrouped(InputArgList &Args, const Info *End = OptionInfos.data() + OptionInfos.size(); StringRef Name = Str.ltrim(PrefixChars); - const Info *Start = std::lower_bound( - OptionInfos.data() + FirstSearchableIndex, End, Name.data()); + const Info *Start = + std::lower_bound(OptionInfos.data() + FirstSearchableIndex, End, Name); const Info *Fallback = nullptr; unsigned Prev = Index; @@ -403,19 +395,19 @@ std::unique_ptr<Arg> OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, unsigned FlagsToInclude, unsigned FlagsToExclude) const { unsigned Prev = Index; - const char *Str = Args.getArgString(Index); + StringRef Str = Args.getArgString(Index); // Anything that doesn't start with PrefixesUnion is an input, as is '-' // itself. if (isInput(PrefixesUnion, Str)) - return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, Str); + return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, Str.data()); const Info *Start = OptionInfos.data() + FirstSearchableIndex; const Info *End = OptionInfos.data() + OptionInfos.size(); - StringRef Name = StringRef(Str).ltrim(PrefixChars); + StringRef Name = Str.ltrim(PrefixChars); // Search for the first next option which could be a prefix. - Start = std::lower_bound(Start, End, Name.data()); + Start = std::lower_bound(Start, End, Name); // Options are stored in sorted order, with '\0' at the end of the // alphabet. Since the only options which can accept a string must @@ -455,9 +447,9 @@ std::unique_ptr<Arg> OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, // If we failed to find an option and this arg started with /, then it's // probably an input path. if (Str[0] == '/') - return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, Str); + return std::make_unique<Arg>(getOption(InputOptionID), Str, Index++, Str.data()); - return std::make_unique<Arg>(getOption(UnknownOptionID), Str, Index++, Str); + return std::make_unique<Arg>(getOption(UnknownOptionID), Str, Index++, Str.data()); } InputArgList OptTable::ParseArgs(ArrayRef<const char *> ArgArr, |