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 <[email protected]>
Date: Wed, 21 Jan 2026 20:34:46 +0800
Subject: [PATCH] [clang] Optimize Lexer hot path to reduce compile time

Signed-off-by: yronglin <[email protected]>
---
 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;
       }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to