Skip to content

Commit bdc9cf2

Browse files
committed
[silgen] Use Builtin.ImplicitIsolationActor instead of Optional<any Actor> to represent the implicit isolated parameter.
NOTE: We are not performing any bitmasking at all now. This is so that we can transition the code base/tests to expect Builtin.ImplicitIsolationActor instead of Optional<any Actor>. NOTE: The actual test changes are in the next commit. I did this to make it easier to review the changes. This should not have any user visible changes.
1 parent 09d2f27 commit bdc9cf2

16 files changed

+373
-106
lines changed

include/swift/SIL/ConcurrencyUtils.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===--- ConcurrencyUtils.h -----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SIL_CONCURRENCYUTILS_H
14+
#define SWIFT_SIL_CONCURRENCYUTILS_H
15+
16+
#include "swift/SIL/SILType.h"
17+
18+
namespace swift {
19+
20+
class SILValue;
21+
class SILBuilder;
22+
class SILLocation;
23+
24+
/// Clear the implicit isolated bits of value.
25+
///
26+
/// \p value must be Builtin.ImplicitIsolationActor
27+
///
28+
/// \p finalType if empty, we always return
29+
/// Builtin.ImplicitIsolationActor. Otherwise we bitcast to finalType after
30+
/// tieing the lifetime of the result to \p value.
31+
SILValue clearImplicitIsolationActorBits(SILBuilder &b, SILLocation loc,
32+
SILValue value,
33+
SILType finalType = {});
34+
35+
SILValue setImplicitIsolationActorBits(SILBuilder &b, SILLocation loc,
36+
SILValue value);
37+
38+
} // namespace swift
39+
40+
#endif

include/swift/SIL/SILBuilder.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,17 @@ class SILBuilder {
13341334
forwardingOwnershipKind));
13351335
}
13361336

