[modules] Remove CXX_BASE_SPECIFIERS_OFFSETS table. Instead of storing an ID of

a table entry in the corresponding decl, store an offset from the current
record to the relevant CXX_BASE_SPECIFIERS record. This results in fewer
indirections and a minor .pcm file size reduction.

llvm-svn: 266266
This commit is contained in:
Richard Smith 2016-04-14 00:29:55 +00:00
parent 42b5969862
commit 645d2cfd9c
10 changed files with 30 additions and 172 deletions

View File

@ -523,6 +523,13 @@ class CXXRecordDecl : public RecordDecl {
return getVBasesSlowCase();
}
ArrayRef<CXXBaseSpecifier> bases() const {
return llvm::makeArrayRef(getBases(), NumBases);
}
ArrayRef<CXXBaseSpecifier> vbases() const {
return llvm::makeArrayRef(getVBases(), NumVBases);
}
private:
CXXBaseSpecifier *getBasesSlowCase() const;
CXXBaseSpecifier *getVBasesSlowCase() const;

View File

@ -491,9 +491,7 @@ namespace clang {
// ID 30 used to be a decl update record. These are now in the DECLTYPES
// block.
/// \brief Record code for the table of offsets to CXXBaseSpecifier
/// sets.
CXX_BASE_SPECIFIER_OFFSETS = 31,
// ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records.
/// \brief Record code for \#pragma diagnostic mappings.
DIAG_PRAGMA_MAPPINGS = 32,

View File

@ -1687,11 +1687,6 @@ public:
/// redeclaration chain for \p D.
void CompleteRedeclChain(const Decl *D) override;
/// \brief Read a CXXBaseSpecifiers ID form the given record and
/// return its global bit offset.
uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
unsigned &Idx);
CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
/// \brief Resolve the offset of a statement into a statement.

View File

@ -409,35 +409,6 @@ private:
/// file.
unsigned NumVisibleDeclContexts;
/// \brief The offset of each CXXBaseSpecifier set within the AST.
SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets;
/// \brief The first ID number we can use for our own base specifiers.
serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID;
/// \brief The base specifiers ID that will be assigned to the next new
/// set of C++ base specifiers.
serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID;
/// \brief A set of C++ base specifiers that is queued to be written into the
/// AST file.
struct QueuedCXXBaseSpecifiers {
QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { }
QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID,
CXXBaseSpecifier const *Bases,
CXXBaseSpecifier const *BasesEnd)
: ID(ID), Bases(Bases), BasesEnd(BasesEnd) { }
serialization::CXXBaseSpecifiersID ID;
CXXBaseSpecifier const * Bases;
CXXBaseSpecifier const * BasesEnd;
};
/// \brief Queue of C++ base specifiers to be written to the AST file,
/// in the order they should be written.
SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
/// \brief A mapping from each known submodule to its ID number, which will
/// be a positive integer.
llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
@ -466,7 +437,6 @@ private:
void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
bool isModule);
void WriteCXXBaseSpecifiersOffsets();
unsigned TypeExtQualAbbrev;
unsigned TypeFunctionProtoAbbrev;
@ -574,11 +544,6 @@ public:
/// \brief Emit a CXXTemporary.
void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record);
/// \brief Emit a set of C++ base specifiers to the record.
void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
CXXBaseSpecifier const *BasesEnd,
RecordDataImpl &Record);
/// \brief Get the unique number used to refer to the given selector.
serialization::SelectorID getSelectorRef(Selector Sel);
@ -666,16 +631,6 @@ public:
/// within the method pool/selector table.
void SetSelectorOffset(Selector Sel, uint32_t Offset);
/// \brief Flush all of the C++ base specifier sets that have been added
/// via \c AddCXXBaseSpecifiersRef().
void FlushCXXBaseSpecifiers();
/// \brief Flush all pending records that are tacked onto the end of
/// decl and decl update records.
void FlushPendingAfterDecl() {
FlushCXXBaseSpecifiers();
}
/// \brief Record an ID for the given switch-case statement.
unsigned RecordSwitchCaseID(SwitchCase *S);
@ -877,11 +832,11 @@ public:
return Writer->AddCXXTemporary(Temp, *Record);
}
/// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
/// \brief Emit a set of C++ base specifiers.
void AddCXXBaseSpecifiersRef(const CXXBaseSpecifier *BasesBegin,
const CXXBaseSpecifier *BasesEnd) {
return Writer->AddCXXBaseSpecifiersRef(BasesBegin, BasesEnd, *Record);
}
void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
/// \brief Emit a reference to a type.
void AddTypeRef(QualType T) {
@ -947,9 +902,6 @@ public:
return Writer->AddUnresolvedSet(Set, *Record);
}
/// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
/// \brief Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer*> CtorInits);

