https://github.com/serge-sans-paille created https://github.com/llvm/llvm-project/pull/70381
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) >From 2631a5163de552a8e482f5cbc51525fb8bb5082f 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 | 33 +++++++++++++++------ clang/lib/Lex/Preprocessor.cpp | 41 ++------------------------ 2 files changed, 27 insertions(+), 47 deletions(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 18d88407ae12c90..c9ecb0844526eeb 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 (*CurLexerKindType)(Preprocessor &, Token &); + CurLexerKindType CurLexerKind = &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; + CurLexerKindType CurLexerKind; Module *TheSubmodule; std::unique_ptr<Lexer> TheLexer; PreprocessorLexer *ThePPLexer; @@ -776,7 +771,7 @@ 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(CurLexerKindType CurLexerKind, Module *TheSubmodule, std::unique_ptr<Lexer> &&TheLexer, PreprocessorLexer *ThePPLexer, std::unique_ptr<TokenLexer> &&TheTokenLexer, @@ -2899,6 +2894,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