LLVM  8.0.1
MIPatternMatch.h
Go to the documentation of this file.
1 //== ----- llvm/CodeGen/GlobalISel/MIPatternMatch.h --------------------- == //
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// Contains matchers for matching SSA Machine Instructions.
11 //
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_GMIR_PATTERNMATCH_H
14 #define LLVM_GMIR_PATTERNMATCH_H
15 
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/APInt.h"
20 
21 namespace llvm {
22 namespace MIPatternMatch {
23 
24 template <typename Reg, typename Pattern>
25 bool mi_match(Reg R, MachineRegisterInfo &MRI, Pattern &&P) {
26  return P.match(MRI, R);
27 }
28 
29 // TODO: Extend for N use.
30 template <typename SubPatternT> struct OneUse_match {
31  SubPatternT SubPat;
32  OneUse_match(const SubPatternT &SP) : SubPat(SP) {}
33 
34  template <typename OpTy>
35  bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
36  return MRI.hasOneUse(Reg) && SubPat.match(MRI, Reg);
37  }
38 };
39 
40 template <typename SubPat>
42  return SP;
43 }
44 
45 struct ConstantMatch {
46  int64_t &CR;
47  ConstantMatch(int64_t &C) : CR(C) {}
48  bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
49  if (auto MaybeCst = getConstantVRegVal(Reg, MRI)) {
50  CR = *MaybeCst;
51  return true;
52  }
53  return false;
54  }
55 };
56 
57 inline ConstantMatch m_ICst(int64_t &Cst) { return ConstantMatch(Cst); }
58 
59 // TODO: Rework this for different kinds of MachineOperand.
60 // Currently assumes the Src for a match is a register.
61 // We might want to support taking in some MachineOperands and call getReg on
62 // that.
63 
65  bool match(const MachineRegisterInfo &MRI, unsigned Reg) { return true; }
67  return MO->isReg();
68  }
69 };
70 
72 
73 /// Matching combinators.
74 template <typename... Preds> struct And {
75  template <typename MatchSrc>
76  bool match(MachineRegisterInfo &MRI, MatchSrc &&src) {
77  return true;
78  }
79 };
80 
81 template <typename Pred, typename... Preds>
82 struct And<Pred, Preds...> : And<Preds...> {
83  Pred P;
84  And(Pred &&p, Preds &&... preds)
85  : And<Preds...>(std::forward<Preds>(preds)...), P(std::forward<Pred>(p)) {
86  }
87  template <typename MatchSrc>
88  bool match(MachineRegisterInfo &MRI, MatchSrc &&src) {
89  return P.match(MRI, src) && And<Preds...>::match(MRI, src);
90  }
91 };
92 
93 template <typename... Preds> struct Or {
94  template <typename MatchSrc>
95  bool match(MachineRegisterInfo &MRI, MatchSrc &&src) {
96  return false;
97  }
98 };
99 
100 template <typename Pred, typename... Preds>
101 struct Or<Pred, Preds...> : Or<Preds...> {
102  Pred P;
103  Or(Pred &&p, Preds &&... preds)
104  : Or<Preds...>(std::forward<Preds>(preds)...), P(std::forward<Pred>(p)) {}
105  template <typename MatchSrc>
106  bool match(MachineRegisterInfo &MRI, MatchSrc &&src) {
107  return P.match(MRI, src) || Or<Preds...>::match(MRI, src);
108  }
109 };
110 
111 template <typename... Preds> And<Preds...> m_all_of(Preds &&... preds) {
112  return And<Preds...>(std::forward<Preds>(preds)...);
113 }
114 
115 template <typename... Preds> Or<Preds...> m_any_of(Preds &&... preds) {
116  return Or<Preds...>(std::forward<Preds>(preds)...);
117 }
118 
119 template <typename BindTy> struct bind_helper {
120  static bool bind(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V) {
121  VR = V;
122  return true;
123  }
124 };
125 
126 template <> struct bind_helper<MachineInstr *> {
127  static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI,
128  unsigned Reg) {
129  MI = MRI.getVRegDef(Reg);
130  if (MI)
131  return true;
132  return false;
133  }
134 };
135 
136 template <> struct bind_helper<LLT> {
137  static bool bind(const MachineRegisterInfo &MRI, LLT &Ty, unsigned Reg) {
138  Ty = MRI.getType(Reg);
139  if (Ty.isValid())
140  return true;
141  return false;
142  }
143 };
144 
145 template <> struct bind_helper<const ConstantFP *> {
146  static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F,
147  unsigned Reg) {
148  F = getConstantFPVRegVal(Reg, MRI);
149  if (F)
150  return true;
151  return false;
152  }
153 };
154 
155 template <typename Class> struct bind_ty {
156  Class &VR;
157 
158  bind_ty(Class &V) : VR(V) {}
159 
160  template <typename ITy> bool match(const MachineRegisterInfo &MRI, ITy &&V) {
161  return bind_helper<Class>::bind(MRI, VR, V);
162  }
163 };
164 
165 inline bind_ty<unsigned> m_Reg(unsigned &R) { return R; }
167 inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
168 
169 // Helper for matching G_FCONSTANT
170 inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
171 
172 // General helper for all the binary generic MI such as G_ADD/G_SUB etc
173 template <typename LHS_P, typename RHS_P, unsigned Opcode,
174  bool Commutable = false>
176  LHS_P L;
177  RHS_P R;
178 
179  BinaryOp_match(const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
180  template <typename OpTy> bool match(MachineRegisterInfo &MRI, OpTy &&Op) {
181  MachineInstr *TmpMI;
182  if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
183  if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 3) {
184  return (L.match(MRI, TmpMI->getOperand(1).getReg()) &&
185  R.match(MRI, TmpMI->getOperand(2).getReg())) ||
186  (Commutable && (R.match(MRI, TmpMI->getOperand(1).getReg()) &&
187  L.match(MRI, TmpMI->getOperand(2).getReg())));
188  }
189  }
190  return false;
191  }
192 };
193 
194 template <typename LHS, typename RHS>
196 m_GAdd(const LHS &L, const RHS &R) {
198 }
199 
200 template <typename LHS, typename RHS>
202  const RHS &R) {
204 }
205 
206 template <typename LHS, typename RHS>
208 m_GMul(const LHS &L, const RHS &R) {
210 }
211 
212 template <typename LHS, typename RHS>
214 m_GFAdd(const LHS &L, const RHS &R) {
216 }
217 
218 template <typename LHS, typename RHS>
220 m_GFMul(const LHS &L, const RHS &R) {
222 }
223 
224 template <typename LHS, typename RHS>
226 m_GFSub(const LHS &L, const RHS &R) {
228 }
229 
230 template <typename LHS, typename RHS>
232 m_GAnd(const LHS &L, const RHS &R) {
234 }
235 
236 template <typename LHS, typename RHS>
238  const RHS &R) {
240 }
241 
242 // Helper for unary instructions (G_[ZSA]EXT/G_TRUNC) etc
243 template <typename SrcTy, unsigned Opcode> struct UnaryOp_match {
244  SrcTy L;
245 
246  UnaryOp_match(const SrcTy &LHS) : L(LHS) {}
247  template <typename OpTy> bool match(MachineRegisterInfo &MRI, OpTy &&Op) {
248  MachineInstr *TmpMI;
249  if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
250  if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 2) {
251  return L.match(MRI, TmpMI->getOperand(1).getReg());
252  }
253  }
254  return false;
255  }
256 };
257 
258 template <typename SrcTy>
260 m_GAnyExt(const SrcTy &Src) {
262 }
263 
264 template <typename SrcTy>
267 }
268 
269 template <typename SrcTy>
272 }
273 
274 template <typename SrcTy>
277 }
278 
279 template <typename SrcTy>
282 }
283 
284 template <typename SrcTy>
286 m_GBitcast(const SrcTy &Src) {
288 }
289 
290 template <typename SrcTy>
292 m_GPtrToInt(const SrcTy &Src) {
294 }
295 
296 template <typename SrcTy>
298 m_GIntToPtr(const SrcTy &Src) {
300 }
301 
302 template <typename SrcTy>
304 m_GFPTrunc(const SrcTy &Src) {
306 }
307 
308 template <typename SrcTy>
311 }
312 
313 template <typename SrcTy>
316 }
317 
318 template <typename SrcTy>
320  return UnaryOp_match<SrcTy, TargetOpcode::COPY>(std::forward<SrcTy>(Src));
321 }
322 
323 // Helper for checking if a Reg is of specific type.
324 struct CheckType {
326  CheckType(const LLT &Ty) : Ty(Ty) {}
327 
328  bool match(MachineRegisterInfo &MRI, unsigned Reg) {
329  return MRI.getType(Reg) == Ty;
330  }
331 };
332 
333 inline CheckType m_SpecificType(LLT Ty) { return Ty; }
334 
335 } // namespace GMIPatternMatch
336 } // namespace llvm
337 
338 #endif
uint64_t CallInst * C
BinaryOp_match< LHS, RHS, TargetOpcode::G_FMUL, true > m_GFMul(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_INTTOPTR > m_GIntToPtr(const SrcTy &Src)
BinaryOp_match(const LHS_P &LHS, const RHS_P &RHS)
bool match(MachineRegisterInfo &MRI, MatchSrc &&src)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
static bool bind(const MachineRegisterInfo &MRI, BindTy &VR, BindTy &V)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static bool bind(const MachineRegisterInfo &MRI, LLT &Ty, unsigned Reg)
const ConstantFP * getConstantFPVRegVal(unsigned VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:201
bool match(const MachineRegisterInfo &MRI, MachineOperand *MO)
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
bool match(const MachineRegisterInfo &MRI, ITy &&V)
F(f)
static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F, unsigned Reg)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
Definition: BitVector.h:938
UnaryOp_match< SrcTy, TargetOpcode::G_FPTRUNC > m_GFPTrunc(const SrcTy &Src)
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:412
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
This file implements a class to represent arbitrary precision integral constant values and operations...
bool mi_match(Reg R, MachineRegisterInfo &MRI, Pattern &&P)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Matching combinators.
BinaryOp_match< LHS, RHS, TargetOpcode::G_FSUB, false > m_GFSub(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
And< Preds... > m_all_of(Preds &&... preds)
bool match(MachineRegisterInfo &MRI, unsigned Reg)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
bind_ty< LLT > m_Type(LLT &Ty)
bool match(MachineRegisterInfo &MRI, MatchSrc &&src)
UnaryOp_match< SrcTy, TargetOpcode::G_FPEXT > m_GFPExt(const SrcTy &Src)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(MachineRegisterInfo &MRI, MatchSrc &&src)
#define P(N)
OneUse_match(const SubPatternT &SP)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
unsigned const MachineRegisterInfo * MRI
bool match(const MachineRegisterInfo &MRI, unsigned Reg)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
This file declares a class to represent arbitrary precision floating point values and provide a varie...
bool isValid() const
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI, unsigned Reg)
UnaryOp_match< SrcTy, TargetOpcode::G_FNEG > m_GFNeg(const SrcTy &Src)
bool match(const MachineRegisterInfo &MRI, unsigned Reg)
MachineOperand class - Representation of each machine instruction operand.
CheckType m_SpecificType(LLT Ty)
Optional< int64_t > getConstantVRegVal(unsigned VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:185
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_FABS > m_GFabs(const SrcTy &Src)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
BinaryOp_match< LHS, RHS, TargetOpcode::G_MUL, true > m_GMul(const LHS &L, const RHS &R)
Representation of each machine instruction.
Definition: MachineInstr.h:64
bool match(MachineRegisterInfo &MRI, OpTy &&Op)
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
ConstantMatch m_ICst(int64_t &Cst)
bool match(const MachineRegisterInfo &MRI, unsigned Reg)
UnaryOp_match< SrcTy, TargetOpcode::G_PTRTOINT > m_GPtrToInt(const SrcTy &Src)
bind_ty< const ConstantFP * > m_GFCst(const ConstantFP *&C)
BinaryOp_match< LHS, RHS, TargetOpcode::G_FADD, true > m_GFAdd(const LHS &L, const RHS &R)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
aarch64 promote const
operand_type_match m_Reg()
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
bool match(MachineRegisterInfo &MRI, MatchSrc &&src)
bool match(MachineRegisterInfo &MRI, OpTy &&Op)