Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 6bb02a2

Browse files
committed
[Sema] Implement __make_integer_seq
This new builtin template allows for incredibly fast instantiations of templates like std::integer_sequence. Performance numbers follow: My work station has 64 GB of ram + 20 Xeon Cores at 2.8 GHz. __make_integer_seq<std::integer_sequence, int, 90000> takes 0.25 seconds. std::make_integer_sequence<int, 90000> takes unbound time, it is still running. Clang is consuming gigabytes of memory. Differential Revision: http://reviews.llvm.org/D13786 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@252036 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0c29653 commit 6bb02a2

23 files changed

+308
-4
lines changed

‎include/clang/AST/ASTContext.h‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ namespace clang {
7070
class VTableContextBase;
7171

7272
namespace Builtin { class Context; }
73+
enum BuiltinTemplateKind : int;
7374

7475
namespace comments {
7576
class FullComment;
@@ -246,6 +247,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
246247
/// The identifier 'NSCopying'.
247248
IdentifierInfo *NSCopyingName = nullptr;
248249

250+
/// The identifier '__make_integer_seq'.
251+
mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
252+
249253
QualType ObjCConstantStringType;
250254
mutable RecordDecl *CFConstantStringTypeDecl;
251255

@@ -399,6 +403,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
399403

400404
TranslationUnitDecl *TUDecl;
401405
mutable ExternCContextDecl *ExternCContext;
406+
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
402407

403408
/// \brief The associated SourceManager object.a
404409
SourceManager &SourceMgr;
@@ -868,6 +873,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
868873
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
869874

870875
ExternCContextDecl *getExternCContextDecl() const;
876+
BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
871877

872878
// Builtin Types.
873879
CanQualType VoidTy;
@@ -941,6 +947,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
941947
void PrintStats() const;
942948
const SmallVectorImpl<Type *>& getTypes() const { return Types; }
943949

950+
BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
951+
const IdentifierInfo *II) const;
952+
944953
/// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
945954
/// declaration.
946955
RecordDecl *buildImplicitRecord(StringRef Name,
@@ -1444,6 +1453,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
14441453
return NSCopyingName;
14451454
}
14461455

1456+
IdentifierInfo *getMakeIntegerSeqName() const {
1457+
if (!MakeIntegerSeqName)
1458+
MakeIntegerSeqName = &Idents.get("__make_integer_seq");
1459+
return MakeIntegerSeqName;
1460+
}
1461+
14471462
/// \brief Retrieve the Objective-C "instancetype" type, if already known;
14481463
/// otherwise, returns a NULL type;
14491464
QualType getObjCInstanceType() {

‎include/clang/AST/DataRecursiveASTVisitor.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,10 @@ DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
15511551
TRY_TO(TraverseFunctionInstantiations(D));
15521552
})
15531553

1554+
DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1555+
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1556+
})
1557+
15541558
DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
15551559
// D is the "T" in something like
15561560
// template <template <typename> class T> class container { };

‎include/clang/AST/DeclTemplate.h‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
namespace clang {
2727

28+
enum BuiltinTemplateKind : int;
2829
class TemplateParameterList;
2930
class TemplateDecl;
3031
class RedeclarableTemplateDecl;
@@ -1490,6 +1491,35 @@ class TemplateTemplateParmDecl final
14901491
friend TrailingObjects;
14911492
};
14921493

1494+
/// \brief Represents the builtin template declaration which is used to
1495+
/// implement __make_integer_seq. It serves no real purpose beyond existing as
1496+
/// a place to hold template parameters.
1497+
class BuiltinTemplateDecl : public TemplateDecl {
1498+
void anchor() override;
1499+
1500+
BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1501+
DeclarationName Name, BuiltinTemplateKind BTK);
1502+
1503+
BuiltinTemplateKind BTK;
1504+
1505+
public:
1506+
// Implement isa/cast/dyncast support
1507+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1508+
static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1509+
1510+
static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1511+
DeclarationName Name,
1512+
BuiltinTemplateKind BTK) {
1513+
return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1514+
}
1515+
1516+
SourceRange getSourceRange() const override LLVM_READONLY {
1517+
return SourceRange();
1518+
}
1519+
1520+
BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
1521+
};
1522+
14931523
/// \brief Represents a class template specialization, which refers to
14941524
/// a class template with a given set of template arguments.
14951525
///

‎include/clang/AST/RecursiveASTVisitor.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,10 @@ DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
16031603
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
16041604
})
16051605

1606+
DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1607+
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1608+
})
1609+
16061610
DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
16071611
// D is the "T" in something like "template<typename T> class vector;"
16081612
if (D->getTypeForDecl())

‎include/clang/Basic/Builtins.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,12 @@ class Context {
205205
};
206206

