Skip to content

Commit fd3e3cf

Browse files
Merge pull request #32657 from aschwaighofer/wip_prespecialize_exported
Preliminary support for `_specialize(exported: true, ...)`
2 parents 67d311d + d6d79c6 commit fd3e3cf

File tree

98 files changed

+2479
-387
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2479
-387
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,7 @@ Function Specializations
995995
::
996996

997997
specialization ::= type '_' type* 'Tg' SPEC-INFO // Generic re-abstracted specialization
998+
specialization ::= type '_' type* 'Ts' SPEC-INFO // Generic re-abstracted prespecialization
998999
specialization ::= type '_' type* 'TG' SPEC-INFO // Generic not re-abstracted specialization
9991000
specialization ::= type '_' type* 'Ti' SPEC-INFO // Inlined function with generic substitutions.
10001001

include/swift/AST/Attr.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,11 @@ SIMPLE_DECL_ATTR(globalActor, GlobalActor,
584584
APIStableToAdd | APIBreakingToRemove,
585585
104)
586586

587+
SIMPLE_DECL_ATTR(_specializeExtension, SpecializeExtension,
588+
OnExtension | UserInaccessible |
589+
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
590+
105)
591+
587592
#undef TYPE_ATTR
588593
#undef DECL_ATTR_ALIAS
589594
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Attr.h

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,12 @@ class SynthesizedProtocolAttr : public DeclAttribute {
14081408

14091409
/// The @_specialize attribute, which forces specialization on the specified
14101410
/// type list.
1411-
class SpecializeAttr : public DeclAttribute {
1411+
class SpecializeAttr final
1412+
: public DeclAttribute,
1413+
private llvm::TrailingObjects<SpecializeAttr, Identifier> {
1414+
friend class SpecializeAttrTargetDeclRequest;
1415+
friend TrailingObjects;
1416+
14121417
public:
14131418
// NOTE: When adding new kinds, you must update the inline bitfield macro.
14141419
enum class SpecializationKind {
@@ -1420,18 +1425,48 @@ class SpecializeAttr : public DeclAttribute {
14201425
TrailingWhereClause *trailingWhereClause;
14211426
GenericSignature specializedSignature;
14221427

1428+
DeclNameRef targetFunctionName;
1429+
LazyMemberLoader *resolver = nullptr;
1430+
uint64_t resolverContextData;
1431+
size_t numSPIGroups;
1432+
14231433
SpecializeAttr(SourceLoc atLoc, SourceRange Range,
14241434
TrailingWhereClause *clause, bool exported,
1425-
SpecializationKind kind,
1426-
GenericSignature specializedSignature);
1435+
SpecializationKind kind, GenericSignature specializedSignature,
1436+
DeclNameRef targetFunctionName,
1437+
ArrayRef<Identifier> spiGroups);
14271438

14281439
public:
14291440
static SpecializeAttr *create(ASTContext &Ctx, SourceLoc atLoc,
14301441
SourceRange Range, TrailingWhereClause *clause,
14311442
bool exported, SpecializationKind kind,
1443+
DeclNameRef targetFunctionName,
1444+
ArrayRef<Identifier> spiGroups,
14321445
GenericSignature specializedSignature
14331446
= nullptr);
14341447

1448+
static SpecializeAttr *create(ASTContext &ctx, bool exported,
1449+
SpecializationKind kind,
1450+
ArrayRef<Identifier> spiGroups,
1451+
GenericSignature specializedSignature,
1452+
DeclNameRef replacedFunction);
1453+
1454+
static SpecializeAttr *create(ASTContext &ctx, bool exported,
1455+
SpecializationKind kind,
1456+
ArrayRef<Identifier> spiGroups,
1457+
GenericSignature specializedSignature,
1458+
DeclNameRef replacedFunction,
1459+
LazyMemberLoader *resolver, uint64_t data);
1460+
1461+
/// Name of SPIs declared by the attribute.
1462+
///
1463+
/// Note: A single SPI name per attribute is currently supported but this
1464+
/// may change with the syntax change.
1465+
ArrayRef<Identifier> getSPIGroups() const {
1466+
return { this->template getTrailingObjects<Identifier>(),
1467+
numSPIGroups };
1468+
}
1469+
14351470
TrailingWhereClause *getTrailingWhereClause() const;
14361471

14371472
GenericSignature getSpecializedSignature() const {
@@ -1458,6 +1493,13 @@ class SpecializeAttr : public DeclAttribute {
14581493
return getSpecializationKind() == SpecializationKind::Partial;
14591494
}
14601495

1496+
DeclNameRef getTargetFunctionName() const {
1497+
return targetFunctionName;
1498+
}
1499+
1500+
/// \p forDecl is the value decl that the attribute belongs to.
1501+
ValueDecl *getTargetFunctionDecl(const ValueDecl *forDecl) const;
1502+
14611503
static bool classof(const DeclAttribute *DA) {
14621504
return DA->getKind() == DAK_Specialize;
14631505
}

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2187,7 +2187,8 @@ class ValueDecl : public Decl {
21872187
/// implementations for the requirements of a public protocol, even when
21882188
/// the default implementations are not visible to name lookup.
21892189
bool isAccessibleFrom(const DeclContext *DC,
2190-
bool forConformance = false) const;
2190+
bool forConformance = false,
2191+
bool includeInlineable = false) const;
21912192

21922193
/// Returns whether this declaration should be treated as \c open from
21932194
/// \p useDC. This is very similar to #getFormalAccess, but takes

include/swift/AST/DeclContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
490490
/// Determine whether the innermost context is generic.
491491
bool isInnermostContextGeneric() const;
492492

493+
/// Determine whether this or any parent context is a `@_specialize` extension
494+
/// context.
495+
bool isInSpecializeExtensionContext() const;
496+
493497
/// Get the most optimal resilience expansion for code in this context.
494498
/// If the body is able to be inlined into functions in other resilience
495499
/// domains, this ensures that only sufficiently-conservative access patterns

include/swift/AST/DiagnosticsParse.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,8 @@ ERROR(expected_sil_function_type, none,
626626
"sil function expected to have SIL function type", ())
627627
ERROR(sil_dynamically_replaced_func_not_found,none,
628628
"dynamically replaced function not found %0", (Identifier))
629+
ERROR(sil_specialize_target_func_not_found,none,
630+
"_specialize target function not found %0", (Identifier))
629631
ERROR(sil_availability_expected_version,none,
630632
"expected version number in 'available' attribute", ())
631633

@@ -1579,6 +1581,10 @@ ERROR(attr_specialize_parameter_already_defined,none,
15791581

15801582
ERROR(attr_specialize_expected_partial_or_full,none,
15811583
"expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute", ())
1584+
ERROR(attr_specialize_expected_function,none,
1585+
"expected a function name as the value of the 'target' parameter in '_specialize' attribute", ())
1586+
ERROR(attr_specialize_expected_spi_name,none,
1587+
"expected an SPI identifier as the value of the 'spi' parameter in '_specialize' attribute", ())
15821588

15831589
// _implements
15841590
ERROR(attr_implements_expected_member_name,PointsToFirstBadToken,

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5125,6 +5125,12 @@ ERROR(specialize_attr_missing_constraint,none,
51255125
"Missing constraint for %0 in '_specialize' attribute", (DeclName))
51265126
ERROR(specialize_attr_unsupported_kind_of_req,none,
51275127
"Only same-type and layout requirements are supported by '_specialize' attribute", ())
5128+
ERROR(specialize_target_function_not_found, none,
5129+
"target function %0 could not be found", (DeclNameRef))
5130+
ERROR(specialize_target_function_of_type_not_found, none,
5131+
"target function %0 of type %1 could not be found", (DeclNameRef, Type))
5132+
NOTE(specialize_found_function_of_type, none,
5133+
"found function %0 of type %1", (DeclName, Type))
51285134

51295135
//------------------------------------------------------------------------------
51305136
// MARK: Variable usage diagnostics

include/swift/AST/LazyResolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ class alignas(void*) LazyMemberLoader {
114114
/// Returns the type for a given @_typeEraser() attribute.
115115
virtual Type loadTypeEraserType(const TypeEraserAttr *TRA,
116116
uint64_t contextData) = 0;
117+
118+
// Returns the target parameter of the `@_specialize` attribute or null.
119+
virtual ValueDecl *loadTargetFunctionDecl(const SpecializeAttr *attr,
120+
uint64_t contextData) = 0;
117121
};
118122

119123
/// A class that can lazily load conformances from a serialized format.

include/swift/AST/LookupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ enum NLOptions : unsigned {
5050
/// Include synonyms declared with @_implements()
5151
NL_IncludeAttributeImplements = 1 << 5,
5252

53+
// Include @usableFromInline and @inlinable
54+
NL_IncludeUsableFromInlineAndInlineable = 1 << 6,
55+
5356
/// The default set of options used for qualified name lookup.
5457
///
5558
/// FIXME: Eventually, add NL_ProtocolMembers to this, once all of the

include/swift/AST/Module.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,13 @@ class ModuleDecl : public DeclContext, public TypeDecl {
578578
const ModuleDecl *importedModule,
579579
llvm::SmallSetVector<Identifier, 4> &spiGroups) const;
580580

581+
// Is \p attr accessible as an explictly imported SPI from this module?
582+
bool isImportedAsSPI(const SpecializeAttr *attr,
583+
const ValueDecl *targetDecl) const;
584+
585+
// Is \p spiGroup accessible as an explictly imported SPI from this module?
586+
bool isImportedAsSPI(Identifier spiGroup, const ModuleDecl *fromModule) const;
587+
581588
/// \sa getImportedModules
582589
enum class ImportFilterKind {
583590
/// Include imports declared with `@_exported`.

include/swift/AST/ModuleNameLookup.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ void simple_display(llvm::raw_ostream &out, ResolutionKind kind);
5656
/// \param moduleScopeContext The top-level context from which the lookup is
5757
/// being performed, for checking access. This must be either a
5858
/// FileUnit or a Module.
59+
/// \param options name lookup options. Currently only used to communicate the
60+
/// NL_IncludeUsableFromInlineAndInlineable option.
5961
void lookupInModule(const DeclContext *moduleOrFile,
6062
DeclName name, SmallVectorImpl<ValueDecl *> &decls,
6163
NLKind lookupKind, ResolutionKind resolutionKind,
62-
const DeclContext *moduleScopeContext);
64+
const DeclContext *moduleScopeContext,
65+
NLOptions options);
6366

6467
/// Performs a qualified lookup into the given module and, if necessary, its
6568
/// reexports, observing proper shadowing rules.

include/swift/AST/NameLookup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ enum class UnqualifiedLookupFlags {
225225
/// This lookup should include results from outside the innermost scope with
226226
/// results.
227227
IncludeOuterResults = 1 << 4,
228+
// This lookup should include results that are @inlinable or
229+
// @usableFromInline.
230+
IncludeInlineableAndUsableFromInline = 1 << 5,
228231
};
229232

230233
using UnqualifiedLookupOptions = OptionSet<UnqualifiedLookupFlags>;

include/swift/AST/NameLookupRequests.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,12 @@ using QualifiedLookupResult = SmallVector<ValueDecl *, 4>;
437437

438438
/// Performs a lookup into a given module and its imports.
439439
class LookupInModuleRequest
440-
: public SimpleRequest<LookupInModuleRequest,
441-
QualifiedLookupResult(
442-
const DeclContext *, DeclName, NLKind,
443-
namelookup::ResolutionKind, const DeclContext *),
444-
RequestFlags::Uncached | RequestFlags::DependencySink> {
440+
: public SimpleRequest<
441+
LookupInModuleRequest,
442+
QualifiedLookupResult(const DeclContext *, DeclName, NLKind,
443+
namelookup::ResolutionKind, const DeclContext *,
444+
NLOptions),
445+
RequestFlags::Uncached | RequestFlags::DependencySink> {
445446
public:
446447
using SimpleRequest::SimpleRequest;
447448

@@ -452,7 +453,7 @@ class LookupInModuleRequest
452453
QualifiedLookupResult
453454
evaluate(Evaluator &evaluator, const DeclContext *moduleOrFile, DeclName name,
454455
NLKind lookupKind, namelookup::ResolutionKind resolutionKind,
455-
const DeclContext *moduleScopeContext) const;
456+
const DeclContext *moduleScopeContext, NLOptions options) const;
456457

457458
public:
458459
// Incremental dependencies

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,6 +2177,25 @@ class DynamicallyReplacedDeclRequest
21772177
bool isCached() const { return true; }
21782178
};
21792179

2180+
class SpecializeAttrTargetDeclRequest
2181+
: public SimpleRequest<SpecializeAttrTargetDeclRequest,
2182+
ValueDecl *(const ValueDecl *, SpecializeAttr *),
2183+
RequestFlags::Cached> {
2184+
public:
2185+
using SimpleRequest::SimpleRequest;
2186+
2187+
private:
2188+
friend SimpleRequest;
2189+
2190+
// Evaluation.
2191+
ValueDecl *evaluate(Evaluator &evaluator, const ValueDecl *vd,
2192+
SpecializeAttr *attr) const;
2193+
2194+
public:
2195+
// Caching.
2196+
bool isCached() const { return true; }
2197+
};
2198+
21802199
class TypeCheckSourceFileRequest
21812200
: public SimpleRequest<
21822201
TypeCheckSourceFileRequest, evaluator::SideEffect(SourceFile *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ SWIFT_REQUEST(TypeChecker, DynamicallyReplacedDeclRequest,
6767
Cached, NoLocationInfo)
6868
SWIFT_REQUEST(TypeChecker, SemanticMembersRequest,
6969
ArrayRef<Decl *>(IterableDeclContext *), Cached, NoLocationInfo)
70+
SWIFT_REQUEST(TypeChecker, SpecializeAttrTargetDeclRequest,
71+
ValueDecl *(const ValueDecl *, SpecializeAttr *),
72+
Cached, NoLocationInfo)
7073
SWIFT_REQUEST(TypeChecker, EnumRawValuesRequest,
7174
evaluator::SideEffect (EnumDecl *, TypeResolutionStage),
7275
SeparatelyCached, NoLocationInfo)

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ NODE(ResilientProtocolWitnessTable)
104104
NODE(GenericSpecialization)
105105
NODE(GenericSpecializationNotReAbstracted)
106106
NODE(GenericSpecializationParam)
107+
NODE(GenericSpecializationPrespecialized)
107108
NODE(InlinedGenericFunction)
108109
NODE(GenericTypeMetadataPattern)
109110
CONTEXT_NODE(Getter)

include/swift/Parse/Parser.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,14 +1003,22 @@ class Parser {
10031003
/// Parse the @_specialize attribute.
10041004
/// \p closingBrace is the expected closing brace, which can be either ) or ]
10051005
/// \p Attr is where to store the parsed attribute
1006-
bool parseSpecializeAttribute(swift::tok ClosingBrace, SourceLoc AtLoc,
1007-
SourceLoc Loc, SpecializeAttr *&Attr);
1006+
bool parseSpecializeAttribute(
1007+
swift::tok ClosingBrace, SourceLoc AtLoc, SourceLoc Loc,
1008+
SpecializeAttr *&Attr,
1009+
llvm::function_ref<bool(Parser &)> parseSILTargetName =
1010+
[](Parser &) { return false; },
1011+
llvm::function_ref<bool(Parser &)> parseSILSIPModule =
1012+
[](Parser &) { return false; });
10081013

10091014
/// Parse the arguments inside the @_specialize attribute
10101015
bool parseSpecializeAttributeArguments(
10111016
swift::tok ClosingBrace, bool &DiscardAttribute, Optional<bool> &Exported,
10121017
Optional<SpecializeAttr::SpecializationKind> &Kind,
1013-
TrailingWhereClause *&TrailingWhereClause);
1018+
TrailingWhereClause *&TrailingWhereClause, DeclNameRef &targetFunction,
1019+
SmallVectorImpl<Identifier> &spiGroups,
1020+
llvm::function_ref<bool(Parser &)> parseSILTargetName,
1021+
llvm::function_ref<bool(Parser &)> parseSILSIPModule);
10141022

10151023
/// Parse the @_implements attribute.
10161024
/// \p Attr is where to store the parsed attribute

0 commit comments

Comments
 (0)