Introduce a simple "hint" scheme to eliminate the quadratic behavior

associated with deserializing macro history for an identifier.

llvm-svn: 165729
This commit is contained in:
Douglas Gregor 2012-10-11 17:41:54 +00:00
parent b29e6c6e84
commit e740089d29
4 changed files with 14 additions and 11 deletions

View File

@ -519,7 +519,8 @@ public:
/// \brief Specify a macro for this identifier. /// \brief Specify a macro for this identifier.
void setMacroInfo(IdentifierInfo *II, MacroInfo *MI); void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
/// \brief Add a MacroInfo that was loaded from an AST file. /// \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 /// \brief Make the given MacroInfo, that was loaded from an AST file and
/// previously hidden, visible. /// previously hidden, visible.
void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI); void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI);

View File

@ -1433,7 +1433,7 @@ public:
unsigned LocalID); unsigned LocalID);
/// \brief Retrieve the macro with the given ID. /// \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 /// \brief Retrieve the global macro ID corresponding to the given local
/// ID within the given module file. /// ID within the given module file.
@ -1582,7 +1582,7 @@ public:
Expr *ReadSubExpr(); Expr *ReadSubExpr();
/// \brief Reads the macro record located at the given offset. /// \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 /// \brief Determine the global preprocessed entity ID that corresponds to
/// the given local ID within the given module. /// the given local ID within the given module.

View File

@ -55,7 +55,8 @@ void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
II->setChangedSinceDeserialization(); II->setChangedSinceDeserialization();
} }
void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI) { void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
MacroInfo *Hint) {
assert(MI && "Missing macro?"); assert(MI && "Missing macro?");
assert(MI->isFromAST() && "Macro is not from an AST?"); assert(MI->isFromAST() && "Macro is not from an AST?");
assert(!MI->getPreviousDefinition() && "Macro already in chain?"); 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. // 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 = Hint? Hint : StoredMI;
MacroInfo *Prev = StoredMI;
while (Prev->getPreviousDefinition()) while (Prev->getPreviousDefinition())
Prev = Prev->getPreviousDefinition(); Prev = Prev->getPreviousDefinition();
Prev->setPreviousDefinition(MI); Prev->setPreviousDefinition(MI);

View File

@ -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; llvm::BitstreamCursor &Stream = F.MacroCursor;
// Keep track of where we are in the stream, then jump back there // 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); MI->setHidden(Hidden);
// Finally, install the macro. // 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 // Remember that we saw this macro last so that we add the tokens that
// form its body to it. // form its body to it.
@ -5795,7 +5796,7 @@ IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
return LocalID + I->second; return LocalID + I->second;
} }
MacroInfo *ASTReader::getMacro(MacroID ID) { MacroInfo *ASTReader::getMacro(MacroID ID, MacroInfo *Hint) {
if (ID == 0) if (ID == 0)
return 0; return 0;
@ -5811,7 +5812,7 @@ MacroInfo *ASTReader::getMacro(MacroID ID) {
assert(I != GlobalMacroMap.end() && "Corrupted global macro map"); assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
ModuleFile *M = I->second; ModuleFile *M = I->second;
unsigned Index = ID - M->BaseMacroID; unsigned Index = ID - M->BaseMacroID;
ReadMacroRecord(*M, M->MacroOffsets[Index]); ReadMacroRecord(*M, M->MacroOffsets[Index], Hint);
} }
return MacrosLoaded[ID]; return MacrosLoaded[ID];
@ -6512,9 +6513,10 @@ void ASTReader::finishPendingActions() {
for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) { for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {
// FIXME: std::move here // FIXME: std::move here
SmallVector<MacroID, 2> GlobalIDs = PendingMacroIDs.begin()[I].second; SmallVector<MacroID, 2> GlobalIDs = PendingMacroIDs.begin()[I].second;
MacroInfo *Hint = 0;
for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs; for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
++IDIdx) { ++IDIdx) {
getMacro(GlobalIDs[IDIdx]); Hint = getMacro(GlobalIDs[IDIdx], Hint);
} }
} }
PendingMacroIDs.clear(); PendingMacroIDs.clear();