Skip to content

Commit

Permalink
[Serialization] Store DeclID in two slots to utilize VBR6 format
Browse files Browse the repository at this point in the history
  • Loading branch information
ChuanqiXu9 committed Jun 24, 2024
1 parent 79b0966 commit 0e6b0ee
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 108 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ using unaligned_decl_id_t =
serialization::DeclID, llvm::endianness::native,
llvm::support::unaligned>;

/// The number of slots needed to record a DeclID in bitstreams.
const unsigned int DeclIDSerialiazedSize = 2;

/// The number of predefined preprocessed entity IDs.
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;

Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ class ASTReader

/// An array of lexical contents of a declaration context, as a sequence of
/// Decl::Kind, DeclID pairs.
using LexicalContents = ArrayRef<serialization::unaligned_decl_id_t>;
using LexicalContents = ArrayRef<uint32_t>;

/// Map from a DeclContext to its lexical contents.
llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
Expand Down Expand Up @@ -945,8 +945,7 @@ class ASTReader
SmallVector<uint64_t, 8> DelayedDeleteExprs;

// A list of late parsed template function data with their module files.
SmallVector<std::pair<ModuleFile *, SmallVector<uint64_t, 1>>, 4>
LateParsedTemplates;
SmallVector<std::pair<ModuleFile *, RecordData>, 4> LateParsedTemplates;

/// The IDs of all decls to be checked for deferred diags.
///
Expand Down
19 changes: 19 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class ASTRecordReader
/// Skips the specified number of values.
void skipInts(unsigned N) { Idx += N; }

/// Skips the specified number of DeclIDs.
void skipDeclRefs(unsigned N) {
Idx += N * serialization::DeclIDSerialiazedSize;
}

/// Retrieve the global submodule ID its local ID number.
serialization::SubmoduleID
getGlobalSubmoduleID(unsigned LocalID) {
Expand Down Expand Up @@ -187,12 +192,26 @@ class ASTRecordReader
/// Reads a declaration from the given position in a record in the
/// given module, advancing Idx.
Decl *readDecl() {
#ifndef NDEBUG
unsigned OldIdx = Idx;
Decl *D = Reader->ReadDecl(*F, Record, Idx);
assert(Idx - OldIdx == serialization::DeclIDSerialiazedSize);
return D;
#endif
return Reader->ReadDecl(*F, Record, Idx);
}
Decl *readDeclRef() {
return readDecl();
}

template <class DeclKind, class Func> void readDeclArray(Func &&ConsumeFunc) {
unsigned LengthOfArray = readInt();
unsigned End = Idx + LengthOfArray;

while (Idx < End)
ConsumeFunc(readDeclAs<DeclKind>());
}

/// Reads a declaration from the given position in the record,
/// advancing Idx.
///
Expand Down
27 changes: 27 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,39 @@ class ASTRecordWriter

/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
#ifndef NDEBUG
unsigned OldSize = size();
Writer->AddDeclRef(D, *Record);
assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
return;
#endif
return Writer->AddDeclRef(D, *Record);
}
void writeDeclRef(const Decl *D) {
AddDeclRef(D);
}

void writeNullDeclRef() {
#ifndef NDEBUG
unsigned OldSize = size();
#endif

push_back(0);
push_back(0);

#ifndef NDEBUG
assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
#endif
}

template <class DeclKind> void writeDeclArray(ArrayRef<DeclKind *> Array) {
unsigned ElementNum = Array.size();
push_back(ElementNum * serialization::DeclIDSerialiazedSize);

for (DeclKind *D : Array)
AddDeclRef(D);
}

/// Emit a declaration name.
void AddDeclarationName(DeclarationName Name) {
writeDeclarationName(Name);
Expand Down
44 changes: 23 additions & 21 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1306,9 +1306,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
auto &Lex = LexicalDecls[DC];
if (!Lex.first) {
Lex = std::make_pair(
&M, llvm::ArrayRef(
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
Blob.size() / sizeof(DeclID)));
&M, llvm::ArrayRef(reinterpret_cast<const uint32_t *>(Blob.data()),
Blob.size() / sizeof(uint32_t)));
}
DC->setHasExternalLexicalStorage(true);
return false;
Expand Down Expand Up @@ -3422,8 +3421,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
case TU_UPDATE_LEXICAL: {
DeclContext *TU = ContextObj->getTranslationUnitDecl();
LexicalContents Contents(
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
static_cast<unsigned int>(Blob.size() / sizeof(DeclID)));
reinterpret_cast<const uint32_t *>(Blob.data()),
static_cast<unsigned int>(Blob.size() / sizeof(uint32_t)));
TULexicalDecls.push_back(std::make_pair(&F, Contents));
TU->setHasExternalLexicalStorage(true);
break;
Expand Down Expand Up @@ -3696,7 +3695,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case VTABLE_USES:
if (Record.size() % 3 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1 + 1) != 0)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"Invalid VTABLE_USES record");

