Author: Haojian Wu Date: 2020-09-21T13:08:53+02:00 New Revision: af29591650c43bd3bdc380c9d47b8bfd0f1664a2
URL: https://github.com/llvm/llvm-project/commit/af29591650c43bd3bdc380c9d47b8bfd0f1664a2 DIFF: https://github.com/llvm/llvm-project/commit/af29591650c43bd3bdc380c9d47b8bfd0f1664a2.diff LOG: [AST] Reduce the size of TemplateArgumentLocInfo. allocate the underlying data of Template kind separately, this would reduce AST memory usage - TemplateArgumentLocInfo 24 => 8 bytes - TemplateArgumentLoc 48 => 32 bytes - DynTypeNode 56 => 40 bytes ASTContext::.getASTAllocatedMemory changes: SemaDecl.cpp 255.5 MB => 247.5MB SemaExpr.cpp 293.5 MB => 283.5MB Differential Revision: https://reviews.llvm.org/D87080 Added: Modified: clang/include/clang/AST/Expr.h clang/include/clang/AST/TemplateBase.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/TemplateBase.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Sema/SemaTemplateVariadic.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 1672fd707c6d..1ea454514b2f 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -960,6 +960,11 @@ class Expr : public ValueStmt { T->getStmtClass() <= lastExprConstant; } }; +// PointerLikeTypeTraits is specialized so it can be used with a forward-decl of +// Expr. Verify that we got it right. +static_assert(llvm::PointerLikeTypeTraits<Expr *>::NumLowBitsAvailable <= + llvm::detail::ConstantLog2<alignof(Expr)>::value, + "PointerLikeTypeTraits<Expr*> assumes too much alignment."); //===----------------------------------------------------------------------===// // Wrapper Expressions. diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 51fd8ba51034..b7af5c7d7bd9 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -36,6 +36,17 @@ namespace llvm { class FoldingSetNodeID; +// Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a +// full definition of Expr, but this file only sees a forward del because of +// the dependency. +template <> struct PointerLikeTypeTraits<clang::Expr *> { + static inline void *getAsVoidPointer(clang::Expr *P) { return P; } + static inline clang::Expr *getFromVoidPointer(void *P) { + return static_cast<clang::Expr *>(P); + } + static constexpr int NumLowBitsAvailable = 2; +}; + } // namespace llvm namespace clang { @@ -393,7 +404,7 @@ class TemplateArgument { /// Location information for a TemplateArgument. struct TemplateArgumentLocInfo { private: - struct T { + struct TemplateTemplateArgLocInfo { // FIXME: We'd like to just use the qualifier in the TemplateName, // but template arguments get canonicalized too quickly. NestedNameSpecifier *Qualifier; @@ -402,47 +413,42 @@ struct TemplateArgumentLocInfo { unsigned EllipsisLoc; }; - union { - struct T Template; - Expr *Expression; - TypeSourceInfo *Declarator; - }; - -public: - constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {} + llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *> + Pointer; - TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} + TemplateTemplateArgLocInfo *getTemplate() const { + return Pointer.get<TemplateTemplateArgLocInfo *>(); + } - TemplateArgumentLocInfo(Expr *E) : Expression(E) {} +public: + constexpr TemplateArgumentLocInfo() {} + TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; } - TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, + TemplateArgumentLocInfo(Expr *E) { Pointer = E; } + // Ctx is used for allocation -- this case is unusually large and also rare, + // so we store the payload out-of-line. + TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc, - SourceLocation EllipsisLoc) { - Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); - Template.QualifierLocData = QualifierLoc.getOpaqueData(); - Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); - Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); - } + SourceLocation EllipsisLoc); TypeSourceInfo *getAsTypeSourceInfo() const { - return Declarator; + return Pointer.get<TypeSourceInfo *>(); } - Expr *getAsExpr() const { - return Expression; - } + Expr *getAsExpr() const { return Pointer.get<Expr *>(); } NestedNameSpecifierLoc getTemplateQualifierLoc() const { - return NestedNameSpecifierLoc(Template.Qualifier, - Template.QualifierLocData); + const auto *Template = getTemplate(); + return NestedNameSpecifierLoc(Template->Qualifier, + Template->QualifierLocData); } SourceLocation getTemplateNameLoc() const { - return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); + return SourceLocation::getFromRawEncoding(getTemplate()->TemplateNameLoc); } SourceLocation getTemplateEllipsisLoc() const { - return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); + return SourceLocation::getFromRawEncoding(getTemplate()->EllipsisLoc); } }; @@ -475,12 +481,12 @@ class TemplateArgumentLoc { Argument.getKind() == TemplateArgument::Expression); } - TemplateArgumentLoc(const TemplateArgument &Argument, + TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc = SourceLocation()) : Argument(Argument), - LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { + LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) { assert(Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index dd3c8518c2a3..11bf629ecdde 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -882,11 +882,9 @@ ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) { import(FromInfo.getTemplateEllipsisLoc()); if (!ToTemplateEllipsisLocOrErr) return ToTemplateEllipsisLocOrErr.takeError(); - ToInfo = TemplateArgumentLocInfo( - *ToTemplateQualifierLocOrErr, - *ToTemplateNameLocOrErr, - *ToTemplateEllipsisLocOrErr); + Importer.getToContext(), *ToTemplateQualifierLocOrErr, + *ToTemplateNameLocOrErr, *ToTemplateEllipsisLocOrErr); } return TemplateArgumentLoc(Arg, ToInfo); diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 6a3d2b30e46e..a9113720fd45 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -502,6 +502,17 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, llvm_unreachable("Invalid TemplateArgument Kind!"); } +clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo( + ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) { + TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo; + Template->Qualifier = QualifierLoc.getNestedNameSpecifier(); + Template->QualifierLocData = QualifierLoc.getOpaqueData(); + Template->TemplateNameLoc = TemplateNameLoc.getRawEncoding(); + Template->EllipsisLoc = EllipsisLoc.getRawEncoding(); + Pointer = Template; +} + const ASTTemplateArgumentListInfo * ASTTemplateArgumentListInfo::Create(const ASTContext &C, const TemplateArgumentListInfo &List) { diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 57c11ca5571d..09c8f4be9f73 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -582,7 +582,7 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); ArgInfos[i] = TemplateArgumentLocInfo( - Builder.getWithLocInContext(Context), Loc, + Context, Builder.getWithLocInContext(Context), Loc, Args[i].getKind() == TemplateArgument::Template ? SourceLocation() : Loc); break; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index b126fd9c8006..8baf5b96fbf8 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -938,11 +938,10 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, TArg = TemplateArgument(Template, Optional<unsigned int>()); else TArg = Template; - return TemplateArgumentLoc(TArg, - Arg.getScopeSpec().getWithLocInContext( - SemaRef.Context), - Arg.getLocation(), - Arg.getEllipsisLoc()); + return TemplateArgumentLoc( + SemaRef.Context, TArg, + Arg.getScopeSpec().getWithLocInContext(SemaRef.Context), + Arg.getLocation(), Arg.getEllipsisLoc()); } } @@ -5271,15 +5270,17 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, if (TName.isNull()) return TemplateArgumentLoc(); - return TemplateArgumentLoc(TemplateArgument(TName), - TempTempParm->getDefaultArgument().getTemplateQualifierLoc(), - TempTempParm->getDefaultArgument().getTemplateNameLoc()); + return TemplateArgumentLoc( + Context, TemplateArgument(TName), + TempTempParm->getDefaultArgument().getTemplateQualifierLoc(), + TempTempParm->getDefaultArgument().getTemplateNameLoc()); } /// Convert a template-argument that we parsed as a type into a template, if /// possible. C++ permits injected-class-names to perform dual service as /// template template arguments and as template type arguments. -static TemplateArgumentLoc convertTypeTemplateArgumentToTemplate(TypeLoc TLoc) { +static TemplateArgumentLoc +convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) { // Extract and step over any surrounding nested-name-specifier. NestedNameSpecifierLoc QualLoc; if (auto ETLoc = TLoc.getAs<ElaboratedTypeLoc>()) { @@ -5289,11 +5290,10 @@ static TemplateArgumentLoc convertTypeTemplateArgumentToTemplate(TypeLoc TLoc) { QualLoc = ETLoc.getQualifierLoc(); TLoc = ETLoc.getNamedTypeLoc(); } - // If this type was written as an injected-class-name, it can be used as a // template template argument. if (auto InjLoc = TLoc.getAs<InjectedClassNameTypeLoc>()) - return TemplateArgumentLoc(InjLoc.getTypePtr()->getTemplateName(), + return TemplateArgumentLoc(Context, InjLoc.getTypePtr()->getTemplateName(), QualLoc, InjLoc.getNameLoc()); // If this type was written as an injected-class-name, it may have been @@ -5303,7 +5303,8 @@ static TemplateArgumentLoc convertTypeTemplateArgumentToTemplate(TypeLoc TLoc) { if (auto RecLoc = TLoc.getAs<RecordTypeLoc>()) if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RecLoc.getDecl())) - return TemplateArgumentLoc(TemplateName(CTSD->getSpecializedTemplate()), + return TemplateArgumentLoc(Context, + TemplateName(CTSD->getSpecializedTemplate()), QualLoc, RecLoc.getNameLoc()); return TemplateArgumentLoc(); @@ -5542,7 +5543,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, // itself. if (Arg.getArgument().getKind() == TemplateArgument::Type) { TemplateArgumentLoc ConvertedArg = convertTypeTemplateArgumentToTemplate( - Arg.getTypeSourceInfo()->getTypeLoc()); + Context, Arg.getTypeSourceInfo()->getTypeLoc()); if (!ConvertedArg.getArgument().isNull()) Arg = ConvertedArg; } @@ -5861,8 +5862,9 @@ bool Sema::CheckTemplateArgumentList( if (Name.isNull()) return true; - Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc, - TempParm->getDefaultArgument().getTemplateNameLoc()); + Arg = TemplateArgumentLoc( + Context, TemplateArgument(Name), QualifierLoc, + TempParm->getDefaultArgument().getTemplateNameLoc()); } // Introduce an instantiation record that describes where we are using diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 7aa94502fa84..b266f360a138 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2670,11 +2670,11 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); if (Arg.getKind() == TemplateArgument::Template) - return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context), - Loc); + return TemplateArgumentLoc(Context, Arg, + Builder.getWithLocInContext(Context), Loc); - return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context), - Loc, Loc); + return TemplateArgumentLoc( + Context, Arg, Builder.getWithLocInContext(Context), Loc, Loc); } case TemplateArgument::Expression: diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 921d94036a2c..cbbb44b82adc 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2915,7 +2915,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( if (!TName.isNull()) Param->setDefaultArgument( SemaRef.Context, - TemplateArgumentLoc(TemplateArgument(TName), + TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName), D->getDefaultArgument().getTemplateQualifierLoc(), D->getDefaultArgument().getTemplateNameLoc())); } diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 623d808b59f6..3c927f6b749f 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1095,7 +1095,7 @@ Sema::getTemplateArgumentPackExpansionPattern( case TemplateArgument::TemplateExpansion: Ellipsis = OrigLoc.getTemplateEllipsisLoc(); NumExpansions = Argument.getNumTemplateExpansions(); - return TemplateArgumentLoc(Argument.getPackExpansionPattern(), + return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), OrigLoc.getTemplateQualifierLoc(), OrigLoc.getTemplateNameLoc()); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6457b192477e..8439e72025b8 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3546,12 +3546,12 @@ class TreeTransform { } case TemplateArgument::Template: - return TemplateArgumentLoc(TemplateArgument( - Pattern.getArgument().getAsTemplate(), - NumExpansions), - Pattern.getTemplateQualifierLoc(), - Pattern.getTemplateNameLoc(), - EllipsisLoc); + return TemplateArgumentLoc( + SemaRef.Context, + TemplateArgument(Pattern.getArgument().getAsTemplate(), + NumExpansions), + Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(), + EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: @@ -4289,8 +4289,8 @@ bool TreeTransform<Derived>::TransformTemplateArgument( if (Template.isNull()) return true; - Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc, - Input.getTemplateNameLoc()); + Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template), + QualifierLoc, Input.getTemplateNameLoc()); return false; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index fddc068162b8..b2780db85166 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7095,15 +7095,15 @@ ASTRecordReader::readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) { NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); - return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - SourceLocation()); + return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, SourceLocation()); } case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); SourceLocation EllipsisLoc = readSourceLocation(); - return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - EllipsisLoc); + return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, EllipsisLoc); } case TemplateArgument::Null: case TemplateArgument::Integral: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits