Skip to content

Commit 1609122

Browse files
authored
Merge pull request swiftlang#59809 from ktoso/pick-dist-properties-xedin
🍒[5.7][Distributed] Implement distributed computed properties via special accessor
2 parents 6d09e5d + 50e04f2 commit 1609122

30 files changed

+478
-123
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class ASTMangler : public Mangler {
197197
Type GlobalActorBound,
198198
ModuleDecl *Module);
199199

200-
std::string mangleDistributedThunk(const FuncDecl *thunk);
200+
std::string mangleDistributedThunk(const AbstractFunctionDecl *thunk);
201201

202202
/// Mangle a completion handler block implementation function, used for importing ObjC
203203
/// APIs as async.

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ SIMPLE_DECL_ATTR(_inheritActorContext, InheritActorContext,
661661
// 117 was 'spawn' and is now unused
662662

663663
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,
664-
DeclModifier | OnClass | OnFunc | OnVar |
664+
DeclModifier | OnClass | OnFunc | OnAccessor | OnVar |
665665
ABIBreakingToAdd | ABIBreakingToRemove |
666666
APIBreakingToAdd | APIBreakingToRemove,
667667
118)

include/swift/AST/Decl.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
412412
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
413413
StaticSpelling : 2
414414
);
415-
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+2+8+1+1+1+1+1+1,
415+
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+2+8+1+1+1+1+1+1+1,
416416
/// \see AbstractFunctionDecl::BodyKind
417417
BodyKind : 3,
418418

@@ -439,7 +439,11 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
439439

440440
/// Whether peeking into this function detected nested type declarations.
441441
/// This is set when skipping over the decl at parsing.
442-
HasNestedTypeDeclarations : 1
442+
HasNestedTypeDeclarations : 1,
443+
444+
/// Whether this function is a distributed thunk for a distributed
445+
/// function or computed property.
446+
DistributedThunk: 1
443447
);
444448

