@@ -413,24 +413,23 @@ static void emitPackExpansionPack(
413413 IGF.Builder .emitBlock (loop);
414414 ConditionalDominanceScope condition (IGF);
415415
416- auto *element = elementForIndex (phi);
416+ IGF.withLocalStackPackAllocs ([&]() {
417+ auto *element = elementForIndex (phi);
417418
418- // Store the element metadata into to the current destination index.
419- auto *eltIndex = IGF.Builder .CreateAdd (dynamicIndex, phi);
420- Address eltPtr (
421- IGF.Builder .CreateInBoundsGEP (pack.getElementType (),
422- pack.getAddress (),
423- eltIndex),
424- pack.getElementType (),
425- pack.getAlignment ());
419+ // Store the element metadata into to the current destination index.
420+ auto *eltIndex = IGF.Builder .CreateAdd (dynamicIndex, phi);
421+ Address eltPtr (IGF.Builder .CreateInBoundsGEP (pack.getElementType (),
422+ pack.getAddress (), eltIndex),
423+ pack.getElementType (), pack.getAlignment ());
426424
427- IGF.Builder .CreateStore (element, eltPtr);
425+ IGF.Builder .CreateStore (element, eltPtr);
426+ });
428427
429428 // Increment our counter.
430429 auto *next = IGF.Builder .CreateAdd (phi,
431430 llvm::ConstantInt::get (IGF.IGM .SizeTy , 1 ));
432431
433- phi->addIncoming (next, loop );
432+ phi->addIncoming (next, IGF. Builder . GetInsertBlock () );
434433
435434 // Repeat the loop.
436435 IGF.Builder .CreateBr (check);
@@ -717,6 +716,20 @@ void IRGenFunction::eraseStackPackWitnessTableAlloc(StackAddress addr,
717716 (void )removed;
718717}
719718
719+ void IRGenFunction::withLocalStackPackAllocs (llvm::function_ref<void ()> fn) {
720+ auto oldSize = OutstandingStackPackAllocs.size ();
721+ fn ();
722+ SmallVector<StackPackAlloc, 2 > allocs;
723+ for (auto index = oldSize, size = OutstandingStackPackAllocs.size ();
724+ index < size; ++index) {
725+ allocs.push_back (OutstandingStackPackAllocs[index]);
726+ }
727+ while (OutstandingStackPackAllocs.size () > oldSize) {
728+ OutstandingStackPackAllocs.pop_back ();
729+ }
730+ cleanupStackAllocPacks (*this , allocs);
731+ }
732+
720733llvm::Value *irgen::emitWitnessTablePackRef (IRGenFunction &IGF,
721734 CanPackType packType,
722735 PackConformance *conformance) {
@@ -970,42 +983,46 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
970983 auto *materialize = IGF.createBasicBlock (" pack-index-element-metadata" );
971984 IGF.Builder .emitBlock (materialize);
972985
973- llvm::Value *metadata = nullptr ;
974- llvm::SmallVector<llvm::Value *, 2 > wtables;
975- wtables.reserve (conformances.size ());
976- if (auto expansionTy = dyn_cast<PackExpansionType>(elementTy)) {
977- // Actually materialize %inner. Then use it to get the metadata from the
978- // pack expansion at that index.
979- auto *relativeIndex = IGF.Builder .CreateSub (index, lowerBound);
980- auto context =
981- OpenedElementContext::createForContextualExpansion (IGF.IGM .Context , expansionTy);
982- auto patternTy = expansionTy.getPatternType ();
983- metadata = emitPackExpansionElementMetadata (IGF, context, patternTy,
984- relativeIndex, request);
985- for (auto conformance : conformances) {
986- auto patternConformance = conformance.getPack ()->getPatternConformances ()[i];
987- auto *wtable = emitPackExpansionElementWitnessTable (
988- IGF, context, patternTy, patternConformance,
989- &metadata, relativeIndex);
990- wtables.push_back (wtable);
986+ IGF.withLocalStackPackAllocs ([&]() {
987+ llvm::Value *metadata = nullptr ;
988+ llvm::SmallVector<llvm::Value *, 2 > wtables;
989+ wtables.reserve (conformances.size ());
990+ if (auto expansionTy = dyn_cast<PackExpansionType>(elementTy)) {
991+ // Actually materialize %inner. Then use it to get the metadata from
992+ // the pack expansion at that index.
993+ auto *relativeIndex = IGF.Builder .CreateSub (index, lowerBound);
994+ auto context = OpenedElementContext::createForContextualExpansion (
995+ IGF.IGM .Context , expansionTy);
996+ auto patternTy = expansionTy.getPatternType ();
997+ metadata = emitPackExpansionElementMetadata (IGF, context, patternTy,
998+ relativeIndex, request);
999+ for (auto conformance : conformances) {
1000+ auto patternConformance =
1001+ conformance.getPack ()->getPatternConformances ()[i];
1002+ auto *wtable = emitPackExpansionElementWitnessTable (
1003+ IGF, context, patternTy, patternConformance, &metadata,
1004+ relativeIndex);
1005+ wtables.push_back (wtable);
1006+ }
1007+ } else {
1008+ metadata = IGF.emitTypeMetadataRef (elementTy, request).getMetadata ();
1009+ for (auto conformance : conformances) {
1010+ auto patternConformance =
1011+ conformance.getPack ()->getPatternConformances ()[i];
1012+ llvm::Value *_metadata = nullptr ;
1013+ auto *wtable = emitWitnessTableRef (IGF, elementTy,
1014+ /* srcMetadataCache=*/ &_metadata,
1015+ patternConformance);
1016+ wtables.push_back (wtable);
1017+ }
9911018 }
992- } else {
993- metadata = IGF.emitTypeMetadataRef (elementTy, request).getMetadata ();
994- for (auto conformance : conformances) {
995- auto patternConformance = conformance.getPack ()->getPatternConformances ()[i];
996- llvm::Value *_metadata = nullptr ;
997- auto *wtable =
998- emitWitnessTableRef (IGF, elementTy, /* srcMetadataCache=*/ &_metadata,
999- patternConformance);
1000- wtables.push_back (wtable);
1019+ metadataPhi->addIncoming (metadata, IGF.Builder .GetInsertBlock ());
1020+ for (auto i : indices (wtables)) {
1021+ auto *wtable = wtables[i];
1022+ auto *wtablePhi = wtablePhis[i];
1023+ wtablePhi->addIncoming (wtable, IGF.Builder .GetInsertBlock ());
10011024 }
1002- }
1003- metadataPhi->addIncoming (metadata, IGF.Builder .GetInsertBlock ());
1004- for (auto i : indices (wtables)) {
1005- auto *wtable = wtables[i];
1006- auto *wtablePhi = wtablePhis[i];
1007- wtablePhi->addIncoming (wtable, IGF.Builder .GetInsertBlock ());
1008- }
1025+ });
10091026 IGF.Builder .CreateBr (exit);
10101027 // }} Finished emitting emit_i.
10111028
0 commit comments