Skip to content

Commit efb889e

Browse files
committed
[Distributed] Skeleton implementation of distributed computed properties
1 parent 473d440 commit efb889e

20 files changed

+374
-87
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/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: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
155155

156156
SWIFT_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
157157
SWIFT_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
158-
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1+1+1,
158+
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1+1+1+1,
159159
IsSuper : 1,
160160
IsImplicitlyAsync : 1,
161-
IsImplicitlyThrows : 1
161+
IsImplicitlyThrows : 1,
162+
ShouldApplyDistributedThunk: 1
162163
);
163164
SWIFT_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);
164165

@@ -1655,6 +1656,18 @@ class LookupExpr : public Expr {
16551656
Bits.LookupExpr.IsImplicitlyThrows = isImplicitlyThrows;
16561657
}
16571658

1659+
/// Informs IRGen to that this expression should be applied as its distributed
1660+
/// thunk, rather than invoking the function directly.
1661+
///
1662+
/// Only intended to be set on distributed get-only computed properties.
1663+
bool shouldApplyLookupDistributedThunk() const {
1664+
return Bits.LookupExpr.ShouldApplyDistributedThunk;
1665+
}
1666+
1667+
void setShouldApplyLookupDistributedThunk(bool flag) {
1668+
Bits.LookupExpr.ShouldApplyDistributedThunk = flag;
1669+
}
1670+
16581671
static bool classof(const Expr *E) {
16591672
return E->getKind() >= ExprKind::First_LookupExpr &&
16601673
E->getKind() <= ExprKind::Last_LookupExpr;

include/swift/AST/StorageImpl.h

Lines changed: 8 additions & 0 deletions
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+
// DirectToDistributedThunkAccessor,
113117
};
114118

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

