Skip to content

Commit c2b2f13

Browse files
committed
SIL representation
1 parent 71f46a4 commit c2b2f13

19 files changed

+129
-29
lines changed

include/swift/AST/Availability.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ class AvailabilityInference {
316316
static Optional<AvailabilityContext> annotatedAvailableRange(const Decl *D,
317317
ASTContext &C);
318318

319+
static AvailabilityContext
320+
annotatedAvailableRangeForAttr(const SpecializeAttr* attr, ASTContext &ctx);
321+
319322
};
320323

321324
} // end namespace swift

include/swift/Parse/Parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@ class Parser {
10491049
/// \p Attr is where to store the parsed attribute
10501050
bool parseSpecializeAttribute(
10511051
swift::tok ClosingBrace, SourceLoc AtLoc, SourceLoc Loc,
1052-
SpecializeAttr *&Attr,
1052+
SpecializeAttr *&Attr, AvailabilityContext *SILAvailability,
10531053
llvm::function_ref<bool(Parser &)> parseSILTargetName =
10541054
[](Parser &) { return false; },
10551055
llvm::function_ref<bool(Parser &)> parseSILSIPModule =
@@ -1060,6 +1060,7 @@ class Parser {
10601060
swift::tok ClosingBrace, bool &DiscardAttribute, Optional<bool> &Exported,
10611061
Optional<SpecializeAttr::SpecializationKind> &Kind,
10621062
TrailingWhereClause *&TrailingWhereClause, DeclNameRef &targetFunction,
1063+
AvailabilityContext *SILAvailability,
10631064
SmallVectorImpl<Identifier> &spiGroups,
10641065
SmallVectorImpl<AvailableAttr *> &availableAttrs,
10651066
llvm::function_ref<bool(Parser &)> parseSILTargetName,

include/swift/SIL/SILFunction.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ class SILSpecializeAttr final {
7272
GenericSignature specializedSignature,
7373
bool exported, SpecializationKind kind,
7474
SILFunction *target, Identifier spiGroup,
75-
const ModuleDecl *spiModule);
75+
const ModuleDecl *spiModule,
76+
AvailabilityContext availability);
7677

7778
bool isExported() const {
7879
return exported;
@@ -110,20 +111,26 @@ class SILSpecializeAttr final {
110111
return spiModule;
111112
}
112113

114+
AvailabilityContext getAvailability() const {
115+
return availability;
116+
}
117+
113118
void print(llvm::raw_ostream &OS) const;
114119

115120
private:
116121
SpecializationKind kind;
117122
bool exported;
118123
GenericSignature specializedSignature;
119124
Identifier spiGroup;
125+
AvailabilityContext availability;
120126
const ModuleDecl *spiModule = nullptr;
121127
SILFunction *F = nullptr;
122128
SILFunction *targetFunction = nullptr;
123129

124130
SILSpecializeAttr(bool exported, SpecializationKind kind,
125131
GenericSignature specializedSignature, SILFunction *target,
126-
Identifier spiGroup, const ModuleDecl *spiModule);
132+
Identifier spiGroup, const ModuleDecl *spiModule,
133+
AvailabilityContext availability);
127134
};
128135

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

lib/AST/Availability.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,33 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
176176
VersionRange::allGTE(bestAvailAttr->Introduced.getValue())};
177177
}
178178

