[clang] [clang] Optimize Lexer hot path to reduce compile time (PR #177153)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 21 04:37:44 PST 2026
https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/177153
This patch fix this compile time regression that introduced in https://github.com/llvm/llvm-project/pull/173789. The regression was fixed by add an early-exit optimization in the hot Lexer path.
>From 528d0a627204a122ea86d20d0e8f1ba491ce6727 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Wed, 21 Jan 2026 20:34:46 +0800
Subject: [PATCH] [clang] Optimize Lexer hot path to reduce compile time
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/include/clang/Lex/Preprocessor.h | 12 ++++++++++++
clang/lib/Lex/Lexer.cpp | 20 ++++++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 5adc45a19ca79..f286e0d8bb348 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -1871,6 +1871,18 @@ class Preprocessor {
/// read is the correct one.
bool HandleModuleContextualKeyword(Token &Result,
bool TokAtPhysicalStartOfLine);
+ /// Quick check whether current token at physical start of line or previous
+ /// export tok was at physical start of line. This is used as an early-exit
+ /// optimization in the hot Lexer::Lex path.
+ //
+ // Returns true if the current token could potentially be a module directive
+ // introducer.
+ bool isModuleDirectiveIntroducerAtPhysicalStartOfLine(
+ bool TokAtPhysicalStartOfLine) {
+ return TokAtPhysicalStartOfLine ||
+ (LastTokenWasExportKeyword.isValid() &&
+ LastTokenWasExportKeyword.isAtPhysicalStartOfLine());
+ }
/// Get the start location of the first pp-token in main file.
SourceLocation getMainFileFirstPPTokenLoc() const {
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 2c4ba70551fab..c10ca8925586e 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -4058,10 +4058,14 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) {
// so it's safe to access member variables after this call returns.
bool returnedToken = LexIdentifierContinue(Result, CurPtr);
- if (returnedToken && !LexingRawMode && !Is_PragmaLexer &&
- !ParsingPreprocessorDirective && LangOpts.CPlusPlusModules &&
- Result.isModuleContextualKeyword() &&
- PP->HandleModuleContextualKeyword(Result, TokAtPhysicalStartOfLine))
+ if (LLVM_UNLIKELY(returnedToken && !LexingRawMode && !Is_PragmaLexer &&
+ !ParsingPreprocessorDirective &&
+ LangOpts.CPlusPlusModules &&
+ PP->isModuleDirectiveIntroducerAtPhysicalStartOfLine(
+ TokAtPhysicalStartOfLine) &&
+ Result.isModuleContextualKeyword() &&
+ PP->HandleModuleContextualKeyword(
+ Result, TokAtPhysicalStartOfLine)))
goto HandleDirective;
return returnedToken;
}
@@ -4637,8 +4641,12 @@ bool Lexer::LexDependencyDirectiveToken(Token &Result) {
Result.setRawIdentifierData(TokPtr);
if (!isLexingRawMode()) {
const IdentifierInfo *II = PP->LookUpIdentifierInfo(Result);
- if (LangOpts.CPlusPlusModules && Result.isModuleContextualKeyword() &&
- PP->HandleModuleContextualKeyword(Result, Result.isAtStartOfLine())) {
+ if (LLVM_UNLIKELY(LangOpts.CPlusPlusModules &&
+ PP->isModuleDirectiveIntroducerAtPhysicalStartOfLine(
+ Result.isAtStartOfLine()) &&
+ Result.isModuleContextualKeyword() &&
+ PP->HandleModuleContextualKeyword(
+ Result, Result.isAtStartOfLine()))) {
PP->HandleDirective(Result);
return false;
}
More information about the cfe-commits
mailing list