Skip to content

Commit a05fef5

Browse files
committed
Implement parameter arity reabstraction.
This is largely a matter of changing the main loop over subst params in TranslateArguments to use the generators I added, then plugging back into the general reabstraction infrastructure. Because we don't have pack coroutines, we're kind of stuck in the code generation for pack reabstraction: we have to write +1 r-values into a temporary tuple and then write those tuple element addresses into the output pack. It's not great. We also have lifetime problems with things like non-escaping closures --- we have that problem outside of reabstraction thunks, too. Other than that glaring problem, I'm feeling relatively good about the code here. It's missing some peepholes, but it should work. But that that's not to say that arity reabstraction works in general; my attempts to test it have been exposing some problems elsewhere, and in particular the closure case crashes, which is really bad. But this gets a few more things working, and this PR is quite large already.
1 parent 5f1a669 commit a05fef5

File tree

7 files changed

+1111
-102
lines changed

7 files changed

+1111
-102
lines changed

lib/SILGen/Cleanup.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,58 @@ CleanupCloner::cloneForTuplePackExpansionComponent(SILValue tupleAddr,
444444
/*start at */ SILValue());
445445
return ManagedValue(tupleAddr, cleanup);
446446
}
447+
448+
ManagedValue
449+
CleanupCloner::cloneForPackPackExpansionComponent(SILValue packAddr,
450+
CanPackType formalPackType,
451+
unsigned componentIndex) const {
452+
if (isLValue) {
453+
return ManagedValue::forLValue(packAddr);
454+
}
455+
456+
if (!hasCleanup) {
457+
return ManagedValue::forUnmanaged(packAddr);
458+
}
459+
460+
assert(!writebackBuffer.has_value());
461+
auto expansionTy = packAddr->getType().getPackElementType(componentIndex);
462+
if (expansionTy.getPackExpansionPatternType().isTrivial(SGF.F))
463+
return ManagedValue::forUnmanaged(packAddr);
464+
465+
auto cleanup =
466+
SGF.enterPartialDestroyRemainingPackCleanup(packAddr, formalPackType,
467+
componentIndex,
468+
/*start at */ SILValue());
469+
return ManagedValue(packAddr, cleanup);
470+
}
471+
472+
ManagedValue
473+
CleanupCloner::cloneForRemainingPackComponents(SILValue packAddr,
474+
CanPackType formalPackType,
475+
unsigned firstComponentIndex) const {
476+
if (isLValue) {
477+
return ManagedValue::forLValue(packAddr);
478+
}
479+
480+
if (!hasCleanup) {
481+
return ManagedValue::forUnmanaged(packAddr);
482+
}
483+
484+
assert(!writebackBuffer.has_value());
485+
bool isTrivial = true;
486+
auto packTy = packAddr->getType().castTo<SILPackType>();
487+
for (auto eltTy : packTy->getElementTypes().slice(firstComponentIndex)) {
488+
if (!SILType::getPrimitiveObjectType(eltTy).isTrivial(SGF.F)) {
489+
isTrivial = false;
490+
break;
491+
}
492+
}
493+
494+
if (isTrivial)
495+
return ManagedValue::forUnmanaged(packAddr);
496+
497+
auto cleanup =
498+
SGF.enterDestroyRemainingPackComponentsCleanup(packAddr, formalPackType,
499+
firstComponentIndex);
500+
return ManagedValue(packAddr, cleanup);
501+
}

lib/SILGen/Cleanup.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,14 @@ class CleanupCloner {
342342
CanPackType inducedPackType,
343343
unsigned componentIndex) const;
344344

345+
ManagedValue cloneForPackPackExpansionComponent(SILValue packAddr,
346+
CanPackType formalPackType,
347+
unsigned componentIndex) const;
348+
349+
ManagedValue cloneForRemainingPackComponents(SILValue packAddr,
350+
CanPackType formalPackType,
351+
unsigned firstComponentIndex) const;
352+
345353
static void
346354
getClonersForRValue(SILGenFunction &SGF, const RValue &rvalue,
347355
SmallVectorImpl<CleanupCloner> &resultingCloners);

lib/SILGen/SILGenFunction.h

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,28 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
24272427
unsigned componentIndex,
24282428
SILValue limitWithinComponent);
24292429

