Skip to content

Commit 8519540

Browse files
committed
[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 (cherry picked from commit 390afe3)
1 parent f8ec8ac commit 8519540

File tree

11 files changed

+125
-162
lines changed

11 files changed

+125
-162
lines changed

include/swift/SIL/ConcurrencyUtils.h

Lines changed: 0 additions & 38 deletions
This file was deleted.

lib/IRGen/IRGenSIL.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ class LoweredValue {
312312
bool isBoxWithAddress() const {
313313
return kind == Kind::OwnedAddress;
314314
}
315-
315+
316+
bool isExplosionVector() const { return kind == Kind::ExplosionVector; }
317+
316318
const StackAddress &getStackAddress() const {
317319
return Storage.get<StackAddress>(kind);
318320
}
@@ -3387,12 +3389,10 @@ void IRGenSILFunction::visitExistentialMetatypeInst(
33873389
setLoweredExplosion(i, result);
33883390
}
33893391

3390-
static void emitApplyArgument(IRGenSILFunction &IGF,
3391-
SILValue arg,
3392-
SILType paramType,
3393-
Explosion &out,
3394-
SILInstruction *apply = nullptr,
3395-
unsigned idx = 0) {
3392+
static void emitApplyArgument(IRGenSILFunction &IGF, SILValue arg,
3393+
SILType paramType, Explosion &out,
3394+
SILInstruction *apply = nullptr, unsigned idx = 0,
3395+
bool isImplicitIsolatedParameter = false) {
33963396
bool isSubstituted = (arg->getType() != paramType);
33973397

33983398
// For indirect arguments, we just need to pass a pointer.
@@ -3434,7 +3434,20 @@ static void emitApplyArgument(IRGenSILFunction &IGF,
34343434
}
34353435
canForwardLoadToIndirect = true;
34363436
}();
3437-
IGF.getLoweredExplosion(arg, out);
3437+
3438+
// If we are emitting a parameter for an implicit isolated parameter, then
3439+
// we need to clear the implicit isolated actor bits.
3440+
if (isImplicitIsolatedParameter) {
3441+
auto &loweredValue = IGF.getLoweredValue(arg);
3442+
assert(loweredValue.isExplosionVector() &&
3443+
"Should be an explosion of two pointers");
3444+
auto explosionVector = loweredValue.getKnownExplosionVector();
3445+
assert(explosionVector.size() == 2 && "We should have two values");
3446+
out.add(explosionVector[0]);
3447+
out.add(clearImplicitIsolatedActorBits(IGF, explosionVector[1]));
3448+
} else {
3449+
IGF.getLoweredExplosion(arg, out);
3450+
}
34383451
if (canForwardLoadToIndirect) {
34393452
IGF.setForwardableArgument(idx);
34403453
}
@@ -3852,6 +3865,20 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
38523865
}
38533866
}
38543867

3868+
// Extract the implicit isolated parameter so that we can mask it as
3869+
// appropriate.
3870+
//
3871+
// NOTE: We cannot just drop_front since we could be between the indirect
3872+
// results and the parameters.
3873+
std::optional<unsigned> implicitIsolatedParameterIndex;
3874+
if (auto actorIsolation = site.getFunction()->getActorIsolation();
3875+
actorIsolation && actorIsolation->isCallerIsolationInheriting() &&
3876+
site.isCallerIsolationInheriting()) {
3877+
auto *iso = site.getIsolatedArgumentOperandOrNullPtr();
3878+
assert(iso);
3879+
implicitIsolatedParameterIndex = site.getAppliedArgIndex(*iso);
3880+
}
3881+
38553882
// Lower the arguments and return value in the callee's generic context.
38563883
GenericContextScope scope(IGM,
38573884
origCalleeType->getInvocationGenericSignature());
@@ -3912,8 +3939,11 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
39123939
emission->setIndirectTypedErrorResultSlot(addr.getAddress());
39133940
continue;
39143941
}
3942+
39153943
emitApplyArgument(*this, args[index], emission->getParameterType(index),
3916-
llArgs, site.getInstruction(), index);
3944+
llArgs, site.getInstruction(), index,
3945+
implicitIsolatedParameterIndex &&
3946+
*implicitIsolatedParameterIndex == index);
39173947
}
39183948

39193949
// Pass the generic arguments.

