@@ -200,15 +200,11 @@ template <typename Ops_t, unsigned Opcode, bool Commutative,
200200struct Recipe_match {
201201 Ops_t Ops;
202202
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" );
212208 }
213209
214210 bool match (const VPValue *V) const {
@@ -254,7 +250,6 @@ struct Recipe_match {
254250 // Check for recipes that do not have opcodes.
255251 if constexpr (std::is_same<RecipeTy, VPScalarIVStepsRecipe>::value ||
256252 std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value ||
257- std::is_same<RecipeTy, VPWidenSelectRecipe>::value ||
258253 std::is_same<RecipeTy, VPDerivedIVRecipe>::value ||
259254 std::is_same<RecipeTy, VPWidenGEPRecipe>::value)
260255 return DefR;
@@ -270,195 +265,128 @@ struct Recipe_match {
270265 }
271266};
272267
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>;
284273
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>;
287278
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>;
292282
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+ }
318288
319289// / BuildVector is matches only its opcode, w/o matching its operands as the
320290// / 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>();
335293}
336294
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- }
363295template <typename Op0_t>
364- inline UnaryVPInstruction_match<Op0_t, Instruction::Freeze>
296+ inline VPInstruction_match< Instruction::Freeze, Op0_t >
365297m_Freeze (const Op0_t &Op0) {
366298 return m_VPInstruction<Instruction::Freeze>(Op0);
367299}
368300
369301template <typename Op0_t>
370- inline UnaryVPInstruction_match<Op0_t, VPInstruction::BranchOnCond>
302+ inline VPInstruction_match< VPInstruction::BranchOnCond, Op0_t >
371303m_BranchOnCond (const Op0_t &Op0) {
372304 return m_VPInstruction<VPInstruction::BranchOnCond>(Op0);
373305}
374306
375307template <typename Op0_t>
376- inline UnaryVPInstruction_match<Op0_t, VPInstruction::Broadcast>
308+ inline VPInstruction_match< VPInstruction::Broadcast, Op0_t >
377309m_Broadcast (const Op0_t &Op0) {
378310 return m_VPInstruction<VPInstruction::Broadcast>(Op0);
379311}
380312
381313template <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 >
383315m_ActiveLaneMask (const Op0_t &Op0, const Op1_t &Op1) {
384316 return m_VPInstruction<VPInstruction::ActiveLaneMask>(Op0, Op1);
385317}
386318
387319template <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 >
389321m_BranchOnCount (const Op0_t &Op0, const Op1_t &Op1) {
390322 return m_VPInstruction<VPInstruction::BranchOnCount>(Op0, Op1);
391323}
392324
393325template <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);
396328}
397329
398330template <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) {
401332 return m_Unary<Instruction::Trunc, Op0_t>(Op0);
402333}
403334
404335template <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) {
406337 return m_Unary<Instruction::ZExt, Op0_t>(Op0);
407338}
408339
409340template <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) {
411342 return m_Unary<Instruction::SExt, Op0_t>(Op0);
412343}
413344
414345template <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 >>
417348m_ZExtOrSExt (const Op0_t &Op0) {
418349 return m_CombineOr (m_ZExt (Op0), m_SExt (Op0));
419350}
420351
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);
426356}
427357
428358template <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 >
430360m_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);
432362}
433363
434364template <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) {
437367 return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1);
438368}
439369
440370template <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>
443372m_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);
445374}
446375
447376// / Match a binary OR operation. Note that while conceptually the operands can
448377// / be matched commutatively, \p Commutative defaults to false in line with the
449378// / IR-based pattern matching infrastructure. Use m_c_BinaryOr for a commutative
450379// / 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 >
453382m_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);
455384}
456385
457386template <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>
460388m_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);
462390}
463391
464392// / 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) {
523451
524452template <typename Op0_t, typename Op1_t>
525453using 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>;
529457
530458template <typename Op0_t, typename Op1_t>
531459inline GEPLikeRecipe_match<Op0_t, Op1_t> m_GetElementPtr (const Op0_t &Op0,
532460 const Op1_t &Op1) {
533461 return GEPLikeRecipe_match<Op0_t, Op1_t>(Op0, Op1);
534462}
535463
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-
541464template <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>
543466m_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>(
545468 {Op0, Op1, Op2});
546469}
547470
548471template <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 >>
552475m_Not (const Op0_t &Op0) {
553476 return m_CombineOr (m_VPInstruction<VPInstruction::Not>(Op0),
554477 m_c_Binary<Instruction::Xor>(m_AllOnes (), Op0));
555478}
556479
557480template <typename Op0_t, typename Op1_t>
558481inline 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 >>>
562484m_LogicalAnd (const Op0_t &Op0, const Op1_t &Op1) {
563485 return m_CombineOr (
564486 m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1),
565487 m_Select (Op0, Op1, m_False ()));
566488}
567489
568490template <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>
571492m_LogicalOr (const Op0_t &Op0, const Op1_t &Op1) {
572493 return m_Select (Op0, m_True (), Op1);
573494}
574495
575496template <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>;
578499
579500template <typename Op0_t, typename Op1_t, typename Op2_t>
580501inline VPScalarIVSteps_match<Op0_t, Op1_t, Op2_t>
0 commit comments