2430+
/// Enter a cleanup to destroy the following values in a
2431+
/// pack-expansion component of a pack. Note that this only destroys
2432+
/// the values *in that specific component*, not all the other values
2433+
/// in the pack.
2434+
///
2435+
/// \param currentIndexWithinComponent - the current index in the
2436+
/// pack expansion component; any elements in the component that
2437+
/// *follow* this component will be destroyed. If nil, all the
2438+
/// elements in the component will be destroyed
2439+
CleanupHandle
2440+
enterPartialDestroyRemainingPackCleanup(SILValue addr,
2441+
CanPackType formalPackType,
2442+
unsigned componentIndex,
2443+
SILValue currentIndexWithinComponent);
2444+
2445+
/// Enter a cleanup to destroy all of the components in a pack starting
2446+
/// at a particular component index.
2447+
CleanupHandle
2448+
enterDestroyRemainingPackComponentsCleanup(SILValue addr,
2449+
CanPackType formalPackType,
2450+
unsigned componentIndex);
2451+
24302452
/// Enter a cleanup to destroy the preceding values in a pack-expansion
24312453
/// component of a tuple.
24322454
///
@@ -2439,7 +2461,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
24392461
SILValue limitWithinComponent);
24402462

24412463
/// Enter a cleanup to destroy the following values in a
2442-
/// pack-expansion component of a tuple
2464+
/// pack-expansion component of a tuple. Note that this only destroys
2465+
/// the values *in that specific component*, not all the other values
2466+
/// in the tuple.
24432467
///
24442468
/// \param currentIndexWithinComponent - the current index in the
24452469
/// pack expansion component; any elements in the component that
@@ -2560,6 +2584,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
25602584
std::pair<GenericEnvironment*, SILType>
25612585
createOpenedElementValueEnvironment(SILType packExpansionTy);
25622586

2587+
GenericEnvironment *
2588+
createOpenedElementValueEnvironment(ArrayRef<SILType> packExpansionTys,
2589+
ArrayRef<SILType*> eltTys);
2590+
25632591
/// Emit a dynamic loop over a single pack-expansion component of a pack.
25642592
///
25652593
/// \param formalPackType - a pack type with the right shape for the
@@ -2610,6 +2638,26 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
26102638
SILValue packExpansionIndex,
26112639
SILValue packIndex)> emitBody);
26122640

2641+
/// Emit a transform on each element of a pack-expansion component
2642+
/// of a pack, write the result into a pack-expansion component of
2643+
/// another pack.
2644+
///
2645+
/// \param inputPackAddr - the address of the input pack; the cleanup
2646+
/// on this pack should be a cleanup for just the pack component,
2647+
/// not for the entire pack
2648+
ManagedValue emitPackTransform(SILLocation loc,
2649+
ManagedValue inputPackAddr,
2650+
CanPackType inputFormalPackType,
2651+
unsigned inputComponentIndex,
2652+
SILValue outputPackAddr,
2653+
CanPackType outputFormalPackType,
2654+
unsigned outputComponentIndex,
2655+
bool isSimpleProjection,
2656+
bool outputIsPlusOne,
2657+
llvm::function_ref<ManagedValue(ManagedValue input,
2658+
SILType outputTy,
2659+
SGFContext context)> emitBody);
2660+
26132661
/// Emit a loop which destroys a prefix of a pack expansion component
26142662
/// of a pack value.
26152663
///
@@ -2634,7 +2682,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
26342682
/// overall pack value
26352683
void emitDestroyPack(SILLocation loc,
26362684
SILValue packAddr,
2637-
CanPackType formalPackType);
2685+
CanPackType formalPackType,
2686+
unsigned firstComponentIndex = 0);
26382687

26392688
/// Emit a loop which destroys a prefix of a pack expansion component
26402689
/// of a tuple value.
@@ -2669,6 +2718,23 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
26692718
CanPackType inducedPackType,
26702719
unsigned componentIndex,
26712720
SILValue currentIndexWithinComponent);
2721+
2722+
/// Emit a loop which destroys a suffix of a pack expansion component
2723+
/// of a pack value.
2724+
///
2725+
/// \param packAddr - the address of the overall pack value
2726+
/// \param formalPackType - a pack type with the same shape as the
2727+
/// component types of the overall pack value
2728+
/// \param componentIndex - the index of the pack expansion component
2729+
/// within the pack
2730+
/// \param currentIndexWithinComponent - the current index in the
2731+
/// pack expansion component; all elements *following* this index will
2732+
/// be destroyed
2733+
void emitPartialDestroyRemainingPack(SILLocation loc,
2734+
SILValue packAddr,
2735+
CanPackType formalPackType,
2736+
unsigned componentIndex,
2737+
SILValue currentIndexWithinComponent);
26722738
};
26732739

26742740

0 commit comments

Comments
 (0)