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