forked from OSchip/llvm-project
[modules] D29951: Load lazily the template specialization in multi-module setups.
Currently, we load all template specialization if we have more than one module attached and we touch anything around the template definition. This patch registers the template specializations as lazily-loadable entities. In some TUs it reduces the amount of deserializations by 1%. llvm-svn: 305120
This commit is contained in:
parent
416e0592d5
commit
497a99523a
|
@ -216,6 +216,30 @@ namespace clang {
|
||||||
TypedefNameForLinkage(nullptr), HasPendingBody(false),
|
TypedefNameForLinkage(nullptr), HasPendingBody(false),
|
||||||
IsDeclMarkedUsed(false) {}
|
IsDeclMarkedUsed(false) {}
|
||||||
|
|
||||||
|
template <typename T> static
|
||||||
|
void AddLazySpecializations(T *D,
|
||||||
|
SmallVectorImpl<serialization::DeclID>& IDs) {
|
||||||
|
if (IDs.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME: We should avoid this pattern of getting the ASTContext.
|
||||||
|
ASTContext &C = D->getASTContext();
|
||||||
|
|
||||||
|
auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
|
||||||
|
|
||||||
|
if (auto &Old = LazySpecializations) {
|
||||||
|
IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
|
||||||
|
std::sort(IDs.begin(), IDs.end());
|
||||||
|
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
|
||||||
|
*Result = IDs.size();
|
||||||
|
std::copy(IDs.begin(), IDs.end(), Result + 1);
|
||||||
|
|
||||||
|
LazySpecializations = Result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename DeclT>
|
template <typename DeclT>
|
||||||
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
|
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
|
||||||
static Decl *getMostRecentDeclImpl(...);
|
static Decl *getMostRecentDeclImpl(...);
|
||||||
|
@ -244,7 +268,7 @@ namespace clang {
|
||||||
void ReadFunctionDefinition(FunctionDecl *FD);
|
void ReadFunctionDefinition(FunctionDecl *FD);
|
||||||
void Visit(Decl *D);
|
void Visit(Decl *D);
|
||||||
|
|
||||||
void UpdateDecl(Decl *D);
|
void UpdateDecl(Decl *D, llvm::SmallVectorImpl<serialization::DeclID>&);
|
||||||
|
|
||||||
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
||||||
ObjCCategoryDecl *Next) {
|
ObjCCategoryDecl *Next) {
|
||||||
|
@ -1952,21 +1976,6 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
||||||
return Redecl;
|
return Redecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old,
|
|
||||||
SmallVectorImpl<DeclID> &IDs) {
|
|
||||||
assert(!IDs.empty() && "no IDs to add to list");
|
|
||||||
if (Old) {
|
|
||||||
IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
|
|
||||||
std::sort(IDs.begin(), IDs.end());
|
|
||||||
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *Result = new (Context) DeclID[1 + IDs.size()];
|
|
||||||
*Result = IDs.size();
|
|
||||||
std::copy(IDs.begin(), IDs.end(), Result + 1);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||||
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
||||||
|
|
||||||
|
@ -1975,12 +1984,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||||
// the specializations.
|
// the specializations.
|
||||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||||
ReadDeclIDList(SpecIDs);
|
ReadDeclIDList(SpecIDs);
|
||||||
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||||
if (!SpecIDs.empty()) {
|
|
||||||
auto *CommonPtr = D->getCommonPtr();
|
|
||||||
CommonPtr->LazySpecializations = newDeclIDList(
|
|
||||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
|
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
|
||||||
|
@ -2007,12 +2011,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
||||||
// the specializations.
|
// the specializations.
|
||||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||||
ReadDeclIDList(SpecIDs);
|
ReadDeclIDList(SpecIDs);
|
||||||
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||||
if (!SpecIDs.empty()) {
|
|
||||||
auto *CommonPtr = D->getCommonPtr();
|
|
||||||
CommonPtr->LazySpecializations = newDeclIDList(
|
|
||||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2118,12 +2117,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
||||||
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
||||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||||
ReadDeclIDList(SpecIDs);
|
ReadDeclIDList(SpecIDs);
|
||||||
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||||
if (!SpecIDs.empty()) {
|
|
||||||
auto *CommonPtr = D->getCommonPtr();
|
|
||||||
CommonPtr->LazySpecializations = newDeclIDList(
|
|
||||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3667,6 +3661,9 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
||||||
Decl *D = Record.D;
|
Decl *D = Record.D;
|
||||||
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
|
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
|
||||||
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
||||||
|
|
||||||
|
llvm::SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
|
||||||
|
|
||||||
if (UpdI != DeclUpdateOffsets.end()) {
|
if (UpdI != DeclUpdateOffsets.end()) {
|
||||||
auto UpdateOffsets = std::move(UpdI->second);
|
auto UpdateOffsets = std::move(UpdI->second);
|
||||||
DeclUpdateOffsets.erase(UpdI);
|
DeclUpdateOffsets.erase(UpdI);
|
||||||
|
@ -3691,7 +3688,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
||||||
|
|
||||||
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
|
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
Reader.UpdateDecl(D);
|
Reader.UpdateDecl(D, PendingLazySpecializationIDs);
|
||||||
|
|
||||||
// We might have made this declaration interesting. If so, remember that
|
// We might have made this declaration interesting. If so, remember that
|
||||||
// we need to hand it off to the consumer.
|
// we need to hand it off to the consumer.
|
||||||
|
@ -3703,6 +3700,17 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add the lazy specializations to the template.
|
||||||
|
assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
|
||||||
|
isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
|
||||||
|
"Must not have pending specializations");
|
||||||
|
if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
|
||||||
|
ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
|
||||||
|
else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
|
||||||
|
ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs);
|
||||||
|
else if (auto *VTD = dyn_cast<VarTemplateDecl>(D))
|
||||||
|
ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs);
|
||||||
|
PendingLazySpecializationIDs.clear();
|
||||||
|
|
||||||
// Load the pending visible updates for this decl context, if it has any.
|
// Load the pending visible updates for this decl context, if it has any.
|
||||||
auto I = PendingVisibleUpdates.find(ID);
|
auto I = PendingVisibleUpdates.find(ID);
|
||||||
|
@ -3899,7 +3907,8 @@ static void forAllLaterRedecls(DeclT *D, Fn F) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTDeclReader::UpdateDecl(Decl *D) {
|
void ASTDeclReader::UpdateDecl(Decl *D,
|
||||||
|
llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
|
||||||
while (Record.getIdx() < Record.size()) {
|
while (Record.getIdx() < Record.size()) {
|
||||||
switch ((DeclUpdateKind)Record.readInt()) {
|
switch ((DeclUpdateKind)Record.readInt()) {
|
||||||
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
||||||
|
@ -3915,8 +3924,8 @@ void ASTDeclReader::UpdateDecl(Decl *D) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
||||||
// It will be added to the template's specializations set when loaded.
|
// It will be added to the template's lazy specialization set.
|
||||||
(void)Record.readDecl();
|
PendingLazySpecializationIDs.push_back(ReadDeclID());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
||||||
|
|
Loading…
Reference in New Issue