Skip to content

Commit d42b260

Browse files
authored
Merge pull request #84732 from rjmccall/variadic-witness-fixes-6.2
[6.2] Fix some major SILGen bugs with pack handling:
2 parents 2a18def + fd918f1 commit d42b260

File tree

5 files changed

+297
-22
lines changed

5 files changed

+297
-22
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,8 @@ class Callee {
524524

525525
auto &ci = SGF.getConstantInfo(SGF.getTypeExpansionContext(), c);
526526
return Callee(
527-
Kind::WitnessMethod, SGF, c, ci.FormalPattern, ci.FormalType,
527+
Kind::WitnessMethod, SGF, c,
528+
ci.FormalPattern.withSubstitutions(subs), ci.FormalType,
528529
subs.mapIntoTypeExpansionContext(SGF.getTypeExpansionContext()), l);
529530
}
530531
static Callee forDynamic(SILGenFunction &SGF,

lib/SILGen/SILGenPack.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,8 +1131,9 @@ SILGenFunction::emitPackTransform(SILLocation loc,
11311131
outputEltAddr = outputElt.forward(*this);
11321132

11331133
// Otherwise, if the value is not already in the temporary, put it there.
1134-
} else if (!outputElt.isInContext()) {
1135-
outputElt.forwardInto(*this, loc, outputEltInit.get());
1134+
} else {
1135+
if (!outputElt.isInContext())
1136+
outputElt.forwardInto(*this, loc, outputEltInit.get());
11361137
outputEltInit->getManagedAddress().forward(*this);
11371138
}
11381139

lib/SILGen/SILGenPoly.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,8 +2417,15 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
24172417
return innerPackParam.getConvention();
24182418
}
24192419

