Skip to content

Commit c8ac000

Browse files
committed
Record specialized signature in (SIL)SpecializeAttr.
Rather than storing the set of input requirements in a (SIL)SpecializeAttr, store the specialized generic signature. This prevents clients from having to rebuild the same specialized generic signature on every use.
1 parent 8ad76a1 commit c8ac000

File tree

17 files changed

+94
-224
lines changed

17 files changed

+94
-224
lines changed

include/swift/AST/Attr.h

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,9 @@ class DeclAttribute : public AttributeBase {
258258
ownership : NumReferenceOwnershipBits
259259
);
260260

261-
SWIFT_INLINE_BITFIELD_FULL(SpecializeAttr, DeclAttribute, 1+1+32,
261+
SWIFT_INLINE_BITFIELD(SpecializeAttr, DeclAttribute, 1+1,
262262
exported : 1,
263-
kind : 1,
264-
: NumPadBits,
265-
numRequirements : 32
263+
kind : 1
266264
);
267265

268266
SWIFT_INLINE_BITFIELD(SynthesizedProtocolAttr, DeclAttribute,
@@ -1236,39 +1234,29 @@ class SpecializeAttr : public DeclAttribute {
12361234

12371235
private:
12381236
TrailingWhereClause *trailingWhereClause;
1239-
1240-
Requirement *getRequirementsData() {
1241-
return reinterpret_cast<Requirement *>(this+1);
1242-
}
1237+
GenericSignature *specializedSignature;
12431238

12441239
SpecializeAttr(SourceLoc atLoc, SourceRange Range,
12451240
TrailingWhereClause *clause, bool exported,
1246-
SpecializationKind kind);
1247-
1248-
SpecializeAttr(SourceLoc atLoc, SourceRange Range,
1249-
ArrayRef<Requirement> requirements,
1250-
bool exported,
1251-
SpecializationKind kind);
1241+
SpecializationKind kind,
1242+
GenericSignature *specializedSignature);
12521243

12531244
public:
12541245
static SpecializeAttr *create(ASTContext &Ctx, SourceLoc atLoc,
12551246
SourceRange Range, TrailingWhereClause *clause,
1256-
bool exported, SpecializationKind kind);
1257-
1258-
static SpecializeAttr *create(ASTContext &Ctx, SourceLoc atLoc,
1259-
SourceRange Range,
1260-
ArrayRef<Requirement> requirement,
1261-
bool exported, SpecializationKind kind);
1247+
bool exported, SpecializationKind kind,
1248+
GenericSignature *specializedSignature
1249+
= nullptr);
12621250

12631251
TrailingWhereClause *getTrailingWhereClause() const;
12641252

1265-
ArrayRef<Requirement> getRequirements() const;
1266-
1267-
MutableArrayRef<Requirement> getRequirements() {
1268-
return { getRequirementsData(), Bits.SpecializeAttr.numRequirements };
1253+
GenericSignature *getSpecializedSgnature() const {
1254+
return specializedSignature;
12691255
}
12701256

1271-
void setRequirements(ASTContext &Ctx, ArrayRef<Requirement> requirements);
1257+
void setSpecializedSignature(GenericSignature *newSig) {
1258+
specializedSignature = newSig;
1259+
}
12721260

12731261
bool isExported() const {
12741262
return Bits.SpecializeAttr.exported;

include/swift/SIL/SILFunction.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,9 @@ class SILSpecializeAttr final {
7070
};
7171

7272
static SILSpecializeAttr *create(SILModule &M,
73-
ArrayRef<Requirement> requirements,
73+
GenericSignature *specializedSignature,
7474
bool exported, SpecializationKind kind);
7575

76-
ArrayRef<Requirement> getRequirements() const;
77-
7876
bool isExported() const {
7977
return exported;
8078
}
@@ -91,24 +89,24 @@ class SILSpecializeAttr final {
9189
return kind;
9290
}
9391

92+
GenericSignature *getSpecializedSignature() const {
93+
return specializedSignature;
94+
}
95+
9496
SILFunction *getFunction() const {
9597
return F;
9698
}
9799

98100
void print(llvm::raw_ostream &OS) const;
99101

100102
private:
101-
unsigned numRequirements;
102103
SpecializationKind kind;
103104
bool exported;
104-
SILFunction *F;
105+
GenericSignature *specializedSignature;
106+
SILFunction *F = nullptr;
105107

106-
SILSpecializeAttr(ArrayRef<Requirement> requirements, bool exported,
107-
SpecializationKind kind);
108-
109-
Requirement *getRequirementsData() {
110-
return reinterpret_cast<Requirement *>(this+1);
111-
}
108+
SILSpecializeAttr(bool exported, SpecializationKind kind,
109+
GenericSignature *specializedSignature);
112110
};
113111

114112
/// SILFunction - A function body that has been lowered to SIL. This consists of

include/swift/SILOptimizer/Utils/Generics.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,8 @@ class ReabstractionInfo {
147147
OptRemark::Emitter *ORE = nullptr);
148148

149149
/// Constructs the ReabstractionInfo for generic function \p Callee with
150-
/// additional requirements. Requirements may contain new layout,
151-
/// conformances or same concrete type requirements.
152-
ReabstractionInfo(SILFunction *Callee, ArrayRef<Requirement> Requirements);
150+
/// a specialization signature.
151+
ReabstractionInfo(SILFunction *Callee, GenericSignature *SpecializedSig);
153152

154153
IsSerialized_t isSerialized() const {
155154
return Serialized;

include/swift/Serialization/ModuleFormat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 513; // Added copy_unmanaged_value.
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 514; // specialize attr
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1642,7 +1642,8 @@ namespace decls_block {
16421642
using SpecializeDeclAttrLayout = BCRecordLayout<
16431643
Specialize_DECL_ATTR,
16441644
BCFixed<1>, // exported flag
1645-
BCFixed<1> // specialization kind
1645+
BCFixed<1>, // specialization kind
1646+
GenericSignatureIDField // specialized signature
16461647
>;
16471648

16481649
#define SIMPLE_DECL_ATTR(X, CLASS, ...) \

lib/AST/Attr.cpp

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,11 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
561561

562562
Printer << "exported: "<< exported << ", ";
563563
Printer << "kind: " << kind << ", ";
564+
ArrayRef<Requirement> requirements;
565+
if (auto sig = attr->getSpecializedSgnature())
566+
requirements = sig->getRequirements();
564567

565-
if (!attr->getRequirements().empty()) {
568+
if (!requirements.empty()) {
566569
Printer << "where ";
567570
}
568571
std::function<Type(Type)> GetInterfaceType;
@@ -578,7 +581,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
578581
return GenericEnv->getSugaredType(Ty);
579582
};
580583
}
581-
interleave(attr->getRequirements(),
584+
interleave(requirements,
582585
[&](Requirement req) {
583586
auto FirstTy = GetInterfaceType(req.getFirstType());
584587
if (req.getKind() != RequirementKind::Layout) {
@@ -1089,38 +1092,14 @@ const AvailableAttr *AvailableAttr::isUnavailable(const Decl *D) {
10891092
SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
10901093
TrailingWhereClause *clause,
10911094
bool exported,
1092-
SpecializationKind kind)
1093-
: DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false),
1094-
trailingWhereClause(clause) {
1095+
SpecializationKind kind,
1096+
GenericSignature *specializedSignature)
1097+
: DeclAttribute(DAK_Specialize, atLoc, range,
1098+
/*Implicit=*/clause == nullptr),
1099+
trailingWhereClause(clause),
1100+
specializedSignature(specializedSignature) {
10951101
Bits.SpecializeAttr.exported = exported;
10961102
Bits.SpecializeAttr.kind = unsigned(kind);
1097-
Bits.SpecializeAttr.numRequirements = 0;
1098-
}
1099-
1100-
SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
1101-
ArrayRef<Requirement> requirements,
1102-
bool exported,
1103-
SpecializationKind kind)
1104-
: DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false) {
1105-
Bits.SpecializeAttr.exported = exported;
1106-
Bits.SpecializeAttr.kind = unsigned(kind);
1107-
Bits.SpecializeAttr.numRequirements = requirements.size();
1108-
std::copy(requirements.begin(), requirements.end(), getRequirementsData());
1109-
}
1110-
1111-
void SpecializeAttr::setRequirements(ASTContext &Ctx,
1112-
ArrayRef<Requirement> requirements) {
1113-
unsigned numClauseRequirements =
1114-
(trailingWhereClause) ? trailingWhereClause->getRequirements().size() : 0;
1115-
assert(requirements.size() <= numClauseRequirements);
1116-
if (!numClauseRequirements)
1117-
return;
1118-
Bits.SpecializeAttr.numRequirements = requirements.size();
1119-
std::copy(requirements.begin(), requirements.end(), getRequirementsData());
1120-
}
1121-
1122-
ArrayRef<Requirement> SpecializeAttr::getRequirements() const {
1123-
return const_cast<SpecializeAttr*>(this)->getRequirements();
11241103
}
11251104

11261105
TrailingWhereClause *SpecializeAttr::getTrailingWhereClause() const {
@@ -1131,29 +1110,12 @@ SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc,
11311110
SourceRange range,
11321111
TrailingWhereClause *clause,
11331112
bool exported,
1134-
SpecializationKind kind) {
1135-
unsigned numRequirements = (clause) ? clause->getRequirements().size() : 0;
1136-
unsigned size =
1137-
sizeof(SpecializeAttr) + (numRequirements * sizeof(Requirement));
1138-
void *mem = Ctx.Allocate(size, alignof(SpecializeAttr));
1139-
return new (mem)
1140-
SpecializeAttr(atLoc, range, clause, exported, kind);
1141-
}
1142-
1143-
SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc,
1144-
SourceRange range,
1145-
ArrayRef<Requirement> requirements,
1146-
bool exported,
1147-
SpecializationKind kind) {
1148-
unsigned numRequirements = requirements.size();
1149-
unsigned size =
1150-
sizeof(SpecializeAttr) + (numRequirements * sizeof(Requirement));
1151-
void *mem = Ctx.Allocate(size, alignof(SpecializeAttr));
1152-
return new (mem)
1153-
SpecializeAttr(atLoc, range, requirements, exported, kind);
1113+
SpecializationKind kind,
1114+
GenericSignature *specializedSignature) {
1115+
return new (Ctx) SpecializeAttr(atLoc, range, clause, exported, kind,
1116+
specializedSignature);
11541117
}
11551118

1156-
11571119
ImplementsAttr::ImplementsAttr(SourceLoc atLoc, SourceRange range,
11581120
TypeLoc ProtocolType,
11591121
DeclName MemberName,

lib/ParseSIL/ParseSIL.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/GenericEnvironment.h"
1717
#include "swift/AST/NameLookup.h"
1818
#include "swift/AST/ProtocolConformance.h"
19+
#include "swift/AST/TypeCheckRequests.h"
1920
#include "swift/Basic/Defer.h"
2021
#include "swift/Basic/Timer.h"
2122
#include "swift/Demangling/Demangle.h"
@@ -5460,12 +5461,19 @@ bool SILParserTUState::parseDeclSIL(Parser &P) {
54605461

54615462
if (GenericEnv && !SpecAttrs.empty()) {
54625463
for (auto &Attr : SpecAttrs) {
5463-
SmallVector<Requirement, 4> requirements;
5464+
SmallVector<Requirement, 2> requirements;
54645465
// Resolve types and convert requirements.
54655466
FunctionState.convertRequirements(FunctionState.F,
54665467
Attr.requirements, requirements);
5468+
GenericSignature *genericSig = evaluateOrDefault(
5469+
P.Context.evaluator,
5470+
AbstractGenericSignatureRequest{
5471+
FunctionState.F->getGenericEnvironment()->getGenericSignature(),
5472+
/*addedGenericParams=*/{ },
5473+
std::move(requirements)},
5474+
nullptr);
54675475
FunctionState.F->addSpecializeAttr(SILSpecializeAttr::create(
5468-
FunctionState.F->getModule(), requirements, Attr.exported,
5476+
FunctionState.F->getModule(), genericSig, Attr.exported,
54695477
Attr.kind));
54705478
}
54715479
}

lib/SIL/SILFunction.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,16 @@
2828
using namespace swift;
2929
using namespace Lowering;
3030

31-
ArrayRef<Requirement> SILSpecializeAttr::getRequirements() const {
32-
return {const_cast<SILSpecializeAttr *>(this)->getRequirementsData(),
33-
numRequirements};
34-
}
35-
36-
SILSpecializeAttr::SILSpecializeAttr(ArrayRef<Requirement> requirements,
37-
bool exported, SpecializationKind kind)
38-
: numRequirements(requirements.size()), kind(kind), exported(exported) {
39-
std::copy(requirements.begin(), requirements.end(), getRequirementsData());
40-
}
31+
SILSpecializeAttr::SILSpecializeAttr(bool exported, SpecializationKind kind,
32+
GenericSignature *specializedSig)
33+
: kind(kind), exported(exported), specializedSignature(specializedSig) { }
4134

4235
SILSpecializeAttr *SILSpecializeAttr::create(SILModule &M,
43-
ArrayRef<Requirement> requirements,
36+
GenericSignature *specializedSig,
4437
bool exported,
4538
SpecializationKind kind) {
46-
unsigned size =
47-
sizeof(SILSpecializeAttr) + sizeof(Requirement) * requirements.size();
48-
void *buf = M.allocate(size, alignof(SILSpecializeAttr));
49-
return ::new (buf) SILSpecializeAttr(requirements, exported, kind);
39+
void *buf = M.allocate(sizeof(SILSpecializeAttr), alignof(SILSpecializeAttr));
40+
return ::new (buf) SILSpecializeAttr(exported, kind, specializedSig);
5041
}
5142

5243
void SILFunction::addSpecializeAttr(SILSpecializeAttr *Attr) {

lib/SIL/SILFunctionBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ void SILFunctionBuilder::addFunctionAttributes(SILFunction *F,
5252
SA->getSpecializationKind() == SpecializeAttr::SpecializationKind::Full
5353
? SILSpecializeAttr::SpecializationKind::Full
5454
: SILSpecializeAttr::SpecializationKind::Partial;
55-
F->addSpecializeAttr(SILSpecializeAttr::create(M, SA->getRequirements(),
56-
SA->isExported(), kind));
55+
F->addSpecializeAttr(
56+
SILSpecializeAttr::create(M, SA->getSpecializedSgnature(),
57+
SA->isExported(), kind));
5758
}
5859

5960
if (auto *OA = Attrs.getAttribute<OptimizeAttr>()) {

lib/SIL/SILPrinter.cpp

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,34 +3032,8 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
30323032

30333033
OS << "exported: " << exported << ", ";
30343034
OS << "kind: " << kind << ", ";
3035-
3036-
if (!getRequirements().empty()) {
3037-
OS << "where ";
3038-
SILFunction *F = getFunction();
3039-
assert(F);
3040-
auto GenericEnv = F->getGenericEnvironment();
3041-
interleave(getRequirements(),
3042-
[&](Requirement req) {
3043-
if (!GenericEnv) {
3044-
req.print(OS, SubPrinter);
3045-
return;
3046-
}
3047-
// Use GenericEnvironment to produce user-friendly
3048-
// names instead of something like t_0_0.
3049-
auto FirstTy = GenericEnv->getSugaredType(req.getFirstType());
3050-
if (req.getKind() != RequirementKind::Layout) {
3051-
auto SecondTy =
3052-
GenericEnv->getSugaredType(req.getSecondType());
3053-
Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
3054-
ReqWithDecls.print(OS, SubPrinter);
3055-
} else {
3056-
Requirement ReqWithDecls(req.getKind(), FirstTy,
3057-
req.getLayoutConstraint());
3058-
ReqWithDecls.print(OS, SubPrinter);
3059-
}
3060-
},
3061-
[&] { OS << ", "; });
3062-
}
3035+
OS << "signature: ";
3036+
getSpecializedSignature()->print(OS);
30633037
}
30643038

30653039
//===----------------------------------------------------------------------===//

lib/SILOptimizer/IPO/EagerSpecializer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,7 @@ void EagerSpecializerTransform::run() {
764764
// TODO: Use a decision-tree to reduce the amount of dynamic checks being
765765
// performed.
766766
for (auto *SA : F.getSpecializeAttrs()) {
767-
auto AttrRequirements = SA->getRequirements();
768-
ReInfoVec.emplace_back(&F, AttrRequirements);
767+
ReInfoVec.emplace_back(&F, SA->getSpecializedSignature());
769768
auto *NewFunc = eagerSpecialize(FuncBuilder, &F, *SA, ReInfoVec.back());
770769

771770
SpecializedFuncs.push_back(NewFunc);

0 commit comments

Comments
 (0)