@@ -33,6 +33,12 @@ template <typename Pattern>
33
33
return P.match (MRI, &MI);
34
34
}
35
35
36
+ template <typename Pattern>
37
+ [[nodiscard]] bool mi_match (const MachineInstr &MI,
38
+ const MachineRegisterInfo &MRI, Pattern &&P) {
39
+ return P.match (MRI, &MI);
40
+ }
41
+
36
42
// TODO: Extend for N use.
37
43
template <typename SubPatternT> struct OneUse_match {
38
44
SubPatternT SubPat;
@@ -337,6 +343,21 @@ template <> struct bind_helper<MachineInstr *> {
337
343
}
338
344
};
339
345
346
+ template <> struct bind_helper <const MachineInstr *> {
347
+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
348
+ Register Reg) {
349
+ MI = MRI.getVRegDef (Reg);
350
+ if (MI)
351
+ return true ;
352
+ return false ;
353
+ }
354
+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
355
+ const MachineInstr *Inst) {
356
+ MI = Inst;
357
+ return MI;
358
+ }
359
+ };
360
+
340
361
template <> struct bind_helper <LLT> {
341
362
static bool bind (const MachineRegisterInfo &MRI, LLT &Ty, Register Reg) {
342
363
Ty = MRI.getType (Reg);
@@ -368,6 +389,9 @@ template <typename Class> struct bind_ty {
368
389
369
390
inline bind_ty<Register> m_Reg (Register &R) { return R; }
370
391
inline bind_ty<MachineInstr *> m_MInstr (MachineInstr *&MI) { return MI; }
392
+ inline bind_ty<const MachineInstr *> m_MInstr (const MachineInstr *&MI) {
393
+ return MI;
394
+ }
371
395
inline bind_ty<LLT> m_Type (LLT &Ty) { return Ty; }
372
396
inline bind_ty<CmpInst::Predicate> m_Pred (CmpInst::Predicate &P) { return P; }
373
397
inline operand_type_match m_Pred () { return operand_type_match (); }
@@ -418,26 +442,30 @@ inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
418
442
419
443
// General helper for all the binary generic MI such as G_ADD/G_SUB etc
420
444
template <typename LHS_P, typename RHS_P, unsigned Opcode,
421
- bool Commutable = false >
445
+ bool Commutable = false , unsigned Flags = MachineInstr::NoFlags >
422
446
struct BinaryOp_match {
423
447
LHS_P L;
424
448
RHS_P R;
425
449
426
450
BinaryOp_match (const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
427
451
template <typename OpTy>
428
452
bool match (const MachineRegisterInfo &MRI, OpTy &&Op) {
429
- MachineInstr *TmpMI;
453
+ const MachineInstr *TmpMI;
430
454
if (mi_match (Op, MRI, m_MInstr (TmpMI))) {
431
455
if (TmpMI->getOpcode () == Opcode && TmpMI->getNumOperands () == 3 ) {
432
- return (L.match (MRI, TmpMI->getOperand (1 ).getReg ()) &&
433
- R.match (MRI, TmpMI->getOperand (2 ).getReg ())) ||
434
- // NOTE: When trying the alternative operand ordering
435
- // with a commutative operation, it is imperative to always run
436
- // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
437
- // (i.e. `R`). Otherwsie, m_DeferredReg/Type will not work as
438
- // expected.
439
- (Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
440
- R.match (MRI, TmpMI->getOperand (1 ).getReg ())));
456
+ if (!(L.match (MRI, TmpMI->getOperand (1 ).getReg ()) &&
457
+ R.match (MRI, TmpMI->getOperand (2 ).getReg ())) &&
458
+ // NOTE: When trying the alternative operand ordering
459
+ // with a commutative operation, it is imperative to always run
460
+ // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
461
+ // (i.e. `R`). Otherwsie, m_DeferredReg/Type will not work as
462
+ // expected.
463
+ !(Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
464
+ R.match (MRI, TmpMI->getOperand (1 ).getReg ()))))
465
+ return false ;
466
+ if (Flags == MachineInstr::NoFlags)
467
+ return true ;
468
+ return (TmpMI->getFlags () & Flags) == Flags;
441
469
}
442
470
}
443
471
return false ;
@@ -559,6 +587,19 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
559
587
return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true >(L, R);
560
588
}
561
589
590
+ template <typename LHS, typename RHS>
591
+ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
592
+ MachineInstr::Disjoint>
593
+ m_GDisjointOr (const LHS &L, const RHS &R) {
594
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
595
+ MachineInstr::Disjoint>(L, R);
596
+ }
597
+
598
+ template <typename LHS, typename RHS>
599
+ inline auto m_GAddLike (const LHS &L, const RHS &R) {
600
+ return m_any_of (m_GAdd (L, R), m_GDisjointOr (L, R));
601
+ }
602
+
562
603
template <typename LHS, typename RHS>
563
604
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false >
564
605
m_GShl (const LHS &L, const RHS &R) {
0 commit comments