@@ -789,12 +789,10 @@ namespace {
789
789
790
790
791
791
static llvm::Constant *getAssignBoxedOpaqueExistentialBufferFunction (
792
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
793
- llvm::Type *existContainerPointerTy);
792
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout);
794
793
795
794
static llvm::Constant *getDestroyBoxedOpaqueExistentialBufferFunction (
796
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
797
- llvm::Type *existContainerPointerTy);
795
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout);
798
796
799
797
static llvm::Constant *
800
798
getProjectBoxedOpaqueExistentialFunction (IRGenFunction &IGF,
@@ -843,13 +841,14 @@ class OpaqueExistentialTypeInfo final :
843
841
void assignWithCopy (IRGenFunction &IGF, Address dest, Address src, SILType T,
844
842
bool isOutlined) const override {
845
843
846
- auto objPtrTy = dest.getAddress ()->getType ();
847
-
848
844
// Use copy-on-write existentials?
849
845
auto fn = getAssignBoxedOpaqueExistentialBufferFunction (
850
- IGF.IGM , getLayout (), objPtrTy);
846
+ IGF.IGM , getLayout ());
847
+ auto *type = IGF.IGM .getExistentialPtrTy (getLayout ().getNumTables ());
848
+ auto *destAddr = IGF.Builder .CreateBitCast (dest.getAddress (), type);
849
+ auto *srcAddr = IGF.Builder .CreateBitCast (src.getAddress (), type);
851
850
auto call =
852
- IGF.Builder .CreateCall (fn, {dest. getAddress (), src. getAddress () });
851
+ IGF.Builder .CreateCall (fn, {destAddr, srcAddr });
853
852
call->setCallingConv (IGF.IGM .DefaultCC );
854
853
call->setDoesNotThrow ();
855
854
return ;
@@ -904,12 +903,15 @@ class OpaqueExistentialTypeInfo final :
904
903
}
905
904
}
906
905
907
- void destroy (IRGenFunction &IGF, Address addr , SILType T,
906
+ void destroy (IRGenFunction &IGF, Address buffer , SILType T,
908
907
bool isOutlined) const override {
909
908
// Use copy-on-write existentials?
910
909
auto fn = getDestroyBoxedOpaqueExistentialBufferFunction (
911
- IGF.IGM , getLayout (), addr.getAddress ()->getType ());
912
- auto call = IGF.Builder .CreateCall (fn, {addr.getAddress ()});
910
+ IGF.IGM , getLayout ());
911
+ auto *addr = IGF.Builder .CreateBitCast (
912
+ buffer.getAddress (),
913
+ IGF.IGM .getExistentialPtrTy (getLayout ().getNumTables ()));
914
+ auto call = IGF.Builder .CreateCall (fn, {addr});
913
915
call->setCallingConv (IGF.IGM .DefaultCC );
914
916
call->setDoesNotThrow ();
915
917
return ;
@@ -1355,6 +1357,36 @@ createErrorExistentialTypeInfo(IRGenModule &IGM,
1355
1357
refcounting);
1356
1358
}
1357
1359
1360
+ llvm::Type *TypeConverter::getExistentialType (unsigned numWitnessTables) {
1361
+ llvm::StructType *&type = OpaqueExistentialTypes[numWitnessTables];
1362
+ if (type)
1363
+ return type;
1364
+
1365
+ SmallVector<llvm::Type*, 5 > fields;
1366
+
1367
+ fields.push_back (IGM.getFixedBufferTy ());
1368
+ fields.push_back (IGM.TypeMetadataPtrTy );
1369
+
1370
+ for (auto i : range (numWitnessTables)) {
1371
+ fields.push_back (IGM.WitnessTablePtrTy );
1372
+ (void ) i;
1373
+ }
1374
+
1375
+ llvm::SmallString<40 > typeName;
1376
+ llvm::raw_svector_ostream (typeName)
1377
+ << " __opaque_existential_type_"
1378
+ << numWitnessTables;
1379
+
1380
+ type = llvm::StructType::create (IGM.getLLVMContext (), StringRef (typeName));
1381
+ type->setBody (fields);
1382
+
1383
+ return type;
1384
+ }
1385
+
1386
+ llvm::PointerType *IRGenModule::getExistentialPtrTy (unsigned numTables) {
1387
+ return Types.getExistentialType (numTables)->getPointerTo ();
1388
+ }
1389
+
1358
1390
static const TypeInfo *createExistentialTypeInfo (IRGenModule &IGM, CanType T) {
1359
1391
auto layout = T.getExistentialLayout ();
1360
1392
@@ -1767,24 +1799,26 @@ void irgen::emitExistentialMetatypeContainer(IRGenFunction &IGF,
1767
1799
});
1768
1800
}
1769
1801
1770
- void irgen::emitMetatypeOfOpaqueExistential (IRGenFunction &IGF, Address addr ,
1802
+ void irgen::emitMetatypeOfOpaqueExistential (IRGenFunction &IGF, Address buffer ,
1771
1803
SILType type, Explosion &out) {
1772
1804
assert (type.isExistentialType ());
1773
1805
assert (!type.isClassExistentialType ());
1774
1806
auto &baseTI = IGF.getTypeInfo (type).as <OpaqueExistentialTypeInfo>();
1775
1807
1776
1808
// Get the static metadata.
1777
1809
auto existLayout = baseTI.getLayout ();
1778
- llvm::Value *metadata = existLayout.loadMetadataRef (IGF, addr );
1810
+ llvm::Value *metadata = existLayout.loadMetadataRef (IGF, buffer );
1779
1811
1780
1812
// Project the buffer and apply the 'typeof' value witness.
1781
- Address buffer = existLayout.projectExistentialBuffer (IGF, addr);
1782
1813
llvm::Value *object;
1783
1814
1815
+ auto *addr = IGF.Builder .CreateBitCast (
1816
+ buffer.getAddress (),
1817
+ IGF.IGM .getExistentialPtrTy (existLayout.getNumTables ()));
1784
1818
auto *projectFunc = getProjectBoxedOpaqueExistentialFunction (
1785
1819
IGF, OpenedExistentialAccess::Immutable, existLayout);
1786
1820
auto *addrOfValue =
1787
- IGF.Builder .CreateCall (projectFunc, {buffer. getAddress () , metadata});
1821
+ IGF.Builder .CreateCall (projectFunc, {addr , metadata});
1788
1822
addrOfValue->setCallingConv (IGF.IGM .DefaultCC );
1789
1823
addrOfValue->setDoesNotThrow ();
1790
1824
object = addrOfValue;
@@ -1796,7 +1830,7 @@ void irgen::emitMetatypeOfOpaqueExistential(IRGenFunction &IGF, Address addr,
1796
1830
out.add (dynamicType);
1797
1831
1798
1832
// Get the witness tables.
1799
- baseTI.emitLoadOfTables (IGF, addr , out);
1833
+ baseTI.emitLoadOfTables (IGF, buffer , out);
1800
1834
}
1801
1835
1802
1836
void irgen::emitMetatypeOfBoxedExistential (IRGenFunction &IGF, Explosion &value,
@@ -1967,10 +2001,9 @@ static Address castToOpaquePtr(IRGenFunction &IGF, Address addr) {
1967
2001
}
1968
2002
1969
2003
static llvm::Constant *getAllocateBoxedOpaqueExistentialBufferFunction (
1970
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
1971
- llvm::Type *existContainerPointerTy) {
2004
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout) {
1972
2005
1973
- llvm::Type *argTys[] = {existContainerPointerTy };
2006
+ llvm::Type *argTys[] = {IGM. getExistentialPtrTy (existLayout. getNumTables ()) };
1974
2007
1975
2008
// __swift_allocate_boxed_opaque_existential__N is the well-known function for
1976
2009
// allocating buffers in existential containers of types with N witness
@@ -2051,20 +2084,22 @@ Address irgen::emitAllocateBoxedOpaqueExistentialBuffer(
2051
2084
}
2052
2085
// / Call a function to handle the non-fixed case.
2053
2086
auto *allocateFun = getAllocateBoxedOpaqueExistentialBufferFunction (
2054
- IGF.IGM , existLayout, existentialContainer.getAddress ()->getType ());
2087
+ IGF.IGM , existLayout);
2088
+ auto *existentialAddr = IGF.Builder .CreateBitCast (
2089
+ existentialContainer.getAddress (),
2090
+ IGF.IGM .getExistentialPtrTy (existLayout.getNumTables ()));
2055
2091
auto *call =
2056
- IGF.Builder .CreateCall (allocateFun, {existentialContainer. getAddress () });
2092
+ IGF.Builder .CreateCall (allocateFun, {existentialAddr });
2057
2093
call->setCallingConv (IGF.IGM .DefaultCC );
2058
2094
call->setDoesNotThrow ();
2059
2095
auto addressOfValue = IGF.Builder .CreateBitCast (call, valuePointerType);
2060
2096
return valueTI.getAddressForPointer (addressOfValue);
2061
2097
}
2062
2098
2063
2099
static llvm::Constant *getDeallocateBoxedOpaqueExistentialBufferFunction (
2064
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
2065
- llvm::Type *existContainerPointerTy) {
2100
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout) {
2066
2101
2067
- llvm::Type *argTys[] = {existContainerPointerTy };
2102
+ llvm::Type *argTys[] = {IGM. getExistentialPtrTy (existLayout. getNumTables ()) };
2068
2103
2069
2104
// __swift_deallocate_boxed_opaque_existential_N is the well-known function
2070
2105
// for deallocating buffers in existential containers of types with N witness
@@ -2141,9 +2176,11 @@ void irgen::emitDeallocateBoxedOpaqueExistentialBuffer(
2141
2176
OpaqueExistentialLayout existLayout = existentialTI.getLayout ();
2142
2177
2143
2178
auto *deallocateFun = getDeallocateBoxedOpaqueExistentialBufferFunction (
2144
- IGF.IGM , existLayout, existentialContainer.getAddress ()->getType ());
2145
- auto *call = IGF.Builder .CreateCall (deallocateFun,
2146
- {existentialContainer.getAddress ()});
2179
+ IGF.IGM , existLayout);
2180
+ auto *bufferAddr = IGF.Builder .CreateBitCast (
2181
+ existentialContainer.getAddress (),
2182
+ IGF.IGM .getExistentialPtrTy (existLayout.getNumTables ()));
2183
+ auto *call = IGF.Builder .CreateCall (deallocateFun, {bufferAddr});
2147
2184
call->setCallingConv (IGF.IGM .DefaultCC );
2148
2185
call->setDoesNotThrow ();
2149
2186
return ;
@@ -2155,7 +2192,7 @@ getProjectBoxedOpaqueExistentialFunction(IRGenFunction &IGF,
2155
2192
OpaqueExistentialLayout existLayout) {
2156
2193
2157
2194
auto &IGM = IGF.IGM ;
2158
- auto *existentialBufferTy = IGM.getFixedBufferTy ()-> getPointerTo ( );
2195
+ auto *existentialBufferTy = IGM.getExistentialPtrTy (existLayout. getNumTables () );
2159
2196
llvm::Type *argTys[] = {existentialBufferTy, IGM.TypeMetadataPtrTy };
2160
2197
2161
2198
// __swift_project_boxed_opaque_existential_N is the well-known function for
@@ -2278,11 +2315,13 @@ Address irgen::emitOpaqueBoxedExistentialProjection(
2278
2315
wtables);
2279
2316
}
2280
2317
2281
- Address buffer = layout.projectExistentialBuffer (IGF, base);
2282
2318
auto *projectFunc =
2283
2319
getProjectBoxedOpaqueExistentialFunction (IGF, accessKind, layout);
2320
+ auto *bufferAddr = IGF.Builder .CreateBitCast (
2321
+ base.getAddress (),
2322
+ IGF.IGM .getExistentialPtrTy (layout.getNumTables ()));
2284
2323
auto *addrOfValue =
2285
- IGF.Builder .CreateCall (projectFunc, {buffer. getAddress () , metadata});
2324
+ IGF.Builder .CreateCall (projectFunc, {bufferAddr , metadata});
2286
2325
addrOfValue->setCallingConv (IGF.IGM .DefaultCC );
2287
2326
addrOfValue->setDoesNotThrow ();
2288
2327
@@ -2309,10 +2348,10 @@ static void initBufferWithCopyOfReference(IRGenFunction &IGF,
2309
2348
}
2310
2349
2311
2350
static llvm::Constant *getAssignBoxedOpaqueExistentialBufferFunction (
2312
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
2313
- llvm::Type *existContainerPointerTy) {
2351
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout) {
2314
2352
2315
- llvm::Type *argTys[] = {existContainerPointerTy, existContainerPointerTy};
2353
+ llvm::Type *argTys[] = {IGM.getExistentialPtrTy (existLayout.getNumTables ()),
2354
+ IGM.getExistentialPtrTy (existLayout.getNumTables ())};
2316
2355
2317
2356
// __swift_assign_box_in_existentials_N is the well-known function for
2318
2357
// assigning buffers in existential containers of types with N witness
@@ -2528,10 +2567,9 @@ static llvm::Constant *getAssignBoxedOpaqueExistentialBufferFunction(
2528
2567
}
2529
2568
2530
2569
static llvm::Constant *getDestroyBoxedOpaqueExistentialBufferFunction (
2531
- IRGenModule &IGM, OpaqueExistentialLayout existLayout,
2532
- llvm::Type *existContainerPointerTy) {
2570
+ IRGenModule &IGM, OpaqueExistentialLayout existLayout) {
2533
2571
2534
- llvm::Type *argTys[] = {existContainerPointerTy };
2572
+ llvm::Type *argTys[] = {IGM. getExistentialPtrTy (existLayout. getNumTables ()) };
2535
2573
2536
2574
llvm::SmallString<40 > fnName;
2537
2575
llvm::raw_svector_ostream (fnName)
0 commit comments