@@ -200,15 +200,11 @@ template <typename Ops_t, unsigned Opcode, bool Commutative,
200
200
struct Recipe_match {
201
201
Ops_t Ops;
202
202
203
- Recipe_match () : Ops() {
204
- static_assert (std::tuple_size<Ops_t>::value == 0 &&
205
- " constructor can only be used with zero operands" );
206
- }
207
- Recipe_match (Ops_t Ops) : Ops(Ops) {}
208
- template <typename A_t, typename B_t>
209
- Recipe_match (A_t A, B_t B) : Ops({A, B}) {
210
- static_assert (std::tuple_size<Ops_t>::value == 2 &&
211
- " constructor can only be used for binary matcher" );
203
+ template <typename ... OpTy> Recipe_match (OpTy... Ops) : Ops(Ops...) {
204
+ static_assert (std::tuple_size<Ops_t>::value == sizeof ...(Ops) &&
205
+ " number of operands in constructor doesn't match Ops_t" );
206
+ static_assert ((!Commutative || std::tuple_size<Ops_t>::value == 2 ) &&
207
+ " only binary ops can be commutative" );
212
208
}
213
209
214
210
bool match (const VPValue *V) const {
@@ -254,7 +250,6 @@ struct Recipe_match {
254
250
// Check for recipes that do not have opcodes.
255
251
if constexpr (std::is_same<RecipeTy, VPScalarIVStepsRecipe>::value ||
256
252
std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value ||
257
- std::is_same<RecipeTy, VPWidenSelectRecipe>::value ||
258
253
std::is_same<RecipeTy, VPDerivedIVRecipe>::value ||
259
254
std::is_same<RecipeTy, VPWidenGEPRecipe>::value)
260
255
return DefR;
@@ -270,195 +265,128 @@ struct Recipe_match {
270
265
}
271
266
};
272
267
273
- template <unsigned Opcode, typename ... RecipeTys>
274
- using ZeroOpRecipe_match =
275
- Recipe_match<std::tuple<>, Opcode, false , RecipeTys...>;
276
-
277
- template <typename Op0_t, unsigned Opcode, typename ... RecipeTys>
278
- using UnaryRecipe_match =
279
- Recipe_match<std::tuple<Op0_t>, Opcode, false , RecipeTys...>;
280
-
281
- template <typename Op0_t, unsigned Opcode>
282
- using UnaryVPInstruction_match =
283
- UnaryRecipe_match<Op0_t, Opcode, VPInstruction>;
268
+ template <unsigned Opcode, typename ... OpTys>
269
+ using AllRecipe_match =
270
+ Recipe_match<std::tuple<OpTys...>, Opcode, /* Commutative*/ false ,
271
+ VPWidenRecipe, VPReplicateRecipe, VPWidenCastRecipe,
272
+ VPInstruction, VPWidenSelectRecipe>;
284
273
285
- template <unsigned Opcode>
286
- using ZeroOpVPInstruction_match = ZeroOpRecipe_match<Opcode, VPInstruction>;
274
+ template <unsigned Opcode, typename ... OpTys>
275
+ using AllRecipe_commutative_match =
276
+ Recipe_match<std::tuple<OpTys...>, Opcode, /* Commutative*/ true ,
277
+ VPWidenRecipe, VPReplicateRecipe, VPInstruction>;
287
278
288
- template <typename Op0_t, unsigned Opcode>
289
- using AllUnaryRecipe_match =
290
- UnaryRecipe_match<Op0_t, Opcode, VPWidenRecipe, VPReplicateRecipe,
291
- VPWidenCastRecipe, VPInstruction>;
279
+ template <unsigned Opcode, typename ... OpTys>
280
+ using VPInstruction_match = Recipe_match<std::tuple<OpTys...>, Opcode,
281
+ /* Commutative*/ false , VPInstruction>;
292
282
293
- template <typename Op0_t, typename Op1_t, unsigned Opcode, bool Commutative,
294
- typename ... RecipeTys>
295
- using BinaryRecipe_match =
296
- Recipe_match<std::tuple<Op0_t, Op1_t>, Opcode, Commutative, RecipeTys...>;
297
-
298
- template <typename Op0_t, typename Op1_t, unsigned Opcode>
299
- using BinaryVPInstruction_match =
300
- BinaryRecipe_match<Op0_t, Op1_t, Opcode, /* Commutative*/ false ,
301
- VPInstruction>;
302
-
303
- template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode,
304
- bool Commutative, typename ... RecipeTys>
305
- using TernaryRecipe_match = Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t>,
306
- Opcode, Commutative, RecipeTys...>;
307
-
308
- template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode>
309
- using TernaryVPInstruction_match =
310
- TernaryRecipe_match<Op0_t, Op1_t, Op2_t, Opcode, /* Commutative*/ false ,
311
- VPInstruction>;
312
-
313
- template <typename Op0_t, typename Op1_t, unsigned Opcode,
314
- bool Commutative = false >
315
- using AllBinaryRecipe_match =
316
- BinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative, VPWidenRecipe,
317
- VPReplicateRecipe, VPWidenCastRecipe, VPInstruction>;
283
+ template <unsigned Opcode, typename ... OpTys>
284
+ inline VPInstruction_match<Opcode, OpTys...>
285
+ m_VPInstruction (const OpTys &...Ops) {
286
+ return VPInstruction_match<Opcode, OpTys...>(Ops...);
287
+ }
318
288
319
289
// / BuildVector is matches only its opcode, w/o matching its operands as the
320
290
// / number of operands is not fixed.
321
- inline ZeroOpVPInstruction_match<VPInstruction::BuildVector> m_BuildVector () {
322
- return ZeroOpVPInstruction_match<VPInstruction::BuildVector>();
323
- }
324
-
325
- template <unsigned Opcode, typename Op0_t>
326
- inline UnaryVPInstruction_match<Op0_t, Opcode>
327
- m_VPInstruction (const Op0_t &Op0) {
328
- return UnaryVPInstruction_match<Op0_t, Opcode>(Op0);
329
- }
330
-
331
- template <unsigned Opcode, typename Op0_t, typename Op1_t>
332
- inline BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>
333
- m_VPInstruction (const Op0_t &Op0, const Op1_t &Op1) {
334
- return BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>(Op0, Op1);
291
+ inline VPInstruction_match<VPInstruction::BuildVector> m_BuildVector () {
292
+ return m_VPInstruction<VPInstruction::BuildVector>();
335
293
}
336
294
337
- template <unsigned Opcode, typename Op0_t, typename Op1_t, typename Op2_t>
338
- inline TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>
339
- m_VPInstruction (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
340
- return TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>(
341
- {Op0, Op1, Op2});
342
- }
343
-
344
- template <typename Op0_t, typename Op1_t, typename Op2_t, typename Op3_t,
345
- unsigned Opcode, bool Commutative, typename ... RecipeTys>
346
- using Recipe4Op_match = Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t, Op3_t>,
347
- Opcode, Commutative, RecipeTys...>;
348
-
349
- template <typename Op0_t, typename Op1_t, typename Op2_t, typename Op3_t,
350
- unsigned Opcode>
351
- using VPInstruction4Op_match =
352
- Recipe4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode, /* Commutative*/ false ,
353
- VPInstruction>;
354
-
355
- template <unsigned Opcode, typename Op0_t, typename Op1_t, typename Op2_t,
356
- typename Op3_t>
357
- inline VPInstruction4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode>
358
- m_VPInstruction (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2,
359
- const Op3_t &Op3) {
360
- return VPInstruction4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode>(
361
- {Op0, Op1, Op2, Op3});
362
- }
363
295
template <typename Op0_t>
364
- inline UnaryVPInstruction_match<Op0_t, Instruction::Freeze>
296
+ inline VPInstruction_match< Instruction::Freeze, Op0_t >
365
297
m_Freeze (const Op0_t &Op0) {
366
298
return m_VPInstruction<Instruction::Freeze>(Op0);
367
299
}
368
300
369
301
template <typename Op0_t>
370
- inline UnaryVPInstruction_match<Op0_t, VPInstruction::BranchOnCond>
302
+ inline VPInstruction_match< VPInstruction::BranchOnCond, Op0_t >
371
303
m_BranchOnCond (const Op0_t &Op0) {
372
304
return m_VPInstruction<VPInstruction::BranchOnCond>(Op0);
373
305
}
374
306
375
307
template <typename Op0_t>
376
- inline UnaryVPInstruction_match<Op0_t, VPInstruction::Broadcast>
308
+ inline VPInstruction_match< VPInstruction::Broadcast, Op0_t >
377
309
m_Broadcast (const Op0_t &Op0) {
378
310
return m_VPInstruction<VPInstruction::Broadcast>(Op0);
379
311
}
380
312
381
313
template <typename Op0_t, typename Op1_t>
382
- inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::ActiveLaneMask>
314
+ inline VPInstruction_match< VPInstruction::ActiveLaneMask, Op0_t, Op1_t >
383
315
m_ActiveLaneMask (const Op0_t &Op0, const Op1_t &Op1) {
384
316
return m_VPInstruction<VPInstruction::ActiveLaneMask>(Op0, Op1);
385
317
}
386
318
387
319
template <typename Op0_t, typename Op1_t>
388
- inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::BranchOnCount>
320
+ inline VPInstruction_match< VPInstruction::BranchOnCount, Op0_t, Op1_t >
389
321
m_BranchOnCount (const Op0_t &Op0, const Op1_t &Op1) {
390
322
return m_VPInstruction<VPInstruction::BranchOnCount>(Op0, Op1);
391
323
}
392
324
393
325
template <unsigned Opcode, typename Op0_t>
394
- inline AllUnaryRecipe_match<Op0_t, Opcode > m_Unary (const Op0_t &Op0) {
395
- return AllUnaryRecipe_match<Op0_t, Opcode >(Op0);
326
+ inline AllRecipe_match<Opcode, Op0_t > m_Unary (const Op0_t &Op0) {
327
+ return AllRecipe_match<Opcode, Op0_t >(Op0);
396
328
}
397
329
398
330
template <typename Op0_t>
399
- inline AllUnaryRecipe_match<Op0_t, Instruction::Trunc>
400
- m_Trunc (const Op0_t &Op0) {
331
+ inline AllRecipe_match<Instruction::Trunc, Op0_t> m_Trunc (const Op0_t &Op0) {
401
332
return m_Unary<Instruction::Trunc, Op0_t>(Op0);
402
333
}
403
334
404
335
template <typename Op0_t>
405
- inline AllUnaryRecipe_match<Op0_t, Instruction::ZExt> m_ZExt (const Op0_t &Op0) {
336
+ inline AllRecipe_match< Instruction::ZExt, Op0_t > m_ZExt (const Op0_t &Op0) {
406
337
return m_Unary<Instruction::ZExt, Op0_t>(Op0);
407
338
}
408
339
409
340
template <typename Op0_t>
410
- inline AllUnaryRecipe_match<Op0_t, Instruction::SExt> m_SExt (const Op0_t &Op0) {
341
+ inline AllRecipe_match< Instruction::SExt, Op0_t > m_SExt (const Op0_t &Op0) {
411
342
return m_Unary<Instruction::SExt, Op0_t>(Op0);
412
343
}
413
344
414
345
template <typename Op0_t>
415
- inline match_combine_or<AllUnaryRecipe_match<Op0_t, Instruction::ZExt>,
416
- AllUnaryRecipe_match<Op0_t, Instruction::SExt>>
346
+ inline match_combine_or<AllRecipe_match< Instruction::ZExt, Op0_t >,
347
+ AllRecipe_match< Instruction::SExt, Op0_t >>
417
348
m_ZExtOrSExt (const Op0_t &Op0) {
418
349
return m_CombineOr (m_ZExt (Op0), m_SExt (Op0));
419
350
}
420
351
421
- template <unsigned Opcode, typename Op0_t, typename Op1_t,
422
- bool Commutative = false >
423
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative>
424
- m_Binary (const Op0_t &Op0, const Op1_t &Op1) {
425
- return AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative>(Op0, Op1);
352
+ template <unsigned Opcode, typename Op0_t, typename Op1_t>
353
+ inline AllRecipe_match<Opcode, Op0_t, Op1_t> m_Binary (const Op0_t &Op0,
354
+ const Op1_t &Op1) {
355
+ return AllRecipe_match<Opcode, Op0_t, Op1_t>(Op0, Op1);
426
356
}
427
357
428
358
template <unsigned Opcode, typename Op0_t, typename Op1_t>
429
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, true >
359
+ inline AllRecipe_commutative_match<Opcode, Op0_t, Op1_t >
430
360
m_c_Binary (const Op0_t &Op0, const Op1_t &Op1) {
431
- return AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, true >(Op0, Op1);
361
+ return AllRecipe_commutative_match<Opcode, Op0_t, Op1_t >(Op0, Op1);
432
362
}
433
363
434
364
template <typename Op0_t, typename Op1_t>
435
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Mul>
436
- m_Mul ( const Op0_t &Op0, const Op1_t &Op1) {
365
+ inline AllRecipe_match< Instruction::Mul, Op0_t, Op1_t> m_Mul ( const Op0_t &Op0,
366
+ const Op1_t &Op1) {
437
367
return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1);
438
368
}
439
369
440
370
template <typename Op0_t, typename Op1_t>
441
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Mul,
442
- /* Commutative =*/ true >
371
+ inline AllRecipe_commutative_match<Instruction::Mul, Op0_t, Op1_t>
443
372
m_c_Mul (const Op0_t &Op0, const Op1_t &Op1) {
444
- return m_Binary <Instruction::Mul, Op0_t, Op1_t, true >(Op0, Op1);
373
+ return m_c_Binary <Instruction::Mul, Op0_t, Op1_t>(Op0, Op1);
445
374
}
446
375
447
376
// / Match a binary OR operation. Note that while conceptually the operands can
448
377
// / be matched commutatively, \p Commutative defaults to false in line with the
449
378
// / IR-based pattern matching infrastructure. Use m_c_BinaryOr for a commutative
450
379
// / version of the matcher.
451
- template <typename Op0_t, typename Op1_t, bool Commutative = false >
452
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or, Commutative >
380
+ template <typename Op0_t, typename Op1_t>
381
+ inline AllRecipe_match< Instruction::Or, Op0_t, Op1_t >
453
382
m_BinaryOr (const Op0_t &Op0, const Op1_t &Op1) {
454
- return m_Binary<Instruction::Or, Op0_t, Op1_t, Commutative >(Op0, Op1);
383
+ return m_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1);
455
384
}
456
385
457
386
template <typename Op0_t, typename Op1_t>
458
- inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or,
459
- /* Commutative*/ true >
387
+ inline AllRecipe_commutative_match<Instruction::Or, Op0_t, Op1_t>
460
388
m_c_BinaryOr (const Op0_t &Op0, const Op1_t &Op1) {
461
- return m_BinaryOr<Op0_t, Op1_t, /* Commutative */ true >(Op0, Op1);
389
+ return m_c_Binary<Instruction::Or, Op0_t, Op1_t >(Op0, Op1);
462
390
}
463
391
464
392
// / ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
@@ -523,58 +451,51 @@ m_SpecificICmp(CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
523
451
524
452
template <typename Op0_t, typename Op1_t>
525
453
using GEPLikeRecipe_match =
526
- BinaryRecipe_match< Op0_t, Op1_t, Instruction::GetElementPtr, false ,
527
- VPWidenRecipe, VPReplicateRecipe, VPWidenGEPRecipe ,
528
- VPInstruction>;
454
+ Recipe_match<std::tuple< Op0_t, Op1_t> , Instruction::GetElementPtr,
455
+ /* Commutative */ false , VPWidenRecipe, VPReplicateRecipe,
456
+ VPWidenGEPRecipe, VPInstruction>;
529
457
530
458
template <typename Op0_t, typename Op1_t>
531
459
inline GEPLikeRecipe_match<Op0_t, Op1_t> m_GetElementPtr (const Op0_t &Op0,
532
460
const Op1_t &Op1) {
533
461
return GEPLikeRecipe_match<Op0_t, Op1_t>(Op0, Op1);
534
462
}
535
463
536
- template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode>
537
- using AllTernaryRecipe_match =
538
- Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t>, Opcode, false ,
539
- VPReplicateRecipe, VPInstruction, VPWidenSelectRecipe>;
540
-
541
464
template <typename Op0_t, typename Op1_t, typename Op2_t>
542
- inline AllTernaryRecipe_match< Op0_t, Op1_t, Op2_t, Instruction::Select >
465
+ inline AllRecipe_match<Instruction::Select, Op0_t, Op1_t, Op2_t>
543
466
m_Select (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
544
- return AllTernaryRecipe_match< Op0_t, Op1_t, Op2_t, Instruction::Select >(
467
+ return AllRecipe_match<Instruction::Select, Op0_t, Op1_t, Op2_t>(
545
468
{Op0, Op1, Op2});
546
469
}
547
470
548
471
template <typename Op0_t>
549
- inline match_combine_or<UnaryVPInstruction_match<Op0_t, VPInstruction::Not>,
550
- AllBinaryRecipe_match<int_pred_ty<is_all_ones>, Op0_t,
551
- Instruction::Xor, true >>
472
+ inline match_combine_or<VPInstruction_match< VPInstruction::Not, Op0_t >,
473
+ AllRecipe_commutative_match<
474
+ Instruction::Xor, int_pred_ty<is_all_ones>, Op0_t >>
552
475
m_Not (const Op0_t &Op0) {
553
476
return m_CombineOr (m_VPInstruction<VPInstruction::Not>(Op0),
554
477
m_c_Binary<Instruction::Xor>(m_AllOnes (), Op0));
555
478
}
556
479
557
480
template <typename Op0_t, typename Op1_t>
558
481
inline match_combine_or<
559
- BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::LogicalAnd>,
560
- AllTernaryRecipe_match<Op0_t, Op1_t, specific_intval<1 >,
561
- Instruction::Select>>
482
+ VPInstruction_match<VPInstruction::LogicalAnd, Op0_t, Op1_t>,
483
+ AllRecipe_match<Instruction::Select, Op0_t, Op1_t, specific_intval<1 >>>
562
484
m_LogicalAnd (const Op0_t &Op0, const Op1_t &Op1) {
563
485
return m_CombineOr (
564
486
m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1),
565
487
m_Select (Op0, Op1, m_False ()));
566
488
}
567
489
568
490
template <typename Op0_t, typename Op1_t>
569
- inline AllTernaryRecipe_match<Op0_t, specific_intval<1 >, Op1_t,
570
- Instruction::Select>
491
+ inline AllRecipe_match<Instruction::Select, Op0_t, specific_intval<1 >, Op1_t>
571
492
m_LogicalOr (const Op0_t &Op0, const Op1_t &Op1) {
572
493
return m_Select (Op0, m_True (), Op1);
573
494
}
574
495
575
496
template <typename Op0_t, typename Op1_t, typename Op2_t>
576
- using VPScalarIVSteps_match =
577
- TernaryRecipe_match<Op0_t, Op1_t, Op2_t, 0 , false , VPScalarIVStepsRecipe>;
497
+ using VPScalarIVSteps_match = Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t>, 0 ,
498
+ false , VPScalarIVStepsRecipe>;
578
499
579
500
template <typename Op0_t, typename Op1_t, typename Op2_t>
580
501
inline VPScalarIVSteps_match<Op0_t, Op1_t, Op2_t>
0 commit comments