179+
AvailabilityContext
180+
AvailabilityInference::annotatedAvailableRangeForAttr(const SpecializeAttr* attr,
181+
ASTContext &ctx) {
182+
183+
const AvailableAttr *bestAvailAttr = nullptr;
184+
185+
for (auto *availAttr : attr->getAvailabeAttrs()) {
186+
if (availAttr == nullptr || !availAttr->Introduced.hasValue() ||
187+
!availAttr->isActivePlatform(ctx) ||
188+
availAttr->isLanguageVersionSpecific() ||
189+
availAttr->isPackageDescriptionVersionSpecific()) {
190+
continue;
191+
}
192+
193+
if (isBetterThan(availAttr, bestAvailAttr))
194+
bestAvailAttr = availAttr;
195+
}
196+
197+
if (bestAvailAttr) {
198+
return AvailabilityContext{
199+
VersionRange::allGTE(bestAvailAttr->Introduced.getValue())
200+
};
201+
}
202+
203+
return AvailabilityContext::alwaysAvailable();
204+
}
205+
179206
AvailabilityContext AvailabilityInference::availableRange(const Decl *D,
180207
ASTContext &Ctx) {
181208
Optional<AvailabilityContext> AnnotatedRange =

lib/Parse/ParseDecl.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -582,10 +582,11 @@ bool Parser::parseSpecializeAttributeArguments(
582582
swift::tok ClosingBrace, bool &DiscardAttribute, Optional<bool> &Exported,
583583
Optional<SpecializeAttr::SpecializationKind> &Kind,
584584
swift::TrailingWhereClause *&TrailingWhereClause,
585-
DeclNameRef &targetFunction, SmallVectorImpl<Identifier> &spiGroups,
585+
DeclNameRef &targetFunction, AvailabilityContext *SILAvailability, SmallVectorImpl<Identifier> &spiGroups,
586586
SmallVectorImpl<AvailableAttr *> &availableAttrs,
587587
llvm::function_ref<bool(Parser &)> parseSILTargetName,
588588
llvm::function_ref<bool(Parser &)> parseSILSIPModule) {
589+
bool isSIL = SILAvailability != nullptr;
589590
SyntaxParsingContext ContentContext(SyntaxContext,
590591
SyntaxKind::SpecializeAttributeSpecList);
591592
// Parse optional "exported" and "kind" labeled parameters.
@@ -601,7 +602,8 @@ bool Parser::parseSpecializeAttributeArguments(
601602
: SyntaxKind::LabeledSpecializeEntry));
602603
if (ParamLabel != "exported" && ParamLabel != "kind" &&
603604
ParamLabel != "target" && ParamLabel != "spi" &&
604-
ParamLabel != "spiModule" && ParamLabel != "availability") {
605+
ParamLabel != "spiModule" && ParamLabel != "availability" &&
606+
(!isSIL || ParamLabel != "available")) {
605607
diagnose(Tok.getLoc(), diag::attr_specialize_unknown_parameter_name,
606608
ParamLabel);
607609
}
@@ -627,6 +629,15 @@ bool Parser::parseSpecializeAttributeArguments(
627629
diagnose(Tok.getLoc(), diag::attr_specialize_parameter_already_defined,
628630
ParamLabel);
629631
}
632+
if (ParamLabel == "available") {
633+
SourceRange range;
634+
llvm::VersionTuple version;
635+
if (parseVersionTuple(version, range,
636+
diag::sil_availability_expected_version))
637+
return false;
638+
639+
*SILAvailability = AvailabilityContext(VersionRange::allGTE(version));
640+
}
630641
if (ParamLabel == "availability") {
631642
SourceRange attrRange;
632643
auto Loc = Tok.getLoc();
@@ -877,7 +888,7 @@ bool Parser::parseAvailability(
877888

878889
bool Parser::parseSpecializeAttribute(
879890
swift::tok ClosingBrace, SourceLoc AtLoc, SourceLoc Loc,
880-
SpecializeAttr *&Attr,
891+
SpecializeAttr *&Attr, AvailabilityContext *SILAvailability,
881892
llvm::function_ref<bool(Parser &)> parseSILTargetName,
882893
llvm::function_ref<bool(Parser &)> parseSILSIPModule) {
883894
assert(ClosingBrace == tok::r_paren || ClosingBrace == tok::r_square);
@@ -896,7 +907,7 @@ bool Parser::parseSpecializeAttribute(
896907
SmallVector<AvailableAttr *, 4> availableAttrs;
897908
if (!parseSpecializeAttributeArguments(
898909
ClosingBrace, DiscardAttribute, exported, kind, trailingWhereClause,
899-
targetFunction, spiGroups, availableAttrs, parseSILTargetName,
910+
targetFunction, SILAvailability, spiGroups, availableAttrs, parseSILTargetName,
900911
parseSILSIPModule)) {
901912
return false;
902913
}
@@ -2588,7 +2599,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
25882599
return false;
25892600
}
25902601
SpecializeAttr *Attr;
2591-
if (!parseSpecializeAttribute(tok::r_paren, AtLoc, Loc, Attr))
2602+
if (!parseSpecializeAttribute(tok::r_paren, AtLoc, Loc, Attr, nullptr))
25922603
return false;
25932604

25942605
Attributes.add(Attr);

lib/SIL/IR/SILFunction.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ STATISTIC(MaxBitfieldID, "Max value of SILFunction::currentBitfieldID");
4040
SILSpecializeAttr::SILSpecializeAttr(bool exported, SpecializationKind kind,
4141
GenericSignature specializedSig,
4242
SILFunction *target, Identifier spiGroup,
43-
const ModuleDecl *spiModule)
43+
const ModuleDecl *spiModule,
44+
AvailabilityContext availability)
4445
: kind(kind), exported(exported), specializedSignature(specializedSig),
45-
spiGroup(spiGroup), spiModule(spiModule), targetFunction(target) {
46+
spiGroup(spiGroup), availability(availability), spiModule(spiModule), targetFunction(target) {
4647
if (targetFunction)
4748
targetFunction->incrementRefCount();
4849
}
@@ -51,10 +52,11 @@ SILSpecializeAttr *
5152
SILSpecializeAttr::create(SILModule &M, GenericSignature specializedSig,
5253
bool exported, SpecializationKind kind,
5354
SILFunction *target, Identifier spiGroup,
54-
const ModuleDecl *spiModule) {
55+
const ModuleDecl *spiModule,
56+
AvailabilityContext availability) {
5557
void *buf = M.allocate(sizeof(SILSpecializeAttr), alignof(SILSpecializeAttr));
5658
return ::new (buf) SILSpecializeAttr(exported, kind, specializedSig, target,
57-
spiGroup, spiModule);
59+
spiGroup, spiModule, availability);
5860
}
5961

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

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,20 @@ void SILFunctionBuilder::addFunctionAttributes(
8080
if (hasSPI) {
8181
spiGroupIdent = spiGroups[0];
8282
}
83+
auto availability =
84+
AvailabilityInference::annotatedAvailableRangeForAttr(SA,
85+
M.getSwiftModule()->getASTContext());
8386
if (targetFunctionDecl) {
8487
SILDeclRef declRef(targetFunctionDecl, constant.kind, false);
8588
targetFunction = getOrCreateDeclaration(targetFunctionDecl, declRef);
8689
F->addSpecializeAttr(SILSpecializeAttr::create(
8790
M, SA->getSpecializedSignature(), SA->isExported(), kind,
8891
targetFunction, spiGroupIdent,
89-
attributedFuncDecl->getModuleContext()));
92+
attributedFuncDecl->getModuleContext(), availability));
9093
} else {
9194
F->addSpecializeAttr(SILSpecializeAttr::create(
9295
M, SA->getSpecializedSignature(), SA->isExported(), kind, nullptr,
93-
spiGroupIdent, attributedFuncDecl->getModuleContext()));
96+
spiGroupIdent, attributedFuncDecl->getModuleContext(), availability));
9497
}
9598
}
9699

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3711,6 +3711,10 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
37113711
if (targetFunction) {
37123712
OS << "target: \"" << targetFunction->getName() << "\", ";
37133713
}
3714+
if (!availability.isAlwaysAvailable()) {
3715+
auto version = availability.getOSVersion().getLowerEndpoint();
3716+
OS << "available: " << version.getAsString() << ", ";
3717+
}
37143718
if (!requirements.empty()) {
37153719
OS << "where ";
37163720
SILFunction *F = getFunction();

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ namespace {
114114
SILFunction *target = nullptr;
115115
Identifier spiGroupID;
116116
ModuleDecl *spiModule;
117+
AvailabilityContext availability = AvailabilityContext::alwaysAvailable();
117118
};
118119

119120
class SILParser {
@@ -1092,9 +1093,9 @@ static bool parseDeclSILOptional(bool *isTransparent,
10921093
SpecializeAttr *Attr;
10931094
StringRef targetFunctionName;
10941095
ModuleDecl *module = nullptr;
1095-
1096+
AvailabilityContext availability = AvailabilityContext::alwaysAvailable();
10961097
if (!SP.P.parseSpecializeAttribute(
1097-
tok::r_square, AtLoc, Loc, Attr,
1098+
tok::r_square, AtLoc, Loc, Attr, &availability,
10981099
[&targetFunctionName](Parser &P) -> bool {
10991100
if (P.Tok.getKind() != tok::string_literal) {
11001101
P.diagnose(P.Tok, diag::expected_in_attribute_list);
@@ -1136,6 +1137,7 @@ static bool parseDeclSILOptional(bool *isTransparent,
11361137
: SILSpecializeAttr::SpecializationKind::Partial;
11371138
SpecAttr.exported = Attr->isExported();
11381139
SpecAttr.target = targetFunction;
1140+
SpecAttr.availability = availability;
11391141
SpecAttrs->emplace_back(SpecAttr);
11401142
if (!Attr->getSPIGroups().empty()) {
11411143
SpecAttr.spiGroupID = Attr->getSPIGroups()[0];
@@ -6279,7 +6281,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
62796281
GenericSignature());
62806282
FunctionState.F->addSpecializeAttr(SILSpecializeAttr::create(
62816283
FunctionState.F->getModule(), genericSig, Attr.exported,
6282-
Attr.kind, Attr.target, Attr.spiGroupID, Attr.spiModule));
6284+
Attr.kind, Attr.target, Attr.spiGroupID, Attr.spiModule, Attr.availability));
62836285
}
62846286
}
62856287

lib/SILGen/SILGen.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2209,9 +2209,12 @@ static void transferSpecializeAttributeTargets(SILGenModule &SGM, SILModule &M,
22092209
if (hasSPIGroup) {
22102210
spiGroupIdent = spiGroups[0];
22112211
}
2212+
auto availability =
2213+
AvailabilityInference::annotatedAvailableRangeForAttr(SA,
2214+
M.getSwiftModule()->getASTContext());
22122215
targetSILFunction->addSpecializeAttr(SILSpecializeAttr::create(
22132216
M, SA->getSpecializedSignature(), SA->isExported(), kind, nullptr,
2214-
spiGroupIdent, vd->getModuleContext()));
2217+
spiGroupIdent, vd->getModuleContext(), availability));
22152218
}
22162219
}
22172220
}

0 commit comments

Comments
 (0)