Skip to content

Commit c4622a2

Browse files
authored
Merge pull request #71099 from gottesmm/pr-387f6b4fba6f40c5cb78dd54f3fd718902f9d38d
[region-isolation] Make it so that we only propagate actor self if the callee takes self as isolated.
2 parents 6c27021 + bfc12c5 commit c4622a2

33 files changed

+330
-125
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,8 @@ enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedTypeAttrKind : size_t {
12061206
BridgedTypeAttrKind_moveOnly,
12071207
BridgedTypeAttrKind_thin,
12081208
BridgedTypeAttrKind_thick,
1209-
BridgedTypeAttrKind_Count
1209+
BridgedTypeAttrKind_Count,
1210+
BridgedTypeAttrKind_isolated,
12101211
};
12111212

12121213
SWIFT_NAME("BridgedTypeAttrKind.init(from:)")

include/swift/AST/Attr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ TYPE_ATTR(yield_many)
9999
TYPE_ATTR(captures_generics)
100100
// Used at the SIL level to mark a type as moveOnly.
101101
TYPE_ATTR(moveOnly)
102+
TYPE_ATTR(isolated)
102103

103104
// SIL metatype attributes.
104105
TYPE_ATTR(thin)

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
291291
bool visitComponent(CanType type1, CanType type2,
292292
SILParameterInfo param1, SILParameterInfo param2) {
293293
if (param1.getConvention() != param2.getConvention() ||
294-
param1.getOptions().containsOnly(param2.getOptions()))
294+
!param1.getOptions().containsOnly(param2.getOptions()))
295295
return asImpl().visitDifferentTypeStructure(type1, type2);
296296

297297
return asImpl().visit(param1.getInterfaceType(),
@@ -410,6 +410,7 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
410410
return asImpl().visit(CanType(componentType1), CanType(componentType2));
411411
}
412412

