[clang] [clang] Change representation of CurLexerKind (PR #70381)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 27 13:08:10 PDT 2023
https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/70381
>From 6a41a1f9a48135fe1a43b70904e105fe638189ce Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at 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..1997f485c5e6170 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;
- }
+ 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;
More information about the cfe-commits
mailing list