From e740089d297199c43085e680cee0293c1af73193 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 11 Oct 2012 17:41:54 +0000 Subject: [PATCH] Introduce a simple "hint" scheme to eliminate the quadratic behavior associated with deserializing macro history for an identifier. llvm-svn: 165729 --- clang/include/clang/Lex/Preprocessor.h | 3 ++- clang/include/clang/Serialization/ASTReader.h | 4 ++-- clang/lib/Lex/PPMacroExpansion.cpp | 6 +++--- clang/lib/Serialization/ASTReader.cpp | 12 +++++++----- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 2c0814c91073..7888a26fcbda 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -519,7 +519,8 @@ public: /// \brief Specify a macro for this identifier. void setMacroInfo(IdentifierInfo *II, MacroInfo *MI); /// \brief Add a MacroInfo that was loaded from an AST file. - void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI); + void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI, + MacroInfo *Hint = 0); /// \brief Make the given MacroInfo, that was loaded from an AST file and /// previously hidden, visible. void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI); diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 2a9afc92e9b8..4e8531a820eb 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1433,7 +1433,7 @@ public: unsigned LocalID); /// \brief Retrieve the macro with the given ID. - MacroInfo *getMacro(serialization::MacroID ID); + MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0); /// \brief Retrieve the global macro ID corresponding to the given local /// ID within the given module file. @@ -1582,7 +1582,7 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(ModuleFile &F, uint64_t Offset); + void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0); /// \brief Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 8db74f28d414..c7178166507a 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -55,7 +55,8 @@ void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) { II->setChangedSinceDeserialization(); } -void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI) { +void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI, + MacroInfo *Hint) { assert(MI && "Missing macro?"); assert(MI->isFromAST() && "Macro is not from an AST?"); assert(!MI->getPreviousDefinition() && "Macro already in chain?"); @@ -105,8 +106,7 @@ void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI) { } // The macro is not a definition; put it at the end of the list. - // FIXME: Adding macro history is quadratic, but a hint could fix this. - MacroInfo *Prev = StoredMI; + MacroInfo *Prev = Hint? Hint : StoredMI; while (Prev->getPreviousDefinition()) Prev = Prev->getPreviousDefinition(); Prev->setPreviousDefinition(MI); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 736f082d6f38..5657ee23bc12 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1241,7 +1241,8 @@ bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, } } -void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { +void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset, + MacroInfo *Hint) { llvm::BitstreamCursor &Stream = F.MacroCursor; // Keep track of where we are in the stream, then jump back there @@ -1370,7 +1371,7 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { MI->setHidden(Hidden); // Finally, install the macro. - PP.addLoadedMacroInfo(II, MI); + PP.addLoadedMacroInfo(II, MI, Hint); // Remember that we saw this macro last so that we add the tokens that // form its body to it. @@ -5795,7 +5796,7 @@ IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) { return LocalID + I->second; } -MacroInfo *ASTReader::getMacro(MacroID ID) { +MacroInfo *ASTReader::getMacro(MacroID ID, MacroInfo *Hint) { if (ID == 0) return 0; @@ -5811,7 +5812,7 @@ MacroInfo *ASTReader::getMacro(MacroID ID) { assert(I != GlobalMacroMap.end() && "Corrupted global macro map"); ModuleFile *M = I->second; unsigned Index = ID - M->BaseMacroID; - ReadMacroRecord(*M, M->MacroOffsets[Index]); + ReadMacroRecord(*M, M->MacroOffsets[Index], Hint); } return MacrosLoaded[ID]; @@ -6512,9 +6513,10 @@ void ASTReader::finishPendingActions() { for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) { // FIXME: std::move here SmallVector GlobalIDs = PendingMacroIDs.begin()[I].second; + MacroInfo *Hint = 0; for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs; ++IDIdx) { - getMacro(GlobalIDs[IDIdx]); + Hint = getMacro(GlobalIDs[IDIdx], Hint); } } PendingMacroIDs.clear();