Skip to content

Commit 9e560ce

Browse files
author
Joe Shajrawi
committed
[LoadableByAddress] handle functions that return a closure in a tuple
1 parent 6a604b6 commit 9e560ce

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,8 @@ class LoadableByAddress : public SILModuleTransform {
16031603
SmallVectorImpl<SILInstruction *> &Delete);
16041604
bool recreateApply(SILInstruction &I,
16051605
SmallVectorImpl<SILInstruction *> &Delete);
1606+
bool recreateTupleInstr(SILInstruction &I,
1607+
SmallVectorImpl<SILInstruction *> &Delete);
16061608
bool recreateConvInstr(SILInstruction &I,
16071609
SmallVectorImpl<SILInstruction *> &Delete);
16081610
bool recreateBuiltinInstr(SILInstruction &I,
@@ -2613,6 +2615,34 @@ bool LoadableByAddress::fixStoreToBlockStorageInstr(
26132615
return true;
26142616
}
26152617

2618+
bool LoadableByAddress::recreateTupleInstr(
2619+
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
2620+
auto *tupleInstr = dyn_cast<TupleInst>(&I);
2621+
if (!tupleInstr)
2622+
return false;
2623+
2624+
// Check if we need to recreate the tuple:
2625+
auto *F = tupleInstr->getFunction();
2626+
auto *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
2627+
GenericEnvironment *genEnv = F->getGenericEnvironment();
2628+
auto resultTy = tupleInstr->getType();
2629+
auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod);
2630+
if (resultTy == newResultTy)
2631+
return true;
2632+
2633+
// The tuple type have changed based on its members.
2634+
// For example if one or more of them are ‘large’ loadable types
2635+
SILBuilderWithScope tupleBuilder(tupleInstr);
2636+
SmallVector<SILValue, 8> elems;
2637+
for (auto elem : tupleInstr->getElements()) {
2638+
elems.push_back(elem);
2639+
}
2640+
auto *newTuple = tupleBuilder.createTuple(tupleInstr->getLoc(), elems);
2641+
tupleInstr->replaceAllUsesWith(newTuple);
2642+
Delete.push_back(tupleInstr);
2643+
return true;
2644+
}
2645+
26162646
bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
26172647
SmallVectorImpl<SILInstruction *> &Delete) {
26182648
auto *convInstr = dyn_cast<SingleValueInstruction>(&I);
@@ -2851,7 +2881,9 @@ void LoadableByAddress::run() {
28512881
SmallVector<SILInstruction *, 32> Delete;
28522882
for (SILBasicBlock &BB : CurrF) {
28532883
for (SILInstruction &I : BB) {
2854-
if (recreateConvInstr(I, Delete))
2884+
if (recreateTupleInstr(I, Delete))
2885+
continue;
2886+
else if (recreateConvInstr(I, Delete))
28552887
continue;
28562888
else if (recreateBuiltinInstr(I, Delete))
28572889
continue;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -Xllvm -sil-verify-after-pass=loadable-address -emit-ir -o %t.ll %s
2+
3+
// Just make sure we don't crash.
4+
5+
6+
struct Large {
7+
var a: Int = 1
8+
var b: Int = 1
9+
var c: Int = 1
10+
var d: Int = 1
11+
var e: Int = 1
12+
var f: Int = 1
13+
var g: Int = 1
14+
var h: Int = 1
15+
}
16+
17+
func test(_ x: Large) -> (Large, (Large) -> Large) {
18+
return (x, {$0})
19+
}

0 commit comments

Comments
 (0)