View File

@ -399,13 +399,6 @@ public:
/// as a local ID (for this module file).
llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
/// \brief The number of C++ base specifier sets in this AST file.
unsigned LocalNumCXXBaseSpecifiers;
/// \brief Offset of each C++ base specifier set within the bitstream,
/// indexed by the C++ base specifier set ID (-1).
const uint32_t *CXXBaseSpecifiersOffsets;
/// \brief Array of file-level DeclIDs sorted by file.
const serialization::DeclID *FileSortedDecls;
unsigned NumFileSortedDecls;

View File

@ -3053,17 +3053,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
F.ObjCCategories.swap(Record);
break;
case CXX_BASE_SPECIFIER_OFFSETS: {
if (F.LocalNumCXXBaseSpecifiers != 0) {
Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");
return Failure;
}
F.LocalNumCXXBaseSpecifiers = Record[0];
F.CXXBaseSpecifiersOffsets = (const uint32_t *)Blob.data();
break;
}
case DIAG_PRAGMA_MAPPINGS:
if (F.PragmaDiagMappings.empty())
F.PragmaDiagMappings.swap(Record);
@ -6312,18 +6301,6 @@ ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) {
return ReadCXXCtorInitializers(*Loc.F, Record, Idx);
}
uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M,
const RecordData &Record,
unsigned &Idx) {
if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXBaseSpecifiers) {
Error("malformed AST file: missing C++ base specifier");
return 0;
}
unsigned LocalID = Record[Idx++];
return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
}
CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
RecordLocation Loc = getLocalBitOffset(Offset);
BitstreamCursor &Cursor = Loc.F->DeclsCursor;

View File

@ -1479,10 +1479,10 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.NumBases = Record[Idx++];
if (Data.NumBases)
Data.Bases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
Data.Bases = ReadGlobalOffset(F, Record, Idx);
Data.NumVBases = Record[Idx++];
if (Data.NumVBases)
Data.VBases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
Data.VBases = ReadGlobalOffset(F, Record, Idx);
Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx);
Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);

View File

