Skip to content

Commit 3b4d03c

Browse files
Merge pull request #63513 from nate-chandler/variadic-generics/irgen/alloc_pack
[IRGen] Lowered de/alloc_pack.
2 parents f22d6d7 + da5b5c1 commit 3b4d03c

File tree

5 files changed

+107
-15
lines changed

5 files changed

+107
-15
lines changed

lib/AST/ParameterPack.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ CanType TypeBase::getReducedShape() {
340340
if (auto *expansionType = getAs<PackExpansionType>())
341341
return expansionType->getReducedShape();
342342

343+
if (auto *silPackType = getAs<SILPackType>()) {
344+
auto can = cast<SILPackType>(silPackType->getCanonicalType());
345+
return can->getReducedShape();
346+
}
347+
343348
SmallVector<Type, 2> rootParameterPacks;
344349
getTypeParameterPacks(rootParameterPacks);
345350

lib/IRGen/GenPack.cpp

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

lib/IRGen/GenPack.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_IRGEN_GENPACK_H
1818
#define SWIFT_IRGEN_GENPACK_H
1919

20+
#include "IRGen.h"
2021
#include "swift/AST/Types.h"
2122
#include "llvm/ADT/STLExtras.h"
2223
#include "llvm/ADT/SmallVector.h"
@@ -32,6 +33,7 @@ namespace swift {
3233
namespace irgen {
3334
class Address;
3435
class IRGenFunction;
36+
class IRGenModule;
3537
class DynamicMetadataRequest;
3638
class MetadataResponse;
3739
class StackAddress;
@@ -83,9 +85,15 @@ llvm::Value *emitIndexOfStructuralPackComponent(IRGenFunction &IGF,
8385
///
8486
/// For indirect packs, note that this is the address of the pack
8587
/// array element, not the address stored in the pack array element.
86-
Address emitStorageAddressOfPackElement(IRGenFunction &IGF,
87-
Address pack, llvm::Value *index,
88-
SILType elementType);
88+
Address emitStorageAddressOfPackElement(IRGenFunction &IGF, Address pack,
89+
llvm::Value *index, SILType elementType,
90+
CanSILPackType packType);
91+
92+
Size getPackElementSize(IRGenModule &, CanSILPackType ty);
93+
94+
StackAddress allocatePack(IRGenFunction &IGF, CanSILPackType packType);
95+
96+
void deallocatePack(IRGenFunction &IGF, StackAddress addr, CanSILPackType packType);
8997

9098
} // end namespace irgen
9199
} // end namespace swift

lib/IRGen/IRGenSIL.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5515,7 +5515,8 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
55155515
}
55165516

55175517
void IRGenSILFunction::visitAllocPackInst(swift::AllocPackInst *i) {
5518-
IGM.unimplemented(i->getLoc().getSourceLoc(), "alloc_pack");
5518+
auto addr = allocatePack(*this, i->getPackType());
5519+
setLoweredStackAddress(i, addr);
55195520
}
55205521

55215522
static void
@@ -5618,7 +5619,9 @@ void IRGenSILFunction::visitDeallocStackRefInst(DeallocStackRefInst *i) {
56185619
}
56195620

56205621
void IRGenSILFunction::visitDeallocPackInst(swift::DeallocPackInst *i) {
5621-
IGM.unimplemented(i->getLoc().getSourceLoc(), "dealloc_pack");
5622+
auto allocatedType = cast<SILPackType>(i->getOperand()->getType().getASTType());
5623+
StackAddress stackAddr = getLoweredStackAddress(i->getOperand());
5624+
deallocatePack(*this, stackAddr, allocatedType);
56225625
}
56235626

56245627
void IRGenSILFunction::visitDeallocRefInst(swift::DeallocRefInst *i) {
@@ -6913,8 +6916,8 @@ void IRGenSILFunction::visitPackElementGetInst(PackElementGetInst *i) {
69136916
auto elementType = i->getElementType();
69146917
auto &elementTI = getTypeInfo(elementType);
69156918

6916-
auto elementStorageAddr =
6917-
emitStorageAddressOfPackElement(*this, pack, index, elementType);
6919+
auto elementStorageAddr = emitStorageAddressOfPackElement(
6920+
*this, pack, index, elementType, i->getPackType());
69186921

69196922
assert(elementType.isAddress() &&
69206923
i->getPackType()->isElementAddress() &&
@@ -6929,8 +6932,8 @@ void IRGenSILFunction::visitPackElementSetInst(PackElementSetInst *i) {
69296932
llvm::Value *index = getLoweredSingletonExplosion(i->getIndex());
69306933

69316934
auto elementType = i->getElementType();
6932-
auto elementStorageAddress =
6933-
emitStorageAddressOfPackElement(*this, pack, index, elementType);
6935+
auto elementStorageAddress = emitStorageAddressOfPackElement(
6936+
*this, pack, index, elementType, i->getPackType());
69346937

69356938
assert(elementType.isAddress() &&
69366939
i->getPackType()->isElementAddress() &&

test/IRGen/variadic_generics.sil

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ bb0(%pack : $*Pack{Int, repeat each T, Int}):
8888
%elementAddr = pack_element_get %index of %pack : $*Pack{Int, repeat each T, Int} as $*Int
8989
%value = load %elementAddr : $*Int
9090
return %value : $Int
91-
}
92-
91+
}
92+
9393
// CHECK-LABEL: define{{.*}} @test_pack_element_set_1(
9494
// CHECK: [[INDEX:%.*]] = add [[INT]] %2, 1
9595
// CHECK: [[ELT_STORAGE:%.*]] = getelementptr inbounds %swift.opaque*, %swift.opaque** %0, [[INT]] [[INDEX]]
@@ -103,6 +103,38 @@ bb0(%pack : $*Pack{Int, repeat each T, Int}, %value : $Int):
103103
%index = scalar_pack_index 2 of $Pack{Int, repeat each T, Int}
104104
%elementAddr = pack_element_get %index of %pack : $*Pack{Int, repeat each T, Int} as $*Int
105105
store %value to %elementAddr : $*Int
106+
%ret = tuple ()
107+
return %ret : $()
108+
}
109+
110+
// CHECK-LABEL: define {{.*}}@test_pack_alloc_1_dynamic(
111+
// CHECK-SAME: i{{(32|64)}} [[PACK_SIZE:%[^,]+]]
112+
// CHECK: [[SIZE:%[^,]+]] = add i64 [[PACK_SIZE]], [[PACK_SIZE]]
113+
// CHECK: [[SP_SAVE:%[^,]+]] = call i8* @llvm.stacksave()
114+
// CHECK: alloca %swift.opaque*, i{{(32|64)}} [[SIZE]]
115+
// CHECK: call void @llvm.stackrestore(i8* [[SP_SAVE]])
116+
sil @test_pack_alloc_1_dynamic : $<T...> () -> () {
117+
// Control flow so that stack saving/restoring is emitted
118+
entry:
119+
cond_br undef, left, right
120+
left:
121+
br exit
122+
right:
123+
br exit
124+
exit:
125+
%addr = alloc_pack $Pack{repeat each T, repeat each T}
126+
dealloc_pack %addr : $*Pack{repeat each T, repeat each T}
127+
%ret = tuple ()
128+
return %ret : $()
129+
}
130+
131+
// CHECK-LABEL: define {{.*}}@test_pack_alloc_2_static
132+
// CHECK: [[STACK:%[^,]+]] = alloca [2 x %swift.opaque*]
133+
// CHECK: call void @llvm.lifetime.start.p0i8
134+
// CHECK: call void @llvm.lifetime.end.p0i8
135+
sil @test_pack_alloc_2_static : $<T...> () -> () {
136+
%addr = alloc_pack $Pack{Int, Int}
137+
dealloc_pack %addr : $*Pack{Int, Int}
106138
%ret = tuple ()
107139
return %ret : $()
108140
}

0 commit comments

Comments
 (0)