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