Skip to content

Commit c1f110c

Browse files
committed
Generalize the handling of pack cleanups in reabstraction thunks
The result-reabstraction code doesn't need to handle cleanups properly during the planning phase because of course we don't have any values yet. That is not true of argument reabstraction, so we need to make sure that the recursive emitters can produce values with cleanups so that we can collect and forward those cleanups correctly when emitting the call. As part of this, I've changed the code so that it should forward outer addresses to inner address more consistently; it wouldn't have done this before if we were breaking apart or assembling a pack. I'm not sure I can directly test this without figuring out a way to get SILGen to reabstract both sides of a function, though. I'm not sure this is really doing borrowed vs owned arguments correctly, if e.g. we need to rebstract one component of a tuple that's otherwise borrowed.
1 parent 6dc298a commit c1f110c

5 files changed

+382
-198
lines changed

lib/SILGen/SILGenFunction.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,13 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
25152515
CanPackType formalPackType,
25162516
unsigned componentIndex);
25172517

2518+
/// Enter a cleanup to destroy the preceding components of a pack,
2519+
/// leading up to (but not including) a particular component index.
2520+
CleanupHandle
2521+
enterDestroyPrecedingPackComponentsCleanup(SILValue addr,
2522+
CanPackType formalPackType,
2523+
unsigned componentIndex);
2524+
25182525
/// Enter a cleanup to destroy the preceding values in a pack-expansion
25192526
/// component of a tuple.
25202527
///
@@ -2766,7 +2773,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
27662773
void emitDestroyPack(SILLocation loc,
27672774
SILValue packAddr,
27682775
CanPackType formalPackType,
2769-
unsigned firstComponentIndex = 0);
2776+
unsigned beginIndex,
2777+
unsigned endIndex);
27702778

27712779
/// Emit instructions to destroy a suffix of a tuple value.
27722780
///

lib/SILGen/SILGenPack.cpp

+28-13
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,26 @@ class DeallocPackCleanup : public Cleanup {
4444
class DestroyPackCleanup : public Cleanup {
4545
SILValue Addr;
4646
CanPackType FormalPackType;
47-
unsigned FirstComponentIndex;
47+
unsigned BeginIndex, EndIndex;
4848
public:
4949
DestroyPackCleanup(SILValue addr, CanPackType formalPackType,
50-
unsigned firstComponentIndex = 0)
50+
unsigned beginIndex, unsigned endIndex)
5151
: Addr(addr), FormalPackType(formalPackType),
52-
FirstComponentIndex(firstComponentIndex) {}
52+
BeginIndex(beginIndex), EndIndex(endIndex) {}
5353

5454
void emit(SILGenFunction &SGF, CleanupLocation l,
5555
ForUnwind_t forUnwind) override {
56-
SGF.emitDestroyPack(l, Addr, FormalPackType, FirstComponentIndex);
56+
SGF.emitDestroyPack(l, Addr, FormalPackType, BeginIndex, EndIndex);
5757
}
5858

5959
void dump(SILGenFunction &) const override {
6060
#ifndef NDEBUG
6161
llvm::errs() << "DestroyPackCleanup\n"
62-
<< "State: " << getState() << "\n"
63-
<< "Addr: " << Addr << "FormalPackType: " << FormalPackType
64-
<< "FirstComponentIndex:" << FirstComponentIndex << "\n";
62+
<< "State:" << getState() << "\n"
63+
<< "Addr:" << Addr << "\n"
64+
<< "FormalPackType:" << FormalPackType << "\n"
65+
<< "BeginIndex:" << BeginIndex << "\n"
66+
<< "EndIndex:" << EndIndex << "\n";
6567
#endif
6668
}
6769
};
@@ -295,19 +297,29 @@ CleanupHandle SILGenFunction::enterDeallocPackCleanup(SILValue temp) {
295297

296298
CleanupHandle SILGenFunction::enterDestroyPackCleanup(SILValue addr,
297299
CanPackType formalPackType) {
298-
Cleanups.pushCleanup<DestroyPackCleanup>(addr, formalPackType);
300+
Cleanups.pushCleanup<DestroyPackCleanup>(addr, formalPackType,
301+
0, formalPackType->getNumElements());
299302
return Cleanups.getTopCleanup();
300303
}
301304

302305
CleanupHandle
303-
SILGenFunction::enterDestroyRemainingPackComponentsCleanup(SILValue addr,
306+
SILGenFunction::enterDestroyPrecedingPackComponentsCleanup(SILValue addr,
304307
CanPackType formalPackType,
305308
unsigned componentIndex) {
306309
Cleanups.pushCleanup<DestroyPackCleanup>(addr, formalPackType,
307-
componentIndex);
310+
0, componentIndex);
308311
return Cleanups.getTopCleanup();
309312
}
310313

314+
CleanupHandle
315+
SILGenFunction::enterDestroyRemainingPackComponentsCleanup(SILValue addr,
316+
CanPackType formalPackType,
317+
unsigned componentIndex) {
318+
Cleanups.pushCleanup<DestroyPackCleanup>(addr, formalPackType,
319+
componentIndex,
320+
formalPackType->getNumElements());
321+
return Cleanups.getTopCleanup();
322+
}
311323

312324
CleanupHandle
313325
SILGenFunction::enterPartialDestroyPackCleanup(SILValue addr,
@@ -369,12 +381,15 @@ SILGenFunction::enterDestroyRemainingTupleElementsCleanup(SILValue addr,
369381

370382
void SILGenFunction::emitDestroyPack(SILLocation loc, SILValue packAddr,
371383
CanPackType formalPackType,
372-
unsigned firstComponentIndex) {
384+
unsigned beginIndex,
385+
unsigned endIndex) {
373386
auto packTy = packAddr->getType().castTo<SILPackType>();
374387

388+
assert(beginIndex <= endIndex);
389+
assert(endIndex <= packTy->getNumElements());
390+
375391
// Destroy each of the elements of the pack.
376-
for (auto componentIndex :
377-
range(firstComponentIndex, packTy->getNumElements())) {
392+
for (auto componentIndex : range(beginIndex, endIndex)) {
378393
auto eltTy = packTy->getSILElementType(componentIndex);
379394

380395
// We can skip this if the whole thing is trivial.

0 commit comments

Comments
 (0)