@@ -1136,13 +1136,7 @@ MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
1136
1136
1137
1137
// / Emit a string encoding the labels in the given tuple type.
1138
1138
static llvm::Constant *getTupleLabelsString (IRGenModule &IGM,
1139
- CanTupleType type,
1140
- bool useLabels) {
1141
- // If we were asked to ignore the labels, do so.
1142
- if (!useLabels) {
1143
- return llvm::ConstantPointerNull::get (IGM.Int8PtrTy );
1144
- }
1145
-
1139
+ CanTupleType type) {
1146
1140
bool hasLabels = false ;
1147
1141
llvm::SmallString<128 > buffer;
1148
1142
for (auto &elt : type->getElements ()) {
@@ -1175,21 +1169,55 @@ static llvm::Constant *emitEmptyTupleTypeMetadataRef(IRGenModule &IGM) {
1175
1169
IGM.FullTypeMetadataStructTy , fullMetadata, indices);
1176
1170
}
1177
1171
1178
- using GetElementMetadataFn =
1179
- llvm::function_ref<MetadataResponse(CanType eltType,
1180
- DynamicMetadataRequest eltRequest)>;
1172
+ static MetadataResponse emitDynamicTupleTypeMetadataRef (IRGenFunction &IGF,
1173
+ CanTupleType type,
1174
+ DynamicMetadataRequest request) {
1175
+ SmallVector<Type, 2 > types;
1176
+ types.append (type.getElementTypes ().begin (),
1177
+ type.getElementTypes ().end ());
1178
+
1179
+ CanPackType packType = CanPackType (PackType::get (IGF.IGM .Context , types));
1180
+
1181
+ auto *shapeExpression = IGF.emitPackShapeExpression (packType);
1182
+ auto addr = emitTypeMetadataPack (IGF, packType, MetadataState::Abstract);
1183
+
1184
+ auto *pointerToFirst = IGF.Builder .CreatePointerCast (
1185
+ addr.getAddressPointer (), IGF.IGM .TypeMetadataPtrPtrTy );
1186
+
1187
+ llvm::Value *args[] = {
1188
+ request.get (IGF),
1189
+ shapeExpression,
1190
+ pointerToFirst,
1191
+ getTupleLabelsString (IGF.IGM , type),
1192
+ llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
1193
+ };
1194
+
1195
+ auto call = IGF.Builder .CreateCall (
1196
+ IGF.IGM .getGetTupleMetadataFunctionPointer (), args);
1197
+ call->setCallingConv (IGF.IGM .SwiftCC );
1198
+ call->setDoesNotThrow ();
1199
+
1200
+ Optional<unsigned > elementCount = 0 ;
1201
+ if (auto *constant = dyn_cast<llvm::ConstantInt>(shapeExpression))
1202
+ elementCount = constant->getValue ().getZExtValue ();
1203
+
1204
+ cleanupTypeMetadataPack (IGF, addr, elementCount);
1205
+
1206
+ return MetadataResponse::handle (IGF, request, call);
1207
+ }
1181
1208
1182
1209
static MetadataResponse emitTupleTypeMetadataRef (IRGenFunction &IGF,
1183
1210
CanTupleType type,
1184
- DynamicMetadataRequest request,
1185
- bool useLabels,
1186
- GetElementMetadataFn getMetadataRecursive) {
1211
+ DynamicMetadataRequest request) {
1212
+ if (type->containsPackExpansionType ())
1213
+ return emitDynamicTupleTypeMetadataRef (IGF, type, request);
1214
+
1187
1215
auto getElementMetadata = [&](CanType type) {
1188
1216
// Just request the elements to be abstract so that we can always build
1189
1217
// the metadata.
1190
1218
// TODO: if we have a collector, or if this is a blocking request, maybe
1191
1219
// we should build a stronger request?
1192
- return getMetadataRecursive (type, MetadataState::Abstract).getMetadata ();
1220
+ return IGF. emitTypeMetadataRef (type, MetadataState::Abstract).getMetadata ();
1193
1221
};
1194
1222
1195
1223
switch (type->getNumElements ()) {
@@ -1200,7 +1228,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
1200
1228
case 1 :
1201
1229
// For metadata purposes, we consider a singleton tuple to be
1202
1230
// isomorphic to its element type. ???
1203
- return getMetadataRecursive (type.getElementType (0 ), request);
1231
+ return IGF. emitTypeMetadataRef (type.getElementType (0 ), request);
1204
1232
1205
1233
case 2 : {
1206
1234
auto elt0Metadata = getElementMetadata (type.getElementType (0 ));
@@ -1209,7 +1237,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
1209
1237
llvm::Value *args[] = {
1210
1238
request.get (IGF),
1211
1239
elt0Metadata, elt1Metadata,
1212
- getTupleLabelsString (IGF.IGM , type, useLabels ),
1240
+ getTupleLabelsString (IGF.IGM , type),
1213
1241
llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
1214
1242
};
1215
1243
@@ -1229,7 +1257,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
1229
1257
llvm::Value *args[] = {
1230
1258
request.get (IGF),
1231
1259
elt0Metadata, elt1Metadata, elt2Metadata,
1232
- getTupleLabelsString (IGF.IGM , type, useLabels ),
1260
+ getTupleLabelsString (IGF.IGM , type),
1233
1261
llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
1234
1262
};
1235
1263
@@ -1241,50 +1269,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
1241
1269
return MetadataResponse::handle (IGF, request, call);
1242
1270
}
1243
1271
default :
1244
- // TODO: use a caching entrypoint (with all information
1245
- // out-of-line) for non-dependent tuples.
1246
-
1247
- llvm::Value *pointerToFirst = nullptr ; // appease -Wuninitialized
1248
-
1249
- auto elements = type.getElementTypes ();
1250
- auto arrayTy = llvm::ArrayType::get (IGF.IGM .TypeMetadataPtrTy ,
1251
- elements.size ());
1252
- Address buffer = IGF.createAlloca (arrayTy,IGF.IGM .getPointerAlignment (),
1253
- " tuple-elements" );
1254
- IGF.Builder .CreateLifetimeStart (buffer,
1255
- IGF.IGM .getPointerSize () * elements.size ());
1256
- for (auto i : indices (elements)) {
1257
- // Find the metadata pointer for this element.
1258
- llvm::Value *eltMetadata = getElementMetadata (elements[i]);
1259
-
1260
- // GEP to the appropriate element and store.
1261
- Address eltPtr = IGF.Builder .CreateStructGEP (buffer, i,
1262
- IGF.IGM .getPointerSize ());
1263
- IGF.Builder .CreateStore (eltMetadata, eltPtr);
1264
-
1265
- // Remember the GEP to the first element.
1266
- if (i == 0 ) pointerToFirst = eltPtr.getAddress ();
1267
- }
1268
-
1269
- TupleTypeFlags flags =
1270
- TupleTypeFlags ().withNumElements (elements.size ());
1271
- llvm::Value *args[] = {
1272
- request.get (IGF),
1273
- llvm::ConstantInt::get (IGF.IGM .SizeTy , flags.getIntValue ()),
1274
- pointerToFirst,
1275
- getTupleLabelsString (IGF.IGM , type, useLabels),
1276
- llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
1277
- };
1278
-
1279
- auto call = IGF.Builder .CreateCall (
1280
- IGF.IGM .getGetTupleMetadataFunctionPointer (), args);
1281
- call->setCallingConv (IGF.IGM .SwiftCC );
1282
- call->setDoesNotThrow ();
1283
-
1284
- IGF.Builder .CreateLifetimeEnd (buffer,
1285
- IGF.IGM .getPointerSize () * elements.size ());
1286
-
1287
- return MetadataResponse::handle (IGF, request, call);
1272
+ return emitDynamicTupleTypeMetadataRef (IGF, type, request);
1288
1273
}
1289
1274
}
1290
1275
@@ -1442,11 +1427,7 @@ namespace {
1442
1427
if (auto cached = tryGetLocal (type, request))
1443
1428
return cached;
1444
1429
1445
- auto response = emitTupleTypeMetadataRef (IGF, type, request,
1446
- /* labels*/ true ,
1447
- [&](CanType eltType, DynamicMetadataRequest eltRequest) {
1448
- return IGF.emitTypeMetadataRef (eltType, eltRequest);
1449
- });
1430
+ auto response = emitTupleTypeMetadataRef (IGF, type, request);
1450
1431
1451
1432
return setLocal (type, response);
1452
1433
}
0 commit comments