@@ -2416,8 +2416,15 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
2416
2416
return innerPackParam.getConvention ();
2417
2417
}
2418
2418
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 ());
2421
2428
}
2422
2429
2423
2430
// / Given an element of an inner pack that we're emitting into,
@@ -2770,15 +2777,29 @@ ManagedValue TranslateArguments::expandPackInnerParam(
2770
2777
// cleanup onto the elements.
2771
2778
auto outerComponent = outerParam.projectPackComponent (SGF, Loc);
2772
2779
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);
2782
2803
2783
2804
ManagedValue inner =
2784
2805
SGF.emitPackTransform (Loc, outerComponent,
@@ -2787,13 +2808,18 @@ ManagedValue TranslateArguments::expandPackInnerParam(
2787
2808
innerPackAddr,
2788
2809
innerFormalPackType,
2789
2810
innerComponentIndex,
2790
- /* is trivial */ forwardouterToinner ,
2811
+ /* is simple projection */ forwardOuterToInner ,
2791
2812
innerIsPlusOne,
2792
2813
[&](ManagedValue outerEltAddr, SILType innerEltTy,
2793
2814
SGFContext ctxt) {
2794
2815
// 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.
2796
2821
return outerEltAddr;
2822
+ }
2797
2823
2798
2824
// Otherwise, map the subst pattern types into element context.
2799
2825
CanType innerSubstEltType =
@@ -3454,8 +3480,8 @@ class ResultPlanner : public ExpanderBase<ResultPlanner, IndirectSlot> {
3454
3480
return temporary;
3455
3481
}
3456
3482
3457
- IndirectSlot getInnerPackExpansionSlot (SILValue packAddr) {
3458
- return IndirectSlot (packAddr);
3483
+ IndirectSlot getInnerPackExpansionSlot (ManagedValue packAddr) {
3484
+ return IndirectSlot (packAddr. getLValueAddress () );
3459
3485
}
3460
3486
3461
3487
IndirectSlot getInnerPackElementSlot (SILType elementTy) {
@@ -3809,8 +3835,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuples(
3809
3835
ManagedValue outerPackComponent =
3810
3836
outerElt.projectPackComponent (SGF, Loc);
3811
3837
3812
- auto innerEltSlot = asImpl (). getInnerPackExpansionSlot (
3813
- innerElt. getPackValue ().getLValueAddress ());
3838
+ auto innerEltSlot =
3839
+ asImpl ().getInnerPackExpansionSlot (innerElt. getPackValue ());
3814
3840
ManagedValue innerPackComponent = asImpl ().expandPackExpansion (
3815
3841
innerElt.getOrigType (),
3816
3842
cast<PackExpansionType>(innerElt.getSubstType ()),
@@ -4590,8 +4616,8 @@ void ExpanderBase<Impl, InnerSlotType>::expandParallelTuplesOuterIndirect(
4590
4616
continue ;
4591
4617
}
4592
4618
4593
- auto innerExpansionSlot = asImpl (). getInnerPackExpansionSlot (
4594
- innerElt. getPackValue ().getLValueAddress ());
4619
+ auto innerExpansionSlot =
4620
+ asImpl ().getInnerPackExpansionSlot (innerElt. getPackValue ());
4595
4621
asImpl ().expandPackExpansion (innerElt.getOrigType (),
4596
4622
cast<PackExpansionType>(innerElt.getSubstType ()),
4597
4623
outerElt.getOrigType (),
0 commit comments