LLVM: include/llvm/CodeGen/GlobalISel/MIPatternMatch.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_CODEGEN_GLOBALISEL_MIPATTERNMATCH_H
14#define LLVM_CODEGEN_GLOBALISEL_MIPATTERNMATCH_H
15
20
21namespace llvm {
22namespace MIPatternMatch {
23
24template <typename Reg, typename Pattern>
28}
29
30template
34}
35
36
40
43 }
44};
45
46template
48 return SP;
49}
50
54
57 }
58};
59
60template
62 return SP;
63}
64
65template
68
69template <>
73}
74
75template <>
79}
80
85 if (auto MaybeCst = matchConstant(Reg, MRI)) {
86 CR = *MaybeCst;
87 return true;
88 }
89 return false;
90 }
91};
92
95}
98}
99
100template
103
104template <>
108}
109
110template <>
111inline std::optional<int64_t>
114}
115
120 if (auto MaybeCst = matchConstant(Reg, MRI)) {
121 CR = *MaybeCst;
122 return true;
123 }
124
125 if (auto MaybeCstSplat = matchConstantSplat(Reg, MRI)) {
126 CR = *MaybeCstSplat;
127 return true;
128 }
129
130 return false;
131 };
132};
133
136}
137
140}
141
148 }
149};
150
153}
154
162 }
163};
164
167}
168
176 };
177};
178
179inline GFCstOrSplatGFCstMatch
182}
183
184
189 int64_t MatchedVal;
191 }
192};
193
194
197}
198
199
206 false);
207 }
208};
209
210
213}
214
215
221 int64_t MatchedVal;
223 return true;
225 false);
226 }
227};
228
229
230
231inline SpecificConstantOrSplatMatch
234}
235
236
237
241}
242
243
244
250 }
251};
252
253
256}
257
258
259
260
261
262
266 return MO->isReg();
267 }
268};
269
271
272
273template <typename... Preds> struct And {
274 template
276 return true;
277 }
278};
279
280template <typename Pred, typename... Preds>
281struct And<Pred, Preds...> : And<Preds...> {
283 And(Pred &&p, Preds &&... preds)
284 : And<Preds...>(std::forward(preds)...), P(std::forward(p)) {
285 }
286 template
289 }
290};
291
292template <typename... Preds> struct Or {
293 template
295 return false;
296 }
297};
298
299template <typename Pred, typename... Preds>
300struct Or<Pred, Preds...> : Or<Preds...> {
302 Or(Pred &&p, Preds &&... preds)
303 : Or<Preds...>(std::forward(preds)...), P(std::forward(p)) {}
304 template
307 }
308};
309
310template <typename... Preds> And<Preds...> m_all_of(Preds &&... preds) {
311 return And<Preds...>(std::forward(preds)...);
312}
313
314template <typename... Preds> Or<Preds...> m_any_of(Preds &&... preds) {
315 return Or<Preds...>(std::forward(preds)...);
316}
317
320 VR = V;
321 return true;
322 }
323};
324
329 if (MI)
330 return true;
331 return false;
332 }
335 MI = Inst;
336 return MI;
337 }
338};
339
344 return true;
345 return false;
346 }
347};
348
353 if (F)
354 return true;
355 return false;
356 }
357};
358
361
363
366 }
367};
368
374
377 return VR == V;
378 }
379};
380
383 return VT == MRI.getType(R);
384 }
385};
386
389
391
394 }
395};
396
397
398
399
400
401
404
409 return TmpMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
410 return false;
411 }
412};
413
415
416
418
419
420template <typename LHS_P, typename RHS_P, unsigned Opcode,
421 bool Commutable = false>
425
427 template
434
435
436
437
438
441 }
442 }
443 return false;
444 }
445};
446
447
448template <typename LHS_P, typename RHS_P, bool Commutable = false>
453
456 template
464
465
466
467
468
471 }
472 }
473 return false;
474 }
475};
476
477template <typename LHS, typename RHS>
479 const RHS &R) {
481}
482
483template <typename LHS, typename RHS>
484inline BinaryOpc_match<LHS, RHS, true>
487}
488
489template <typename LHS, typename RHS>
493}
494
495template <typename LHS, typename RHS>
499}
500
501template <typename LHS, typename RHS>
505 R);
506}
507
508template <typename LHS, typename RHS>
512}
513
514template <typename LHS, typename RHS>
516 const RHS &R) {
518}
519
520template <typename LHS, typename RHS>
524}
525
526template <typename LHS, typename RHS>
530}
531
532template <typename LHS, typename RHS>
536}
537
538template <typename LHS, typename RHS>
542}
543
544template <typename LHS, typename RHS>
548}
549
550template <typename LHS, typename RHS>
554}
555
556template <typename LHS, typename RHS>
558 const RHS &R) {
560}
561
562template <typename LHS, typename RHS>
566}
567
568template <typename LHS, typename RHS>
572}
573
574template <typename LHS, typename RHS>
578}
579
580template <typename LHS, typename RHS>
584}
585
586template <typename LHS, typename RHS>
590}
591
592template <typename LHS, typename RHS>
596}
597
598template <typename LHS, typename RHS>
602}
603
604
605template <typename SrcTy, unsigned Opcode> struct UnaryOp_match {
607
609 template
615 }
616 }
617 return false;
618 }
619};
620
621template
622inline UnaryOp_match<SrcTy, TargetOpcode::G_ANYEXT>
625}
626
627template
630}
631
632template
635}
636
637template
640}
641
642template
645}
646
647template
648inline UnaryOp_match<SrcTy, TargetOpcode::G_BITCAST>
651}
652
653template
654inline UnaryOp_match<SrcTy, TargetOpcode::G_PTRTOINT>
657}
658
659template
660inline UnaryOp_match<SrcTy, TargetOpcode::G_INTTOPTR>
663}
664
665template
666inline UnaryOp_match<SrcTy, TargetOpcode::G_FPTRUNC>
669}
670
671template
674}
675
676template
679}
680
681template
684}
685
686template
689}
690
691
692
693template <typename Pred_P, typename LHS_P, typename RHS_P, unsigned Opcode,
694 bool Commutable = false>
699
702
703 template
707 return false;
708
709 auto TmpPred =
711 if (.match(MRI, TmpPred))
712 return false;
716 return true;
717
718
719
720
721 if (Commutable && L.match(MRI, RHS) && R.match(MRI, LHS) &&
723 return true;
724 return false;
725 }
726};
727
728template <typename Pred, typename LHS, typename RHS>
729inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP>
732}
733
734template <typename Pred, typename LHS, typename RHS>
735inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP>
738}
739
740
741
742
743
744
745
746
747
748
749template <typename Pred, typename LHS, typename RHS>
750inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP, true>
753}
754
755
756
757
758
759
760
761
762
763
764template <typename Pred, typename LHS, typename RHS>
765inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP, true>
768}
769
770
774
776 return MRI.getType(Reg) == Ty;
777 }
778};
779
781
782template <typename Src0Ty, typename Src1Ty, typename Src2Ty, unsigned Opcode>
787
790 template
798 }
799 }
800 return false;
801 }
802};
803template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
804inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
805 TargetOpcode::G_INSERT_VECTOR_ELT>
806m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
808 TargetOpcode::G_INSERT_VECTOR_ELT>(Src0, Src1, Src2);
809}
810
811template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
812inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_SELECT>
813m_GISelect(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
815 Src0, Src1, Src2);
816}
817
818
819
820template
824}
825
826
827
828template
832}
833
834}
835}
836
837#endif
unsigned const MachineRegisterInfo * MRI
This file implements a class to represent arbitrary precision integral constant values and operations...
Class for arbitrary precision integers.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
ConstantFP - Floating Point Values [float, double].
This class represents an Operation in the Expression.
constexpr bool isValid() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumOperands() const
Retuns the total number of operands.
const MachineOperand & getOperand(unsigned i) const
unsigned getNumDefs() const
Returns the total number of definitions.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
unsigned getPredicate() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
@ C
The default llvm calling convention, compatible with C.
operand_type_match m_Reg()
SpecificConstantOrSplatMatch m_SpecificICstOrSplat(int64_t RequestedValue)
Matches a RequestedValue constant or a constant splat of RequestedValue.
std::optional< ConstT > matchConstantSplat(Register, const MachineRegisterInfo &)
BinaryOp_match< LHS, RHS, TargetOpcode::G_BUILD_VECTOR, false > m_GBuildVector(const LHS &L, const RHS &R)
GCstAndRegMatch m_GCst(std::optional< ValueAndVReg > &ValReg)
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
SpecificConstantMatch m_SpecificICst(int64_t RequestedValue)
Matches a constant equal to RequestedValue.
operand_type_match m_Pred()
BinaryOp_match< LHS, RHS, TargetOpcode::G_UMIN, true > m_GUMin(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_XOR, true > m_GXor(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
deferred_ty< LLT > m_DeferredType(LLT &Ty)
UnaryOp_match< SrcTy, TargetOpcode::G_FPEXT > m_GFPExt(const SrcTy &Src)
SpecificConstantMatch m_ZeroInt()
{ Convenience matchers for specific integer values.
ConstantMatch< APInt > m_ICst(APInt &Cst)
UnaryOp_match< SrcTy, TargetOpcode::G_FSQRT > m_GFSqrt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_INTTOPTR > m_GIntToPtr(const SrcTy &Src)
SpecificConstantMatch m_AllOnesInt()
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
ICstOrSplatMatch< APInt > m_ICstOrSplat(APInt &Cst)
SpecificConstantSplatMatch m_SpecificICstSplat(int64_t RequestedValue)
Matches a constant splat of RequestedValue.
ImplicitDefMatch m_GImplicitDef()
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CheckType m_SpecificType(LLT Ty)
deferred_ty< Register > m_DeferredReg(Register &R)
Similar to m_SpecificReg/Type, but the specific value to match originated from an earlier sub-pattern...
BinaryOp_match< LHS, RHS, TargetOpcode::G_UMAX, true > m_GUMax(const LHS &L, const RHS &R)
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
BinaryOpc_match< LHS, RHS, true > m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FADD, true > m_GFAdd(const LHS &L, const RHS &R)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP, true > m_c_GFCmp(const Pred &P, const LHS &L, const RHS &R)
G_FCMP matcher that also matches commuted compares.
UnaryOp_match< SrcTy, TargetOpcode::G_PTRTOINT > m_GPtrToInt(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FSUB, false > m_GFSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ASHR, false > m_GAShr(const LHS &L, const RHS &R)
TernaryOp_match< Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_SELECT > m_GISelect(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
SpecificRegisterMatch m_SpecificReg(Register RequestedReg)
Matches a register only if it is equal to RequestedReg.
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_BUILD_VECTOR_TRUNC, false > m_GBuildVectorTrunc(const LHS &L, const RHS &R)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
UnaryOp_match< SrcTy, TargetOpcode::G_FNEG > m_GFNeg(const SrcTy &Src)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP, true > m_c_GICmp(const Pred &P, const LHS &L, const RHS &R)
G_ICMP matcher that also matches commuted compares.
GFCstAndRegMatch m_GFCst(std::optional< FPValueAndVReg > &FPValReg)
TernaryOp_match< Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_INSERT_VECTOR_ELT > m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
GFCstOrSplatGFCstMatch m_GFCstOrSplat(std::optional< FPValueAndVReg > &FPValReg)
And< Preds... > m_all_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SMIN, true > m_GSMin(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_FABS > m_GFabs(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_FPTRUNC > m_GFPTrunc(const SrcTy &Src)
std::optional< ConstT > matchConstant(Register, const MachineRegisterInfo &)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FMUL, true > m_GFMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_MUL, true > m_GMul(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
bind_ty< LLT > m_Type(LLT &Ty)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SMAX, true > m_GSMax(const LHS &L, const RHS &R)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP > m_GFCmp(const Pred &P, const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
This is an optimization pass for GlobalISel generic memory operations.
const ConstantFP * getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI)
std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
std::optional< APInt > getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI)
std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
std::optional< FPValueAndVReg > getFConstantSplat(Register VReg, const MachineRegisterInfo &MRI, bool AllowUndef=true)
Returns a floating point scalar constant of a build vector splat if it exists.
std::optional< FPValueAndVReg > getFConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_FCONSTANT returns it...
bool isBuildVectorConstantSplat(const Register Reg, const MachineRegisterInfo &MRI, int64_t SplatValue, bool AllowUndef)
Return true if the specified register is defined by G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all ...
std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
std::optional< int64_t > getIConstantSplatSExtVal(const Register Reg, const MachineRegisterInfo &MRI)
Implement std::hash so that hash_code can be used in STL containers.
And(Pred &&p, Preds &&... preds)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
BinaryOp_match(const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
BinaryOpc_match(unsigned Opcode, const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, Register Reg)
CompareOp_match(const Pred_P &Pred, const LHS_P &LHS, const RHS_P &RHS)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
GCstAndRegMatch(std::optional< ValueAndVReg > &ValReg)
std::optional< ValueAndVReg > & ValReg
GFCstAndRegMatch(std::optional< FPValueAndVReg > &FPValReg)
std::optional< FPValueAndVReg > & FPValReg
bool match(const MachineRegisterInfo &MRI, Register Reg)
GFCstOrSplatGFCstMatch(std::optional< FPValueAndVReg > &FPValReg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
std::optional< FPValueAndVReg > & FPValReg
ICstOrSplatMatch(ConstT &C)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
OneNonDBGUse_match(const SubPatternT &SP)
bool match(const MachineRegisterInfo &MRI, Register Reg)
OneUse_match(const SubPatternT &SP)
bool match(const MachineRegisterInfo &MRI, Register Reg)
Or(Pred &&p, Preds &&... preds)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(const MachineRegisterInfo &MRI, MatchSrc &&src)
Matcher for a specific constant value.
SpecificConstantMatch(int64_t RequestedVal)
bool match(const MachineRegisterInfo &MRI, Register Reg)
Matcher for a specific constant or constant splat.
bool match(const MachineRegisterInfo &MRI, Register Reg)
SpecificConstantOrSplatMatch(int64_t RequestedVal)
Matcher for a specific constant splat.
SpecificConstantSplatMatch(int64_t RequestedVal)
bool match(const MachineRegisterInfo &MRI, Register Reg)
bool match(const MachineRegisterInfo &MRI, Register Reg)
SpecificRegisterMatch(Register RequestedReg)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
TernaryOp_match(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
bool match(const MachineRegisterInfo &MRI, OpTy &&Op)
UnaryOp_match(const SrcTy &LHS)
static bool bind(const MachineRegisterInfo &MRI, LLT &Ty, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI, MachineInstr *Inst)
static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F, Register Reg)
static bool bind(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V)
bool match(const MachineRegisterInfo &MRI, ITy &&V)
static bool match(const MachineRegisterInfo &MRI, LLT VT, Register R)
static bool match(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V)
bool match(const MachineRegisterInfo &MRI, ITy &&V)
bool match(const MachineRegisterInfo &MRI, MachineOperand *MO)
bool match(const MachineRegisterInfo &MRI, Register Reg)