2420-
ParamInfo getInnerPackExpansionSlot(SILValue packAddr) {
2421-
return ParamInfo(IndirectSlot(packAddr), getInnerPackConvention());
2420+
ParamInfo getInnerPackExpansionSlot(ManagedValue packAddr) {
2421+
// Ignore the ownership of the pack address --- it'll be an
2422+
// l-value or r-value depending on what kind of argument we're
2423+
// producing, but there's no meaningful ownership yet, and in
2424+
// any case it won't have any cleanups attached.
2425+
assert(!packAddr.hasCleanup());
2426+
2427+
return ParamInfo(IndirectSlot(packAddr.getValue()),
2428+
getInnerPackConvention());
24222429
}
24232430

24242431
/// Given an element of an inner pack that we're emitting into,
@@ -2771,15 +2778,29 @@ ManagedValue TranslateArguments::expandPackInnerParam(
27712778
// cleanup onto the elements.
27722779
auto outerComponent = outerParam.projectPackComponent(SGF, Loc);
27732780

2774-
// We can only do direct forwarding of of the pack elements in
2775-
// one very specific case right now. That isn't great, but we
2776-
// have to live with it.
2777-
bool forwardouterToinner =
2778-
(outerExpansionTy.getPatternType()
2779-
== innerExpansionTy.getPatternType());
2780-
2781-
// The result of the transformation will be +1 unless we do that.
2782-
bool innerIsPlusOne = !forwardouterToinner;
2781+
bool patternTypesMatch =
2782+
outerExpansionTy.getPatternType() == innerExpansionTy.getPatternType();
2783+
2784+
auto innerPatternTypeIsTrivial =
2785+
SGF.getTypeLowering(innerExpansionTy.getPatternType()).isTrivial();
2786+
bool outerIsConsumed = outerComponent.hasCleanup();
2787+
bool innerIsConsumed =
2788+
isConsumedParameterInCaller(innerPackParam.getConvention());
2789+
2790+
// We can only do direct forwarding of of the pack elements (without
2791+
// needing temporary memory) if they have exactly the same type and
2792+
// we're not turning a borrowed parameter into a consuming one.
2793+
bool forwardOuterToInner =
2794+
(patternTypesMatch &&
2795+
(innerPatternTypeIsTrivial || outerIsConsumed || !innerIsConsumed));
2796+
2797+
// The result of the transformation function below will be +1 unless
2798+
// we directly forward that (or if direct forwarding produces an owned
2799+
// or trivial value).
2800+
bool innerIsPlusOne =
2801+
(!forwardOuterToInner ||
2802+
innerPatternTypeIsTrivial ||
2803+
outerIsConsumed);
27832804

27842805
ManagedValue inner =
27852806
SGF.emitPackTransform(Loc, outerComponent,
@@ -2788,13 +2809,18 @@ ManagedValue TranslateArguments::expandPackInnerParam(
27882809
innerPackAddr,
27892810
innerFormalPackType,
27902811
innerComponentIndex,
2791-
/*is trivial*/ forwardouterToinner,
2812+
/*is simple projection*/ forwardOuterToInner,
27922813
innerIsPlusOne,
27932814
[&](ManagedValue outerEltAddr, SILType innerEltTy,
27942815
SGFContext ctxt) {
27952816
// If we decided to just forward, we can do that now.
2796-
if (forwardouterToinner)
2817+
if (forwardOuterToInner) {
2818+
// It's okay to return an owned value here even if we're
2819+
// producing this for a borrowed parameter. We'll end up with
2820+
// an argument with cleanups, which in the end we just won't
2821+
// forward.
27972822
return outerEltAddr;
2823+
}
27982824

27992825
// Otherwise, map the subst pattern types into element context.
28002826
CanType innerSubstEltType =
@@ -3455,8 +3481,8 @@ class ResultPlanner : public ExpanderBase<ResultPlanner, IndirectSlot> {
34553481
return temporary;
34563482
}
34573483

3458-
IndirectSlot getInnerPackExpansionSlot(SILValue packAddr) {
3459-
return IndirectSlot(packAddr);
3484+
IndirectSlot getInnerPackExpansionSlot(ManagedValue packAddr) {
3485+
return IndirectSlot(packAddr.getLValueAddress());
34603486
}
34613487

34623488
IndirectSlot getInnerPackElementSlot(SILType elementTy) {
@@ -3810,8 +3836,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuples(
38103836
ManagedValue outerPackComponent =
38113837
outerElt.projectPackComponent(SGF, Loc);
38123838

3813-
auto innerEltSlot = asImpl().getInnerPackExpansionSlot(
3814-
innerElt.getPackValue().getLValueAddress());
3839+
auto innerEltSlot =
3840+
asImpl().getInnerPackExpansionSlot(innerElt.getPackValue());
38153841
ManagedValue innerPackComponent = asImpl().expandPackExpansion(
38163842
innerElt.getOrigType(),
38173843
cast<PackExpansionType>(innerElt.getSubstType()),
@@ -4591,8 +4617,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuplesOuterIndirect(
45914617
continue;
45924618
}
45934619

4594-
auto innerExpansionSlot = asImpl().getInnerPackExpansionSlot(
4595-
innerElt.getPackValue().getLValueAddress());
4620+
auto innerExpansionSlot =
4621+
asImpl().getInnerPackExpansionSlot(innerElt.getPackValue());
45964622
asImpl().expandPackExpansion(innerElt.getOrigType(),
45974623
cast<PackExpansionType>(innerElt.getSubstType()),
45984624
outerElt.getOrigType(),

lib/SILGen/SILGenProlog.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ class ArgumentInitHelper {
902902
ManagedValue argrv = makeArgument(loc, pd);
903903
if (pd->isInOut()) {
904904
assert(argrv.getType().isAddress() && "expected inout to be address");
905+
} else if (argrv.getType().is<SILPackType>()) {
906+
assert(argrv.getType().isAddress() && "expected pack to be address");
905907
} else if (!pd->isImmutableInFunctionBody()) {
906908
// If it's a locally mutable parameter, then we need to move the argument
907909
// value into a local box to hold the mutated value.

0 commit comments

Comments
 (0)