Skip to content

Commit a9d409d

Browse files
authored
Merge pull request #83346 from gottesmm/pr-df6aafa41c61b9a9a6ee4965a1564ec2946a0dc9
[concurrency] Change #isolated to mask out the TBI bits of the witness pointer of the implicit isolated any Actor pointer so we can do optimizations on TBI supporting platforms in the future.
2 parents 9120a53 + 390afe3 commit a9d409d

File tree

97 files changed

+1484
-666
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1484
-666
lines changed

SwiftCompilerSources/Sources/SIL/ForwardingInstruction.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,12 @@ extension BorrowedFromInst: ForwardingInstruction {
467467
public var canForwardOwnedValues: Bool { false }
468468
}
469469

470+
extension ImplicitActorToOpaqueIsolationCastInst: ConversionInstruction {
471+
public var preservesRepresentation: Bool { true }
472+
public var canForwardGuaranteedValues: Bool { true }
473+
public var canForwardOwnedValues: Bool { false }
474+
}
475+
470476
// -----------------------------------------------------------------------------
471477
// ownership transition instructions
472478

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,3 +2060,6 @@ final public class MergeIsolationRegionInst : Instruction {
20602060

20612061
final public class IgnoredUseInst : Instruction, UnaryInstruction {
20622062
}
2063+
2064+
final public class ImplicitActorToOpaqueIsolationCastInst
2065+
: SingleValueInstruction, UnaryInstruction {}

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ private func registerSILClasses() {
265265
register(ThunkInst.self)
266266
register(MergeIsolationRegionInst.self)
267267
register(IgnoredUseInst.self)
268+
register(ImplicitActorToOpaqueIsolationCastInst.self)
268269
}
269270

270271
private func registerUtilities() {

docs/ABI/Mangling.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,9 @@ Types
705705
type ::= type 'Bv' NATURAL '_' // Builtin.Vec<n>x<type>
706706
type ::= type type 'BV' // Builtin.FixedArray<N, T>
707707
type ::= 'Bw' // Builtin.Word
708+
#if SWIFT_RUNTIME_VERSION >= 6.2
709+
type ::= 'BA' // Builtin.ImplicitActor
710+
#endif
708711
type ::= function-signature 'c' // function type (escaping)
709712
type ::= function-signature 'X' FUNCTION-KIND // special function type
710713
type ::= bound-generic-type

docs/SIL/Instructions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,6 +4555,9 @@ copy.
45554555
The resulting value must meet the usual ownership requirements; for
45564556
example, a trivial type must have '.none' ownership.
45574557

4558+
NOTE: A guaranteed result value is assumed to be a non-dependent guaranteed
4559+
value like a function argument.
4560+
45584561
### ref_to_raw_pointer
45594562

45604563
```
@@ -4871,6 +4874,27 @@ TODO
48714874

48724875
TODO
48734876

4877+
### cast_implicitactor_to_opaqueisolation
4878+
4879+
```
4880+
sil-instruction ::= 'cast_implicitactor_to_opaqueisolation' sil-operand
4881+
4882+
%1 = cast_implicitactor_to_opaqueisolation %0 : $Builtin.ImplicitActor
4883+
// %0 must have guaranteed ownership
4884+
// %1 must have guaranteed ownership
4885+
// %1 will have type $Optional<any Actor>
4886+
```
4887+
4888+
Convert a `$Builtin.ImplicitActor` to a `$Optional<any Actor>` masking out any
4889+
bits that we have stolen from the witness table pointer.
4890+
4891+
At IRGen time, we lower this to the relevant masking operations, allowing us to
4892+
avoid exposing these low level details to the SIL optimizer. On platforms where
4893+
we support TBI, IRGen uses a mask that is the bottom 2 bits of the top nibble of
4894+
the pointer. On 64 bit platforms this is bit 60,61. If the platform does not
4895+
support TBI, then IRGen uses the bottom two tagged pointer bits of the pointer
4896+
(bits 0,1).
4897+
48744898
## Checked Conversions
48754899

48764900
Some user-level cast operations can fail and thus require runtime

include/swift/AST/DiagnosticsParse.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,12 @@ ERROR(sil_operand_has_incorrect_moveonlywrapped,none,
621621
ERROR(sil_operand_not_ref_storage_address,none,
622622
"%0 operand of '%1' must have address of %2 type",
623623
(StringRef, StringRef, ReferenceOwnership))
624+
ERROR(sil_operand_has_wrong_ownership_kind,none,
625+
"operand has ownership kind %0 but ownership kind %1 was expected",
626+
(StringRef, StringRef))
627+
ERROR(sil_operand_has_incompatible_ownership_kind,none,
628+
"operand has ownership kind %0 but ownership kind compatible with %1 was expected",
629+
(StringRef, StringRef))
624630
ERROR(sil_integer_literal_not_integer_type,none,
625631
"integer_literal instruction requires a 'Builtin.Int<n>' type", ())
626632
ERROR(sil_integer_literal_not_well_formed,none,

include/swift/AST/TypeNodes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ ABSTRACT_TYPE(Builtin, Type)
143143
BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
144144
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
145145
BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
146-
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinUnboundGeneric)
146+
BUILTIN_CONCRETE_TYPE(BuiltinImplicitActor, BuiltinType)
147+
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinImplicitActor)
147148
TYPE(Tuple, Type)
148149
ABSTRACT_TYPE(ReferenceStorage, Type)
149150
#define REF_STORAGE(Name, ...) \
@@ -233,6 +234,7 @@ SINGLETON_TYPE(RawPointer, BuiltinRawPointer)
233234
SINGLETON_TYPE(RawUnsafeContinuation, BuiltinRawUnsafeContinuation)
234235
SINGLETON_TYPE(NativeObject, BuiltinNativeObject)
235236
SINGLETON_TYPE(BridgeObject, BuiltinBridgeObject)
237+
SINGLETON_TYPE(ImplicitActor, BuiltinImplicitActor)
236238
SINGLETON_TYPE(UnsafeValueBuffer, BuiltinUnsafeValueBuffer)
237239
SINGLETON_TYPE(DefaultActorStorage, BuiltinDefaultActorStorage)
238240
SINGLETON_TYPE(NonDefaultDistributedActorStorage, BuiltinNonDefaultDistributedActorStorage)

include/swift/AST/Types.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,13 @@ class alignas(1 << TypeAlignInBits) TypeBase
10031003
/// Determines whether this type is an any actor type.
10041004
bool isAnyActorType();
10051005

1006+
/// Is this a type whose value is a value that a function can use in an
1007+
/// isolated parameter position. This could be a type that actually conforms
1008+
/// to AnyActor or it could be a type like any Actor, Optional<any Actor> or
1009+
/// Builtin.ImplicitActor that do not conform to Actor but from which we can
1010+
/// derive a value that conforms to the Actor protocol.
1011+
bool canBeIsolatedTo();
1012+
10061013
/// Returns true if this type conforms to Sendable, or if its a function type
10071014
/// that is @Sendable.
10081015
bool isSendableType();
@@ -2019,6 +2026,19 @@ BEGIN_CAN_TYPE_WRAPPER(BuiltinVectorType, BuiltinType)
20192026
PROXY_CAN_TYPE_SIMPLE_GETTER(getElementType)
20202027
END_CAN_TYPE_WRAPPER(BuiltinVectorType, BuiltinType)
20212028

2029+
class BuiltinImplicitActorType : public BuiltinType {
2030+
friend class ASTContext;
2031+
2032+
BuiltinImplicitActorType(const ASTContext &context)
2033+
: BuiltinType(TypeKind::BuiltinImplicitActor, context) {}
2034+
2035+
public:
2036+
static bool classof(const TypeBase *T) {
2037+
return T->getKind() == TypeKind::BuiltinImplicitActor;
2038+
}
2039+
};
2040+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinImplicitActorType, BuiltinType)
2041+
20222042
/// Size descriptor for a builtin integer type. This is either a fixed bit
20232043
/// width or an abstract target-dependent value such as "size of a pointer".
20242044
class BuiltinIntegerWidth {

include/swift/SIL/InstWrappers.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ class ForwardingOperation {
301301
return &forwardingInst->getOperandRef(TuplePackExtractInst::TupleOperand);
302302
case SILInstructionKind::BorrowedFromInst:
303303
return &forwardingInst->getOperandRef(0);
304+
case SILInstructionKind::ImplicitActorToOpaqueIsolationCastInst:
305+
return &forwardingInst->getOperandRef(0);
304306
default:
305307
int numRealOperands = forwardingInst->getNumRealOperands();
306308
if (numRealOperands == 0) {
@@ -344,6 +346,7 @@ class ForwardingOperation {
344346
case SILInstructionKind::StructExtractInst:
345347
case SILInstructionKind::DifferentiableFunctionExtractInst:
346348
case SILInstructionKind::LinearFunctionExtractInst:
349+
case SILInstructionKind::ImplicitActorToOpaqueIsolationCastInst:
347350
return true;
348351
default:
349352
return false;
@@ -352,6 +355,8 @@ class ForwardingOperation {
352355

353356
/// Return true if the forwarded value has the same representation. If true,
354357
/// then the result can be mapped to the same storage without a move or copy.
358+
///
359+
/// See ForwardingInstruction.swift preservesRepresentation().
355360
bool hasSameRepresentation() const;
356361

357362
/// Return true if the forwarded value is address-only either before or after

include/swift/SIL/SILBuilder.h

Lines changed: 36 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());
@@ -2334,6 +2345,19 @@ class SILBuilder {
23342345
getSILDebugLocation(Loc), Operand, Kind));
23352346
}
23362347

2348+
SILValue emitUncheckedOwnershipConversion(SILLocation Loc, SILValue Operand,
2349+
ValueOwnershipKind Kind) {
2350+
if (!hasOwnership())
2351+
return Operand;
2352+
return createUncheckedOwnershipConversion(Loc, Operand, Kind);
2353+
}
2354+
2355+
ImplicitActorToOpaqueIsolationCastInst *
2356+
createImplicitActorToOpaqueIsolationCast(SILLocation Loc, SILValue Value) {
2357+
return insert(new (getModule()) ImplicitActorToOpaqueIsolationCastInst(
2358+
getSILDebugLocation(Loc), Value));
2359+
}
2360+
23372361
FixLifetimeInst *createFixLifetime(SILLocation Loc, SILValue Operand) {
23382362
return insert(new (getModule())
23392363
FixLifetimeInst(getSILDebugLocation(Loc), Operand));
@@ -2353,6 +2377,18 @@ class SILBuilder {
23532377
dependenceKind);
23542378
}
23552379

2380+
/// Emit a mark_dependence instruction placing the kind only if ownership is
2381+
/// set in the current function.
2382+
///
2383+
/// This is intended to be used in code that is generic over Ownership SSA and
2384+
/// non-Ownership SSA code.
2385+
SILValue emitMarkDependence(SILLocation Loc, SILValue value, SILValue base,
2386+
MarkDependenceKind dependenceKind) {
2387+
return createMarkDependence(Loc, value, base, value->getOwnershipKind(),
2388+
hasOwnership() ? dependenceKind
2389+
: MarkDependenceKind::Escaping);
2390+
}
2391+
23562392
MarkDependenceInst *
23572393
createMarkDependence(SILLocation Loc, SILValue value, SILValue base,
23582394
ValueOwnershipKind forwardingOwnershipKind,

0 commit comments

Comments
 (0)