diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-10-30 00:23:06 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-10-30 00:23:06 +0000 |
commit | 295a2a617ac335f590e430ab7fcd98f8ce109251 (patch) | |
tree | f99afd1bb537d0c93b87cd955cefe6e810cc36e0 /lib | |
parent | 20e047abc5f19dc948436c0fb891450d9cd40667 (diff) |
Make the deserialization of macro definitions lazy, so that we can
load identifiers without loading their corresponding macro
definitions. This is likely to improve PCH performance slightly, and
reduces deserialization stack depth considerably when using
preprocessor metaprogramming.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117750 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 15 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 51 |
2 files changed, 65 insertions, 1 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 68fc56f7b7..a9f4cacf6c 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -20,12 +20,27 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/ExternalPreprocessorSource.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> #include <ctime> using namespace clang; +MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const { + assert(II->hasMacroDefinition() && "Identifier is not a macro!"); + + llvm::DenseMap<IdentifierInfo*, MacroInfo*>::const_iterator Pos + = Macros.find(II); + if (Pos == Macros.end()) { + // Load this macro from the external source. + getExternalSource()->LoadMacroDefinition(II); + Pos = Macros.find(II); + } + assert(Pos != Macros.end() && "Identifier macro info is missing!"); + return Pos->second; +} + /// setMacroInfo - Specify a macro for this identifier. /// void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) { diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index aa76765dc9..22d3cbc68f 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -682,7 +682,7 @@ public: // definition. if (hasMacroDefinition) { uint32_t Offset = ReadUnalignedLE32(d); - Reader.ReadMacroRecord(F, Offset); + Reader.SetIdentifierIsMacro(II, F, Offset); DataLen -= 4; } @@ -1568,6 +1568,22 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { } } +void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, + uint64_t Offset) { + // Note that this identifier has a macro definition. + II->setHasMacroDefinition(true); + + // Adjust the offset based on our position in the chain. + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Chain[I] == &F) + break; + + Offset += Chain[I]->SizeInBits; + } + + UnreadMacroRecordOffsets[II] = Offset; +} + void ASTReader::ReadDefinedMacros() { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PerFileData &F = *Chain[N - I - 1]; @@ -1629,6 +1645,39 @@ void ASTReader::ReadDefinedMacros() { } } } + + // Drain the unread macro-record offsets map. + while (!UnreadMacroRecordOffsets.empty()) + LoadMacroDefinition(UnreadMacroRecordOffsets.begin()); +} + +void ASTReader::LoadMacroDefinition( + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) { + assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition"); + PerFileData *F = 0; + uint64_t Offset = Pos->second; + UnreadMacroRecordOffsets.erase(Pos); + + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Offset < Chain[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + if (!F) { + Error("Malformed macro record offset"); + return; + } + + ReadMacroRecord(*F, Offset); +} + +void ASTReader::LoadMacroDefinition(IdentifierInfo *II) { + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos + = UnreadMacroRecordOffsets.find(II); + LoadMacroDefinition(Pos); } MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) { |