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( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits