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),
|
||||
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>
|
||||
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
|
||||
static Decl *getMostRecentDeclImpl(...);
|
||||
|
@ -244,7 +268,7 @@ namespace clang {
|
|||
void ReadFunctionDefinition(FunctionDecl *FD);
|
||||
void Visit(Decl *D);
|
||||
|
||||
void UpdateDecl(Decl *D);
|
||||
void UpdateDecl(Decl *D, llvm::SmallVectorImpl<serialization::DeclID>&);
|
||||
|
||||
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
||||
ObjCCategoryDecl *Next) {
|
||||
|
@ -1952,21 +1976,6 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
|||
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) {
|
||||
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
||||
|
||||
|
@ -1975,12 +1984,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
|||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
|
||||
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
|
||||
|
@ -2007,12 +2011,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2118,12 +2117,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3667,6 +3661,9 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
|||
Decl *D = Record.D;
|
||||
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
|
||||
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
||||
|
||||
llvm::SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
|
||||
|
||||
if (UpdI != DeclUpdateOffsets.end()) {
|
||||
auto UpdateOffsets = std::move(UpdI->second);
|
||||
DeclUpdateOffsets.erase(UpdI);
|
||||
|
@ -3691,7 +3688,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
|||
|
||||
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
|
||||
SourceLocation());
|
||||
Reader.UpdateDecl(D);
|
||||
Reader.UpdateDecl(D, PendingLazySpecializationIDs);
|
||||
|
||||
// We might have made this declaration interesting. If so, remember that
|
||||
// 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.
|
||||
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()) {
|
||||
switch ((DeclUpdateKind)Record.readInt()) {
|
||||
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
||||
|
@ -3915,8 +3924,8 @@ void ASTDeclReader::UpdateDecl(Decl *D) {
|
|||
}
|
||||
|
||||
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
||||
// It will be added to the template's specializations set when loaded.
|
||||
(void)Record.readDecl();
|
||||
// It will be added to the template's lazy specialization set.
|
||||
PendingLazySpecializationIDs.push_back(ReadDeclID());
|
||||
break;
|
||||
|
||||
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
||||
|
|
Loading…
Reference in New Issue