@ -961,7 +961,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(UPDATE_VISIBLE);
RECORD(DECL_UPDATE_OFFSETS);
RECORD(DECL_UPDATES);
RECORD(CXX_BASE_SPECIFIER_OFFSETS);
RECORD(DIAG_PRAGMA_MAPPINGS);
RECORD(CUDA_SPECIAL_DECL_REFS);
RECORD(HEADER_SEARCH_TABLE);
@ -2724,26 +2723,6 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record);
}
void ASTWriter::WriteCXXBaseSpecifiersOffsets() {
if (CXXBaseSpecifiersOffsets.empty())
return;
// Create a blob abbreviation for the C++ base specifiers offsets.
using namespace llvm;
auto *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 base specifier offsets table.
RecordData::value_type Record[] = {CXX_BASE_SPECIFIER_OFFSETS,
CXXBaseSpecifiersOffsets.size()};
Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record,
bytes(CXXBaseSpecifiersOffsets));
}
//===----------------------------------------------------------------------===//
// Type Serialization
//===----------------------------------------------------------------------===//
@ -4095,7 +4074,6 @@ ASTWriter::ASTWriter(
FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
NumStatements(0), NumMacros(0),
NumLexicalDeclContexts(0), NumVisibleDeclContexts(0),
NextCXXBaseSpecifiersID(1),
TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),
DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0),
UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0),
@ -4496,7 +4474,6 @@ uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
WriteTypeDeclOffsets();
if (!DeclUpdatesOffsetsRecord.empty())
Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
WriteCXXBaseSpecifiersOffsets();
WriteFileDeclIDsMap();
WriteSourceManagerBlock(Context.getSourceManager(), PP);
WriteComments();
@ -4778,8 +4755,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
OffsetsRecord.push_back(GetDeclRef(D));
OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
FlushPendingAfterDecl();
}
}
@ -4877,16 +4852,6 @@ 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 ASTRecordWriter::AddTemplateArgumentLocInfo(
TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) {
switch (Kind) {
@ -5421,43 +5386,23 @@ void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
: SourceLocation());
}
void ASTWriter::FlushCXXBaseSpecifiers() {
RecordData Record;
unsigned N = CXXBaseSpecifiersToWrite.size();
for (unsigned I = 0; I != N; ++I) {
Record.clear();
static uint64_t EmitCXXBaseSpecifiers(ASTWriter &W,
ArrayRef<CXXBaseSpecifier> Bases) {
ASTWriter::RecordData Record;
ASTRecordWriter Writer(W, Record);
Writer.push_back(Bases.size());
const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases,
*BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd;
for (auto &Base : Bases)
Writer.AddCXXBaseSpecifier(Base);
// Write the base specifier set.
ASTRecordWriter Writer(*this, Record);
Writer.push_back(BEnd - B);
for (; B != BEnd; ++B)
Writer.AddCXXBaseSpecifier(*B);
uint64_t Offset = Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS);
// Record the offset of this base-specifier set.
//
// FIXME: We don't need an indirect lookup table for these; instead, write
// the base specifier record prior to the decl record and store its offset
// from the decl record rather than its ID.
unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1;
if (Index == CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.push_back(Offset);
else {
if (Index > CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.resize(Index + 1);
CXXBaseSpecifiersOffsets[Index] = Offset;
}
}
assert(N == CXXBaseSpecifiersToWrite.size() &&
"added more base specifiers while writing base specifiers");
CXXBaseSpecifiersToWrite.clear();
return Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS);
}
// FIXME: Move this out of the main ASTRecordWriter interface.
void ASTRecordWriter::AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases) {
AddOffset(EmitCXXBaseSpecifiers(*Writer, Bases));
}
static uint64_t
EmitCXXCtorInitializers(ASTWriter &W,
ArrayRef<CXXCtorInitializer *> CtorInits) {
@ -5550,13 +5495,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
Record->push_back(Data.NumBases);
if (Data.NumBases > 0)
AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases);
AddCXXBaseSpecifiers(Data.bases());
// FIXME: Make VBases lazily computed when needed to avoid storing them.
Record->push_back(Data.NumVBases);
if (Data.NumVBases > 0)
AddCXXBaseSpecifiersRef(Data.getVBases(),
Data.getVBases() + Data.NumVBases);
AddCXXBaseSpecifiers(Data.vbases());
AddUnresolvedSet(Data.Conversions.get(*Writer->Context));
AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context));

View File

@ -49,14 +49,7 @@ namespace clang {
if (!Code)
llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
D->getDeclKindName() + "'");
auto Offset = Record.Emit(Code, AbbrevToUse);
// Flush any base specifiers and ctor initializers that
// were written as part of this declaration.
Writer.FlushPendingAfterDecl();
return Offset;
return Record.Emit(Code, AbbrevToUse);
}
void Visit(Decl *D);

View File

@ -37,7 +37,6 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0),
SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr),
LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0),
LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(nullptr),
FileSortedDecls(nullptr), NumFileSortedDecls(0),
ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0),
LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)