https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/70381
>From 7711f8c85c7e106b2662d1a2505f91f0417fac5a Mon Sep 17 00:00:00 2001 From: serge-sans-paille <sguel...@mozilla.com> Date: Thu, 26 Oct 2023 22:31:43 +0200 Subject: [PATCH] [clang] Change representation of CurLexerKind Previous representation used an enumeration combined to a switch to dispatch to the appropriate lexer. Use function pointer so that the dispatching is just an indirect call, which is actually better because lexing is a costly task compared to a function call. This also makes the code slightly cleaner, speedup on compile time tracker are consistent and range form -0.05% to -0.20% for NewPM-O0-g, see https://llvm-compile-time-tracker.com/compare.php?from=f9906508bc4f05d3950e2219b4c56f6c078a61ef&to=608c85ec1283638db949d73e062bcc3355001ce4&stat=instructions:u Considering just the preprocessing task, preprocessing the sqlite amalgametion takes -0.6% instructions (according to valgrind --tool=callgrind) --- clang/include/clang/Lex/Preprocessor.h | 44 ++++++++++++++++++-------- clang/lib/Lex/Preprocessor.cpp | 41 ++---------------------- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 18d88407ae12c90..2d59918c039b115 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -751,13 +751,8 @@ class Preprocessor { std::unique_ptr<TokenLexer> CurTokenLexer; /// The kind of lexer we're currently working with. - enum CurLexerKind { - CLK_Lexer, - CLK_TokenLexer, - CLK_CachingLexer, - CLK_DependencyDirectivesLexer, - CLK_LexAfterModuleImport - } CurLexerKind = CLK_Lexer; + typedef bool (*LexerCallback)(Preprocessor &, Token &); + LexerCallback CurLexerCallback = &CLK_Lexer; /// If the current lexer is for a submodule that is being built, this /// is that submodule. @@ -767,7 +762,7 @@ class Preprocessor { /// \#included, and macros currently being expanded from, not counting /// CurLexer/CurTokenLexer. struct IncludeStackInfo { - enum CurLexerKind CurLexerKind; + LexerCallback CurLexerCallback; Module *TheSubmodule; std::unique_ptr<Lexer> TheLexer; PreprocessorLexer *ThePPLexer; @@ -776,12 +771,12 @@ class Preprocessor { // The following constructors are completely useless copies of the default // versions, only needed to pacify MSVC. - IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule, + IncludeStackInfo(LexerCallback CurLexerCallback, Module *TheSubmodule, std::unique_ptr<Lexer> &&TheLexer, PreprocessorLexer *ThePPLexer, std::unique_ptr<TokenLexer> &&TheTokenLexer, ConstSearchDirIterator TheDirLookup) - : CurLexerKind(std::move(CurLexerKind)), + : CurLexerCallback(std::move(CurLexerCallback)), TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)), ThePPLexer(std::move(ThePPLexer)), TheTokenLexer(std::move(TheTokenLexer)), @@ -1901,7 +1896,7 @@ class Preprocessor { /// Determine whether it's possible for a future call to Lex to produce an /// annotation token created by a previous call to EnterAnnotationToken. bool mightHavePendingAnnotationTokens() { - return CurLexerKind != CLK_Lexer; + return CurLexerCallback != CLK_Lexer; } /// Update the current token to represent the provided @@ -2430,8 +2425,9 @@ class Preprocessor { friend void TokenLexer::ExpandFunctionArguments(); void PushIncludeMacroStack() { - assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer"); - IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule, + assert(CurLexerCallback != CLK_CachingLexer && + "cannot push a caching lexer"); + IncludeMacroStack.emplace_back(CurLexerCallback, CurLexerSubmodule, std::move(CurLexer), CurPPLexer, std::move(CurTokenLexer), CurDirLookup); CurPPLexer = nullptr; @@ -2443,7 +2439,7 @@ class Preprocessor { CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer); CurDirLookup = IncludeMacroStack.back().TheDirLookup; CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule; - CurLexerKind = IncludeMacroStack.back().CurLexerKind; + CurLexerCallback = IncludeMacroStack.back().CurLexerCallback; IncludeMacroStack.pop_back(); } @@ -2899,6 +2895,26 @@ class Preprocessor { /// \return true iff this PP is currently in a "-Wunsafe-buffer-usage" /// opt-out region bool isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc); + +private: + /// Helper functions to forward lexing to the actual lexer. They all share the + /// same signature. + static bool CLK_Lexer(Preprocessor &P, Token &Result) { + return P.CurLexer->Lex(Result); + } + static bool CLK_TokenLexer(Preprocessor &P, Token &Result) { + return P.CurTokenLexer->Lex(Result); + } + static bool CLK_CachingLexer(Preprocessor &P, Token &Result) { + P.CachingLex(Result); + return true; + } + static bool CLK_DependencyDirectivesLexer(Preprocessor &P, Token &Result) { + return P.CurLexer->LexDependencyDirectiveToken(Result); + } + static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) { + return P.LexAfterModuleImport(Result); + } }; /// Abstract base class that describes a handler that will receive diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index ede4c51487ffbe7..a1ddb7732b9b857 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -643,23 +643,7 @@ void Preprocessor::SkipTokensWhileUsingPCH() { while (true) { bool InPredefines = (CurLexer && CurLexer->getFileID() == getPredefinesFileID()); - switch (CurLexerKind) { - case CLK_Lexer: - CurLexer->Lex(Tok); - break; - case CLK_TokenLexer: - CurTokenLexer->Lex(Tok); - break; - case CLK_CachingLexer: - CachingLex(Tok); - break; - case CLK_DependencyDirectivesLexer: - CurLexer->LexDependencyDirectiveToken(Tok); - break; - case CLK_LexAfterModuleImport: - LexAfterModuleImport(Tok); - break; - } + (void)CurLexerKind(*this, Tok); if (Tok.is(tok::eof) && !InPredefines) { ReachedMainFileEOF = true; break; @@ -882,27 +866,8 @@ void Preprocessor::Lex(Token &Result) { ++LexLevel; // We loop here until a lex function returns a token; this avoids recursion. - bool ReturnedToken; - do { - switch (CurLexerKind) { - case CLK_Lexer: - ReturnedToken = CurLexer->Lex(Result); - break; - case CLK_TokenLexer: - ReturnedToken = CurTokenLexer->Lex(Result); - break; - case CLK_CachingLexer: - CachingLex(Result); - ReturnedToken = true; - break; - case CLK_DependencyDirectivesLexer: - ReturnedToken = CurLexer->LexDependencyDirectiveToken(Result); - break; - case CLK_LexAfterModuleImport: - ReturnedToken = LexAfterModuleImport(Result); - break; - } - } while (!ReturnedToken); + while (!CurLexerKind(*this, Result)) + ; if (Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure) return; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits