@@ -1190,18 +1190,33 @@ struct VPIRPhi : public VPIRInstruction {
1190
1190
#endif
1191
1191
};
1192
1192
1193
+ // / Helper to manage IR metadata for recipes. It filters out metadata that
1194
+ // / cannot be propagated.
1195
+ class VPIRMetadata {
1196
+ SmallVector<std::pair<unsigned , MDNode *>> Metadata;
1197
+
1198
+ protected:
1199
+ VPIRMetadata () {}
1200
+ VPIRMetadata (Instruction &I) { getMetadataToPropagate (&I, Metadata); }
1201
+
1202
+ public:
1203
+ // / Add all metadata to \p I.
1204
+ void applyMetadata (Instruction &I) const ;
1205
+ };
1206
+
1193
1207
// / VPWidenRecipe is a recipe for producing a widened instruction using the
1194
1208
// / opcode and operands of the recipe. This recipe covers most of the
1195
1209
// / traditional vectorization cases where each recipe transforms into a
1196
1210
// / vectorized version of itself.
1197
- class VPWidenRecipe : public VPRecipeWithIRFlags {
1211
+ class VPWidenRecipe : public VPRecipeWithIRFlags , public VPIRMetadata {
1198
1212
unsigned Opcode;
1199
1213
1200
1214
protected:
1201
1215
template <typename IterT>
1202
1216
VPWidenRecipe (unsigned VPDefOpcode, Instruction &I,
1203
1217
iterator_range<IterT> Operands)
1204
- : VPRecipeWithIRFlags(VPDefOpcode, Operands, I), Opcode(I.getOpcode()) {}
1218
+ : VPRecipeWithIRFlags(VPDefOpcode, Operands, I), VPIRMetadata(I),
1219
+ Opcode (I.getOpcode()) {}
1205
1220
1206
1221
public:
1207
1222
template <typename IterT>
@@ -1236,7 +1251,7 @@ class VPWidenRecipe : public VPRecipeWithIRFlags {
1236
1251
};
1237
1252
1238
1253
// / VPWidenCastRecipe is a recipe to create vector cast instructions.
1239
- class VPWidenCastRecipe : public VPRecipeWithIRFlags {
1254
+ class VPWidenCastRecipe : public VPRecipeWithIRFlags , public VPIRMetadata {
1240
1255
// / Cast instruction opcode.
1241
1256
Instruction::CastOps Opcode;
1242
1257
@@ -1246,15 +1261,15 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags {
1246
1261
public:
1247
1262
VPWidenCastRecipe (Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy,
1248
1263
CastInst &UI)
1249
- : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, UI), Opcode(Opcode ),
1250
- ResultTy (ResultTy) {
1264
+ : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, UI), VPIRMetadata(UI ),
1265
+ Opcode (Opcode), ResultTy(ResultTy) {
1251
1266
assert (UI.getOpcode () == Opcode &&
1252
1267
" opcode of underlying cast doesn't match" );
1253
1268
}
1254
1269
1255
1270
VPWidenCastRecipe (Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
1256
- : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op), Opcode(Opcode ),
1257
- ResultTy(ResultTy) {}
1271
+ : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op), VPIRMetadata( ),
1272
+ Opcode(Opcode), ResultTy(ResultTy) {}
1258
1273
1259
1274
~VPWidenCastRecipe () override = default ;
1260
1275
@@ -1288,7 +1303,7 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags {
1288
1303
};
1289
1304
1290
1305
// / A recipe for widening vector intrinsics.
1291
- class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
1306
+ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags , public VPIRMetadata {
1292
1307
// / ID of the vector intrinsic to widen.
1293
1308
Intrinsic::ID VectorIntrinsicID;
1294
1309
@@ -1309,7 +1324,7 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
1309
1324
ArrayRef<VPValue *> CallArguments, Type *Ty,
1310
1325
DebugLoc DL = {})
1311
1326
: VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, CI),
1312
- VectorIntrinsicID (VectorIntrinsicID), ResultTy(Ty),
1327
+ VPIRMetadata (CI), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
1313
1328
MayReadFromMemory(CI.mayReadFromMemory()),
1314
1329
MayWriteToMemory(CI.mayWriteToMemory()),
1315
1330
MayHaveSideEffects(CI.mayHaveSideEffects()) {}
@@ -1318,7 +1333,7 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
1318
1333
ArrayRef<VPValue *> CallArguments, Type *Ty,
1319
1334
DebugLoc DL = {})
1320
1335
: VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, DL),
1321
- VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
1336
+ VPIRMetadata(), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
1322
1337
LLVMContext &Ctx = Ty->getContext ();
1323
1338
AttributeSet Attrs = Intrinsic::getFnAttributes (Ctx, VectorIntrinsicID);
1324
1339
MemoryEffects ME = Attrs.getMemoryEffects ();
@@ -1374,7 +1389,7 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
1374
1389
};
1375
1390
1376
1391
// / A recipe for widening Call instructions using library calls.
1377
- class VPWidenCallRecipe : public VPRecipeWithIRFlags {
1392
+ class VPWidenCallRecipe : public VPRecipeWithIRFlags , public VPIRMetadata {
1378
1393
// / Variant stores a pointer to the chosen function. There is a 1:1 mapping
1379
1394
// / between a given VF and the chosen vectorized variant, so there will be a
1380
1395
// / different VPlan for each VF with a valid variant.
@@ -1385,7 +1400,7 @@ class VPWidenCallRecipe : public VPRecipeWithIRFlags {
1385
1400
ArrayRef<VPValue *> CallArguments, DebugLoc DL = {})
1386
1401
: VPRecipeWithIRFlags(VPDef::VPWidenCallSC, CallArguments,
1387
1402
*cast<Instruction>(UV)),
1388
- Variant (Variant) {
1403
+ VPIRMetadata (*cast<Instruction>(UV)), Variant(Variant) {
1389
1404
assert (
1390
1405
isa<Function>(getOperand (getNumOperands () - 1 )->getLiveInIRValue ()) &&
1391
1406
" last operand must be the called function" );
@@ -1471,10 +1486,11 @@ class VPHistogramRecipe : public VPRecipeBase {
1471
1486
};
1472
1487
1473
1488
// / A recipe for widening select instructions.
1474
- struct VPWidenSelectRecipe : public VPRecipeWithIRFlags {
1489
+ struct VPWidenSelectRecipe : public VPRecipeWithIRFlags , public VPIRMetadata {
1475
1490
template <typename IterT>
1476
1491
VPWidenSelectRecipe (SelectInst &I, iterator_range<IterT> Operands)
1477
- : VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I) {}
1492
+ : VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I),
1493
+ VPIRMetadata (I) {}
1478
1494
1479
1495
~VPWidenSelectRecipe () override = default ;
1480
1496
@@ -2602,7 +2618,7 @@ class VPPredInstPHIRecipe : public VPSingleDefRecipe {
2602
2618
2603
2619
// / A common base class for widening memory operations. An optional mask can be
2604
2620
// / provided as the last operand.
2605
- class VPWidenMemoryRecipe : public VPRecipeBase {
2621
+ class VPWidenMemoryRecipe : public VPRecipeBase , public VPIRMetadata {
2606
2622
protected:
2607
2623
Instruction &Ingredient;
2608
2624
@@ -2626,8 +2642,8 @@ class VPWidenMemoryRecipe : public VPRecipeBase {
2626
2642
VPWidenMemoryRecipe (const char unsigned SC, Instruction &I,
2627
2643
std::initializer_list<VPValue *> Operands,
2628
2644
bool Consecutive, bool Reverse, DebugLoc DL)
2629
- : VPRecipeBase(SC, Operands, DL), Ingredient (I), Consecutive(Consecutive ),
2630
- Reverse (Reverse) {
2645
+ : VPRecipeBase(SC, Operands, DL), VPIRMetadata (I), Ingredient(I ),
2646
+ Consecutive (Consecutive), Reverse(Reverse) {
2631
2647
assert ((Consecutive || !Reverse) && " Reverse implies consecutive" );
2632
2648
}
2633
2649
0 commit comments