Skip to content

Commit ce162af

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. (cherry picked from commit 788abd0)
1 parent f625cce commit ce162af

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
@@ -1337,6 +1337,17 @@ class SILBuilder {
13371337
forwardingOwnershipKind));
13381338
}
13391339

1340+
/// Create an unchecked_value_cast when Ownership SSA is enabled and
1341+
/// unchecked_bitwise_cast otherwise.
1342+
///
1343+
/// Intended to be used in utility code that needs to support both Ownership
1344+
/// SSA and non-Ownership SSA code.
1345+
SILValue emitUncheckedValueCast(SILLocation loc, SILValue op, SILType ty) {
1346+
if (hasOwnership())
1347+
return createUncheckedValueCast(loc, op, ty);
1348+
return createUncheckedBitwiseCast(loc, op, ty);
1349+
}
1350+
13401351
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
13411352
SILValue Bits) {
13421353
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
@@ -1715,11 +1715,7 @@ class DestructureInputs {
17151715
// implicit isolation parameter.
17161716
if (IsolationInfo && IsolationInfo->isCallerIsolationInheriting() &&
17171717
Convs.hasCallerIsolationParameter()) {
1718-
auto actorProtocol = TC.Context.getProtocol(KnownProtocolKind::Actor);
1719-
auto actorType =
1720-
ExistentialType::get(actorProtocol->getDeclaredInterfaceType());
1721-
addParameter(-1,
1722-
CanType(actorType).wrapInOptionalType(),
1718+
addParameter(-1, CanType(TC.Context.TheImplicitActorType),
17231719
ParameterConvention::Direct_Guaranteed,
17241720
ParameterTypeFlags().withIsolated(true),
17251721
true /*implicit leading parameter*/);

lib/SIL/IR/TypeLowering.cpp

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

2396+
TypeLowering *
2397+
visitBuiltinImplicitActorType(CanBuiltinImplicitActorType type,
2398+
AbstractionPattern origType,
2399+
IsTypeExpansionSensitive_t isSensitive) {
2400+
auto silType = SILType::getPrimitiveObjectType(type);
2401+
auto properties = SILTypeProperties();
2402+
properties.setTypeExpansionSensitive(isSensitive);
2403+
properties.setNonTrivial();
2404+
properties.setLexical(IsLexical);
2405+
return new (TC)
2406+
MiscNontrivialTypeLowering(silType, properties, Expansion);
2407+
}
2408+
23962409
TypeLowering *visitPackType(CanPackType packType,
23972410
AbstractionPattern origType,
23982411
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"
@@ -5860,8 +5861,12 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
58605861
args.push_back({});
58615862
// NOTE: Even though this calls emitActorInstanceIsolation, this also
58625863
// handles glboal actor isolated cases.
5863-
args.back().push_back(SGF.emitActorInstanceIsolation(
5864-
callSite->Loc, executor, executor.getType().getASTType()));
5864+
auto erasedActor =
5865+
SGF.emitActorInstanceIsolation(callSite->Loc, executor,
5866+
executor.getType().getASTType())
5867+
.borrow(SGF, callSite->Loc);
5868+
args.back().push_back(
5869+
SGF.B.convertToImplicitActor(callSite->Loc, erasedActor));
58655870
}
58665871

58675872
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.convertToImplicitActor(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::convertToImplicitActor(SILLocation loc,
1249+
SILValue value) {
1250+
auto type = SILType::getBuiltinImplicitActorType(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.ImplicitActor");
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)