lib/SIL/Utils/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ target_sources(swiftSIL PRIVATE
22
BasicBlockUtils.cpp
33
BitDataflow.cpp
44
CalleeCache.cpp
5-
ConcurrencyUtils.cpp
65
DebugUtils.cpp
76
Dominance.cpp
87
DynamicCasts.cpp

lib/SIL/Utils/ConcurrencyUtils.cpp

Lines changed: 0 additions & 32 deletions
This file was deleted.

lib/SILGen/ConcurrencyUtils.h

Lines changed: 0 additions & 70 deletions
This file was deleted.

lib/SILGen/SILGenApply.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "ArgumentScope.h"
1414
#include "ArgumentSource.h"
1515
#include "Callee.h"
16-
#include "ConcurrencyUtils.h"
1716
#include "Conversion.h"
1817
#include "ExecutorBreadcrumb.h"
1918
#include "FormalEvaluation.h"

lib/SILGen/SILGenBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,13 @@ class SILGenBuilder : public SILBuilder {
562562
convertToImplicitActor(loc, value.borrow(SGF, loc).getValue());
563563
return ManagedValue::forBorrowedRValue(result);
564564
}
565+
566+
using SILBuilder::createImplicitActorToOpaqueIsolationCast;
567+
ManagedValue createImplicitActorToOpaqueIsolationCast(SILLocation loc,
568+
ManagedValue mv) {
569+
return ManagedValue::forBorrowedRValue(
570+
createImplicitActorToOpaqueIsolationCast(loc, mv.getUnmanagedValue()));
571+
}
565572
};
566573

567574
} // namespace Lowering

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "ArgumentScope.h"
1414
#include "ArgumentSource.h"
1515
#include "Callee.h"
16-
#include "ConcurrencyUtils.h"
1716
#include "Condition.h"
1817
#include "Conversion.h"
1918
#include "Initialization.h"
@@ -7321,9 +7320,8 @@ RValue RValueEmitter::visitCurrentContextIsolationExpr(
73217320
assert(isolatedArg &&
73227321
"Caller Isolation Inheriting without isolated parameter");
73237322
auto isolatedMV = ManagedValue::forBorrowedRValue(isolatedArg);
7324-
return clearImplicitActorBits(
7325-
SGF, E, isolatedMV,
7326-
SILType::getOpaqueIsolationType(SGF.getASTContext()));
7323+
return RValue(
7324+
SGF, E, SGF.B.createImplicitActorToOpaqueIsolationCast(E, isolatedMV));
73277325
}
73287326

