Skip to content

Commit f0ebda0

Browse files
committed
IRGen: Add DynamicTupleTypeInfo to model TupleTypes with PackExpansionType elements
For now these are completely resilient blobs, which is wrong because it prevents us from being able to model something like (Int, repeat each T, String). But one step at a time...
1 parent 5daf994 commit f0ebda0

File tree

6 files changed

+54
-1
lines changed

6 files changed

+54
-1
lines changed

lib/IRGen/GenPack.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "IRGenFunction.h"
3131
#include "IRGenModule.h"
3232
#include "MetadataRequest.h"
33+
#include "ResilientTypeInfo.h"
3334

3435
using namespace swift;
3536
using namespace irgen;

lib/IRGen/GenTuple.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "Explosion.h"
3737
#include "IndirectTypeInfo.h"
3838
#include "NonFixedTypeInfo.h"
39+
#include "ResilientTypeInfo.h"
3940

4041
#include "GenTuple.h"
4142

@@ -44,6 +45,33 @@
4445
using namespace swift;
4546
using namespace irgen;
4647

48+
namespace {
49+
/// A type implementation for tuple types with a dynamic number of
50+
/// elements, that is, that contain pack expansion types. For now,
51+
/// these are completely abstract.
52+
class DynamicTupleTypeInfo
53+
: public ResilientTypeInfo<DynamicTupleTypeInfo>
54+
{
55+
public:
56+
DynamicTupleTypeInfo(llvm::Type *T,
57+
IsCopyable_t copyable)
58+
: ResilientTypeInfo(T, copyable, IsABIAccessible) {}
59+
60+
TypeLayoutEntry
61+
*buildTypeLayoutEntry(IRGenModule &IGM,
62+
SILType T,
63+
bool useStructLayouts) const override {
64+
return IGM.typeLayoutCache.getOrCreateResilientEntry(T);
65+
}
66+
};
67+
} // end anonymous namespace
68+
69+
const TypeInfo *
70+
TypeConverter::convertDynamicTupleType(IsCopyable_t copyable) {
71+
llvm::Type *storageType = IGM.OpaqueTy;
72+
return new DynamicTupleTypeInfo(storageType, copyable);
73+
}
74+
4775
namespace {
4876
class TupleFieldInfo : public RecordField<TupleFieldInfo> {
4977
public:
@@ -488,6 +516,11 @@ namespace {
488516
} // end anonymous namespace
489517

490518
const TypeInfo *TypeConverter::convertTupleType(TupleType *tuple) {
519+
if (tuple->containsPackExpansionType()) {
520+
// FIXME: Figure out if its copyable at least
521+
return &getDynamicTupleTypeInfo(IsCopyable);
522+
}
523+
491524
TupleTypeBuilder builder(IGM, SILType::getPrimitiveAddressType(CanType(tuple)));
492525
return builder.layout(tuple->getElements());
493526
}

lib/IRGen/GenType.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,16 @@ const LoadableTypeInfo &TypeConverter::getEmptyTypeInfo() {
18241824
return *EmptyTI;
18251825
}
18261826

1827+
const TypeInfo &
1828+
TypeConverter::getDynamicTupleTypeInfo(IsCopyable_t isCopyable) {
1829+
auto &cache = DynamicTupleTI[(unsigned)isCopyable];
1830+
if (cache) return *cache;
1831+
cache = convertDynamicTupleType(isCopyable);
1832+
cache->NextConverted = FirstType;
1833+
FirstType = cache;
1834+
return *cache;
1835+
}
1836+
18271837
const TypeInfo &
18281838
TypeConverter::getResilientStructTypeInfo(IsCopyable_t isCopyable,
18291839
IsABIAccessible_t isAccessible) {

lib/IRGen/GenType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class TypeConverter {
123123
{nullptr, nullptr},
124124
{nullptr, nullptr},
125125
};
126+
127+
const TypeInfo *DynamicTupleTI[2] = {nullptr, nullptr};
126128

127129
llvm::DenseMap<std::pair<unsigned, unsigned>, const LoadableTypeInfo *>
128130
OpaqueStorageTypes;
@@ -177,6 +179,7 @@ class TypeConverter {
177179
const LoadableTypeInfo *convertBuiltinBridgeObject();
178180
const TypeInfo *convertResilientStruct(IsCopyable_t copyable,
179181
IsABIAccessible_t abiAccessible);
182+
const TypeInfo *convertDynamicTupleType(IsCopyable_t copyable);
180183
#define REF_STORAGE(Name, ...) \
181184
const TypeInfo *convert##Name##StorageType(Name##StorageType *T);
182185
#include "swift/AST/ReferenceStorage.def"
@@ -210,6 +213,7 @@ class TypeConverter {
210213
const LoadableTypeInfo &getIntegerLiteralTypeInfo();
211214
const TypeInfo &getResilientStructTypeInfo(IsCopyable_t copyable,
212215
IsABIAccessible_t abiAccessible);
216+
const TypeInfo &getDynamicTupleTypeInfo(IsCopyable_t isCopyable);
213217
const ProtocolInfo &getProtocolInfo(ProtocolDecl *P, ProtocolInfoKind kind);
214218
const LoadableTypeInfo &getOpaqueStorageTypeInfo(Size storageSize,
215219
Alignment storageAlign);

lib/IRGen/MetadataRequest.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3198,7 +3198,7 @@ class EmitTypeMetadataRefForLayout
31983198
}
31993199

32003200
CanType visitPackExpansionType(CanPackExpansionType ty) {
3201-
llvm_unreachable("");
3201+
return ty;
32023202
}
32033203

32043204
CanType visitTupleType(CanTupleType ty) {
@@ -3533,6 +3533,10 @@ namespace {
35333533

35343534
llvm::Value *visitTupleType(CanTupleType type,
35353535
DynamicMetadataRequest request) {
3536+
// Tuples containing pack expansion types are completely dynamic.
3537+
if (type->containsPackExpansionType())
3538+
return emitFromTypeMetadata(type, request);
3539+
35363540
// Single-element tuples have exactly the same layout as their elements.
35373541
if (type->getNumElements() == 1) {
35383542
return visit(type.getElementType(0), request);

lib/IRGen/ResilientTypeInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_IRGEN_RESILIENTTYPEINFO_H
2121

2222
#include "NonFixedTypeInfo.h"
23+
#include "Outlining.h"
2324

2425
namespace swift {
2526
namespace irgen {

0 commit comments

Comments
 (0)