413+
protected:
413414
template <class T>
414415
bool visitComponentArray(CanType type1, CanType type2, T array1, T array2) {
415416
if (array1.size() != array2.size())

include/swift/AST/Types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4129,6 +4129,9 @@ class SILParameterInfo {
41294129

41304130
/// Set if the given parameter is transferring.
41314131
Transferring = 0x2,
4132+
4133+
/// Set if the given parameter is isolated.
4134+
Isolated = 0x4,
41324135
};
41334136

41344137
using Options = OptionSet<Flag>;

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8086,6 +8086,11 @@ void SILParameterInfo::print(ASTPrinter &Printer,
80868086
Printer << "@transferring ";
80878087
}
80888088

8089+
if (options.contains(SILParameterInfo::Isolated)) {
8090+
options -= SILParameterInfo::Isolated;
8091+
Printer << "@isolated ";
8092+
}
8093+
80898094
// If we did not handle a case in Options, this code was not updated
80908095
// appropriately.
80918096
assert(!bool(options) && "Code not updated for introduced option");

lib/AST/TypeRepr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ void AttributedTypeRepr::printAttrs(ASTPrinter &Printer,
236236
Printer.printSimpleAttr("@Sendable") << " ";
237237
if (hasAttr(TAK_noDerivative))
238238
Printer.printSimpleAttr("@noDerivative") << " ";
239+
if (hasAttr(TAK_isolated))
240+
Printer.printSimpleAttr("@isolated") << " ";
239241

240242
if (hasAttr(TAK_differentiable)) {
241243
Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ extension ASTGenVisitor {
415415
.sil_weak, .sil_unowned, .inout, .block_storage, .box,
416416
.dynamic_self, .sil_unmanaged, .error, .error_indirect,
417417
.error_unowned, .direct, .inout_aliasable,
418-
.in_guaranteed, .in_constant, .captures_generics, .moveOnly:
418+
.in_guaranteed, .in_constant, .captures_generics, .moveOnly,
419+
.isolated:
419420
fallthrough
420421

421422
case .autoclosure, .escaping, .noescape, .noDerivative, .async,

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,8 @@ class DestructureInputs {
17371737
param = param.addingOption(SILParameterInfo::NotDifferentiable);
17381738
if (origFlags.isTransferring())
17391739
param = param.addingOption(SILParameterInfo::Transferring);
1740+
if (origFlags.isIsolated())
1741+
param = param.addingOption(SILParameterInfo::Isolated);
17401742

17411743
Inputs.push_back(param);
17421744
maybeAddForeignParameters();

lib/SILGen/SILGenThunk.cpp

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/ForeignAsyncConvention.h"
3333
#include "swift/AST/ForeignErrorConvention.h"
3434
#include "swift/AST/GenericEnvironment.h"
35+
#include "swift/AST/TypeDifferenceVisitor.h"
3536
#include "swift/Basic/STLExtras.h"
3637
#include "swift/SIL/FormalLinkage.h"
3738
#include "swift/SIL/PrettyStackTrace.h"
@@ -139,6 +140,51 @@ void SILGenModule::emitBackDeploymentThunk(SILDeclRef thunk) {
139140
emitFunctionDefinition(thunk, getFunction(thunk, ForDefinition));
140141
}
141142

143+
namespace {
144+
145+
/// Checker that validates that a distributed thunk is completely the same
146+
/// except that self can vary by isolation.
147+
struct DistributedThunkDiffChecker
148+
: CanTypeDifferenceVisitor<DistributedThunkDiffChecker> {
149+
using SuperTy = CanTypeDifferenceVisitor<DistributedThunkDiffChecker>;
150+
151+
bool visitSILFunctionTypeComponents(CanSILFunctionType type1,
152+
CanSILFunctionType type2) {
153+
// If they do not both have a self param. Just delegate to our parent.
154+
if (!type1->hasSelfParam() || !type2->hasSelfParam()) {
155+
return SuperTy::visitSILFunctionTypeComponents(type1, type2);
156+
}
157+
158+
// Otherwise, we both have self. First check if we have the same number of
159+
// parameters.
160+
auto type1Params = type1->getParameters();
161+
auto type2Params = type2->getParameters();
162+
if (type1Params.size() != type2Params.size())
163+
return visitDifferentTypeStructure(type1, type2);
164+
165+
// Then check if self is the same ignoring isolation.
166+
auto self1 = type1Params.back();
167+
auto self2 = type2Params.back();
168+
auto self1Options = self1.getOptions() - SILParameterInfo::Isolated;
169+
auto self2Options = self2.getOptions() - SILParameterInfo::Isolated;
170+
171+
if (self1.getConvention() != self2.getConvention() ||
172+
!self1Options.containsOnly(self2Options))
173+
return visitDifferentTypeStructure(type1, type2);
174+
175+
// Finally, check our self type, non-self components, results, and yields.
176+
return visit(self1.getInterfaceType(), self2.getInterfaceType()) ||
177+
visitComponentArray(type1, type2, type1Params.drop_back(),
178+
type2Params.drop_back()) ||
179+
visitComponentArray(type1, type2, type1->getResults(),
180+
type2->getResults()) ||
181+
visitComponentArray(type1, type2, type1->getYields(),
182+
type2->getYields());
183+
}
184+
};
185+
186+
} // namespace
187+
142188
SILValue
143189
SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
144190
SILConstantInfo constantInfo,
@@ -171,18 +217,35 @@ SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
171217
auto existingType =
172218
f->getLoweredFunctionTypeInContext(B.getTypeExpansionContext());
173219
if (existingType != constantFnTypeInContext) {
174-
// This can happen for example when using @_silgen_name or @_extern(c)
175-
// attributes
176-
SGM.diagnose(loc.getSourceLoc(), diag::function_type_mismatch, existingType,
177-
constantFnTypeInContext);
178-
SGM.diagnose(f->getLocation().getSourceLoc(), diag::function_declared_here);
179-
return SILUndef::get(constantInfo.getSILType(), F);
220+
auto emitError = [&] {
221+
// This can happen for example when using @_silgen_name or @_extern(c)
222+
// attributes
223+
SGM.diagnose(loc.getSourceLoc(), diag::function_type_mismatch,
224+
existingType, constantFnTypeInContext);
225+
SGM.diagnose(f->getLocation().getSourceLoc(),
226+
diag::function_declared_here);
227+
return SILUndef::get(constantInfo.getSILType(), F);
228+
};
229+
230+
// If we have a distributed thunk, see if we only differ by isolation.
231+
if (f->isDistributed() && f->isThunk()) {
232+
DistributedThunkDiffChecker diffChecker;
233+
if (diffChecker.visit(existingType, constantFnTypeInContext)) {
234+
return emitError();
235+
}
236+
237+
// We differ only by isolation... so do not error.
238+
} else {
239+
// This can happen for example when using @_silgen_name or @_extern(c)
240+
// attributes
241+
return emitError();
242+
}
180243
}
181244

182245
if (callPreviousDynamicReplaceableImpl)
183246
return B.createPreviousDynamicFunctionRef(loc, f);
184-
else
185-
return B.createFunctionRefFor(loc, f);
247+
248+
return B.createFunctionRefFor(loc, f);
186249
}
187250

188251
static const clang::Type *prependParameterType(

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,10 +1619,14 @@ class PartitionOpTranslator {
16191619

16201620
void translateNonIsolationCrossingSILApply(FullApplySite fas) {
16211621
SILMultiAssignOptions options;
1622+
1623+
// If self is an actor and we are isolated to it, propagate actor self.
16221624
if (fas.hasSelfArgument()) {
1623-
if (auto self = fas.getSelfArgument()) {
1624-
if (self->getType().isActor())
1625-
options |= SILMultiAssignFlags::PropagatesActorSelf;
1625+
auto &self = fas.getSelfArgumentOperand();
1626+
if (self.get()->getType().isActor() &&
1627+
fas.getArgumentParameterInfo(self).hasOption(
1628+
SILParameterInfo::Isolated)) {
1629+
options |= SILMultiAssignFlags::PropagatesActorSelf;
16261630
}
16271631
}
16281632

0 commit comments

Comments
 (0)