@@ -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 (),
0 commit comments