aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-25 18:35:21 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-25 18:35:21 +0000
commit8f5dc7fe4d42cea78fa92d1638f753cf65b54cb5 (patch)
treeb2778f92a10f8202a569331f23901443dc3253bf /lib/Frontend
parent83941df2745d69c05acee3174c7a265c206f70d9 (diff)
Write the declaration and type offset arrays into the bitstream as
blobs, so that we don't need to do any work to get these arrays into memory at PCH load time. This gives another 19% performance improvement to the Cocoa-prefixed "Hello, World!". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70059 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/PCHReader.cpp64
-rw-r--r--lib/Frontend/PCHWriter.cpp32
2 files changed, 60 insertions, 36 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 3e612be629..897a0e7713 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1802,21 +1802,21 @@ PCHReader::ReadPCHBlock(uint64_t &PreprocessorBlockOffset) {
break;
case pch::TYPE_OFFSET:
- if (!TypeOffsets.empty()) {
+ if (!TypesLoaded.empty()) {
Error("Duplicate TYPE_OFFSET record in PCH file");
return Failure;
}
- TypeOffsets.swap(Record);
- TypeAlreadyLoaded.resize(TypeOffsets.size(), false);
+ TypeOffsets = (const uint64_t *)BlobStart;
+ TypesLoaded.resize(Record[0]);
break;
case pch::DECL_OFFSET:
- if (!DeclOffsets.empty()) {
+ if (!DeclsLoaded.empty()) {
Error("Duplicate DECL_OFFSET record in PCH file");
return Failure;
}
- DeclOffsets.swap(Record);
- DeclAlreadyLoaded.resize(DeclOffsets.size(), false);
+ DeclOffsets = (const uint64_t *)BlobStart;
+ DeclsLoaded.resize(Record[0]);
break;
case pch::LANGUAGE_OPTIONS:
@@ -2340,9 +2340,8 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
/// so that future GetDecl calls will return this declaration rather
/// than trying to load a new declaration.
inline void PCHReader::LoadedDecl(unsigned Index, Decl *D) {
- assert(!DeclAlreadyLoaded[Index] && "Decl loaded twice?");
- DeclAlreadyLoaded[Index] = true;
- DeclOffsets[Index] = reinterpret_cast<uint64_t>(D);
+ assert(!DeclsLoaded[Index] && "Decl loaded twice?");
+ DeclsLoaded[Index] = D;
}
/// \brief Determine whether the consumer will be interested in seeing
@@ -2591,27 +2590,26 @@ QualType PCHReader::GetType(pch::TypeID ID) {
}
Index -= pch::NUM_PREDEF_TYPE_IDS;
- if (!TypeAlreadyLoaded[Index]) {
- // Load the type from the PCH file.
- TypeOffsets[Index] = reinterpret_cast<uint64_t>(
- ReadTypeRecord(TypeOffsets[Index]).getTypePtr());
- TypeAlreadyLoaded[Index] = true;
- }
+ if (!TypesLoaded[Index])
+ TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]).getTypePtr();
- return QualType(reinterpret_cast<Type *>(TypeOffsets[Index]), Quals);
+ return QualType(TypesLoaded[Index], Quals);
}
Decl *PCHReader::GetDecl(pch::DeclID ID) {
if (ID == 0)
return 0;
+ if (ID > DeclsLoaded.size()) {
+ Error("Declaration ID out-of-range for PCH file");
+ return 0;
+ }
+
unsigned Index = ID - 1;
- assert(Index < DeclAlreadyLoaded.size() && "Declaration ID out of range");
- if (DeclAlreadyLoaded[Index])
- return reinterpret_cast<Decl *>(DeclOffsets[Index]);
+ if (!DeclsLoaded[Index])
+ ReadDeclRecord(DeclOffsets[Index], Index);
- // Load the declaration from the PCH file.
- return ReadDeclRecord(DeclOffsets[Index], Index);
+ return DeclsLoaded[Index];
}
Stmt *PCHReader::GetStmt(uint64_t Offset) {
@@ -2712,12 +2710,12 @@ void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
void PCHReader::PrintStats() {
std::fprintf(stderr, "*** PCH Statistics:\n");
- unsigned NumTypesLoaded = std::count(TypeAlreadyLoaded.begin(),
- TypeAlreadyLoaded.end(),
- true);
- unsigned NumDeclsLoaded = std::count(DeclAlreadyLoaded.begin(),
- DeclAlreadyLoaded.end(),
- true);
+ unsigned NumTypesLoaded =
+ TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
+ (Type *)0);
+ unsigned NumDeclsLoaded =
+ DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
+ (Decl *)0);
unsigned NumIdentifiersLoaded = 0;
for (unsigned I = 0; I < IdentifierData.size(); ++I) {
if ((IdentifierData[I] & 0x01) == 0)
@@ -2729,14 +2727,14 @@ void PCHReader::PrintStats() {
++NumSelectorsLoaded;
}
- if (!TypeAlreadyLoaded.empty())
+ if (!TypesLoaded.empty())
std::fprintf(stderr, " %u/%u types read (%f%%)\n",
- NumTypesLoaded, (unsigned)TypeAlreadyLoaded.size(),
- ((float)NumTypesLoaded/TypeAlreadyLoaded.size() * 100));
- if (!DeclAlreadyLoaded.empty())
+ NumTypesLoaded, (unsigned)TypesLoaded.size(),
+ ((float)NumTypesLoaded/TypesLoaded.size() * 100));
+ if (!DeclsLoaded.empty())
std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
- NumDeclsLoaded, (unsigned)DeclAlreadyLoaded.size(),
- ((float)NumDeclsLoaded/DeclAlreadyLoaded.size() * 100));
+ NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
+ ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
if (!IdentifierData.empty())
std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
NumIdentifiersLoaded, (unsigned)IdentifierData.size(),
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 56c8296c94..91ddbf4182 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -2270,6 +2270,8 @@ PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
NumVisibleDeclContexts(0) { }
void PCHWriter::WritePCH(Sema &SemaRef) {
+ using namespace llvm;
+
ASTContext &Context = SemaRef.Context;
Preprocessor &PP = SemaRef.PP;
@@ -2315,7 +2317,7 @@ void PCHWriter::WritePCH(Sema &SemaRef) {
// Write the remaining PCH contents.
RecordData Record;
- Stream.EnterSubblock(pch::PCH_BLOCK_ID, 3);
+ Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
WriteTargetTriple(Context.Target);
WriteLanguageOptions(Context.getLangOptions());
WriteSourceManagerBlock(Context.getSourceManager());
@@ -2324,8 +2326,32 @@ void PCHWriter::WritePCH(Sema &SemaRef) {
WriteDeclsBlock(Context);
WriteMethodPool(SemaRef);
WriteIdentifierTable(PP);
- Stream.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
- Stream.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
+
+ // Write the type offsets array
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(pch::TYPE_OFFSET));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
+ unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+ Record.clear();
+ Record.push_back(pch::TYPE_OFFSET);
+ Record.push_back(TypeOffsets.size());
+ Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
+ (const char *)&TypeOffsets.front(),
+ TypeOffsets.size() * sizeof(uint64_t));
+
+ // Write the declaration offsets array
+ Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
+ unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+ Record.clear();
+ Record.push_back(pch::DECL_OFFSET);
+ Record.push_back(DeclOffsets.size());
+ Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
+ (const char *)&DeclOffsets.front(),
+ DeclOffsets.size() * sizeof(uint64_t));
// Write the record of special types.
Record.clear();