73297327
if (isolation == ActorIsolation::ActorInstance) {

lib/SILOptimizer/Mandatory/LowerHopToActor.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "swift/AST/ConformanceLookup.h"
1616
#include "swift/Basic/Assertions.h"
1717
#include "swift/Basic/FrozenMultiMap.h"
18-
#include "swift/SIL/ConcurrencyUtils.h"
1918
#include "swift/SIL/Dominance.h"
2019
#include "swift/SIL/SILBuilder.h"
2120
#include "swift/SIL/SILFunction.h"
@@ -353,8 +352,8 @@ static SILValue getExecutorForImplicitActor(SILOptFunctionBuilder &funcBuilder,
353352
auto *front = newFunc->createBasicBlock();
354353
SILBuilder builder(front);
355354
auto *fArg = front->createFunctionArgument(implicitIsolatedActorType);
356-
auto value = clearImplicitActorBits(builder, autoGenLoc, fArg,
357-
SILType::getOpaqueIsolationType(ctx));
355+
auto value = SILValue(
356+
builder.createImplicitActorToOpaqueIsolationCast(autoGenLoc, fArg));
358357
value = getExecutorForOptionalActor(builder, autoGenLoc, value);
359358
builder.createReturn(autoGenLoc, value);
360359
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// RUN: %target-swift-frontend -parse-as-library -emit-ir -disable-llvm-merge-functions-pass %s | %FileCheck --check-prefix=NO-TBI %s
2+
// RUN: %target-swift-frontend -parse-as-library -Xllvm -aarch64-use-tbi -emit-ir -disable-llvm-merge-functions-pass %s | %FileCheck --check-prefix=TBI %s
3+
4+
// This test makes sure that we can properly fold the mask for the witness table
5+
// when we have a #isolation.
6+
7+
// REQUIRES: concurrency
8+
// REQUIRES: CODEGENERATOR=AArch64
9+
// REQUIRES: PTRSIZE=64
10+
// REQUIRES: OS=macosx || OS=ios
11+
// REQUIRES: CPU=arm64
12+
13+
@inline(never)
14+
func useActor(iso: (any Actor)?) {
15+
print(iso!.unownedExecutor)
16+
}
17+
18+
@inline(never)
19+
func implicitParam(_ x: (any Actor)? = #isolation) {
20+
print(x!.unownedExecutor)
21+
}
22+
23+
// #isolation via direct usage
24+
//
25+
// TBI: define swifttailcc void @"$s18isolation_macro_ir46nonisolatedNonsendingUsePoundIsolationDirectlyyyYaF"(ptr swiftasync %0, i64 %1, i64 [[SECOND_WORD:%.*]])
26+
// TBI: [[MASKED_SECOND_WORD:%.*]] = and i64 [[SECOND_WORD]], -3458764513820540929
27+
// TBI: call swiftcc void @"$s18isolation_macro_ir8useActor3isoyScA_pSg_tF"(i64 %1, i64 [[MASKED_SECOND_WORD]])
28+
29+
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir46nonisolatedNonsendingUsePoundIsolationDirectlyyyYaF"(ptr swiftasync %0, i64 [[FIRST_WORD:%.*]], i64 [[SECOND_WORD:%.*]])
30+
// NO-TBI: [[MASKED_SECOND_WORD:%.*]] = and i64 [[SECOND_WORD]], -4
31+
// NO-TBI: call swiftcc void @"$s18isolation_macro_ir8useActor3isoyScA_pSg_tF"(i64 [[FIRST_WORD]], i64 [[MASKED_SECOND_WORD]])
32+
33+
public nonisolated(nonsending) func nonisolatedNonsendingUsePoundIsolationDirectly() async {
34+
let iso = #isolation
35+
useActor(iso: iso)
36+
}
37+
38+
// #isolation via default arg
39+
//
40+
// TBI: define swifttailcc void @"$s18isolation_macro_ir45nonisolatedNonsendingPoundIsolationDefaultArgyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[WORD_2:%.*]])
41+
// TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -3458764513820540929
42+
// TBI: call swiftcc void @"$s18isolation_macro_ir13implicitParamyyScA_pSgF"(i64 {{%.*}}, i64 [[MASKED_WORD_2]])
43+
44+
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir45nonisolatedNonsendingPoundIsolationDefaultArgyyYaF"(ptr swiftasync %0, i64 [[WORD_1:%.*]], i64 [[WORD_2:%.*]])
45+
// NO-TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -4
46+
// NO-TBI: call swiftcc void @"$s18isolation_macro_ir13implicitParamyyScA_pSgF"(i64 {{%.*}}, i64 [[MASKED_WORD_2]])
47+
public nonisolated(nonsending) func nonisolatedNonsendingPoundIsolationDefaultArg() async {
48+
implicitParam()
49+
}
50+
51+
@inline(never)
52+
public nonisolated(nonsending) func calleeFunction() async {
53+
}
54+
55+
// TBI: define swifttailcc void @"$s18isolation_macro_ir14callerFunctionyyYaF"(ptr swiftasync %0, i64 %1, i64 [[WORD_2:%.*]])
56+
// TBI: [[MASKED_WORD_2:%.*]] = and i64 [[WORD_2]], -3458764513820540929
57+
// TBI: musttail call swifttailcc void @"$s18isolation_macro_ir14calleeFunctionyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[MASKED_WORD_2]])
58+
59+
// NO-TBI: define swifttailcc void @"$s18isolation_macro_ir14callerFunctionyyYaF"(ptr swiftasync %0, i64 %1, i64 [[WORD:%.*]])
60+
// NO-TBI: [[MASKED_WORD:%.*]] = and i64 [[WORD]], -4
61+
// NO-TBI: musttail call swifttailcc void @"$s18isolation_macro_ir14calleeFunctionyyYaF"(ptr swiftasync {{%.*}}, i64 {{%.*}}, i64 [[MASKED_WORD]])
62+
@inline(never)
63+
public nonisolated(nonsending) func callerFunction() async {
64+
await calleeFunction()
65+
}

0 commit comments

Comments
 (0)