Expand All @@ -3714,8 +3713,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case PENDING_IMPLICIT_INSTANTIATIONS:

if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
Expand All @@ -3728,7 +3726,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case SEMA_DECL_REFS:
if (Record.size() != 3)
if (Record.size() != 3 * serialization::DeclIDSerialiazedSize)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"Invalid SEMA_DECL_REFS block");
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
Expand Down Expand Up @@ -3786,7 +3784,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
}

case DECL_UPDATE_OFFSETS:
if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"invalid DECL_UPDATE_OFFSETS block in AST file");
Expand All @@ -3803,7 +3801,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
if (Record.size() % 3 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 2) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
Expand Down Expand Up @@ -3898,7 +3896,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case UNDEFINED_BUT_USED:
if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"invalid undefined-but-used record");
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
Expand Down Expand Up @@ -7893,7 +7891,10 @@ GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
return GlobalDeclID(0);
}

return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++]));
uint32_t ModuleFileIndex = Record[Idx++];
uint32_t LocalDeclIndex = Record[Idx++];
return getGlobalDeclID(
F, LocalDeclID::get(*this, F, ModuleFileIndex, LocalDeclIndex));
}

/// Resolve the offset of a statement into a statement.
Expand Down Expand Up @@ -7922,25 +7923,26 @@ void ASTReader::FindExternalLexicalDecls(
SmallVectorImpl<Decl *> &Decls) {
bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};

