@@ -413,24 +413,23 @@ static void emitPackExpansionPack(
413
413
IGF.Builder .emitBlock (loop);
414
414
ConditionalDominanceScope condition (IGF);
415
415
416
- auto *element = elementForIndex (phi);
416
+ IGF.withLocalStackPackAllocs ([&]() {
417
+ auto *element = elementForIndex (phi);
417
418
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 ());
426
424
427
- IGF.Builder .CreateStore (element, eltPtr);
425
+ IGF.Builder .CreateStore (element, eltPtr);
426
+ });
428
427
429
428
// Increment our counter.
430
429
auto *next = IGF.Builder .CreateAdd (phi,
431
430
llvm::ConstantInt::get (IGF.IGM .SizeTy , 1 ));
432
431
433
- phi->addIncoming (next, loop );
432
+ phi->addIncoming (next, IGF. Builder . GetInsertBlock () );
434
433
435
434
// Repeat the loop.
436
435
IGF.Builder .CreateBr (check);
@@ -717,6 +716,20 @@ void IRGenFunction::eraseStackPackWitnessTableAlloc(StackAddress addr,
717
716
(void )removed;
718
717
}
719
718
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
+
720
733
llvm::Value *irgen::emitWitnessTablePackRef (IRGenFunction &IGF,
721
734
CanPackType packType,
722
735
PackConformance *conformance) {
@@ -970,42 +983,46 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
970
983
auto *materialize = IGF.createBasicBlock (" pack-index-element-metadata" );
971
984
IGF.Builder .emitBlock (materialize);
972
985
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
+ }
991
1018
}
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 ());
1001
1024
}
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
+ });
1009
1026
IGF.Builder .CreateBr (exit);
1010
1027
// }} Finished emitting emit_i.
1011
1028
0 commit comments