1337+
/// Create an unchecked_value_cast when Ownership SSA is enabled and
1338+
/// unchecked_bitwise_cast otherwise.
1339+
///
1340+
/// Intended to be used in utility code that needs to support both Ownership
1341+
/// SSA and non-Ownership SSA code.
1342+
SILValue emitUncheckedValueCast(SILLocation loc, SILValue op, SILType ty) {
1343+
if (hasOwnership())
1344+
return createUncheckedValueCast(loc, op, ty);
1345+
return createUncheckedBitwiseCast(loc, op, ty);
1346+
}
1347+
13371348
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
13381349
SILValue Bits) {
13391350
return createRefToBridgeObject(Loc, Ref, Bits, Ref->getOwnershipKind());

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,11 +1704,7 @@ class DestructureInputs {
17041704
// require it.
17051705
if (IsolationInfo && IsolationInfo->isCallerIsolationInheriting() &&
17061706
extInfoBuilder.isAsync() && !Foreign.async) {
1707-
auto actorProtocol = TC.Context.getProtocol(KnownProtocolKind::Actor);
1708-
auto actorType =
1709-
ExistentialType::get(actorProtocol->getDeclaredInterfaceType());
1710-
addParameter(-1,
1711-
CanType(actorType).wrapInOptionalType(),
1707+
addParameter(-1, CanType(TC.Context.TheImplicitIsolationActorType),
17121708
ParameterConvention::Direct_Guaranteed,
17131709
ParameterTypeFlags().withIsolated(true),
17141710
true /*implicit leading parameter*/);

lib/SIL/IR/TypeLowering.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,6 +2382,18 @@ namespace {
23822382
UnsafeValueBufferTypeLowering(silType, Expansion, isSensitive);
23832383
}
23842384

2385+
TypeLowering *visitBuiltinImplicitIsolationActorType(
2386+
CanBuiltinImplicitIsolationActorType type, AbstractionPattern origType,
2387+
IsTypeExpansionSensitive_t isSensitive) {
2388+
auto silType = SILType::getPrimitiveObjectType(type);
2389+
auto properties = SILTypeProperties();
2390+
properties.setTypeExpansionSensitive(isSensitive);
2391+
properties.setNonTrivial();
2392+
properties.setLexical(IsLexical);
2393+
return new (TC)
2394+
MiscNontrivialTypeLowering(silType, properties, Expansion);
2395+
}
2396+
23852397
TypeLowering *visitPackType(CanPackType packType,
23862398
AbstractionPattern origType,
23872399
IsTypeExpansionSensitive_t isSensitive) {

lib/SIL/Utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ target_sources(swiftSIL PRIVATE
22
BasicBlockUtils.cpp
33
BitDataflow.cpp
44
CalleeCache.cpp
5+
ConcurrencyUtils.cpp
56
DebugUtils.cpp
67
Dominance.cpp
78
DynamicCasts.cpp

lib/SIL/Utils/ConcurrencyUtils.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- ConcurrencyUtils.cpp ---------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/SIL/ConcurrencyUtils.h"
14+
15+
#include "swift/SIL/SILBuilder.h"
16+
#include "swift/SIL/SILLocation.h"
17+
18+
using namespace swift;
19+
20+
SILValue swift::clearImplicitIsolationActorBits(SILBuilder &b, SILLocation loc,
21+
SILValue value,
22+
SILType finalType) {
23+
if (!finalType)
24+
finalType =
25+
SILType::getBuiltinImplicitIsolationActorType(b.getASTContext());
26+
if (value->getType() == finalType)
27+
return value;
28+
return b.emitUncheckedValueCast(loc, value, finalType);
29+
}
30+
31+
SILValue swift::setImplicitIsolationActorBits(SILBuilder &b, SILLocation loc,
32+
SILValue value) {
33+
return value;
34+
}

lib/SILGen/ConcurrencyUtils.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===--- ConcurrencyUtils.h -----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SILGEN_CONCURRENCYUTILS_H
14+
#define SWIFT_SILGEN_CONCURRENCYUTILS_H
15+
16+
#include "RValue.h"
17+
#include "SILGenFunction.h"
18+
19+
#include "swift/SIL/ConcurrencyUtils.h"
20+
21+
namespace swift {
22+
23+
class SILLocation;
24+
class Expr;
25+
26+
namespace Lowering {
27+
28+
class SILGenFunction;
29+
class RValue;
30+
class ManagedValue;
31+
32+
inline ManagedValue
33+
clearImplicitIsolationActorBits(SILGenFunction &SGF, SILLocation loc,
34+
ManagedValue implicitIsolatedActor,
35+
SILType type = {}) {
36+
return ManagedValue::forBorrowedRValue(clearImplicitIsolationActorBits(
37+
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue(), type));
38+
}
39+
40+
/// Clear the TBI bits if AArch64HasTBI is set. Otherwise clear the low tagged
41+
/// bits.
42+
///
43+
/// \param expr - the expression which yielded this r-value; its type
44+
/// will become the substituted formal type of this r-value
45+
/// \param implicitIsolatedActor should be an Optional<any Actor>.
46+
inline RValue
47+
clearImplicitIsolationActorBits(SILGenFunction &SGF, Expr *expr,
48+
ManagedValue implicitIsolatedActor,
49+
SILType type = {}) {
50+
return RValue(SGF, expr,
51+
clearImplicitIsolationActorBits(SGF, SILLocation(expr),
52+
implicitIsolatedActor, type));
53+
}
54+
55+
inline ManagedValue
56+
setImplicitIsolationActorBits(SILGenFunction &SGF, SILLocation loc,
57+
ManagedValue implicitIsolatedActor) {
58+
return ManagedValue::forBorrowedRValue(setImplicitIsolationActorBits(
59+
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue()));
60+
}
61+
62+
inline RValue
63+
setImplicitIsolationActorBits(SILGenFunction &SGF, Expr *expr,
64+
ManagedValue implicitIsolatedActor) {
65+
return RValue(SGF, expr,
66+
setImplicitIsolationActorBits(SGF, SILLocation(expr),
67+
implicitIsolatedActor));
68+
}
69+
70+
} // namespace Lowering
71+
72+
} // namespace swift
73+
74+
#endif

lib/SILGen/SILGenApply.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ArgumentScope.h"
1414
#include "ArgumentSource.h"
1515
#include "Callee.h"
16+
#include "ConcurrencyUtils.h"
1617
#include "Conversion.h"
1718
#include "ExecutorBreadcrumb.h"
1819
#include "FormalEvaluation.h"
@@ -5862,8 +5863,12 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
58625863
args.push_back({});
58635864
// NOTE: Even though this calls emitActorInstanceIsolation, this also
58645865
// handles glboal actor isolated cases.
5865-
args.back().push_back(SGF.emitActorInstanceIsolation(
5866-
callSite->Loc, executor, executor.getType().getASTType()));
5866+
auto erasedActor =
5867+
SGF.emitActorInstanceIsolation(callSite->Loc, executor,
5868+
executor.getType().getASTType())
5869+
.borrow(SGF, callSite->Loc);
5870+
args.back().push_back(
5871+
SGF.B.convertToImplicitIsolationActor(callSite->Loc, erasedActor));
58675872
}
58685873

58695874
uncurriedLoc = callSite->Loc;

lib/SILGen/SILGenBridging.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,23 +1667,22 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
16671667
isolatedParameter && isolatedParameter->hasOption(SILParameterInfo::ImplicitLeading)) {
16681668
assert(F.isAsync() && "Can only be async");
16691669
assert(isolation && "No isolation?!");
1670-
switch (isolation->getKind()) {
1671-
case ActorIsolation::Unspecified:
1672-
case ActorIsolation::Nonisolated:
1673-
case ActorIsolation::NonisolatedUnsafe:
1674-
case ActorIsolation::CallerIsolationInheriting:
1675-
args.push_back(emitNonIsolatedIsolation(loc).getValue());
1676-
break;
1677-
case ActorIsolation::ActorInstance:
1678-
llvm::report_fatal_error("Should never see this");
1679-
break;
1680-
case ActorIsolation::GlobalActor:
1681-
args.push_back(emitLoadGlobalActorExecutor(isolation->getGlobalActor()));
1682-
break;
1683-
case ActorIsolation::Erased:
1684-
llvm::report_fatal_error("Should never see this");
1685-
break;
1686-
}
1670+
auto value = [&]() -> SILValue {
1671+
switch (isolation->getKind()) {
1672+
case ActorIsolation::Unspecified:
1673+
case ActorIsolation::Nonisolated:
1674+
case ActorIsolation::NonisolatedUnsafe:
1675+
case ActorIsolation::CallerIsolationInheriting:
1676+
return emitNonIsolatedIsolation(loc).getValue();
1677+
case ActorIsolation::ActorInstance:
1678+
llvm::report_fatal_error("Should never see this");
1679+
case ActorIsolation::GlobalActor:
1680+
return emitLoadGlobalActorExecutor(isolation->getGlobalActor());
1681+
case ActorIsolation::Erased:
1682+
llvm::report_fatal_error("Should never see this");
1683+
}
1684+
}();
1685+
args.push_back(B.convertToImplicitIsolationActor(loc, value));
16871686
}
16881687

16891688
// Bridge the arguments.

lib/SILGen/SILGenBuilder.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,3 +1244,16 @@ ManagedValue SILGenBuilder::borrowObjectRValue(SILGenFunction &SGF,
12441244
}
12451245
return SGF.emitFormalEvaluationManagedBeginBorrow(loc, value);
12461246
}
1247+
1248+
SILValue SILGenBuilder::convertToImplicitIsolationActor(SILLocation loc,
1249+
SILValue value) {
1250+
auto type = SILType::getBuiltinImplicitIsolationActorType(getASTContext());
1251+
if (value->getType() == type)
1252+
return value;
1253+
assert(value->getType() == SILType::getOpaqueIsolationType(getASTContext()) &&
1254+
"Can only convert Optional<any Actor> to "
1255+
"Builtin.ImplicitIsolationActor");
1256+
if (value->getOwnershipKind() != OwnershipKind::Guaranteed)
1257+
value = SGF.emitManagedBeginBorrow(loc, value).getValue();
1258+
return createUncheckedValueCast(loc, value, type);
1259+
}

0 commit comments

Comments
 (0)