[llvm] 6ad1b40 - Optimize OptTable::findNearest implementation and usage
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 19 05:16:53 PST 2023
Author: serge-sans-paille
Date: 2023-01-19T14:16:29+01:00
New Revision: 6ad1b4095172373590134afff19a7fbad9d7889d
URL: https://github.com/llvm/llvm-project/commit/6ad1b4095172373590134afff19a7fbad9d7889d
DIFF: https://github.com/llvm/llvm-project/commit/6ad1b4095172373590134afff19a7fbad9d7889d.diff
LOG: Optimize OptTable::findNearest implementation and usage
When used to find an exact match, some extra context can be used to
totally cut some computations.
This saves 1% of the instruction count when pre processing sqlite3.c
through
valgrind --tool=callgrind ./bin/clang -E sqlite3.c -o/dev/null
Differential Revision: https://reviews.llvm.org/D142026
Added:
Modified:
clang/lib/Driver/Driver.cpp
llvm/include/llvm/Option/OptTable.h
llvm/lib/Option/OptTable.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 555512f8c326a..58e1090673fad 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -313,8 +313,8 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
std::string Nearest;
if (getOpts().findNearest(ArgString, Nearest, IncludedFlagsBitmask,
ExcludedFlagsBitmask) > 1) {
- if (getOpts().findNearest(ArgString, Nearest, options::CC1Option) == 0 &&
- !IsCLMode()) {
+ if (!IsCLMode() &&
+ getOpts().findExact(ArgString, Nearest, options::CC1Option)) {
DiagID = diag::err_drv_unknown_argument_with_suggestion;
Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest;
} else {
@@ -339,8 +339,8 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
// Warn on joined arguments that are similar to a long argument.
std::string ArgString = ArgStrings[A->getIndex()];
std::string Nearest;
- if (getOpts().findNearest("-" + ArgString, Nearest, IncludedFlagsBitmask,
- ExcludedFlagsBitmask) == 0)
+ if (getOpts().findExact("-" + ArgString, Nearest, IncludedFlagsBitmask,
+ ExcludedFlagsBitmask))
Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
<< A->getAsString(Args) << Nearest;
}
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 25d86c04a43bd..8f13a31aa4221 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -175,11 +175,21 @@ class OptTable {
/// \param [in] MinimumLength - Don't find options shorter than this length.
/// For example, a minimum length of 3 prevents "-x" from being considered
/// near to "-S".
+ /// \param [in] MaximumDistance - Don't find options whose distance is greater
+ /// than this value.
///
/// \return The edit distance of the nearest string found.
unsigned findNearest(StringRef Option, std::string &NearestString,
unsigned FlagsToInclude = 0, unsigned FlagsToExclude = 0,
- unsigned MinimumLength = 4) const;
+ unsigned MinimumLength = 4,
+ unsigned MaximumDistance = UINT_MAX - 1) const;
+
+ bool findExact(StringRef Option, std::string &ExactString,
+ unsigned FlagsToInclude = 0,
+ unsigned FlagsToExclude = 0) const {
+ return findNearest(Option, ExactString, FlagsToInclude, FlagsToExclude, 4,
+ 0) == 0;
+ }
/// Parse a single argument; returning the new argument and
/// updating Index.
diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp
index dea9fc0eb7857..10f0658bc965a 100644
--- a/llvm/lib/Option/OptTable.cpp
+++ b/llvm/lib/Option/OptTable.cpp
@@ -227,12 +227,13 @@ OptTable::findByPrefix(StringRef Cur, unsigned int DisableFlags) const {
unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
unsigned FlagsToInclude, unsigned FlagsToExclude,
- unsigned MinimumLength) const {
+ unsigned MinimumLength,
+ unsigned MaximumDistance) const {
assert(!Option.empty());
// Consider each [option prefix + option name] pair as a candidate, finding
// the closest match.
- unsigned BestDistance = UINT_MAX;
+ unsigned BestDistance = MaximumDistance + 1;
SmallString<16> Candidate;
SmallString<16> NormalizedName;
@@ -276,6 +277,14 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
// appropriate one. For example, if a user asks for "--helm", suggest
// "--help" over "-help".
for (auto CandidatePrefix : CandidateInfo.Prefixes) {
+ // If Candidate and NormalizedName have more than 'BestDistance'
+ // characters of
diff erence, no need to compute the edit distance, it's
+ // going to be greater than BestDistance. Don't bother computing Candidate
+ // at all.
+ if (std::abs((ssize_t)(CandidatePrefix.size() + CandidateName.size()) -
+ (ssize_t)NormalizedName.size()) > (ssize_t)BestDistance) {
+ continue;
+ }
Candidate = CandidatePrefix;
Candidate += CandidateName;
unsigned Distance = StringRef(Candidate).edit_distance(
More information about the llvm-commits
mailing list