Skip to content

Commit c815ac1

Browse files
[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)
1 parent fcc26ba commit c815ac1

File tree

5 files changed

+62
-81
lines changed

5 files changed

+62
-81
lines changed

clang/include/clang/Lex/Preprocessor.h

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,8 @@ class Preprocessor {
751751
std::unique_ptr<TokenLexer> CurTokenLexer;
752752

753753
/// The kind of lexer we're currently working with.
754-
enum CurLexerKind {
755-
CLK_Lexer,
756-
CLK_TokenLexer,
757-
CLK_CachingLexer,
758-
CLK_DependencyDirectivesLexer,
759-
CLK_LexAfterModuleImport
760-
} CurLexerKind = CLK_Lexer;
754+
typedef bool (*LexerCallback)(Preprocessor &, Token &);
755+
LexerCallback CurLexerCallback = &CLK_Lexer;
761756

762757
/// If the current lexer is for a submodule that is being built, this
763758
/// is that submodule.
@@ -767,7 +762,7 @@ class Preprocessor {
767762
/// \#included, and macros currently being expanded from, not counting
768763
/// CurLexer/CurTokenLexer.
769764
struct IncludeStackInfo {
770-
enum CurLexerKind CurLexerKind;
765+
LexerCallback CurLexerCallback;
771766
Module *TheSubmodule;
772767
std::unique_ptr<Lexer> TheLexer;
773768
PreprocessorLexer *ThePPLexer;
@@ -776,12 +771,12 @@ class Preprocessor {
776771

777772
// The following constructors are completely useless copies of the default
778773
// versions, only needed to pacify MSVC.
779-
IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
774+
IncludeStackInfo(LexerCallback CurLexerCallback, Module *TheSubmodule,
780775
std::unique_ptr<Lexer> &&TheLexer,
781776
PreprocessorLexer *ThePPLexer,
782777
std::unique_ptr<TokenLexer> &&TheTokenLexer,
783778
ConstSearchDirIterator TheDirLookup)
784-
: CurLexerKind(std::move(CurLexerKind)),
779+
: CurLexerCallback(std::move(CurLexerCallback)),
785780
TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
786781
ThePPLexer(std::move(ThePPLexer)),
787782
TheTokenLexer(std::move(TheTokenLexer)),
@@ -1901,7 +1896,7 @@ class Preprocessor {
19011896
/// Determine whether it's possible for a future call to Lex to produce an
19021897
/// annotation token created by a previous call to EnterAnnotationToken.
19031898
bool mightHavePendingAnnotationTokens() {
1904-
return CurLexerKind != CLK_Lexer;
1899+
return CurLexerCallback != CLK_Lexer;
19051900
}
19061901

19071902
/// Update the current token to represent the provided
@@ -1914,7 +1909,7 @@ class Preprocessor {
19141909

19151910
/// Recompute the current lexer kind based on the CurLexer/
19161911
/// CurTokenLexer pointers.
1917-
void recomputeCurLexerKind();
1912+
void recomputeCurLexerCallback();
19181913

19191914
/// Returns true if incremental processing is enabled
19201915
bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
@@ -2430,8 +2425,9 @@ class Preprocessor {
24302425
friend void TokenLexer::ExpandFunctionArguments();
24312426

24322427
void PushIncludeMacroStack() {
2433-
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
2434-
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
2428+
assert(CurLexerCallback != CLK_CachingLexer &&
2429+
"cannot push a caching lexer");
2430+
IncludeMacroStack.emplace_back(CurLexerCallback, CurLexerSubmodule,
24352431
std::move(CurLexer), CurPPLexer,
24362432
std::move(CurTokenLexer), CurDirLookup);
24372433
CurPPLexer = nullptr;
@@ -2443,7 +2439,7 @@ class Preprocessor {
24432439
CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
24442440
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
24452441
CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule;
2446-
CurLexerKind = IncludeMacroStack.back().CurLexerKind;
2442+
CurLexerCallback = IncludeMacroStack.back().CurLexerCallback;
24472443
IncludeMacroStack.pop_back();
24482444
}
24492445

@@ -2899,6 +2895,26 @@ class Preprocessor {
28992895
/// \return true iff this PP is currently in a "-Wunsafe-buffer-usage"
29002896
/// opt-out region
29012897
bool isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc);
2898+
2899+
private:
2900+
/// Helper functions to forward lexing to the actual lexer. They all share the
2901+
/// same signature.
2902+
static bool CLK_Lexer(Preprocessor &P, Token &Result) {
2903+
return P.CurLexer->Lex(Result);
2904+
}
2905+
static bool CLK_TokenLexer(Preprocessor &P, Token &Result) {
2906+
return P.CurTokenLexer->Lex(Result);
2907+
}
2908+
static bool CLK_CachingLexer(Preprocessor &P, Token &Result) {
2909+
P.CachingLex(Result);
2910+
return true;
2911+
}
2912+
static bool CLK_DependencyDirectivesLexer(Preprocessor &P, Token &Result) {
2913+
return P.CurLexer->LexDependencyDirectiveToken(Result);
2914+
}
2915+
static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) {
2916+
return P.LexAfterModuleImport(Result);
2917+
}
29022918
};
29032919

29042920
/// Abstract base class that describes a handler that will receive

clang/lib/Lex/PPCaching.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void Preprocessor::Backtrack() {
4242
&& "EnableBacktrackAtThisPos was not called!");
4343
CachedLexPos = BacktrackPositions.back();
4444
BacktrackPositions.pop_back();
45-
recomputeCurLexerKind();
45+
recomputeCurLexerCallback();
4646
}
4747

4848
void Preprocessor::CachingLex(Token &Result) {
@@ -88,17 +88,17 @@ void Preprocessor::EnterCachingLexMode() {
8888
"entered caching lex mode while lexing something else");
8989

9090
if (InCachingLexMode()) {
91-
assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind");
91+
assert(CurLexerCallback == CLK_CachingLexer && "Unexpected lexer kind");
9292
return;
9393
}
9494

9595
EnterCachingLexModeUnchecked();
9696
}
9797

9898
void Preprocessor::EnterCachingLexModeUnchecked() {
99-
assert(CurLexerKind != CLK_CachingLexer && "already in caching lex mode");
99+
assert(CurLexerCallback != CLK_CachingLexer && "already in caching lex mode");
100100
PushIncludeMacroStack();
101-
CurLexerKind = CLK_CachingLexer;
101+
CurLexerCallback = CLK_CachingLexer;
102102
}
103103

104104

clang/lib/Lex/PPLexerChange.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
122122
CurPPLexer = TheLexer;
123123
CurDirLookup = CurDir;
124124
CurLexerSubmodule = nullptr;
125-
if (CurLexerKind != CLK_LexAfterModuleImport)
126-
CurLexerKind = TheLexer->isDependencyDirectivesLexer()
127-
? CLK_DependencyDirectivesLexer
128-
: CLK_Lexer;
125+
if (CurLexerCallback != CLK_LexAfterModuleImport)
126+
CurLexerCallback = TheLexer->isDependencyDirectivesLexer()
127+
? CLK_DependencyDirectivesLexer
128+
: CLK_Lexer;
129129

130130
// Notify the client, if desired, that we are in a new source file.
131131
if (Callbacks && !CurLexer->Is_PragmaLexer) {
@@ -161,8 +161,8 @@ void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
161161
PushIncludeMacroStack();
162162
CurDirLookup = nullptr;
163163
CurTokenLexer = std::move(TokLexer);
164-
if (CurLexerKind != CLK_LexAfterModuleImport)
165-
CurLexerKind = CLK_TokenLexer;
164+
if (CurLexerCallback != CLK_LexAfterModuleImport)
165+
CurLexerCallback = CLK_TokenLexer;
166166
}
167167

168168
/// EnterTokenStream - Add a "macro" context to the top of the include stack,
@@ -180,7 +180,7 @@ void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
180180
void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
181181
bool DisableMacroExpansion, bool OwnsTokens,
182182
bool IsReinject) {
183-
if (CurLexerKind == CLK_CachingLexer) {
183+
if (CurLexerCallback == CLK_CachingLexer) {
184184
if (CachedLexPos < CachedTokens.size()) {
185185
assert(IsReinject && "new tokens in the middle of cached stream");
186186
// We're entering tokens into the middle of our cached token stream. We
@@ -216,8 +216,8 @@ void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
216216
PushIncludeMacroStack();
217217
CurDirLookup = nullptr;
218218
CurTokenLexer = std::move(TokLexer);
219-
if (CurLexerKind != CLK_LexAfterModuleImport)
220-
CurLexerKind = CLK_TokenLexer;
219+
if (CurLexerCallback != CLK_LexAfterModuleImport)
220+
CurLexerCallback = CLK_TokenLexer;
221221
}
222222

223223
/// Compute the relative path that names the given file relative to
@@ -452,7 +452,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
452452
CurLexer.reset();
453453

454454
CurPPLexer = nullptr;
455-
recomputeCurLexerKind();
455+
recomputeCurLexerCallback();
456456
return true;
457457
}
458458

clang/lib/Lex/Preprocessor.cpp

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -380,15 +380,15 @@ StringRef Preprocessor::getLastMacroWithSpelling(
380380
return BestSpelling;
381381
}
382382

383-
void Preprocessor::recomputeCurLexerKind() {
383+
void Preprocessor::recomputeCurLexerCallback() {
384384
if (CurLexer)
385-
CurLexerKind = CurLexer->isDependencyDirectivesLexer()
386-
? CLK_DependencyDirectivesLexer
387-
: CLK_Lexer;
385+
CurLexerCallback = CurLexer->isDependencyDirectivesLexer()
386+
? CLK_DependencyDirectivesLexer
387+
: CLK_Lexer;
388388
else if (CurTokenLexer)
389-
CurLexerKind = CLK_TokenLexer;
389+
CurLexerCallback = CLK_TokenLexer;
390390
else
391-
CurLexerKind = CLK_CachingLexer;
391+
CurLexerCallback = CLK_CachingLexer;
392392
}
393393

394394
bool Preprocessor::SetCodeCompletionPoint(FileEntryRef File,
@@ -643,23 +643,7 @@ void Preprocessor::SkipTokensWhileUsingPCH() {
643643
while (true) {
644644
bool InPredefines =
645645
(CurLexer && CurLexer->getFileID() == getPredefinesFileID());
646-
switch (CurLexerKind) {
647-
case CLK_Lexer:
648-
CurLexer->Lex(Tok);
649-
break;
650-
case CLK_TokenLexer:
651-
CurTokenLexer->Lex(Tok);
652-
break;
653-
case CLK_CachingLexer:
654-
CachingLex(Tok);
655-
break;
656-
case CLK_DependencyDirectivesLexer:
657-
CurLexer->LexDependencyDirectiveToken(Tok);
658-
break;
659-
case CLK_LexAfterModuleImport:
660-
LexAfterModuleImport(Tok);
661-
break;
662-
}
646+
CurLexerCallback(*this, Tok);
663647
if (Tok.is(tok::eof) && !InPredefines) {
664648
ReachedMainFileEOF = true;
665649
break;
@@ -868,12 +852,12 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
868852
Identifier.is(tok::kw_import)) &&
869853
!InMacroArgs && !DisableMacroExpansion &&
870854
(getLangOpts().Modules || getLangOpts().DebuggerSupport) &&
871-
CurLexerKind != CLK_CachingLexer) {
855+
CurLexerCallback != CLK_CachingLexer) {
872856
ModuleImportLoc = Identifier.getLocation();
873857
NamedModuleImportPath.clear();
874858
IsAtImport = true;
875859
ModuleImportExpectsIdentifier = true;
876-
CurLexerKind = CLK_LexAfterModuleImport;
860+
CurLexerCallback = CLK_LexAfterModuleImport;
877861
}
878862
return true;
879863
}
@@ -882,27 +866,8 @@ void Preprocessor::Lex(Token &Result) {
882866
++LexLevel;
883867

884868
// We loop here until a lex function returns a token; this avoids recursion.
885-
bool ReturnedToken;
886-
do {
887-
switch (CurLexerKind) {
888-
case CLK_Lexer:
889-
ReturnedToken = CurLexer->Lex(Result);
890-
break;
891-
case CLK_TokenLexer:
892-
ReturnedToken = CurTokenLexer->Lex(Result);
893-
break;
894-
case CLK_CachingLexer:
895-
CachingLex(Result);
896-
ReturnedToken = true;
897-
break;
898-
case CLK_DependencyDirectivesLexer:
899-
ReturnedToken = CurLexer->LexDependencyDirectiveToken(Result);
900-
break;
901-
case CLK_LexAfterModuleImport:
902-
ReturnedToken = LexAfterModuleImport(Result);
903-
break;
904-
}
905-
} while (!ReturnedToken);
869+
while (!CurLexerCallback(*this, Result))
870+
;
906871

907872
if (Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure)
908873
return;
@@ -968,7 +933,7 @@ void Preprocessor::Lex(Token &Result) {
968933
NamedModuleImportPath.clear();
969934
IsAtImport = false;
970935
ModuleImportExpectsIdentifier = true;
971-
CurLexerKind = CLK_LexAfterModuleImport;
936+
CurLexerCallback = CLK_LexAfterModuleImport;
972937
}
973938
break;
974939
} else if (Result.getIdentifierInfo() == getIdentifierInfo("module")) {
@@ -1169,7 +1134,7 @@ void Preprocessor::CollectPpImportSuffix(SmallVectorImpl<Token> &Toks) {
11691134
/// We respond to a pp-import by importing macros from the named module.
11701135
bool Preprocessor::LexAfterModuleImport(Token &Result) {
11711136
// Figure out what kind of lexer we actually have.
1172-
recomputeCurLexerKind();
1137+
recomputeCurLexerCallback();
11731138

11741139
// Lex the next token. The header-name lexing rules are used at the start of
11751140
// a pp-import.
@@ -1186,7 +1151,7 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
11861151
Name += ":";
11871152
NamedModuleImportPath.push_back(
11881153
{getIdentifierInfo(Name), Result.getLocation()});
1189-
CurLexerKind = CLK_LexAfterModuleImport;
1154+
CurLexerCallback = CLK_LexAfterModuleImport;
11901155
return true;
11911156
}
11921157
} else {
@@ -1286,7 +1251,7 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
12861251
NamedModuleImportPath.push_back(
12871252
std::make_pair(Result.getIdentifierInfo(), Result.getLocation()));
12881253
ModuleImportExpectsIdentifier = false;
1289-
CurLexerKind = CLK_LexAfterModuleImport;
1254+
CurLexerCallback = CLK_LexAfterModuleImport;
12901255
return true;
12911256
}
12921257

@@ -1295,7 +1260,7 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
12951260
// attribute-specifier-seq here under the Standard C++ Modules.)
12961261
if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {
12971262
ModuleImportExpectsIdentifier = true;
1298-
CurLexerKind = CLK_LexAfterModuleImport;
1263+
CurLexerCallback = CLK_LexAfterModuleImport;
12991264
return true;
13001265
}
13011266

clang/utils/ClangVisualizers/clang.natvis

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ For later versions of Visual Studio, no setup is required-->
817817
<DisplayString IncludeView="cached"> {IncludeMacroStack._Mypair._Myval2._Mylast - 1,na}</DisplayString>
818818
<DisplayString Condition="CurLexer._Mypair._Myval2 != 0">{CurLexer._Mypair._Myval2,na}</DisplayString>
819819
<DisplayString Condition="CurTokenLexer._Mypair._Myval2 != 0">Expanding Macro: {CurTokenLexer._Mypair._Myval2,na}</DisplayString>
820-
<!-- Can't use CurLexerKind because natvis sees the type rather than the variable -->
820+
<!-- Can't use CurLexerCallback because natvis sees the type rather than the variable -->
821821
<DisplayString Condition="IncludeMacroStack._Mypair._Myval2._Mylast - IncludeMacroStack._Mypair._Myval2._Myfirst">
822822
{this,view(cached)}
823823
</DisplayString>

0 commit comments

Comments
 (0)