Skip to content

Commit 788abd0

Browse files
committed
[silgen] Use Builtin.ImplicitActor 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.ImplicitActor 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 fe9c21f commit 788abd0

16 files changed

+360
-102
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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.ImplicitActor
27+
///
28+
/// \p finalType if empty, we always return
29+
/// Builtin.ImplicitActor. Otherwise we bitcast to finalType after
30+
/// tieing the lifetime of the result to \p value.
31+
SILValue clearImplicitActorBits(SILBuilder &b, SILLocation loc, SILValue value,
32+
SILType finalType = {});
33+
34+
SILValue setImplicitActorBits(SILBuilder &b, SILLocation loc, SILValue value);
35+
36+
} // namespace swift
37+
38+
#endif

include/swift/SIL/SILBuilder.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,17 @@ class SILBuilder {
13301330
forwardingOwnershipKind));
13311331
}
13321332

1333+
/// Create an unchecked_value_cast when Ownership SSA is enabled and
1334+
/// unchecked_bitwise_cast otherwise.
1335+
///
1336+
/// Intended to be used in utility code that needs to support both Ownership
1337+
/// SSA and non-Ownership SSA code.
1338+
SILValue emitUncheckedValueCast(SILLocation loc, SILValue op, SILType ty) {
1339+
if (hasOwnership())
1340+
return createUncheckedValueCast(loc, op, ty);
1341+
return createUncheckedBitwiseCast(loc, op, ty);
1342+
}
1343+
13331344
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
13341345
SILValue Bits) {
13351346
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
@@ -1763,11 +1763,7 @@ class DestructureInputs {
17631763
// implicit isolation parameter.
17641764
if (IsolationInfo && IsolationInfo->isCallerIsolationInheriting() &&
17651765
Convs.hasCallerIsolationParameter()) {
1766-
auto actorProtocol = TC.Context.getProtocol(KnownProtocolKind::Actor);
1767-
auto actorType =
1768-
ExistentialType::get(actorProtocol->getDeclaredInterfaceType());
1769-
addParameter(-1,
1770-
CanType(actorType).wrapInOptionalType(),
1766+
addParameter(-1, CanType(TC.Context.TheImplicitActorType),
17711767
ParameterConvention::Direct_Guaranteed,
17721768
ParameterTypeFlags().withIsolated(true),
17731769
true /*implicit leading parameter*/);

lib/SIL/IR/TypeLowering.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,19 @@ namespace {
23912391
UnsafeValueBufferTypeLowering(silType, Expansion, isSensitive);
23922392
}
23932393

2394+
TypeLowering *
2395+
visitBuiltinImplicitActorType(CanBuiltinImplicitActorType type,
2396+
AbstractionPattern origType,
2397+
IsTypeExpansionSensitive_t isSensitive) {
2398+
auto silType = SILType::getPrimitiveObjectType(type);
2399+
auto properties = SILTypeProperties();
2400+
properties.setTypeExpansionSensitive(isSensitive);
2401+
properties.setNonTrivial();
2402+
properties.setLexical(IsLexical);
2403+
return new (TC)
2404+
MiscNontrivialTypeLowering(silType, properties, Expansion);
2405+
}
2406+
23942407
TypeLowering *visitPackType(CanPackType packType,
23952408
AbstractionPattern origType,
23962409
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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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::clearImplicitActorBits(SILBuilder &b, SILLocation loc,
21+
SILValue value, SILType finalType) {
22+
if (!finalType)
23+
finalType = SILType::getBuiltinImplicitActorType(b.getASTContext());
24+
if (value->getType() == finalType)
25+
return value;
26+
return b.emitUncheckedValueCast(loc, value, finalType);
27+
}
28+
29+
SILValue swift::setImplicitActorBits(SILBuilder &b, SILLocation loc,
30+
SILValue value) {
31+
return value;
32+
}

lib/SILGen/ConcurrencyUtils.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 clearImplicitActorBits(SILGenFunction &SGF, SILLocation loc,
33+
ManagedValue implicitIsolatedActor,
34+
SILType type = {}) {
35+
return ManagedValue::forBorrowedRValue(clearImplicitActorBits(
36+
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue(), type));
37+
}
38+
39+
/// Clear the TBI bits if AArch64HasTBI is set. Otherwise clear the low tagged
40+
/// bits.
41+
///
42+
/// \param expr - the expression which yielded this r-value; its type
43+
/// will become the substituted formal type of this r-value
44+
/// \param implicitIsolatedActor should be an Optional<any Actor>.
45+
inline RValue clearImplicitActorBits(SILGenFunction &SGF, Expr *expr,
46+
ManagedValue implicitIsolatedActor,
47+
SILType type = {}) {
48+
return RValue(SGF, expr,
49+
clearImplicitActorBits(SGF, SILLocation(expr),
50+
implicitIsolatedActor, type));
51+
}
52+
53+
inline ManagedValue setImplicitActorBits(SILGenFunction &SGF, SILLocation loc,
54+
ManagedValue implicitIsolatedActor) {
55+
return ManagedValue::forBorrowedRValue(setImplicitActorBits(
56+
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue()));
57+
}
58+
59+
inline RValue setImplicitActorBits(SILGenFunction &SGF, Expr *expr,
60+
ManagedValue implicitIsolatedActor) {
61+
return RValue(
62+
SGF, expr,
63+
setImplicitActorBits(SGF, SILLocation(expr), implicitIsolatedActor));
64+
}
65+
66+
} // namespace Lowering
67+
68+
} // namespace swift
69+
70+
#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"
@@ -5845,8 +5846,12 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
58455846
args.push_back({});
58465847
// NOTE: Even though this calls emitActorInstanceIsolation, this also
58475848
// handles glboal actor isolated cases.
5848-
args.back().push_back(SGF.emitActorInstanceIsolation(
5849-
callSite->Loc, executor, executor.getType().getASTType()));
5849+
auto erasedActor =
5850+
SGF.emitActorInstanceIsolation(callSite->Loc, executor,
5851+
executor.getType().getASTType())
5852+
.borrow(SGF, callSite->Loc);
5853+
args.back().push_back(
5854+
SGF.B.convertToImplicitActor(callSite->Loc, erasedActor));
58505855
}
58515856

58525857
uncurriedLoc = callSite->Loc;

lib/SILGen/SILGenBridging.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,23 +1674,22 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
16741674
isolatedParameter && isolatedParameter->hasOption(SILParameterInfo::ImplicitLeading)) {
16751675
assert(F.isAsync() && "Can only be async");
16761676
assert(isolation && "No isolation?!");
1677-
switch (isolation->getKind()) {
1678-
case ActorIsolation::Unspecified:
1679-
case ActorIsolation::Nonisolated:
1680-
case ActorIsolation::NonisolatedUnsafe:
1681-
case ActorIsolation::CallerIsolationInheriting:
1682-
args.push_back(emitNonIsolatedIsolation(loc).getValue());
1683-
break;
1684-
case ActorIsolation::ActorInstance:
1685-
llvm::report_fatal_error("Should never see this");
1686-
break;
1687-
case ActorIsolation::GlobalActor:
1688-
args.push_back(emitLoadGlobalActorExecutor(isolation->getGlobalActor()));
1689-
break;
1690-
case ActorIsolation::Erased:
1691-
llvm::report_fatal_error("Should never see this");
1692-
break;
1693-
}
1677+
auto value = [&]() -> SILValue {
1678+
switch (isolation->getKind()) {
1679+
case ActorIsolation::Unspecified:
1680+
case ActorIsolation::Nonisolated:
1681+
case ActorIsolation::NonisolatedUnsafe:
1682+
case ActorIsolation::CallerIsolationInheriting:
1683+
return emitNonIsolatedIsolation(loc).getValue();
1684+
case ActorIsolation::ActorInstance:
1685+
llvm::report_fatal_error("Should never see this");
1686+
case ActorIsolation::GlobalActor:
1687+
return emitLoadGlobalActorExecutor(isolation->getGlobalActor());
1688+
case ActorIsolation::Erased:
1689+
llvm::report_fatal_error("Should never see this");
1690+
}
1691+
}();
1692+
args.push_back(B.convertToImplicitActor(loc, value));
16941693
}
16951694

16961695
// Bridge the arguments.

lib/SILGen/SILGenBuilder.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,3 +1248,16 @@ ManagedValue SILGenBuilder::borrowObjectRValue(SILGenFunction &SGF,
12481248
}
12491249
return SGF.emitFormalEvaluationManagedBeginBorrow(loc, value);
12501250
}
1251+
1252+
SILValue SILGenBuilder::convertToImplicitActor(SILLocation loc,
1253+
SILValue value) {
1254+
auto type = SILType::getBuiltinImplicitActorType(getASTContext());
1255+
if (value->getType() == type)
1256+
return value;
1257+
assert(value->getType() == SILType::getOpaqueIsolationType(getASTContext()) &&
1258+
"Can only convert Optional<any Actor> to "
1259+
"Builtin.ImplicitActor");
1260+
if (value->getOwnershipKind() != OwnershipKind::Guaranteed)
1261+
value = SGF.emitManagedBeginBorrow(loc, value).getValue();
1262+
return createUncheckedValueCast(loc, value, type);
1263+
}

0 commit comments

Comments
 (0)