[clang] af29591 - [AST] Reduce the size of TemplateArgumentLocInfo.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 21 04:09:22 PDT 2020
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:
More information about the cfe-commits
mailing list