Skip to content

Commit f2c5a4c

Browse files
Merge pull request #5206 from swiftwasm/release/5.8
[pull] swiftwasm-release/5.8 from release/5.8
2 parents fd20071 + aa8ff46 commit f2c5a4c

File tree

8 files changed

+214
-36
lines changed

8 files changed

+214
-36
lines changed

lib/SILGen/SILGenBackDeploy.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,20 +176,28 @@ void SILGenFunction::emitBackDeploymentThunk(SILDeclRef thunk) {
176176

177177
F.setGenericEnvironment(SGM.Types.getConstantGenericEnvironment(thunk));
178178

179-
emitBasicProlog(FD->getParameters(), FD->getImplicitSelfDecl(),
180-
FD->getResultInterfaceType(), FD, FD->hasThrows(),
181-
FD->getThrowsLoc());
182-
prepareEpilog(FD->getResultInterfaceType(), FD->hasThrows(),
183-
CleanupLocation(FD));
179+
// Generate the thunk prolog by collecting parameters.
180+
SmallVector<ManagedValue, 4> params;
181+
SmallVector<SILArgument *, 4> indirectParams;
182+
collectThunkParams(loc, params, &indirectParams);
184183

185-
// Gather the entry block's arguments up so that we can forward them.
184+
// Build up the list of arguments that we're going to invoke the the real
185+
// function with.
186186
SmallVector<SILValue, 8> paramsForForwarding;
187-
SILBasicBlock *entryBlock = getFunction().getEntryBlock();
188-
for (SILArgument *arg :
189-
make_range(entryBlock->args_begin(), entryBlock->args_end())) {
190-
paramsForForwarding.emplace_back(arg);
187+
for (auto indirectParam : indirectParams) {
188+
paramsForForwarding.emplace_back(indirectParam);
189+
}
190+
191+
for (auto param : params) {
192+
// We're going to directly call either the original function or the fallback
193+
// function with these arguments and then return. Therefore we just forward
194+
// the arguments instead of handling their ownership conventions.
195+
paramsForForwarding.emplace_back(param.forward(*this));
191196
}
192197

198+
prepareEpilog(FD->getResultInterfaceType(), FD->hasThrows(),
199+
CleanupLocation(FD));
200+
193201
SILBasicBlock *availableBB = createBasicBlock("availableBB");
194202
SILBasicBlock *unavailableBB = createBasicBlock("unavailableBB");
195203

lib/Sema/BuilderTransform.cpp

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,26 +1255,9 @@ class ResultBuilderTransform
12551255
auto *builderCall =
12561256
buildWrappedChainPayload(branchVarRef, i, numPayloads, isOptional);
12571257

1258-
auto isTopLevel = [&](Stmt *anchor) {
1259-
if (ifStmt->getThenStmt() == anchor)
1260-
return true;
1261-
1262-
// The situation is this:
1263-
//
1264-
// if <cond> {
1265-
// ...
1266-
// } else if <other-cond> {
1267-
// ...
1268-
// }
1269-
if (auto *innerIf = getAsStmt<IfStmt>(ifStmt->getElseStmt()))
1270-
return innerIf->getThenStmt() == anchor;
1271-
1272-
return ifStmt->getElseStmt() == anchor;
1273-
};
1274-
12751258
// The operand should have optional type if we had optional results,
12761259
// so we just need to call `buildIf` now, since we're at the top level.
1277-
if (isOptional && isTopLevel(anchor)) {
1260+
if (isOptional) {
12781261
builderCall = buildCallIfWanted(ifStmt->getThenStmt()->getStartLoc(),
12791262
builder.getBuildOptionalId(),
12801263
builderCall, /*argLabels=*/{});

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,15 @@ static void _enqueueCompletedTask(NaiveTaskGroupQueue<ReadyQueueItem> *readyQueu
10601060
readyQueue->enqueue(readyItem);
10611061
}
10621062

1063+
/// This can only be used by a discarding task group;
1064+
/// Other groups must enqueue a complete Task to the ready queue.
1065+
static void _enqueueRawError(DiscardingTaskGroup* _Nonnull group,
1066+
NaiveTaskGroupQueue<ReadyQueueItem> *readyQueue,
1067+
SwiftError *error) {
1068+
auto readyItem = ReadyQueueItem::getRawError(group, error);
1069+
readyQueue->enqueue(readyItem);
1070+
}
1071+
10631072
// TaskGroup is locked upon entry and exit
10641073
void AccumulatingTaskGroup::enqueueCompletedTask(AsyncTask *completedTask, bool hadErrorResult) {
10651074
// Retain the task while it is in the queue; it must remain alive until
@@ -1233,6 +1242,7 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
12331242
}
12341243

12351244
auto afterComplete = statusCompletePendingAssumeRelease();
1245+
(void)afterComplete; // silence "not used" warning
12361246
SWIFT_TASK_GROUP_DEBUG_LOG(this, "offer, either more pending tasks, or no waiting task, status:%s",
12371247
afterComplete.to_string(this).c_str());
12381248
}
@@ -1348,7 +1358,7 @@ void DiscardingTaskGroup::resumeWaitingTaskWithError(
13481358
// we can't just have the parent task set itself up as a waiter.
13491359
// But since it's what we're doing, we basically take the same
13501360
// path as we would if there wasn't a waiter.
1351-
enqueueCompletedTask(completedTask, hadErrorResult);
1361+
_enqueueRawError(this, &readyQueue, error);
13521362
return;
13531363

13541364
#else /* SWIFT_CONCURRENCY_TASK_TO_THREAD_MODEL */

test/AutoDiff/compiler_crashers_fixed/rdar74087329-debug-scope-trampoline-blocks.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-build-swift %s
22
// RUN: %target-swift-frontend -c -g -Xllvm -verify-di-holes=true %s
3+
// REQUIRES: issue63107
34

45
// rdar://74087329 (DI verification failure with trampoline blocks in VJP)
56

test/Concurrency/Runtime/async_taskgroup_void_neverConsumingTasks.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// REQUIRES: executable_test
33
// REQUIRES: concurrency
44
// REQUIRES: concurrency_runtime
5+
6+
// REQUIRES: rdar104332560
7+
58
// UNSUPPORTED: back_deployment_runtime
69
// UNSUPPORTED: OS=linux-gnu
710

test/Constraints/result_builder.swift

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,3 +1252,134 @@ do {
12521252
}
12531253
// CHECK: the answer
12541254
}
1255+
1256+
protocol TestIfSequences {
1257+
}
1258+
1259+
struct A: TestIfSequences {}
1260+
struct B: TestIfSequences {}
1261+
struct C: TestIfSequences {}
1262+
struct D: TestIfSequences {}
1263+
1264+
func testOptionalIfElseSequences() {
1265+
func check<T>(_ v: TestIfSequences,
1266+
@TupleBuilder body: (TestIfSequences) throws -> T) rethrows {
1267+
print(try body(v))
1268+
}
1269+
1270+
check(A()) { v in
1271+
if let a = v as? A {
1272+
a
1273+
} else if let b = v as? B {
1274+
b
1275+
} else if let c = v as? C {
1276+
c
1277+
}
1278+
}
1279+
1280+
check(B()) { v in
1281+
if let a = v as? A {
1282+
a
1283+
} else if let b = v as? B {
1284+
b
1285+
} else if let c = v as? C {
1286+
c
1287+
}
1288+
}
1289+
1290+
check(C()) { v in
1291+
if let a = v as? A {
1292+
a
1293+
} else if let b = v as? B {
1294+
b
1295+
} else if let c = v as? C {
1296+
c
1297+
}
1298+
}
1299+
1300+
check(D()) { v in
1301+
if let a = v as? A {
1302+
a
1303+
} else if let b = v as? B {
1304+
b
1305+
} else if let c = v as? C {
1306+
c
1307+
} else {
1308+
D()
1309+
}
1310+
}
1311+
1312+
check(A()) { v in
1313+
if let a = v as? A {
1314+
a
1315+
} else {
1316+
if let b = v as? B {
1317+
b
1318+
}
1319+
1320+
if let c = v as? C {
1321+
c
1322+
} else if let d = v as? D {
1323+
d
1324+
}
1325+
}
1326+
}
1327+
1328+
check(B()) { v in
1329+
if let a = v as? A {
1330+
a
1331+
} else {
1332+
if let b = v as? B {
1333+
b
1334+
}
1335+
1336+
if let c = v as? C {
1337+
c
1338+
} else if let d = v as? D {
1339+
d
1340+
}
1341+
}
1342+
}
1343+
1344+
check(C()) { v in
1345+
if let a = v as? A {
1346+
a
1347+
} else {
1348+
if let b = v as? B {
1349+
b
1350+
}
1351+
1352+
if let c = v as? C {
1353+
c
1354+
} else if let d = v as? D {
1355+
d
1356+
}
1357+
}
1358+
}
1359+
1360+
check(D()) { v in
1361+
if let a = v as? A {
1362+
a
1363+
} else {
1364+
if let b = v as? B {
1365+
b
1366+
}
1367+
1368+
if let c = v as? C {
1369+
c
1370+
} else if let d = v as? D {
1371+
d
1372+
}
1373+
}
1374+
}
1375+
}
1376+
1377+
testOptionalIfElseSequences()
1378+
// CHECK: Optional(main.Either<main.Either<main.A, main.B>, main.C>.first(main.Either<main.A, main.B>.first(main.A())))
1379+
// CHECK-NEXT: Optional(main.Either<main.Either<main.A, main.B>, main.C>.first(main.Either<main.A, main.B>.second(main.B())))
1380+
// CHECK-NEXT: Optional(main.Either<main.Either<main.A, main.B>, main.C>.second(main.C()))
1381+
// CHECK-NEXT: second(main.Either<main.C, main.D>.second(main.D()))
1382+
// CHECK-NEXT: first(main.A())
1383+
// CHECK-NEXT: second(Optional(main.B()), nil)
1384+
// CHECK-NEXT: second(nil, Optional(main.Either<main.C, main.D>.first(main.C())))
1385+
// CHECK-NEXT: second(nil, Optional(main.Either<main.C, main.D>.second(main.D())))

test/SILGen/back_deploy_attribute_generic_func.swift

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
// REQUIRES: OS=macosx
77

8-
// -- Fallback definition of genericFunc()
8+
// -- Fallback definition of genericFunc(_:)
99
// CHECK-LABEL: sil non_abi [serialized] [ossa] @$s11back_deploy11genericFuncyxxlFTwB : $@convention(thin) <T> (@in_guaranteed T) -> @out T
1010
// CHECK: bb0([[OUT_ARG:%.*]] : $*T, [[IN_ARG:%.*]] : $*T):
1111
// CHECK: copy_addr [[IN_ARG]] to [init] [[OUT_ARG]] : $*T
1212
// CHECK: [[RESULT:%.*]] = tuple ()
1313
// CHECK: return [[RESULT]] : $()
1414

15-
// -- Back deployment thunk for genericFunc()
15+
// -- Back deployment thunk for genericFunc(_:)
1616
// CHECK-LABEL: sil non_abi [serialized] [thunk] [ossa] @$s11back_deploy11genericFuncyxxlFTwb : $@convention(thin) <T> (@in_guaranteed T) -> @out T
1717
// CHECK: bb0([[OUT_ARG:%.*]] : $*T, [[IN_ARG:%.*]] : $*T):
1818
// CHECK: [[MAJOR:%.*]] = integer_literal $Builtin.Word, 10
@@ -36,16 +36,58 @@
3636
// CHECK: [[RESULT:%.*]] = tuple ()
3737
// CHECK: return [[RESULT]] : $()
3838

39-
// -- Original definition of genericFunc()
39+
// -- Original definition of genericFunc(_:)
4040
// CHECK-LABEL: sil [available 10.52] [ossa] @$s11back_deploy11genericFuncyxxlF : $@convention(thin) <T> (@in_guaranteed T) -> @out T
4141
@_backDeploy(before: macOS 10.52)
4242
public func genericFunc<T>(_ t: T) -> T {
4343
return t
4444
}
4545

46+
// -- Fallback definition of genericFuncWithOwnedParam(_:)
47+
// CHECK-LABEL: sil non_abi [serialized] [ossa] @$s11back_deploy25genericFuncWithOwnedParamyyxnlFTwB : $@convention(thin) <T> (@in T) -> ()
48+
// CHECK: bb0([[IN_ARG:%.*]] : $*T):
49+
// CHECK: destroy_addr [[IN_ARG]] : $*T
50+
// CHECK: [[RESULT:%.*]] = tuple ()
51+
// CHECK: return [[RESULT]] : $()
52+
53+
// -- Back deployment thunk for genericFuncWithOwnedParam(_:)
54+
// CHECK-LABEL: sil non_abi [serialized] [thunk] [ossa] @$s11back_deploy25genericFuncWithOwnedParamyyxnlFTwb : $@convention(thin) <T> (@in T) -> ()
55+
// CHECK: bb0([[IN_ARG:%.*]] : $*T):
56+
// CHECK: [[MAJOR:%.*]] = integer_literal $Builtin.Word, 10
57+
// CHECK: [[MINOR:%.*]] = integer_literal $Builtin.Word, 52
58+
// CHECK: [[PATCH:%.*]] = integer_literal $Builtin.Word, 0
59+
// CHECK: [[OSVFN:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1
60+
// CHECK: [[AVAIL:%.*]] = apply [[OSVFN]]([[MAJOR]], [[MINOR]], [[PATCH]]) : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1
61+
// CHECK: cond_br [[AVAIL]], [[AVAIL_BB:bb[0-9]+]], [[UNAVAIL_BB:bb[0-9]+]]
62+
//
63+
// CHECK: [[UNAVAIL_BB]]:
64+
// CHECK: [[FALLBACKFN:%.*]] = function_ref @$s11back_deploy25genericFuncWithOwnedParamyyxnlFTwB : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
65+
// CHECK: {{%.*}} = apply [[FALLBACKFN]]<T>([[IN_ARG]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
66+
// CHECK: br [[RETURN_BB:bb[0-9]+]]
67+
//
68+
// CHECK: [[AVAIL_BB]]:
69+
// CHECK: [[ORIGFN:%.*]] = function_ref @$s11back_deploy25genericFuncWithOwnedParamyyxnlF : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
70+
// CHECK: {{%.*}} = apply [[ORIGFN]]<T>([[IN_ARG]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
71+
// CHECK: br [[RETURN_BB]]
72+
//
73+
// CHECK: [[RETURN_BB]]
74+
// CHECK-NOT: destroy_addr
75+
// CHECK: [[RESULT:%.*]] = tuple ()
76+
// CHECK: return [[RESULT]] : $()
77+
78+
// -- Original definition of genericFuncWithOwnedParam(_:)
79+
// CHECK-LABEL: sil [available 10.52] [ossa] @$s11back_deploy25genericFuncWithOwnedParamyyxnlF : $@convention(thin) <T> (@in T) -> ()
80+
@_backDeploy(before: macOS 10.52)
81+
public func genericFuncWithOwnedParam<T>(_ t: __owned T) { }
82+
83+
struct S {}
84+
4685
// CHECK-LABEL: sil hidden [ossa] @$s11back_deploy6calleryyF : $@convention(thin) () -> ()
4786
func caller() {
48-
// -- Verify the thunk is called
87+
// -- Verify the thunks are called
4988
// CHECK: {{%.*}} = function_ref @$s11back_deploy11genericFuncyxxlFTwb : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
50-
_ = genericFunc(Int32(1))
89+
_ = genericFunc(S())
90+
91+
// CHECK: {{%.*}} = function_ref @$s11back_deploy25genericFuncWithOwnedParamyyxnlFTwb : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
92+
genericFuncWithOwnedParam(S())
5193
}

test/attr/Inputs/BackDeployHelper.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public func v2APIsAreStripped() -> Bool {
3535
/// Describes types that can be appended to.
3636
public protocol Appendable {
3737
associatedtype Element
38-
mutating func append(_ x: Element)
38+
mutating func append(_ x: __owned Element)
3939
}
4040

4141
/// Describes types that can be counted.
@@ -107,7 +107,7 @@ public func pleaseThrow(_ shouldThrow: Bool) throws -> Bool {
107107
@_backDeploy(before: BackDeploy 2.0)
108108
public func genericAppend<T: Appendable>(
109109
_ a: inout T,
110-
_ x: T.Element
110+
_ x: __owned T.Element
111111
) {
112112
return a.append(x)
113113
}

0 commit comments

Comments
 (0)