aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-10-29 22:39:52 +0000
committerDouglas Gregor <dgregor@apple.com>2010-10-29 22:39:52 +0000
commit7c789c1a3f77f24032aa0bed2afacdb9e094e952 (patch)
tree7891cd4684de4f541f141dad60c9698590ead702 /lib/Serialization/ASTWriter.cpp
parent110e8e56af30363072c140285961592b0107f789 (diff)
Make the deserialization of C++ base class specifiers lazy, improving
the performance of C++ PCH and reducing stack depth in the reader. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117732 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r--lib/Serialization/ASTWriter.cpp77
1 files changed, 70 insertions, 7 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 114f9205d4..1fec22be4e 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1725,7 +1725,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
// Create a blob abbreviation for the selector table offsets.
Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
@@ -2230,7 +2230,9 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID),
CollectedStmts(&StmtsToEmit),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
- NumVisibleDeclContexts(0) {
+ NumVisibleDeclContexts(0), FirstCXXBaseSpecifiersID(1),
+ NextCXXBaseSpecifiersID(1)
+{
}
void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
@@ -2401,6 +2403,26 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
WriteTypeDeclOffsets();
+ // Write the C++ base-specifier set offsets.
+ if (!CXXBaseSpecifiersOffsets.empty()) {
+ // Create a blob abbreviation for the C++ base specifiers offsets.
+ using namespace llvm;
+
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+
+ // Write the selector offsets table.
+ Record.clear();
+ Record.push_back(CXX_BASE_SPECIFIER_OFFSETS);
+ Record.push_back(CXXBaseSpecifiersOffsets.size());
+ Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record,
+ (const char *)CXXBaseSpecifiersOffsets.data(),
+ CXXBaseSpecifiersOffsets.size() * sizeof(uint32_t));
+ }
+
// Write the record containing external, unnamed definitions.
if (!ExternalDefinitions.empty())
Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
@@ -2798,6 +2820,16 @@ void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record
AddDeclRef(Temp->getDestructor(), Record);
}
+void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
+ CXXBaseSpecifier const *BasesEnd,
+ RecordDataImpl &Record) {
+ assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded");
+ CXXBaseSpecifiersToWrite.push_back(
+ QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID,
+ Bases, BasesEnd));
+ Record.push_back(NextCXXBaseSpecifiersID++);
+}
+
void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg,
RecordDataImpl &Record) {
@@ -3155,6 +3187,32 @@ void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
AddSourceRange(Base.getSourceRange(), Record);
}
+void ASTWriter::FlushCXXBaseSpecifiers() {
+ RecordData Record;
+ for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) {
+ Record.clear();
+
+ // Record the offset of this base-specifier set.
+ unsigned Index = CXXBaseSpecifiersToWrite[I].ID - FirstCXXBaseSpecifiersID;
+ if (Index == CXXBaseSpecifiersOffsets.size())
+ CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo());
+ else {
+ if (Index > CXXBaseSpecifiersOffsets.size())
+ CXXBaseSpecifiersOffsets.resize(Index + 1);
+ CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo();
+ }
+
+ const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases,
+ *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd;
+ Record.push_back(BEnd - B);
+ for (; B != BEnd; ++B)
+ AddCXXBaseSpecifier(*B, Record);
+ Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record);
+ }
+
+ CXXBaseSpecifiersToWrite.clear();
+}
+
void ASTWriter::AddCXXBaseOrMemberInitializers(
const CXXBaseOrMemberInitializer * const *BaseOrMembers,
unsigned NumBaseOrMembers, RecordDataImpl &Record) {
@@ -3208,13 +3266,15 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
Record.push_back(Data.DeclaredDestructor);
Record.push_back(Data.NumBases);
- for (unsigned i = 0; i != Data.NumBases; ++i)
- AddCXXBaseSpecifier(Data.Bases[i], Record);
-
+ if (Data.NumBases > 0)
+ AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases,
+ Record);
+
// FIXME: Make VBases lazily computed when needed to avoid storing them.
Record.push_back(Data.NumVBases);
- for (unsigned i = 0; i != Data.NumVBases; ++i)
- AddCXXBaseSpecifier(Data.VBases[i], Record);
+ if (Data.NumVBases > 0)
+ AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases,
+ Record);
AddUnresolvedSet(Data.Conversions, Record);
AddUnresolvedSet(Data.VisibleConversions, Record);
@@ -3230,6 +3290,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) {
FirstIdentID == NextIdentID &&
FirstSelectorID == NextSelectorID &&
FirstMacroID == NextMacroID &&
+ FirstCXXBaseSpecifiersID == NextCXXBaseSpecifiersID &&
"Setting chain after writing has started.");
Chain = Reader;
@@ -3238,11 +3299,13 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) {
FirstIdentID += Chain->getTotalNumIdentifiers();
FirstSelectorID += Chain->getTotalNumSelectors();
FirstMacroID += Chain->getTotalNumMacroDefinitions();
+ FirstCXXBaseSpecifiersID += Chain->getTotalNumCXXBaseSpecifiers();
NextDeclID = FirstDeclID;
NextTypeID = FirstTypeID;
NextIdentID = FirstIdentID;
NextSelectorID = FirstSelectorID;
NextMacroID = FirstMacroID;
+ NextCXXBaseSpecifiersID = FirstCXXBaseSpecifiersID;
}
void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {