Skip to content

Commit 444e770

Browse files
committed
[NFC] Generalize createOpenedElementValueEnvironment to also be able
to map formal types into the new environment.
1 parent 000e258 commit 444e770

File tree

5 files changed

+73
-61
lines changed

5 files changed

+73
-61
lines changed

lib/SILGen/ResultPlan.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,13 @@ class PackTransformResultPlan final : public ResultPlan {
529529
auto eltPatternTy =
530530
PackAddr->getType().castTo<SILPackType>()
531531
->getSILElementType(ComponentIndex);
532-
auto result = SGF.createOpenedElementValueEnvironment(eltPatternTy);
533-
auto openedEnv = result.first;
534-
auto eltAddrTy = result.second;
532+
auto substPatternType = FormalPackType.getElementType(ComponentIndex);
533+
534+
SILType eltAddrTy;
535+
CanType substEltType;
536+
auto openedEnv =
537+
SGF.createOpenedElementValueEnvironment({eltPatternTy}, {&eltAddrTy},
538+
{substPatternType}, {&substEltType});
535539

536540
// Loop over the pack, initializing each value with the appropriate
537541
// element.
@@ -560,18 +564,10 @@ class PackTransformResultPlan final : public ResultPlan {
560564
return eltMV;
561565
}();
562566

563-
// Map the formal type into the generic environment.
564-
auto substType = FormalPackType.getElementType(ComponentIndex);
565-
substType = cast<PackExpansionType>(substType).getPatternType();
566-
if (openedEnv) {
567-
substType = openedEnv->mapContextualPackTypeIntoElementContext(
568-
substType);
569-
}
570-
571567
// Finish in the normal way for scalar results.
572568
RValue rvalue =
573569
ScalarResultPlan::finish(SGF, loc, eltMV, OrigPatternType,
574-
substType, eltInit, Rep);
570+
substEltType, eltInit, Rep);
575571
assert(rvalue.isInContext()); (void) rvalue;
576572
});
577573
});

lib/SILGen/SILGenFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
26972697
GenericEnvironment *
26982698
createOpenedElementValueEnvironment(ArrayRef<SILType> packExpansionTys,
26992699
ArrayRef<SILType*> eltTys);
2700+
GenericEnvironment *
2701+
createOpenedElementValueEnvironment(ArrayRef<SILType> packExpansionTys,
2702+
ArrayRef<SILType*> eltTys,
2703+
ArrayRef<CanType> formalPackExpansionTys,
2704+
ArrayRef<CanType*> formalEltTys);
27002705

27012706
/// Emit a dynamic loop over a single pack-expansion component of a pack.
27022707
///

