From 92dd466a1a8b71b8d315d9032d0f365b78697748 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 2 Jun 2011 20:01:46 +0000 Subject: [PATCH] [PCH] Store the offsets of source location file entries and go through them in ASTReader::validateFileEntries(). This avoids going through all source location entries and fixes the performance regression. Many thanks to Doug for the hint! (rdar://9530587) llvm-svn: 132481 --- .../include/clang/Serialization/ASTBitCodes.h | 7 ++++++- clang/include/clang/Serialization/ASTReader.h | 7 +++++++ clang/lib/Serialization/ASTReader.cpp | 16 ++++++++------- clang/lib/Serialization/ASTWriter.cpp | 20 +++++++++++++++++-- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index ae87b291477e..113f73ad7d43 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -367,7 +367,12 @@ namespace clang { OPENCL_EXTENSIONS = 43, /// \brief The list of delegating constructor declarations. - DELEGATING_CTORS = 44 + DELEGATING_CTORS = 44, + + /// \brief Record code for the table of offsets into the block + /// of file source-location information. + FILE_SOURCE_LOCATION_OFFSETS = 45 + }; /// \brief Record types used within a source manager block. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 6d3a0c9bd04d..8923e2ab0d71 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -257,6 +257,13 @@ private: /// AST file. const uint32_t *SLocOffsets; + /// \brief The number of source location file entries in this AST file. + unsigned LocalNumSLocFileEntries; + + /// \brief Offsets for all of the source location file entries in the + /// AST file. + const uint32_t *SLocFileOffsets; + /// \brief The entire size of this module's source location offset range. unsigned LocalSLocSize; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 8b99fc7dfe6e..3c3993f412d3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2193,6 +2193,11 @@ ASTReader::ReadASTBlock(PerFileData &F) { F.LocalSLocSize = Record[1]; break; + case FILE_SOURCE_LOCATION_OFFSETS: + F.SLocFileOffsets = (const uint32_t *)BlobStart; + F.LocalNumSLocFileEntries = Record[0]; + break; + case SOURCE_LOCATION_PRELOADS: if (PreloadSLocEntries.empty()) PreloadSLocEntries.swap(Record); @@ -2372,8 +2377,8 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries() { PerFileData *F = Chain[CI]; llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor; - for (unsigned i = 0, e = F->LocalNumSLocEntries; i != e; ++i) { - SLocEntryCursor.JumpToBit(F->SLocOffsets[i]); + for (unsigned i = 0, e = F->LocalNumSLocFileEntries; i != e; ++i) { + SLocEntryCursor.JumpToBit(F->SLocFileOffsets[i]); unsigned Code = SLocEntryCursor.ReadCode(); if (Code == llvm::bitc::END_BLOCK || Code == llvm::bitc::ENTER_SUBBLOCK || @@ -2429,10 +2434,6 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries() { break; } - - case SM_SLOC_BUFFER_ENTRY: - case SM_SLOC_INSTANTIATION_ENTRY: - break; } } } @@ -5197,7 +5198,8 @@ ASTReader::~ASTReader() { } ASTReader::PerFileData::PerFileData(ASTFileType Ty) - : Type(Ty), SizeInBits(0), LocalNumSLocEntries(0), SLocOffsets(0), LocalSLocSize(0), + : Type(Ty), SizeInBits(0), LocalNumSLocEntries(0), SLocOffsets(0), + SLocFileOffsets(0), LocalSLocSize(0), LocalNumIdentifiers(0), IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0), LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 297115c491c9..3bb27cff0f12 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1449,6 +1449,9 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Write out the source location entry table. We skip the first // entry, which is always the same dummy entry. std::vector SLocEntryOffsets; + // Write out the offsets of only source location file entries. + // We will go through them in ASTReader::validateFileEntries(). + std::vector SLocFileEntryOffsets; RecordData PreloadSLocs; unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); @@ -1463,9 +1466,10 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Figure out which record code to use. unsigned Code; if (SLoc->isFile()) { - if (SLoc->getFile().getContentCache()->OrigEntry) + if (SLoc->getFile().getContentCache()->OrigEntry) { Code = SM_SLOC_FILE_ENTRY; - else + SLocFileEntryOffsets.push_back(Stream.GetCurrentBitNo()); + } else Code = SM_SLOC_BUFFER_ENTRY; } else Code = SM_SLOC_INSTANTIATION_ENTRY; @@ -1565,6 +1569,18 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(SourceMgr.getNextOffset() - BaseOffset); Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets)); + Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(FILE_SOURCE_LOCATION_OFFSETS)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets + unsigned SLocFileOffsetsAbbrev = Stream.EmitAbbrev(Abbrev); + + Record.clear(); + Record.push_back(FILE_SOURCE_LOCATION_OFFSETS); + Record.push_back(SLocFileEntryOffsets.size()); + Stream.EmitRecordWithBlob(SLocFileOffsetsAbbrev, Record, + data(SLocFileEntryOffsets)); + // Write the source location entry preloads array, telling the AST // reader which source locations entries it should load eagerly. Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs);