mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[concurrency] Implement bit masking for TBI when available or in tagged pointer bits otherwise.
Specifically, when TBI is available we use the bottom two bits of the top nibble (bits 60,61). On platforms without TBI, we use the bottom two tagged pointer bits (bits 0, 1). rdar://156525771
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
//===--- ConcurrencyUtils.h -----------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_SIL_CONCURRENCYUTILS_H
|
||||
#define SWIFT_SIL_CONCURRENCYUTILS_H
|
||||
|
||||
#include "swift/SIL/SILType.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
class SILValue;
|
||||
class SILBuilder;
|
||||
class SILLocation;
|
||||
|
||||
/// Clear the implicit isolated bits of value.
|
||||
///
|
||||
/// \p value must be Builtin.ImplicitActor
|
||||
///
|
||||
/// \p finalType if empty, we always return
|
||||
/// Builtin.ImplicitActor. Otherwise we bitcast to finalType after
|
||||
/// tieing the lifetime of the result to \p value.
|
||||
SILValue clearImplicitActorBits(SILBuilder &b, SILLocation loc, SILValue value,
|
||||
SILType finalType = {});
|
||||
|
||||
SILValue setImplicitActorBits(SILBuilder &b, SILLocation loc, SILValue value);
|
||||
|
||||
} // namespace swift
|
||||
|
||||
#endif
|
||||
@@ -312,7 +312,9 @@ public:
|
||||
bool isBoxWithAddress() const {
|
||||
return kind == Kind::OwnedAddress;
|
||||
}
|
||||
|
||||
|
||||
bool isExplosionVector() const { return kind == Kind::ExplosionVector; }
|
||||
|
||||
const StackAddress &getStackAddress() const {
|
||||
return Storage.get<StackAddress>(kind);
|
||||
}
|
||||
@@ -3377,12 +3379,10 @@ void IRGenSILFunction::visitExistentialMetatypeInst(
|
||||
setLoweredExplosion(i, result);
|
||||
}
|
||||
|
||||
static void emitApplyArgument(IRGenSILFunction &IGF,
|
||||
SILValue arg,
|
||||
SILType paramType,
|
||||
Explosion &out,
|
||||
SILInstruction *apply = nullptr,
|
||||
unsigned idx = 0) {
|
||||
static void emitApplyArgument(IRGenSILFunction &IGF, SILValue arg,
|
||||
SILType paramType, Explosion &out,
|
||||
SILInstruction *apply = nullptr, unsigned idx = 0,
|
||||
bool isImplicitIsolatedParameter = false) {
|
||||
bool isSubstituted = (arg->getType() != paramType);
|
||||
|
||||
// For indirect arguments, we just need to pass a pointer.
|
||||
@@ -3424,7 +3424,20 @@ static void emitApplyArgument(IRGenSILFunction &IGF,
|
||||
}
|
||||
canForwardLoadToIndirect = true;
|
||||
}();
|
||||
IGF.getLoweredExplosion(arg, out);
|
||||
|
||||
// If we are emitting a parameter for an implicit isolated parameter, then
|
||||
// we need to clear the implicit isolated actor bits.
|
||||
if (isImplicitIsolatedParameter) {
|
||||
auto &loweredValue = IGF.getLoweredValue(arg);
|
||||
assert(loweredValue.isExplosionVector() &&
|
||||
"Should be an explosion of two pointers");
|
||||
auto explosionVector = loweredValue.getKnownExplosionVector();
|
||||
assert(explosionVector.size() == 2 && "We should have two values");
|
||||
out.add(explosionVector[0]);
|
||||
out.add(clearImplicitIsolatedActorBits(IGF, explosionVector[1]));
|
||||
} else {
|
||||
IGF.getLoweredExplosion(arg, out);
|
||||
}
|
||||
if (canForwardLoadToIndirect) {
|
||||
IGF.setForwardableArgument(idx);
|
||||
}
|
||||
@@ -3842,6 +3855,20 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the implicit isolated parameter so that we can mask it as
|
||||
// appropriate.
|
||||
//
|
||||
// NOTE: We cannot just drop_front since we could be between the indirect
|
||||
// results and the parameters.
|
||||
std::optional<unsigned> implicitIsolatedParameterIndex;
|
||||
if (auto actorIsolation = site.getFunction()->getActorIsolation();
|
||||
actorIsolation && actorIsolation->isCallerIsolationInheriting() &&
|
||||
site.isCallerIsolationInheriting()) {
|
||||
auto *iso = site.getIsolatedArgumentOperandOrNullPtr();
|
||||
assert(iso);
|
||||
implicitIsolatedParameterIndex = site.getAppliedArgIndex(*iso);
|
||||
}
|
||||
|
||||
// Lower the arguments and return value in the callee's generic context.
|
||||
GenericContextScope scope(IGM,
|
||||
origCalleeType->getInvocationGenericSignature());
|
||||
@@ -3902,8 +3929,11 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
|
||||
emission->setIndirectTypedErrorResultSlot(addr.getAddress());
|
||||
continue;
|
||||
}
|
||||
|
||||
emitApplyArgument(*this, args[index], emission->getParameterType(index),
|
||||
llArgs, site.getInstruction(), index);
|
||||
llArgs, site.getInstruction(), index,
|
||||
implicitIsolatedParameterIndex &&
|
||||
*implicitIsolatedParameterIndex == index);
|
||||
}
|
||||
|
||||
// Pass the generic arguments.
|
||||
|
||||
@@ -2,7 +2,6 @@ target_sources(swiftSIL PRIVATE
|
||||
BasicBlockUtils.cpp
|
||||
BitDataflow.cpp
|
||||
CalleeCache.cpp
|
||||
ConcurrencyUtils.cpp
|
||||
DebugUtils.cpp
|
||||
Dominance.cpp
|
||||
DynamicCasts.cpp
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
//===--- ConcurrencyUtils.cpp ---------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/SIL/ConcurrencyUtils.h"
|
||||
|
||||
#include "swift/SIL/SILBuilder.h"
|
||||
#include "swift/SIL/SILLocation.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
SILValue swift::clearImplicitActorBits(SILBuilder &b, SILLocation loc,
|
||||
SILValue value, SILType finalType) {
|
||||
if (!finalType)
|
||||
finalType = SILType::getBuiltinImplicitActorType(b.getASTContext());
|
||||
if (value->getType() == finalType)
|
||||
return value;
|
||||
return b.emitUncheckedValueCast(loc, value, finalType);
|
||||
}
|
||||
|
||||
SILValue swift::setImplicitActorBits(SILBuilder &b, SILLocation loc,
|
||||
SILValue value) {
|
||||
return value;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
//===--- ConcurrencyUtils.h -----------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_SILGEN_CONCURRENCYUTILS_H
|
||||
#define SWIFT_SILGEN_CONCURRENCYUTILS_H
|
||||
|
||||
#include "RValue.h"
|
||||
#include "SILGenFunction.h"
|
||||
|
||||
#include "swift/SIL/ConcurrencyUtils.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
class SILLocation;
|
||||
class Expr;
|
||||
|
||||
namespace Lowering {
|
||||
|
||||
class SILGenFunction;
|
||||
class RValue;
|
||||
class ManagedValue;
|
||||
|
||||
inline ManagedValue clearImplicitActorBits(SILGenFunction &SGF, SILLocation loc,
|
||||
ManagedValue implicitIsolatedActor,
|
||||
SILType type = {}) {
|
||||
return ManagedValue::forBorrowedRValue(clearImplicitActorBits(
|
||||
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue(), type));
|
||||
}
|
||||
|
||||
/// Clear the TBI bits if AArch64HasTBI is set. Otherwise clear the low tagged
|
||||
/// bits.
|
||||
///
|
||||
/// \param expr - the expression which yielded this r-value; its type
|
||||
/// will become the substituted formal type of this r-value
|
||||
/// \param implicitIsolatedActor should be an Optional<any Actor>.
|
||||
inline RValue clearImplicitActorBits(SILGenFunction &SGF, Expr *expr,
|
||||
ManagedValue implicitIsolatedActor,
|
||||
SILType type = {}) {
|
||||
return RValue(SGF, expr,
|
||||
clearImplicitActorBits(SGF, SILLocation(expr),
|
||||
implicitIsolatedActor, type));
|
||||
}
|
||||
|
||||
inline ManagedValue setImplicitActorBits(SILGenFunction &SGF, SILLocation loc,
|
||||
ManagedValue implicitIsolatedActor) {
|
||||
return ManagedValue::forBorrowedRValue(setImplicitActorBits(
|
||||
SGF.B, loc, implicitIsolatedActor.getUnmanagedValue()));
|
||||
}
|
||||
|
||||
inline RValue setImplicitActorBits(SILGenFunction &SGF, Expr *expr,
|
||||
ManagedValue implicitIsolatedActor) {
|
||||
return RValue(
|
||||
SGF, expr,
|
||||
setImplicitActorBits(SGF, SILLocation(expr), implicitIsolatedActor));
|
||||
}
|
||||
|
||||
} // namespace Lowering
|
||||
|
||||
} // namespace swift
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "ArgumentScope.h"
|
||||
#include "ArgumentSource.h"
|
||||
#include "Callee.h"
|
||||
#include "ConcurrencyUtils.h"
|
||||
#include "Conversion.h"
|
||||
#include "ExecutorBreadcrumb.h"
|
||||
#include "FormalEvaluation.h"
|
||||
|
||||
@@ -562,6 +562,13 @@ public:
|
||||
convertToImplicitActor(loc, value.borrow(SGF, loc).getValue());
|
||||
return ManagedValue::forBorrowedRValue(result);
|
||||
}
|
||||
|
||||
using SILBuilder::createImplicitActorToOpaqueIsolationCast;
|
||||
ManagedValue createImplicitActorToOpaqueIsolationCast(SILLocation loc,
|
||||
ManagedValue mv) {
|
||||
return ManagedValue::forBorrowedRValue(
|
||||
createImplicitActorToOpaqueIsolationCast(loc, mv.getUnmanagedValue()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Lowering
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "ArgumentScope.h"
|
||||
#include "ArgumentSource.h"
|
||||
#include "Callee.h"
|
||||
#include "ConcurrencyUtils.h"
|
||||
#include "Condition.h"
|
||||
#include "Conversion.h"
|
||||
#include "Initialization.h"
|
||||
@@ -7491,9 +7490,8 @@ RValue RValueEmitter::visitCurrentContextIsolationExpr(
|
||||
assert(isolatedArg &&
|
||||
"Caller Isolation Inheriting without isolated parameter");
|
||||
auto isolatedMV = ManagedValue::forBorrowedRValue(isolatedArg);
|
||||
return clearImplicitActorBits(
|
||||
SGF, E, isolatedMV,
|
||||
SILType::getOpaqueIsolationType(SGF.getASTContext()));
|
||||
return RValue(
|
||||
SGF, E, SGF.B.createImplicitActorToOpaqueIsolationCast(E, isolatedMV));
|
||||
}
|
||||
|
||||
if (isolation == ActorIsolation::ActorInstance) {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "swift/AST/ConformanceLookup.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include "swift/Basic/FrozenMultiMap.h"
|
||||
#include "swift/SIL/ConcurrencyUtils.h"
|
||||
#include "swift/SIL/Dominance.h"
|
||||
#include "swift/SIL/SILBuilder.h"
|
||||
#include "swift/SIL/SILFunction.h"
|
||||
@@ -353,8 +352,8 @@ static SILValue getExecutorForImplicitActor(SILOptFunctionBuilder &funcBuilder,
|
||||
auto *front = newFunc->createBasicBlock();
|
||||
SILBuilder builder(front);
|
||||
auto *fArg = front->createFunctionArgument(implicitIsolatedActorType);
|
||||
auto value = clearImplicitActorBits(builder, autoGenLoc, fArg,
|
||||
SILType::getOpaqueIsolationType(ctx));
|
||||
auto value = SILValue(
|
||||
builder.createImplicitActorToOpaqueIsolationCast(autoGenLoc, fArg));
|
||||
value = getExecutorForOptionalActor(builder, autoGenLoc, value);
|
||||
builder.createReturn(autoGenLoc, value);
|
||||
}
|
||||
|
||||
65
test/Concurrency/isolation_macro_ir.swift
Normal file
65
test/Concurrency/isolation_macro_ir.swift
Normal file
@@ -0,0 +1,65 @@
|
||||
// RUN: %target-swift-frontend -parse-as-library -emit-ir -disable-llvm-merge-functions-pass %s | %FileCheck --check-prefix=NO-TBI %s
|
||||
// RUN: %target-swift-frontend -parse-as-library -Xllvm -aarch64-use-tbi -emit-ir -disable-llvm-merge-functions-pass %s | %FileCheck --check-prefix=TBI %s
|
||||
|
||||
// This test makes sure that we can properly fold the mask for the witness table
|
||||
// when we have a #isolation.
|
||||
|
||||
// REQUIRES: concurrency
|
||||
// REQUIRES: CODEGENERATOR=AArch64
|
||||
// REQUIRES: PTRSIZE=64
|
||||
// REQUIRES: OS=macosx || OS=ios
|
||||
// REQUIRES: CPU=arm64
|
||||
|
||||
@inline(never)
|
||||
func useActor(iso: (any Actor)?) {
|
||||
print(iso!.unownedExecutor)
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
func implicitParam(_ x: (any Actor)? = #isolation) {
|
||||
print(x!.unownedExecutor)
|
||||
}
|
||||
|
||||
// #isolation via direct usage
|
||||
//
|
||||
// TBI: define swifttailcc void @"$s18isolation_macro_ir46nonisolatedNonsendingUsePoundIsolationDirectlyyyYaF"(ptr swiftasync %0, i64 %1, i64 [[SECOND_WORD:%.*]])
|
||||
// TBI: [[MASKED_SECOND_WORD:%.*]] = and i64 [[SECOND_WORD]], -3458764513820540929
|
||||
// TBI: call swiftcc void @"$s18isolation_macro_ir8useActor3isoyScA_pSg_tF"(i64 %1, i64 [[MASKED_SECOND_WORD]])
|
||||
|
||||
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir46nonisolatedNonsendingUsePoundIsolationDirectlyyyYaF"(ptr swiftasync %0, i64 [[FIRST_WORD:%.*]], i64 [[SECOND_WORD:%.*]])
|
||||
// NO-TBI: [[MASKED_SECOND_WORD:%.*]] = and i64 [[SECOND_WORD]], -4
|
||||
// NO-TBI: call swiftcc void @"$s18isolation_macro_ir8useActor3isoyScA_pSg_tF"(i64 [[FIRST_WORD]], i64 [[MASKED_SECOND_WORD]])
|
||||
|
||||
public nonisolated(nonsending) func nonisolatedNonsendingUsePoundIsolationDirectly() async {
|
||||
let iso = #isolation
|
||||
useActor(iso: iso)
|
||||
}
|
||||
|
||||
// #isolation via default arg
|
||||
//
|
||||
// TBI: define swifttailcc void @"$s18isolation_macro_ir45nonisolatedNonsendingPoundIsolationDefaultArgyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[WORD_2:%.*]])
|
||||
// TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -3458764513820540929
|
||||
// TBI: call swiftcc void @"$s18isolation_macro_ir13implicitParamyyScA_pSgF"(i64 {{%.*}}, i64 [[MASKED_WORD_2]])
|
||||
|
||||
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir45nonisolatedNonsendingPoundIsolationDefaultArgyyYaF"(ptr swiftasync %0, i64 [[WORD_1:%.*]], i64 [[WORD_2:%.*]])
|
||||
// NO-TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -4
|
||||
// NO-TBI: call swiftcc void @"$s18isolation_macro_ir13implicitParamyyScA_pSgF"(i64 {{%.*}}, i64 [[MASKED_WORD_2]])
|
||||
public nonisolated(nonsending) func nonisolatedNonsendingPoundIsolationDefaultArg() async {
|
||||
implicitParam()
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public nonisolated(nonsending) func calleeFunction() async {
|
||||
}
|
||||
|
||||
// TBI: define swifttailcc void @"$s18isolation_macro_ir14callerFunctionyyYaF"(ptr swiftasync %0, i64 %1, i64 [[WORD_2:%.*]])
|
||||
// TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -3458764513820540929
|
||||
// TBI: musttail call swifttailcc void @"$s18isolation_macro_ir14calleeFunctionyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[MASKED_WORD_2]])
|
||||
|
||||
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir14callerFunctionyyYaF"(ptr swiftasync %0, i64 %1, i64 [[WORD:%.*]])
|
||||
// NO-TBI: [[MASKED_WORD:%.*]] = and i64 [[WORD]], -4
|
||||
// NO-TBI: musttail call swifttailcc void @"$s18isolation_macro_ir14calleeFunctionyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[MASKED_WORD]])
|
||||
@inline(never)
|
||||
public nonisolated(nonsending) func callerFunction() async {
|
||||
await calleeFunction()
|
||||
}
|
||||
@@ -15,7 +15,7 @@ func takeDefaulted(iso: isolated (any Actor)? = #isolation) {}
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
// CHECK-NEXT: sil hidden @$s4test21nonisolatedNonsendingyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () {
|
||||
// CHECK: bb0([[IMPLICIT_ACTOR:%.*]] : $Builtin.ImplicitActor):
|
||||
// CHECK: [[ACTOR:%.*]] = unchecked_bitwise_cast [[IMPLICIT_ACTOR]] to $Optional<any Actor>
|
||||
// CHECK: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast [[IMPLICIT_ACTOR]]
|
||||
// CHECK: retain_value [[ACTOR]]
|
||||
// CHECK: debug_value [[ACTOR]], let, name "iso"
|
||||
// CHECK: [[FUNC:%.*]] = function_ref @$s4test4take3isoyScA_pSg_tF : $@convention(thin) (@guaranteed Optional<any Actor>) -> ()
|
||||
@@ -28,7 +28,7 @@ func takeDefaulted(iso: isolated (any Actor)? = #isolation) {}
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
// CHECK-LABEL: sil private @$s4test15containsClosureyyFyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () {
|
||||
// CHECK: bb0(%0 : $Builtin.ImplicitActor):
|
||||
// CHECK: [[ACTOR:%.*]] = unchecked_bitwise_cast %0 to $Optional<any Actor>
|
||||
// CHECK: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0
|
||||
// CHECK-NEXT: // function_ref take(iso:)
|
||||
// CHECK-NEXT: [[FN:%.*]] = function_ref @
|
||||
// CHECK-NEXT: apply [[FN]]([[ACTOR]])
|
||||
@@ -51,12 +51,14 @@ func deferWithIsolatedParam(_ iso: isolated (any Actor)) {
|
||||
// CHECK: bb0(%0 : $any Actor)
|
||||
// CHECK: [[DEFER:%.*]] = function_ref @$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF :
|
||||
// CHECK-NEXT: apply [[DEFER]](%0)
|
||||
// CHECK: } // end sil function '$s4test22deferWithIsolatedParamyyScA_pYiF'
|
||||
|
||||
// CHECK-LABEL: sil private @$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF :
|
||||
// CHECK: bb0(%0 : @closureCapture $any Actor):
|
||||
// CHECK: [[T0:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, %0
|
||||
// CHECK: [[FN:%.*]] = function_ref @$s4test4take3isoyScA_pSg_tF :
|
||||
// CHECK-NEXT: apply [[FN]]([[T0]])
|
||||
// CHECK: } // end sil function '$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF'
|
||||
|
||||
// Check that that happens even with uses in caller-side default
|
||||
// arguments, which capture analysis was not previously walking into.
|
||||
@@ -71,12 +73,14 @@ func deferWithIsolatedParam_defaultedUse(_ iso: isolated (any Actor)) {
|
||||
// CHECK: bb0(%0 : $any Actor):
|
||||
// CHECK: [[DEFER:%.*]] = function_ref @$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF :
|
||||
// CHECK-NEXT: apply [[DEFER]](%0)
|
||||
// CHECK: } // end sil function '$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF'
|
||||
|
||||
// CHECK-LABEL: sil private @$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF :
|
||||
// CHECK: bb0(%0 : @closureCapture $any Actor):
|
||||
// CHECK: [[T0:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, %0
|
||||
// CHECK: [[FN:%.*]] = function_ref @$s4test13takeDefaulted3isoyScA_pSgYi_tF :
|
||||
// CHECK-NEXT: apply [[FN]]([[T0]])
|
||||
// CHECK: } // end sil function '$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF'
|
||||
|
||||
// TODO: we can't currently call nonisolated(nonsending) functions in
|
||||
// defer bodies because they have to be async, but that should be
|
||||
@@ -100,7 +104,7 @@ func hasDefer() async {
|
||||
// CHECK-LABEL: // $defer #1 () in hasDefer()
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
// CHECK: bb0(%0 : $Builtin.ImplicitActor):
|
||||
// CHECK-NEXT: [[ACTOR:%.*]] = unchecked_bitwise_cast %0 to $Optional<any Actor>
|
||||
// CHECK-NEXT: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0
|
||||
// CHECK-NEXT: // function_ref take(iso:)
|
||||
// CHECK-NEXT: [[FN:%.*]] = function_ref @
|
||||
// CHECK-NEXT: apply [[FN]]([[ACTOR]])
|
||||
@@ -122,6 +126,7 @@ func hasNestedDefer() async {
|
||||
// CHECK: // function_ref $defer #1 () in hasNestedDefer()
|
||||
// CHECK-NEXT: [[DEFER:%.*]] = function_ref
|
||||
// CHECK-NEXT: apply [[DEFER]](%0)
|
||||
// CHECK: } // end sil function '$s4test14hasNestedDeferyyYaF'
|
||||
|
||||
// CHECK-LABEL: // $defer #1 () in hasNestedDefer()
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
@@ -129,12 +134,13 @@ func hasNestedDefer() async {
|
||||
// CHECK: // function_ref $defer #1 () in $defer #1 () in hasNestedDefer()
|
||||
// CHECK-NEXT: [[DEFER:%.*]] = function_ref
|
||||
// CHECK-NEXT: apply [[DEFER]](%0)
|
||||
// CHECK: } // end sil function '$s4test14hasNestedDeferyyYaF6$deferL_yyF'
|
||||
|
||||
// CHECK-LABEL: // $defer #1 () in $defer #1 () in hasNestedDefer()
|
||||
// CHECK-NEXT: // Isolation: caller_isolation_inheriting
|
||||
// CHECK-NEXT: sil private @$s4test14hasNestedDeferyyYaF6$deferL_yyFACL_yyF : $@convention(thin) (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () {
|
||||
// CHECK: bb0(%0 : $Builtin.ImplicitActor):
|
||||
// CHECK-NEXT: [[ACTOR:%.*]] = unchecked_bitwise_cast %0 to $Optional<any Actor>
|
||||
// CHECK-NEXT: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0
|
||||
// CHECK-NEXT: // function_ref take(iso:)
|
||||
// CHECK-NEXT: [[FN:%.*]] = function_ref @
|
||||
// CHECK-NEXT: apply [[FN]]([[ACTOR]])
|
||||
|
||||
Reference in New Issue
Block a user