Skip to content

Commit fee0e5c

Browse files
authored
Merge pull request #83555 from rjmccall/variadic-witness-fixes
Fix some major SILGen bugs with pack handling:
2 parents 35e1276 + 8ad4aae commit fee0e5c

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
@@ -523,7 +523,8 @@ class Callee {
523523

524524
auto &ci = SGF.getConstantInfo(SGF.getTypeExpansionContext(), c);
525525
return Callee(
526-
Kind::WitnessMethod, SGF, c, ci.FormalPattern, ci.FormalType,
526+
Kind::WitnessMethod, SGF, c,
527+
ci.FormalPattern.withSubstitutions(subs), ci.FormalType,
527528
substOpaqueTypesWithUnderlyingTypes(subs, SGF.getTypeExpansionContext()), l);
528529
}
529530
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
@@ -2416,8 +2416,15 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
24162416
return innerPackParam.getConvention();
24172417
}
24182418

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

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

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

27832804
ManagedValue inner =
27842805
SGF.emitPackTransform(Loc, outerComponent,
@@ -2787,13 +2808,18 @@ ManagedValue TranslateArguments::expandPackInnerParam(
27872808
innerPackAddr,
27882809
innerFormalPackType,
27892810
innerComponentIndex,
2790-
/*is trivial*/ forwardouterToinner,
2811+
/*is simple projection*/ forwardOuterToInner,
27912812
innerIsPlusOne,
27922813
[&](ManagedValue outerEltAddr, SILType innerEltTy,
27932814
SGFContext ctxt) {
27942815
// If we decided to just forward, we can do that now.
2795-
if (forwardouterToinner)
2816+
if (forwardOuterToInner) {
2817+
// It's okay to return an owned value here even if we're
2818+
// producing this for a borrowed parameter. We'll end up with
2819+
// an argument with cleanups, which in the end we just won't
2820+
// forward.
27962821
return outerEltAddr;
2822+
}
27972823

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

3457-
IndirectSlot getInnerPackExpansionSlot(SILValue packAddr) {
3458-
return IndirectSlot(packAddr);
3483+
IndirectSlot getInnerPackExpansionSlot(ManagedValue packAddr) {
3484+
return IndirectSlot(packAddr.getLValueAddress());
34593485
}
34603486

34613487
IndirectSlot getInnerPackElementSlot(SILType elementTy) {
@@ -3809,8 +3835,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuples(
38093835
ManagedValue outerPackComponent =
38103836
outerElt.projectPackComponent(SGF, Loc);
38113837

3812-
auto innerEltSlot = asImpl().getInnerPackExpansionSlot(
3813-
innerElt.getPackValue().getLValueAddress());
3838+
auto innerEltSlot =
3839+
asImpl().getInnerPackExpansionSlot(innerElt.getPackValue());
38143840
ManagedValue innerPackComponent = asImpl().expandPackExpansion(
38153841
innerElt.getOrigType(),
38163842
cast<PackExpansionType>(innerElt.getSubstType()),
@@ -4590,8 +4616,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuplesOuterIndirect(
45904616
continue;
45914617
}
45924618

4593-
auto innerExpansionSlot = asImpl().getInnerPackExpansionSlot(
4594-
innerElt.getPackValue().getLValueAddress());
4619+
auto innerExpansionSlot =
4620+
asImpl().getInnerPackExpansionSlot(innerElt.getPackValue());
45954621
asImpl().expandPackExpansion(innerElt.getOrigType(),
45964622
cast<PackExpansionType>(innerElt.getSubstType()),
45974623
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)