auto Visit = [&] (ModuleFile *M, LexicalContents LexicalDecls) {
assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
auto Visit = [&](ModuleFile *M, LexicalContents LexicalDecls) {
assert(LexicalDecls.size() % 3 == 0 && "incorrect number of entries");
for (int I = 0, N = LexicalDecls.size(); I != N; I += 3) {
auto K = (Decl::Kind)+LexicalDecls[I];
if (!IsKindWeWant(K))
continue;

auto ID = (DeclID) + LexicalDecls[I + 1];
LocalDeclID ID =
LocalDeclID::get(*this, *M, LexicalDecls[I + 1], LexicalDecls[I + 2]);

// Don't add predefined declarations to the lexical context more
// than once.
if (ID < NUM_PREDEF_DECL_IDS) {
if (PredefsVisited[ID])
if (PredefsVisited[ID.getRawValue()])
continue;

PredefsVisited[ID] = true;
PredefsVisited[ID.getRawValue()] = true;
}

if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) {
if (Decl *D = GetLocalDecl(*M, ID)) {
assert(D->getKind() == K && "wrong kind for lexical decl");
if (!DC->isDeclInLexicalTraversal(D))
Decls.push_back(D);
Expand Down Expand Up @@ -8837,7 +8839,7 @@ void ASTReader::ReadLateParsedTemplates(
&LPTMap) {
for (auto &LPT : LateParsedTemplates) {
ModuleFile *FMod = LPT.first;
RecordDataImpl &LateParsed = LPT.second;
RecordData &LateParsed = LPT.second;
for (unsigned Idx = 0, N = LateParsed.size(); Idx < N;
/* In loop */) {
FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx);
Expand Down
18 changes: 8 additions & 10 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,9 +1020,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
// Templates.
UnresolvedSet<8> Candidates;
unsigned NumCandidates = Record.readInt();
while (NumCandidates--)
Candidates.addDecl(readDeclAs<NamedDecl>());
Record.readDeclArray<NamedDecl>(
[&Candidates](NamedDecl *ND) { Candidates.addDecl(ND); });

// Templates args.
TemplateArgumentListInfo TemplArgsWritten;
Expand Down Expand Up @@ -1152,11 +1151,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setIsPureVirtual(Pure);

// Read in the parameters.
unsigned NumParams = Record.readInt();
SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(readDeclAs<ParmVarDecl>());
Record.readDeclArray<ParmVarDecl>(
[&Params](ParmVarDecl *ParmD) { Params.push_back(ParmD); });
FD->setParams(Reader.getContext(), Params);
}

Expand Down Expand Up @@ -2309,7 +2306,7 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
} else {
// We don't care about which declarations this used to override; we get
// the relevant information from the canonical declaration.
Record.skipInts(NumOverridenMethods);
Record.skipDeclRefs(NumOverridenMethods);
}
}

Expand Down Expand Up @@ -4354,8 +4351,9 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
// FIXME: We have several different dispatches on decl kind here; maybe
// we should instead generate one loop per kind and dispatch up-front?
Decl *MostRecent = FirstLocal;
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
unsigned Idx = N - I - 1;
for (unsigned I = 0, N = Record.size(); I != N;
I += serialization::DeclIDSerialiazedSize) {
unsigned Idx = N - I - serialization::DeclIDSerialiazedSize;
auto *D = ReadDecl(*M, Record, Idx);
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
MostRecent = D;
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,15 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
S->setStartLoc(readSourceLocation());
S->setEndLoc(readSourceLocation());

if (Record.size() - Record.getIdx() == 1) {
unsigned NumDecls =
(Record.size() - Record.getIdx()) / serialization::DeclIDSerialiazedSize;
if (NumDecls == 1) {
// Single declaration
S->setDeclGroup(DeclGroupRef(readDecl()));
} else {
SmallVector<Decl *, 16> Decls;
int N = Record.size() - Record.getIdx();
Decls.reserve(N);
for (int I = 0; I < N; ++I)
Decls.reserve(NumDecls);
for (unsigned I = 0; I < NumDecls; ++I)
Decls.push_back(readDecl());
S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Record.getContext(),
Decls.data(),
Expand Down
28 changes: 19 additions & 9 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3321,7 +3321,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
return 0;

uint64_t Offset = Stream.GetCurrentBitNo();
SmallVector<DeclID, 128> KindDeclPairs;
SmallVector<uint32_t, 128> KindDeclPairs;
for (const auto *D : DC->decls()) {
if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
continue;
Expand All @@ -3336,7 +3336,9 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
continue;

KindDeclPairs.push_back(D->getKind());
KindDeclPairs.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);
KindDeclPairs.push_back(ID.getModuleFileIndex());
KindDeclPairs.push_back(ID.getLocalDeclIndex());
}

++NumLexicalDeclContexts;
Expand Down Expand Up @@ -4451,8 +4453,9 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC)));

// Write the lookup table
RecordData::value_type Record[] = {UPDATE_VISIBLE,
getDeclID(cast<Decl>(DC)).getRawValue()};
LocalDeclID ID = getDeclID(cast<Decl>(DC));
RecordData::value_type Record[] = {UPDATE_VISIBLE, ID.getModuleFileIndex(),
ID.getLocalDeclIndex()};
Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
}

Expand Down Expand Up @@ -5243,9 +5246,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
RecordData SemaDeclRefs;
if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
auto AddEmittedDeclRefOrZero = [this, &SemaDeclRefs](Decl *D) {
if (!D || !wasDeclEmitted(D))
if (!D || !wasDeclEmitted(D)) {
SemaDeclRefs.push_back(0);
else
SemaDeclRefs.push_back(0);
} else
AddDeclRef(D, SemaDeclRefs);
};

Expand Down Expand Up @@ -5679,7 +5683,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
// Create a lexical update block containing all of the declarations in the
// translation unit that do not come from other AST files.
SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
for (const auto *D : TU->noload_decls()) {
if (D->isFromASTFile())
continue;
Expand All @@ -5689,7 +5693,9 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
continue;

NewGlobalKindDeclPairs.push_back(D->getKind());
NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);
NewGlobalKindDeclPairs.push_back(ID.getModuleFileIndex());
NewGlobalKindDeclPairs.push_back(ID.getLocalDeclIndex());
}

auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
Expand All @@ -5704,6 +5710,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
Abv = std::make_shared<llvm::BitCodeAbbrev>();
Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));

Expand Down Expand Up @@ -6195,7 +6202,10 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
}

void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
Record.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);

Record.push_back(ID.getModuleFileIndex());
Record.push_back(ID.getLocalDeclIndex());
}

LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
Expand Down
Loading

0 comments on commit 0e6b0ee

Please sign in to comment.