Skip to content

Commit a045d66

Browse files
authored
Merge pull request #75282 from jckarter/addressable-params-1
[WIP] Prototype an `@_addressable` attribute that puts an argument at a stable address.
2 parents 70ce8c6 + 3c0b08d commit a045d66

File tree

18 files changed

+227
-37
lines changed

18 files changed

+227
-37
lines changed

include/swift/AST/Decl.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6817,6 +6817,9 @@ class ParamDecl : public VarDecl {
68176817

68186818
/// Whether or not this parameter is 'isolated'.
68196819
IsIsolated = 1 << 2,
6820+
6821+
/// Whether this parameter is `@_addressable`.
6822+
IsAddressable = 1 << 3,
68206823

68216824
/// Whether or not this parameter is 'sending'.
68226825
IsSending = 1 << 4,
@@ -7107,6 +7110,18 @@ class ParamDecl : public VarDecl {
71077110
removeFlag(Flag::IsSending);
71087111
}
71097112

7113+
/// Whether or not this parameter is marked with '@_addressable'.
7114+
bool isAddressable() const {
7115+
return getOptions().contains(Flag::IsAddressable);
7116+
}
7117+
7118+
void setAddressable(bool value = true) {
7119+
if (value)
7120+
addFlag(Flag::IsAddressable);
7121+
else
7122+
removeFlag(Flag::IsAddressable);
7123+
}
7124+
71107125
/// Whether or not this parameter is marked with '_const'.
71117126
bool isCompileTimeConst() const {
71127127
return ArgumentNameAndFlags.getInt().contains(

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,10 @@ ERROR(attr_implementation_category_goes_on_objc_attr,none,
18341834
"'@implementation'",
18351835
())
18361836

1837+
ERROR(attr_not_allowed_in_c_functions,none,
1838+
"attribute %0 is not allowed in C function conventions",
1839+
(StringRef))
1840+
18371841
WARNING(objc_implementation_will_become_objc,none,
18381842
"%kind0 will become implicitly '@objc' after adopting '@objc "
18391843
"@implementation'; add '%select{@nonobjc|final}1' to keep the current "

include/swift/AST/TypeAttr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ SIMPLE_TYPE_ATTR(_local, Local)
6464
SIMPLE_TYPE_ATTR(_noMetadata, NoMetadata)
6565
TYPE_ATTR(_opaqueReturnTypeOf, OpaqueReturnTypeOf)
6666
TYPE_ATTR(isolated, Isolated)
67+
SIMPLE_TYPE_ATTR(_addressable, Addressable)
6768

6869
// SIL-specific attributes
6970
SIMPLE_SIL_TYPE_ATTR(async, Async)

include/swift/AST/Types.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,7 +2388,8 @@ class ParameterTypeFlags {
23882388
Isolated = 1 << 7,
23892389
CompileTimeConst = 1 << 8,
23902390
Sending = 1 << 9,
2391-
NumBits = 10
2391+
Addressable = 1 << 10,
2392+
NumBits = 11
23922393
};
23932394
OptionSet<ParameterFlags> value;
23942395
static_assert(NumBits <= 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
@@ -2403,20 +2404,21 @@ class ParameterTypeFlags {
24032404

24042405
ParameterTypeFlags(bool variadic, bool autoclosure, bool nonEphemeral,
24052406
ParamSpecifier specifier, bool isolated, bool noDerivative,
2406-
bool compileTimeConst, bool isSending)
2407+
bool compileTimeConst, bool isSending, bool isAddressable)
24072408
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
24082409
(nonEphemeral ? NonEphemeral : 0) |
24092410
uint8_t(specifier) << SpecifierShift | (isolated ? Isolated : 0) |
24102411
(noDerivative ? NoDerivative : 0) |
24112412
(compileTimeConst ? CompileTimeConst : 0) |
2412-
(isSending ? Sending : 0)) {}
2413+
(isSending ? Sending : 0) |
2414+
(isAddressable ? Addressable : 0)) {}
24132415

24142416
/// Create one from what's present in the parameter type
24152417
inline static ParameterTypeFlags
24162418
fromParameterType(Type paramTy, bool isVariadic, bool isAutoClosure,
24172419
bool isNonEphemeral, ParamSpecifier ownership,
24182420
bool isolated, bool isNoDerivative, bool compileTimeConst,
2419-
bool isSending);
2421+
bool isSending, bool isAddressable);
24202422

24212423
bool isNone() const { return !value; }
24222424
bool isVariadic() const { return value.contains(Variadic); }
@@ -2429,6 +2431,7 @@ class ParameterTypeFlags {
24292431
bool isCompileTimeConst() const { return value.contains(CompileTimeConst); }
24302432
bool isNoDerivative() const { return value.contains(NoDerivative); }
24312433
bool isSending() const { return value.contains(Sending); }
2434+
bool isAddressable() const { return value.contains(Addressable); }
24322435

24332436
/// Get the spelling of the parameter specifier used on the parameter.
24342437
ParamSpecifier getOwnershipSpecifier() const {
@@ -2497,6 +2500,12 @@ class ParameterTypeFlags {
24972500
: value - ParameterTypeFlags::Sending);
24982501
}
24992502

2503+
ParameterTypeFlags withAddressable(bool withAddressable) const {
2504+
return ParameterTypeFlags(withAddressable
2505+
? value | ParameterTypeFlags::Addressable
2506+
: value - ParameterTypeFlags::Addressable);
2507+
}
2508+
25002509
bool operator ==(const ParameterTypeFlags &other) const {
25012510
return value.toRaw() == other.value.toRaw();
25022511
}
@@ -2590,7 +2599,8 @@ class YieldTypeFlags {
25902599
/*nonEphemeral*/ false, getOwnershipSpecifier(),
25912600
/*isolated*/ false, /*noDerivative*/ false,
25922601
/*compileTimeConst*/ false,
2593-
/*is sending*/ false);
2602+
/*is sending*/ false,
2603+
/*is addressable*/ false);
25942604
}
25952605

25962606
bool operator ==(const YieldTypeFlags &other) const {
@@ -3386,6 +3396,8 @@ class AnyFunctionType : public TypeBase {
33863396

33873397
/// Whether the parameter is marked '@noDerivative'.
33883398
bool isNoDerivative() const { return Flags.isNoDerivative(); }
3399+
3400+
bool isAddressable() const { return Flags.isAddressable(); }
33893401

33903402
/// Whether the parameter might be a semantic result for autodiff purposes.
33913403
/// This includes inout parameters.
@@ -8092,7 +8104,7 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
80928104
inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
80938105
Type paramTy, bool isVariadic, bool isAutoClosure, bool isNonEphemeral,
80948106
ParamSpecifier ownership, bool isolated, bool isNoDerivative,
8095-
bool compileTimeConst, bool isSending) {
8107+
bool compileTimeConst, bool isSending, bool isAddressable) {
80968108
// FIXME(Remove InOut): The last caller that needs this is argument
80978109
// decomposition. Start by enabling the assertion there and fixing up those
80988110
// callers, then remove this, then remove
@@ -8103,7 +8115,8 @@ inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
81038115
ownership = ParamSpecifier::InOut;
81048116
}
81058117
return {isVariadic, isAutoClosure, isNonEphemeral, ownership,
8106-
isolated, isNoDerivative, compileTimeConst, isSending};
8118+
isolated, isNoDerivative, compileTimeConst, isSending,
8119+
isAddressable};
81078120
}
81088121