lib/SILGen/SILGenPack.cpp

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -452,44 +452,63 @@ GenericEnvironment *
452452
SILGenFunction::createOpenedElementValueEnvironment(
453453
ArrayRef<SILType> expansionTys,
454454
ArrayRef<SILType*> eltTys) {
455-
// The element-types output array should be the same size as the
456-
// expansion-types input array. We don't currently have a reason
457-
// to allow them to be empty --- we never do this with a dynamic
458-
// set of types --- but maybe it's justifiable.
455+
return createOpenedElementValueEnvironment(expansionTys, eltTys, {}, {});
456+
}
457+
458+
459+
GenericEnvironment *
460+
SILGenFunction::createOpenedElementValueEnvironment(
461+
ArrayRef<SILType> expansionTys,
462+
ArrayRef<SILType*> eltTys,
463+
ArrayRef<CanType> formalExpansionTypes,
464+
ArrayRef<CanType*> formalEltTypes) {
465+
// The element-types output arrays should be the same size as their
466+
// corresponding expansion-types input arrays.
459467
assert(expansionTys.size() == eltTys.size());
460-
assert(!expansionTys.empty());
461-
if (expansionTys.empty()) return nullptr;
468+
assert(formalExpansionTypes.size() == formalEltTypes.size());
462469

463-
auto countArchetype = cast<PackArchetypeType>(
464-
expansionTys[0].castTo<PackExpansionType>().getCountType());
470+
assert(!expansionTys.empty() || !formalExpansionTypes.empty());
471+
auto countArchetype =
472+
cast<PackArchetypeType>(
473+
(expansionTys.empty()
474+
? cast<PackExpansionType>(formalExpansionTypes[0])
475+
: expansionTys[0].castTo<PackExpansionType>()).getCountType());
465476

466477
GenericEnvironment *env = nullptr;
467-
for (auto i : indices(expansionTys)) {
468-
auto exp = expansionTys[i].castTo<PackExpansionType>();
469-
assert((i == 0 ||
470-
countArchetype->getReducedShape() ==
471-
cast<PackArchetypeType>(exp.getCountType())->getReducedShape())
478+
auto processExpansion = [&](CanPackExpansionType expansion) -> CanType {
479+
assert(countArchetype->getReducedShape() ==
480+
cast<PackArchetypeType>(expansion.getCountType())->getReducedShape()
472481
&& "expansions are over packs with different shapes");
473482

474-
// The lowered element type is the lowered pattern type, if that's
475-
// invariant to expansion, or else the expansion mapping of that in
476-
// the opened-element environment.
477-
auto loweredPatternTy = exp.getPatternType();
478-
auto loweredEltTy = loweredPatternTy;
479-
if (!isPatternInvariantToExpansion(loweredPatternTy, countArchetype)) {
480-
// Lazily create the opened-element environment if we find a
481-
// pattern type that's not invariant to expansion.
482-
if (!env) {
483-
auto context = OpenedElementContext::
484-
createForContextualExpansion(SGM.getASTContext(), exp);
485-
env = context.environment;
486-
}
487-
loweredEltTy =
488-
env->mapContextualPackTypeIntoElementContext(loweredPatternTy);
483+
// The element type is the pattern type, if that's invariant to
484+
// expansion, or else the expansion mapping of that in the
485+
// opened-element environment.
486+
auto patternType = expansion.getPatternType();
487+
if (isPatternInvariantToExpansion(patternType, countArchetype))
488+
return patternType;
489+
490+
// Lazily create the opened-element environment if we find a
491+
// pattern type that's not invariant to expansion.
492+
if (!env) {
493+
auto context = OpenedElementContext::
494+
createForContextualExpansion(SGM.getASTContext(), expansion);
495+
env = context.environment;
489496
}
497+
return env->mapContextualPackTypeIntoElementContext(patternType);
498+
};
499+
500+
for (auto i : indices(expansionTys)) {
501+
auto exp = expansionTys[i].castTo<PackExpansionType>();
502+
auto loweredEltTy = processExpansion(exp);
490503
*eltTys[i] = SILType::getPrimitiveAddressType(loweredEltTy);
491504
}
492505

506+
for (auto i : indices(formalExpansionTypes)) {
507+
auto exp = cast<PackExpansionType>(formalExpansionTypes[i]);
508+
auto eltType = processExpansion(exp);
509+
*formalEltTypes[i] = eltType;
510+
}
511+
493512
return env;
494513
}
495514

lib/SILGen/SILGenPoly.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3638,9 +3638,12 @@ void ResultPlanner::Operation::emitReabstractTupleIntoPackExpansion(
36383638
outerComponentIndex);
36393639

36403640
SILType innerEltTy, outerEltTy;
3641+
CanType innerSubstEltType, outerSubstEltType;
36413642
auto openedEnv = SGF.createOpenedElementValueEnvironment(
36423643
{ innerPackExpansionTy, outerPackExpansionTy },
3643-
{ &innerEltTy, &outerEltTy });
3644+
{ &innerEltTy, &outerEltTy },
3645+
{ InnerSubstType, OuterSubstType },
3646+
{ &innerSubstEltType, &outerSubstEltType });
36443647

36453648
auto innerFormalPackType = PackExpansion.InnerFormalPackType;
36463649
auto outerFormalPackType = PackExpansion.OuterFormalPackType;
@@ -3675,20 +3678,11 @@ void ResultPlanner::Operation::emitReabstractTupleIntoPackExpansion(
36753678
CleanupHandle::invalid());
36763679
auto outerResultCtxt = SGFContext(&outerEltInit);
36773680

3678-
CanType innerSubstType = InnerSubstType;
3679-
CanType outerSubstType = OuterSubstType;
3680-
if (openedEnv) {
3681-
innerSubstType =
3682-
openedEnv->mapContextualPackTypeIntoElementContext(innerSubstType);
3683-
outerSubstType =
3684-
openedEnv->mapContextualPackTypeIntoElementContext(outerSubstType);
3685-
}
3686-
36873681
// Reabstract.
36883682
auto outerEltValue =
36893683
SGF.emitTransformedValue(loc, innerEltValue,
3690-
InnerOrigType, innerSubstType,
3691-
OuterOrigType, outerSubstType,
3684+
InnerOrigType, innerSubstEltType,
3685+
OuterOrigType, outerSubstEltType,
36923686
outerEltTy, outerResultCtxt);
36933687

36943688
// Force the value into the outer result address if necessary.

lib/SILGen/SILGenProlog.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,13 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
540540
assert(componentInit);
541541
assert(componentInit->canPerformPackExpansionInitialization());
542542

543-
auto opening = SGF.createOpenedElementValueEnvironment(packComponentTy);
544-
auto openedEnv = opening.first;
545-
auto eltTy = opening.second;
543+
SILType eltTy;
544+
CanType substEltType;
545+
auto openedEnv =
546+
SGF.createOpenedElementValueEnvironment({packComponentTy},
547+
{&eltTy},
548+
{substExpansionType},
549+
{&substEltType});
546550

547551
SGF.emitDynamicPackLoop(loc, inducedPackType, packComponentIndex,
548552
openedEnv, [&](SILValue indexWithinComponent,
@@ -556,12 +560,6 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
556560
SGF.B.createPackElementGet(loc, packIndex, packAddr, eltTy);
557561
auto eltAddrMV = cloner.clone(eltAddr);
558562

559-
CanType substEltType = substExpansionType.getPatternType();
560-
if (openedEnv) {
561-
substEltType =
562-
openedEnv->mapContextualPackTypeIntoElementContext(substEltType);
563-
}
564-
565563
auto result = handleScalar(eltAddrMV, origPatternType, substEltType,
566564
eltInit, /*inout*/ false);
567565
assert(result.isInContext()); (void) result;

0 commit comments

Comments
 (0)