207207
}
208+
209+
/// \brief Kinds of BuiltinTemplateDecl.
210+
enum BuiltinTemplateKind : int {
211+
/// \brief This names the __make_integer_seq BuiltinTemplateDecl.
212+
BTK__make_integer_seq
213+
};
214+
208215
} // end namespace clang
209216
#endif

‎include/clang/Basic/DeclNodes.td‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def Named : Decl<1>;
5959
def VarTemplate : DDecl<RedeclarableTemplate>;
6060
def TypeAliasTemplate : DDecl<RedeclarableTemplate>;
6161
def TemplateTemplateParm : DDecl<Template>;
62+
def BuiltinTemplate : DDecl<Template>;
6263
def Using : DDecl<Named>;
6364
def UsingShadow : DDecl<Named>;
6465
def ObjCMethod : DDecl<Named>, DeclContext;

‎include/clang/Basic/DiagnosticSemaKinds.td‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,13 @@ def err_concept_decl_invalid_specifiers : Error<
19951995
def warn_cxx98_compat_unicode_type : Warning<
19961996
"'%0' type specifier is incompatible with C++98">,
19971997
InGroup<CXX98Compat>, DefaultIgnore;
1998-
1998+
1999+
// __make_integer_seq
2000+
def err_integer_sequence_negative_length : Error<
2001+
"integer sequences must have non-negative sequence length">;
2002+
def err_integer_sequence_integral_element_type : Error<
2003+
"integer sequences must have integral element type">;
2004+
19992005
// Objective-C++
20002006
def err_objc_decls_may_only_appear_in_global_scope : Error<
20012007
"Objective-C declarations may only appear in global scope">;

‎include/clang/Serialization/ASTBitCodes.h‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,13 +982,16 @@ namespace clang {
982982

983983
/// \brief The extern "C" context.
984984
PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12,
985+
986+
/// \brief The internal '__make_integer_seq' template.
987+
PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
985988
};
986989

987990
/// \brief The number of declaration IDs that are predefined.
988991
///
989992
/// For more information about predefined declarations, see the
990993
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
991-
const unsigned int NUM_PREDEF_DECL_IDS = 13;
994+
const unsigned int NUM_PREDEF_DECL_IDS = 14;
992995

993996
/// \brief Record code for a list of local redeclarations of a declaration.
994997
const unsigned int LOCAL_REDECLARATIONS = 50;

‎lib/AST/ASTContext.cpp‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
744744
ucontext_tDecl(nullptr), BlockDescriptorType(nullptr),
745745
BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
746746
FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr),
747-
SourceMgr(SM), LangOpts(LOpts),
747+
MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
748748
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
749749
AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
750750
PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
@@ -913,6 +913,24 @@ ExternCContextDecl *ASTContext::getExternCContextDecl() const {
913913
return ExternCContext;
914914
}
915915

916+
BuiltinTemplateDecl *
917+
ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
918+
const IdentifierInfo *II) const {
919+
auto *BuiltinTemplate = BuiltinTemplateDecl::Create(*this, TUDecl, II, BTK);
920+
BuiltinTemplate->setImplicit();
921+
TUDecl->addDecl(BuiltinTemplate);
922+
923+
return BuiltinTemplate;
924+
}
925+
926+
BuiltinTemplateDecl *
927+
ASTContext::getMakeIntegerSeqDecl() const {
928+
if (!MakeIntegerSeqDecl)
929+
MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,
930+
getMakeIntegerSeqName());
931+
return MakeIntegerSeqDecl;
932+
}
933+
916934
RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
917935
RecordDecl::TagKind TK) const {
918936
SourceLocation Loc;

‎lib/AST/ASTDumper.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/AST/DeclVisitor.h"
2222
#include "clang/AST/StmtVisitor.h"
2323
#include "clang/AST/TypeVisitor.h"
24+
#include "clang/Basic/Builtins.h"
2425
#include "clang/Basic/Module.h"
2526
#include "clang/Basic/SourceManager.h"
2627
#include "llvm/Support/raw_ostream.h"
@@ -447,6 +448,7 @@ namespace {
447448
const ClassTemplatePartialSpecializationDecl *D);
448449
void VisitClassScopeFunctionSpecializationDecl(
449450
const ClassScopeFunctionSpecializationDecl *D);
451+
void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
450452
void VisitVarTemplateDecl(const VarTemplateDecl *D);
451453
void VisitVarTemplateSpecializationDecl(
452454
const VarTemplateSpecializationDecl *D);
@@ -1333,6 +1335,11 @@ void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
13331335
VisitTemplateDecl(D, false);
13341336
}
13351337

1338+
void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
1339+
dumpName(D);
1340+
dumpTemplateParameters(D->getTemplateParameters());
1341+
}
1342+
13361343
void ASTDumper::VisitVarTemplateSpecializationDecl(
13371344
const VarTemplateSpecializationDecl *D) {
13381345
dumpTemplateArgumentList(D->getTemplateArgs());

0 commit comments

Comments
 (0)