Skip to content

Commit 20d39d7

Browse files
committed
[Distributed] Add a new access strategy - DispatchToDistributedThunk
This strategy is used to dispatch accesses to 'distributed' computed property to distributed thunk accessor instead of a regular getter when access happen outside actor isolation context.
1 parent 36572d9 commit 20d39d7

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

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 {

lib/AST/Decl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,10 +2272,8 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
22722272
assert(hasStorage());
22732273
return AccessStrategy::getStorage();
22742274

2275-
// FIXME: For now `DistributedThunk` behaves just like `Ordinary` but it
2276-
// needs a new strategy to be useful.
22772275
case AccessSemantics::DistributedThunk:
2278-
LLVM_FALLTHROUGH;
2276+
return AccessStrategy::getDistributedThunkDispatchStrategy();
22792277

22802278
case AccessSemantics::Ordinary:
22812279
// Skip these checks for local variables, both because they're unnecessary

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ SILGenModule::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
18391839
case AccessStrategy::DirectToAccessor:
18401840
case AccessStrategy::DispatchToAccessor:
18411841
case AccessStrategy::MaterializeToTemporary:
1842+
case AccessStrategy::DispatchToDistributedThunk:
18421843
return false;
18431844
}
18441845
llvm_unreachable("unhandled strategy");

lib/SILGen/SILGenExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,14 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
35083508
// Identify the property by its vtable or wtable slot.
35093509
return SGM.getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage));
35103510
}
3511+
3512+
case AccessStrategy::DispatchToDistributedThunk: {
3513+
auto thunkRef = SILDeclRef(cast<VarDecl>(storage)->getDistributedThunk(),
3514+
SILDeclRef::Kind::Func,
3515+
/*isForeign=*/false,
3516+
/*isDistributed=*/true);
3517+
return SGM.getFunction(thunkRef, NotForDefinition);
3518+
}
35113519
}
35123520
llvm_unreachable("unhandled access strategy");
35133521
}

lib/SILGen/SILGenLValue.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,6 +2683,9 @@ namespace {
26832683
strategy.getWriteStrategy(),
26842684
typeData);
26852685
}
2686+
2687+
case AccessStrategy::DispatchToDistributedThunk:
2688+
return asImpl().emitUsingDistributedThunk();
26862689
}
26872690
llvm_unreachable("unknown kind");
26882691
}
@@ -2888,6 +2891,11 @@ void LValue::addNonMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
28882891
if (address.getType().is<ReferenceStorageType>())
28892892
LV.add<OwnershipComponent>(typeData);
28902893
}
2894+
2895+
void emitUsingDistributedThunk() {
2896+
llvm_unreachable("cannot dispatch non-member var via distributed thunk");
2897+
}
2898+
28912899
} emitter(SGF, loc, var, subs, accessKind, formalRValueType, options,
28922900
actorIso, *this);
28932901

@@ -3183,11 +3191,11 @@ static SGFAccessKind getBaseAccessKind(SILGenModule &SGM,
31833191
}
31843192

31853193
case AccessStrategy::DirectToAccessor:
3186-
case AccessStrategy::DispatchToAccessor: {
3194+
case AccessStrategy::DispatchToAccessor:
3195+
case AccessStrategy::DispatchToDistributedThunk: {
31873196
auto accessor = member->getOpaqueAccessor(strategy.getAccessor());
31883197
return getBaseAccessKindForAccessor(SGM, accessor, baseFormalType);
31893198
}
3190-
31913199
}
31923200
llvm_unreachable("bad access strategy");
31933201
}
@@ -3395,6 +3403,19 @@ void LValue::addMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
33953403
LV.add<OwnershipComponent>(typeData);
33963404
}
33973405
}
3406+
3407+
void emitUsingDistributedThunk() {
3408+
auto *var = cast<VarDecl>(Storage);
3409+
SILDeclRef accessor(var->getDistributedThunk(), SILDeclRef::Kind::Func,
3410+
/*isForeign=*/false, /*isDistributed=*/true);
3411+
3412+
auto typeData = getLogicalStorageTypeData(
3413+
SGF.getTypeExpansionContext(), SGF.SGM, AccessKind, FormalRValueType);
3414+
3415+
asImpl().emitUsingGetterSetter(accessor, /*isDirect=*/false,
3416+
/*isDistributed=*/true, typeData);
3417+
}
3418+
33983419
} emitter(SGF, loc, var, subs, isSuper, accessKind,
33993420
formalRValueType, options, *this,
34003421
/*indices for diags*/ nullptr, /*indices*/ PreparedArguments(),
@@ -3570,6 +3591,10 @@ void LValue::addMemberSubscriptComponent(SILGenFunction &SGF, SILLocation loc,
35703591
void emitUsingStorage(LValueTypeData typeData) {
35713592
llvm_unreachable("subscripts never have storage");
35723593
}
3594+
3595+
void emitUsingDistributedThunk() {
3596+
llvm_unreachable("subscripts cannot be dispatch via distributed thunk");
3597+
}
35733598
} emitter(SGF, loc, decl, subs, isSuper, accessKind, formalRValueType,
35743599
options, *this, argListForDiagnostics, std::move(indices),
35753600
isOnSelfParameter, actorIso);

0 commit comments

Comments
 (0)