81098122
inline const Type *BoundGenericType::getTrailingObjectsPointer() const {

include/swift/Basic/Features.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,8 @@ EXPERIMENTAL_FEATURE(CoroutineAccessorsAllocateInCallee, false)
430430
// When a parameter has unspecified isolation, infer it as main actor isolated.
431431
EXPERIMENTAL_FEATURE(GenerateForceToMainActorThunks, false)
432432

433+
EXPERIMENTAL_FEATURE(AddressableParameters, true)
434+
433435
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
434436
#undef EXPERIMENTAL_FEATURE
435437
#undef UPCOMING_FEATURE

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8576,7 +8576,7 @@ AnyFunctionType::Param ParamDecl::toFunctionParam(Type type) const {
85768576
auto flags = ParameterTypeFlags::fromParameterType(
85778577
type, isVariadic(), isAutoClosure(), isNonEphemeral(), getSpecifier(),
85788578
isIsolated(), /*isNoDerivative*/ false, isCompileTimeConst(),
8579-
isSending());
8579+
isSending(), isAddressable());
85808580
return AnyFunctionType::Param(type, label, flags, internalLabel);
85818581
}
85828582

lib/AST/FeatureSet.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,20 @@ static bool usesFeatureIsolatedAny(Decl *decl) {
290290
});
291291
}
292292

293+
static bool usesFeatureAddressableParameters(Decl *d) {
294+
auto fd = dyn_cast<AbstractFunctionDecl>(d);
295+
if (!fd) {
296+
return false;
297+
}
298+
299+
for (auto pd : *fd->getParameters()) {
300+
if (pd->isAddressable()) {
301+
return true;
302+
}
303+
}
304+
return false;
305+
}
306+
293307
UNINTERESTING_FEATURE(IsolatedAny2)
294308
UNINTERESTING_FEATURE(GlobalActorIsolatedTypesUsability)
295309
UNINTERESTING_FEATURE(ObjCImplementation)

lib/ASTGen/Sources/ASTGen/TypeAttrs.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extension ASTGenVisitor {
5151
switch attrKind {
5252
// Simple type attributes.
5353
case .autoclosure,
54+
.addressable,
5455
.escaping,
5556
.noEscape,
5657
.noDerivative,

lib/Parse/ParsePattern.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ mapParsedParameters(Parser &parser,
631631
// or typealias with underlying function type.
632632
if (ATR->has(TypeAttrKind::Autoclosure))
633633
param->setAutoClosure(true);
634+
if (ATR->has(TypeAttrKind::Addressable))
635+
param->setAddressable(true);
634636

635637
unwrappedType = ATR->getTypeRepr();
636638
continue;

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,12 @@ class DestructureInputs {
17201720
ParameterTypeFlags origFlags) {
17211721
assert(!isa<InOutType>(substType));
17221722

1723+
// If the parameter is marked addressable, lower it with maximal
1724+
// abstraction.
1725+
if (origFlags.isAddressable()) {
1726+
origType = AbstractionPattern::getOpaque();
1727+
}
1728+
17231729
// Tuples get expanded unless they're inout.
17241730
if (origType.isTuple() && ownership != ValueOwnership::InOut) {
17251731
expandTuple(ownership, forSelf, origType, substType, origFlags);

0 commit comments

Comments
 (0)