@@ -865,15 +865,59 @@ void irgen::cleanupTypeMetadataPack(IRGenFunction &IGF,
865865 }
866866}
867867
868- Address irgen::emitStorageAddressOfPackElement (IRGenFunction &IGF,
869- Address pack,
868+ Address irgen::emitStorageAddressOfPackElement (IRGenFunction &IGF, Address pack,
870869 llvm::Value *index,
871- SILType elementType) {
870+ SILType elementType,
871+ CanSILPackType packType) {
872872 // When we have an indirect pack, the elements are pointers, so we can
873873 // simply index into that flat array.
874874 assert (elementType.isAddress () && " direct packs not currently supported" );
875- auto elementSize = IGF.IGM . getPointerSize ( );
875+ auto elementSize = getPackElementSize ( IGF.IGM , packType );
876876 auto elementAddress = IGF.Builder .CreateArrayGEP (pack, index, elementSize);
877877 return IGF.Builder .CreateElementBitCast (elementAddress,
878878 IGF.IGM .getStoragePointerType (elementType));
879879}
880+
881+ Size irgen::getPackElementSize (IRGenModule &IGM, CanSILPackType ty) {
882+ assert (ty->isElementAddress () && " not implemented for direct packs" );
883+ return IGM.getPointerSize ();
884+ }
885+
886+ StackAddress irgen::allocatePack (IRGenFunction &IGF, CanSILPackType packType) {
887+ auto *shape = IGF.emitPackShapeExpression (packType);
888+
889+ auto elementSize = getPackElementSize (IGF.IGM , packType);
890+
891+ if (auto *constantInt = dyn_cast<llvm::ConstantInt>(shape)) {
892+ assert (packType->getNumElements () == constantInt->getValue ());
893+ (void )constantInt;
894+ assert (!packType->containsPackExpansionType ());
895+ unsigned elementCount = packType->getNumElements ();
896+ auto allocType = llvm::ArrayType::get (
897+ IGF.IGM .OpaquePtrTy , elementCount);
898+
899+ auto addr = IGF.createAlloca (allocType, IGF.IGM .getPointerAlignment ());
900+ IGF.Builder .CreateLifetimeStart (addr,
901+ elementSize * elementCount);
902+ return addr;
903+ }
904+
905+ assert (packType->containsPackExpansionType ());
906+ auto addr = IGF.emitDynamicAlloca (IGF.IGM .OpaquePtrTy , shape,
907+ IGF.IGM .getPointerAlignment (),
908+ /* allowTaskAlloc=*/ true );
909+
910+ return addr;
911+ }
912+
913+ void irgen::deallocatePack (IRGenFunction &IGF, StackAddress addr, CanSILPackType packType) {
914+ if (packType->containsPackExpansionType ()) {
915+ IGF.emitDeallocateDynamicAlloca (addr);
916+ return ;
917+ }
918+
919+ auto elementSize = getPackElementSize (IGF.IGM , packType);
920+ auto elementCount = packType->getNumElements ();
921+ IGF.Builder .CreateLifetimeEnd (addr.getAddress (),
922+ elementSize * elementCount);
923+ }
0 commit comments