156+
// static AccessStrategy getDistributedGetAccessor(AccessorKind accessor) {
157+
// assert(accessor == AccessorKind::Get);
158+
// return { DirectToDistributedThunkAccessor, accessor };
159+
// }
152160
static AccessStrategy getMaterializeToTemporary(AccessStrategy read,
153161
AccessStrategy write) {
154162
return { read, write };

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ namespace {
742742

743743
void visitVarDecl(VarDecl *VD) {
744744
printCommon(VD, "var_decl");
745+
if (VD->isDistributed())
746+
PrintWithColorRAII(OS, DeclModifierColor) << " distributed";
745747
if (VD->isLet())
746748
PrintWithColorRAII(OS, DeclModifierColor) << " let";
747749
if (VD->getAttrs().hasAttribute<LazyAttr>())
@@ -2020,6 +2022,9 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
20202022

20212023
void visitMemberRefExpr(MemberRefExpr *E) {
20222024
printCommon(E, "member_ref_expr");
2025+
if (E->shouldApplyLookupDistributedThunk()) {
2026+
OS << " distributed";
2027+
}
20232028
PrintWithColorRAII(OS, DeclColor) << " decl=";
20242029
printDeclRef(E->getMember());
20252030
if (E->getAccessSemantics() != AccessSemantics::Ordinary)

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3484,7 +3484,7 @@ 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,

lib/AST/Decl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,17 @@ getDirectReadAccessStrategy(const AbstractStorageDecl *storage) {
21382138
llvm_unreachable("bad impl kind");
21392139
}
21402140

2141+
//static AccessStrategy
2142+
//getDirectToDistributedThunkAccessorStrategy(const AbstractStorageDecl *storage) {
2143+
// switch (storage->getReadImpl()) {
2144+
// case ReadImplKind::Get:
2145+
// return AccessStrategy::getDistributedGetAccessor(AccessorKind::Get);
2146+
// default:
2147+
// llvm_unreachable("bad impl kind for distributed property accessor");
2148+
// }
2149+
// llvm_unreachable("bad impl kind for distributed property accessor");
2150+
//}
2151+
21412152
static AccessStrategy
21422153
getDirectWriteAccessStrategy(const AbstractStorageDecl *storage) {
21432154
switch (storage->getWriteImpl()) {
@@ -2271,6 +2282,14 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
22712282
if (shouldUseNativeDynamicDispatch())
22722283
return getOpaqueAccessStrategy(this, accessKind, /*dispatch*/ false);
22732284

2285+
// if (auto var = dyn_cast<VarDecl>(this)) {
2286+
// if (var->isDistributed()) {
2287+
// fprintf(stderr, "[%s:%d] (%s) DIST STRATEGY!!\n", __FILE__, __LINE__, __FUNCTION__);
2288+
// var->dump();
2289+
// return getDirectToDistributedThunkAccessorStrategy(this);
2290+
// }
2291+
// }
2292+
22742293
// If the storage is resilient from the given module and resilience
22752294
// expansion, we cannot use direct access.
22762295
//

lib/SILGen/SILGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,9 @@ void SILGenModule::visitVarDecl(VarDecl *vd) {
17661766
if (vd->hasStorage())
17671767
addGlobalVariable(vd);
17681768

1769+
fprintf(stderr, "[%s:%d] (%s) VISIT VAR DECL\n", __FILE__, __LINE__, __FUNCTION__);
1770+
vd->dump();
1771+
17691772
vd->visitEmittedAccessors([&](AccessorDecl *accessor) {
17701773
emitFunction(accessor);
17711774
});
@@ -1832,6 +1835,7 @@ SILGenModule::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
18321835
case AccessStrategy::DirectToAccessor:
18331836
case AccessStrategy::DispatchToAccessor:
18341837
case AccessStrategy::MaterializeToTemporary:
1838+
// case AccessStrategy::DirectToDistributedThunkAccessor:
18351839
return false;
18361840
}
18371841
llvm_unreachable("unhandled strategy");

lib/SILGen/SILGenApply.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
10871087

10881088
// If this is a direct reference to a vardecl, just emit its value directly.
10891089
// Recursive references to callable declarations are allowed.
1090-
if (isa<VarDecl>(e->getDecl())) {
1090+
if (auto var = dyn_cast<VarDecl>(e->getDecl())) {
10911091
visitExpr(e);
10921092
return;
10931093
}
@@ -1123,6 +1123,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11231123

11241124
/// Some special handling may be necessary for thunks:
11251125
if (callSite && callSite->shouldApplyDistributedThunk()) {
1126+
fprintf(stderr, "[%s:%d] (%s) SHOULD APPLY DIST THUNK\n", __FILE__, __LINE__, __FUNCTION__);
1127+
11261128
if (auto distributedThunk = cast<AbstractFunctionDecl>(e->getDecl())->getDistributedThunk()) {
11271129
constant = SILDeclRef(distributedThunk).asDistributed();
11281130
}
@@ -5366,6 +5368,7 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &SGF,
53665368
ArgumentSource &selfValue,
53675369
bool isSuper,
53685370
bool isDirectUse,
5371+
bool isDistributed,
53695372
SubstitutionMap subs,
53705373
bool isOnSelfParameter) {
53715374
auto *decl = cast<AbstractFunctionDecl>(constant.getDecl());
@@ -5445,12 +5448,13 @@ emitSpecializedAccessorFunctionRef(SILGenFunction &SGF,
54455448
ArgumentSource &selfValue,
54465449
bool isSuper,
54475450
bool isDirectUse,
5451+
bool isDistributed,
54485452
bool isOnSelfParameter)
54495453
{
54505454
// Get the accessor function. The type will be a polymorphic function if
54515455
// the Self type is generic.
54525456
Callee callee = getBaseAccessorFunctionRef(SGF, loc, constant, selfValue,
5453-
isSuper, isDirectUse,
5457+
isSuper, isDirectUse, isDistributed,
54545458
substitutions, isOnSelfParameter);
54555459

54565460
// Collect captures if the accessor has them.
@@ -5762,15 +5766,23 @@ SILDeclRef SILGenModule::getAccessorDeclRef(AccessorDecl *accessor) {
57625766
RValue SILGenFunction::emitGetAccessor(SILLocation loc, SILDeclRef get,
57635767
SubstitutionMap substitutions,
57645768
ArgumentSource &&selfValue, bool isSuper,
5765-
bool isDirectUse,
5769+
bool isDirectUse, bool isDistributed,
57665770
PreparedArguments &&subscriptIndices,
5767-
SGFContext c, bool isOnSelfParameter) {
5771+
SGFContext c,
5772+
bool isOnSelfParameter) {
57685773
// Scope any further writeback just within this operation.
57695774
FormalEvaluationScope writebackScope(*this);
57705775

5776+
auto constant = get;
5777+
5778+
// if (isDistributed) {
5779+
// get.dump();
5780+
// assert(false && "should use dist thunk");
5781+
// }
5782+
57715783
Callee getter = emitSpecializedAccessorFunctionRef(
5772-
*this, loc, get, substitutions, selfValue, isSuper, isDirectUse,
5773-
isOnSelfParameter);
5784+
*this, loc, constant, substitutions, selfValue, isSuper, isDirectUse,
5785+
isDistributed, isOnSelfParameter);
57745786
bool hasSelf = (bool)selfValue;
57755787
CanAnyFunctionType accessType = getter.getSubstFormalType();
57765788

@@ -5803,7 +5815,7 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set,
58035815

58045816
Callee setter = emitSpecializedAccessorFunctionRef(
58055817
*this, loc, set, substitutions, selfValue, isSuper, isDirectUse,
5806-
isOnSelfParameter);
5818+
/*isDistributed=*/false, isOnSelfParameter);
58075819
bool hasSelf = (bool)selfValue;
58085820
CanAnyFunctionType accessType = setter.getSubstFormalType();
58095821

@@ -5838,14 +5850,14 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set,
58385850
ManagedValue SILGenFunction::emitAddressorAccessor(
58395851
SILLocation loc, SILDeclRef addressor, SubstitutionMap substitutions,
58405852
ArgumentSource &&selfValue, bool isSuper, bool isDirectUse,
5841-
PreparedArguments &&subscriptIndices, SILType addressType,
5842-
bool isOnSelfParameter) {
5853+
bool isDistributed, PreparedArguments &&subscriptIndices,
5854+
SILType addressType, bool isOnSelfParameter) {
58435855
// Scope any further writeback just within this operation.
58445856
FormalEvaluationScope writebackScope(*this);
58455857

58465858
Callee callee = emitSpecializedAccessorFunctionRef(
58475859
*this, loc, addressor, substitutions, selfValue, isSuper, isDirectUse,
5848-
isOnSelfParameter);
5860+
isDistributed, isOnSelfParameter);
58495861
bool hasSelf = (bool)selfValue;
58505862
CanAnyFunctionType accessType = callee.getSubstFormalType();
58515863

@@ -5900,7 +5912,9 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
59005912
Callee callee =
59015913
emitSpecializedAccessorFunctionRef(*this, loc, accessor,
59025914
substitutions, selfValue,
5903-
isSuper, isDirectUse, isOnSelfParameter);
5915+
isSuper, isDirectUse,
5916+
/*isDistributed=*/false,
5917+
isOnSelfParameter);
59045918

59055919
// We're already in a full formal-evaluation scope.
59065920
// Make a dead writeback scope; applyCoroutine won't try to pop this.

0 commit comments

Comments
 (0)