445449
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2+1,
@@ -5109,6 +5113,13 @@ class AbstractStorageDecl : public ValueDecl {
51095113

51105114
bool hasAnyNativeDynamicAccessors() const;
51115115

5116+
/// Does this have a 'distributed' modifier?
5117+
bool isDistributed() const;
5118+
5119+
/// Return a distributed thunk if this computed property is marked as
5120+
/// 'distributed' and and nullptr otherwise.
5121+
FuncDecl *getDistributedThunk() const;
5122+
51125123
// Implement isa/cast/dyncast/etc.
51135124
static bool classof(const Decl *D) {
51145125
return D->getKind() >= DeclKind::First_AbstractStorageDecl &&
@@ -5342,9 +5353,6 @@ class VarDecl : public AbstractStorageDecl {
53425353
/// Is this an "async let" property?
53435354
bool isAsyncLet() const;
53445355

5345-
/// Does this have a 'distributed' modifier?
5346-
bool isDistributed() const;
5347-
53485356
/// Is this var known to be a "local" distributed actor,
53495357
/// if so the implicit throwing ans some isolation checks can be skipped.
53505358
bool isKnownToBeLocal() const;
@@ -6314,6 +6322,7 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
63146322
Bits.AbstractFunctionDecl.Throws = Throws;
63156323
Bits.AbstractFunctionDecl.HasSingleExpressionBody = false;
63166324
Bits.AbstractFunctionDecl.HasNestedTypeDeclarations = false;
6325+
Bits.AbstractFunctionDecl.DistributedThunk = false;
63176326
}
63186327

63196328
void setBodyKind(BodyKind K) {
@@ -6415,6 +6424,16 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
64156424
/// Returns 'true' if the function is distributed.
64166425
bool isDistributed() const;
64176426

6427+
/// Is this a thunk function used to access a distributed method
6428+
/// or computed property outside of its actor isolation context?
6429+
bool isDistributedThunk() const {
6430+
return Bits.AbstractFunctionDecl.DistributedThunk;
6431+
}
6432+
6433+
void setDistributedThunk(bool isThunk) {
6434+
Bits.AbstractFunctionDecl.DistributedThunk = isThunk;
6435+
}
6436+
64186437
/// For a 'distributed' target (func or computed property),
64196438
/// get the 'thunk' responsible for performing the 'remoteCall'.
64206439
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4833,6 +4833,9 @@ ERROR(distributed_property_cannot_be_static,none,
48334833
ERROR(distributed_property_can_only_be_computed,none,
48344834
"%0 %1 cannot be 'distributed', only computed properties can",
48354835
(DescriptiveDeclKind, DeclName))
4836+
ERROR(distributed_property_accessor_only_get_can_be_distributed,none,
4837+
"only 'get' accessors may be 'distributed'",
4838+
())
48364839
NOTE(distributed_actor_isolated_property,none,
48374840
"access to %0 %1 is only permitted within distributed actor %2",
48384841
(DescriptiveDeclKind, DeclName, DeclName))

include/swift/AST/Expr.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ enum class AccessSemantics : uint8_t {
124124
/// This is an ordinary access to a declaration, using whatever
125125
/// polymorphism is expected.
126126
Ordinary,
127+
128+
/// This is an access to the underlying storage through a distributed thunk.
129+
///
130+
/// The declaration must be a 'distributed' computed property used outside
131+
/// of its actor isolation context.
132+
DistributedThunk,
127133
};
128134

129135
/// Expr - Base class for all expressions in swift.
@@ -1684,6 +1690,14 @@ class MemberRefExpr : public LookupExpr {
16841690
return (AccessSemantics) Bits.MemberRefExpr.Semantics;
16851691
}
16861692

1693+
/// Informs IRGen to that this member should be applied via its distributed
1694+
/// thunk, rather than invoking it directly.
1695+
///
1696+
/// Only intended to be set on distributed get-only computed properties.
1697+
void setAccessViaDistributedThunk() {
1698+
Bits.MemberRefExpr.Semantics = (unsigned)AccessSemantics::DistributedThunk;
1699+
}
1700+
16871701
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
16881702
SourceLoc getStartLoc() const {
16891703
SourceLoc BaseStartLoc = getBase()->getStartLoc();

include/swift/AST/StorageImpl.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ class AccessStrategy {
110110
/// separately performing a Read into a temporary variable followed by
111111
/// a Write access back into the storage.
112112
MaterializeToTemporary,
113+
114+
/// The access is to a computed distributed property, and thus the
115+
/// get-accessor is a distributed thunk which may perform a remote call.
116+
DispatchToDistributedThunk,
113117
};
114118

115119
private:
@@ -149,6 +153,10 @@ class AccessStrategy {
149153
return { dispatched ? DispatchToAccessor : DirectToAccessor, accessor };
150154
}
151155

156+
static AccessStrategy getDistributedThunkDispatchStrategy() {
157+
return {DispatchToDistributedThunk, AccessorKind::Get};
158+
}
159+
152160
static AccessStrategy getMaterializeToTemporary(AccessStrategy read,
153161
AccessStrategy write) {
154162
return { read, write };
@@ -157,7 +165,8 @@ class AccessStrategy {
157165
Kind getKind() const { return TheKind; }
158166

159167
bool hasAccessor() const {
160-
return TheKind == DirectToAccessor || TheKind == DispatchToAccessor;
168+
return TheKind == DirectToAccessor || TheKind == DispatchToAccessor ||
169+
TheKind == DispatchToDistributedThunk;
161170
}
162171

163172
AccessorKind getAccessor() const {

include/swift/AST/TypeCheckRequests.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,17 +1279,22 @@ class GetDistributedRemoteCallArgumentInitFunctionRequest :
12791279
///
12801280
/// The thunk is responsible for invoking 'remoteCall' when invoked on a remote
12811281
/// 'distributed actor'.
1282-
class GetDistributedThunkRequest :
1283-
public SimpleRequest<GetDistributedThunkRequest,
1284-
FuncDecl *(AbstractFunctionDecl *),
1285-
RequestFlags::Cached> {
1282+
class GetDistributedThunkRequest
1283+
: public SimpleRequest<GetDistributedThunkRequest,
1284+
FuncDecl *(
1285+
llvm::PointerUnion<AbstractStorageDecl *,
1286+
AbstractFunctionDecl *>),
1287+
RequestFlags::Cached> {
1288+
using Originator =
1289+
llvm::PointerUnion<AbstractStorageDecl *, AbstractFunctionDecl *>;
1290+
12861291
public:
12871292
using SimpleRequest::SimpleRequest;
12881293

12891294
private:
12901295
friend SimpleRequest;
12911296

1292-
FuncDecl *evaluate(Evaluator &evaluator, AbstractFunctionDecl *distributedFunc) const;
1297+
FuncDecl *evaluate(Evaluator &evaluator, Originator originator) const;
12931298

12941299
public:
12951300
// Caching

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationResultHandlerOnReturnFu
137137
AbstractFunctionDecl *(NominalTypeDecl *),
138138
Cached, NoLocationInfo)
139139
SWIFT_REQUEST(TypeChecker, GetDistributedThunkRequest,
140-
FuncDecl *(AbstractFunctionDecl *),
140+
FuncDecl *(llvm::PointerUnion<AbstractStorageDecl *, AbstractFunctionDecl *>),
141141
Cached, NoLocationInfo)
142142
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest,
143143
VarDecl *(NominalTypeDecl *),

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ static StringRef getAccessSemanticsString(AccessSemantics value) {
255255
case AccessSemantics::Ordinary: return "ordinary";
256256
case AccessSemantics::DirectToStorage: return "direct_to_storage";
257257
case AccessSemantics::DirectToImplementation: return "direct_to_impl";
258+
case AccessSemantics::DistributedThunk: return "distributed_thunk";
258259
}
259260

260261
llvm_unreachable("Unhandled AccessSemantics in switch.");
@@ -742,6 +743,8 @@ namespace {
742743

743744
void visitVarDecl(VarDecl *VD) {
744745
printCommon(VD, "var_decl");
746+
if (VD->isDistributed())
747+
PrintWithColorRAII(OS, DeclModifierColor) << " distributed";
745748
if (VD->isLet())
746749
PrintWithColorRAII(OS, DeclModifierColor) << " let";
747750
if (VD->getAttrs().hasAttribute<LazyAttr>())
@@ -872,6 +875,9 @@ namespace {
872875
if (D->isDistributed()) {
873876
PrintWithColorRAII(OS, ExprModifierColor) << " distributed";
874877
}
878+
if (D->isDistributedThunk()) {
879+
PrintWithColorRAII(OS, ExprModifierColor) << " distributed-thunk";
880+
}
875881

876882
if (auto fac = D->getForeignAsyncConvention()) {
877883
OS << " foreign_async=";

lib/AST/ASTMangler.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3484,10 +3484,33 @@ ASTMangler::mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl) {
34843484
return finalize();
34853485
}
34863486

3487-
std::string ASTMangler::mangleDistributedThunk(const FuncDecl *thunk) {
3487+
std::string ASTMangler::mangleDistributedThunk(const AbstractFunctionDecl *thunk) {
34883488
// Marker protocols cannot be checked at runtime, so there is no point
34893489
// in recording them for distributed thunks.
34903490
llvm::SaveAndRestore<bool> savedAllowMarkerProtocols(AllowMarkerProtocols,
34913491
false);
3492+
3493+
// Since computed property SILDeclRef's refer to the "originator"
3494+
// of the thunk, we need to mangle distributed thunks of accessors
3495+
// specially.
3496+
if (auto *accessor = dyn_cast<AccessorDecl>(thunk)) {
3497+
// TODO: This needs to use accessor type instead of
3498+
// distributed thunk after all SILDeclRefs are switched
3499+
// to use "originator" instead of the thunk itself.
3500+
//
3501+
// ```
3502+
// beginMangling();
3503+
// appendContextOf(thunk);
3504+
// appendDeclName(accessor->getStorage());
3505+
// appendDeclType(accessor, FunctionMangling);
3506+
// appendOperator("F");
3507+
// appendSymbolKind(SymbolKind::DistributedThunk);
3508+
// return finalize();
3509+
// ```
3510+
auto *storage = accessor->getStorage();
3511+
thunk = storage->getDistributedThunk();
3512+
assert(thunk);
3513+
}
3514+
34923515
return mangleEntity(thunk, SymbolKind::DistributedThunk);
34933516
}

0 commit comments

Comments
 (0)