1 //===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides a simple and efficient mechanism for performing general
11 // tree-based pattern matches on the LLVM IR. The power of these routines is
12 // that it allows you to write concise patterns that are expressive and easy to
13 // understand. The other major advantage of this is that it allows you to
14 // trivially capture/bind elements in the pattern to variables. For example,
15 // you can do something like this:
18 // Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
19 // if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
20 // m_And(m_Value(Y), m_ConstantInt(C2))))) {
21 // ... Pattern is matched and variables are bound ...
24 // This is primarily useful to things like the instruction combiner, but can
25 // also be useful for static analysis tools or code generators.
27 //===----------------------------------------------------------------------===//
29 #ifndef LLVM_SUPPORT_PATTERNMATCH_H
30 #define LLVM_SUPPORT_PATTERNMATCH_H
32 #include "llvm/Constants.h"
33 #include "llvm/Instructions.h"
36 namespace PatternMatch {
38 template<typename Val, typename Pattern>
39 bool match(Val *V, const Pattern &P) {
40 return const_cast<Pattern&>(P).match(V);
43 template<typename Class>
45 template<typename ITy>
46 bool match(ITy *V) { return isa<Class>(V); }
49 /// m_Value() - Match an arbitrary value and ignore it.
50 inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
51 /// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
52 inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
55 struct constantint_ty {
56 template<typename ITy>
58 if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
59 const APInt &CIV = CI->getValue();
61 return CIV == static_cast<uint64_t>(Val);
62 // If Val is negative, and CI is shorter than it, truncate to the right
63 // number of bits. If it is larger, then we have to sign extend. Just
64 // compare their negated values.
71 /// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value
74 inline constantint_ty<Val> m_ConstantInt() {
75 return constantint_ty<Val>();
79 template<typename ITy>
81 if (const Constant *C = dyn_cast<Constant>(V))
82 return C->isNullValue();
87 /// m_Zero() - Match an arbitrary zero/null constant.
88 inline zero_ty m_Zero() { return zero_ty(); }
91 template<typename ITy>
93 if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
95 if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
96 if (ConstantInt *CI = cast_or_null<ConstantInt>(CV->getSplatValue()))
102 /// m_One() - Match an integer 1 or a vector with all elements equal to 1.
103 inline one_ty m_One() { return one_ty(); }
106 template<typename ITy>
108 if (const ConstantInt *C = dyn_cast<ConstantInt>(V))
109 return C->isAllOnesValue();
110 if (const ConstantVector *C = dyn_cast<ConstantVector>(V))
111 return C->isAllOnesValue();
116 /// m_AllOnes() - Match an integer or vector with all bits set to true.
117 inline all_ones_ty m_AllOnes() { return all_ones_ty(); }
120 template<typename Class>
123 bind_ty(Class *&V) : VR(V) {}
125 template<typename ITy>
127 if (Class *CV = dyn_cast<Class>(V)) {
135 /// m_Value - Match a value, capturing it if we match.
136 inline bind_ty<Value> m_Value(Value *&V) { return V; }
138 /// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
139 inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
141 /// specificval_ty - Match a specified Value*.
142 struct specificval_ty {
144 specificval_ty(const Value *V) : Val(V) {}
146 template<typename ITy>
152 /// m_Specific - Match if we have a specific specified value.
153 inline specificval_ty m_Specific(const Value *V) { return V; }
156 //===----------------------------------------------------------------------===//
157 // Matchers for specific binary operators.
160 template<typename LHS_t, typename RHS_t,
161 unsigned Opcode, typename ConcreteTy = BinaryOperator>
162 struct BinaryOp_match {
166 BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
168 template<typename OpTy>
169 bool match(OpTy *V) {
170 if (V->getValueID() == Value::InstructionVal + Opcode) {
171 ConcreteTy *I = cast<ConcreteTy>(V);
172 return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
173 R.match(I->getOperand(1));
175 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
176 return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
177 R.match(CE->getOperand(1));
182 template<typename LHS, typename RHS>
183 inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
185 return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
188 template<typename LHS, typename RHS>
189 inline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L,
191 return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
194 template<typename LHS, typename RHS>
195 inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
197 return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
200 template<typename LHS, typename RHS>
201 inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
203 return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
206 template<typename LHS, typename RHS>
207 inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
209 return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
212 template<typename LHS, typename RHS>
213 inline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L,
215 return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
218 template<typename LHS, typename RHS>
219 inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
221 return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
224 template<typename LHS, typename RHS>
225 inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
227 return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
230 template<typename LHS, typename RHS>
231 inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
233 return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
236 template<typename LHS, typename RHS>
237 inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
239 return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
242 template<typename LHS, typename RHS>
243 inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
245 return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
248 template<typename LHS, typename RHS>
249 inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
251 return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
254 template<typename LHS, typename RHS>
255 inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
257 return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
260 template<typename LHS, typename RHS>
261 inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
263 return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
266 template<typename LHS, typename RHS>
267 inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
269 return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
272 template<typename LHS, typename RHS>
273 inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
275 return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
278 template<typename LHS, typename RHS>
279 inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
281 return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
284 template<typename LHS, typename RHS>
285 inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
287 return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
290 //===----------------------------------------------------------------------===//
291 // Matchers for either AShr or LShr .. for convenience
293 template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
298 Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
300 template<typename OpTy>
301 bool match(OpTy *V) {
302 if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
303 V->getValueID() == Value::InstructionVal + Instruction::AShr) {
304 ConcreteTy *I = cast<ConcreteTy>(V);
305 return (I->getOpcode() == Instruction::AShr ||
306 I->getOpcode() == Instruction::LShr) &&
307 L.match(I->getOperand(0)) &&
308 R.match(I->getOperand(1));
310 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
311 return (CE->getOpcode() == Instruction::LShr ||
312 CE->getOpcode() == Instruction::AShr) &&
313 L.match(CE->getOperand(0)) &&
314 R.match(CE->getOperand(1));
319 template<typename LHS, typename RHS>
320 inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
321 return Shr_match<LHS, RHS>(L, R);
324 //===----------------------------------------------------------------------===//
325 // Matchers for binary classes
328 template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
329 struct BinaryOpClass_match {
334 BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
336 : Opcode(&Op), L(LHS), R(RHS) {}
337 BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
338 : Opcode(0), L(LHS), R(RHS) {}
340 template<typename OpTy>
341 bool match(OpTy *V) {
342 if (Class *I = dyn_cast<Class>(V))
343 if (L.match(I->getOperand(0)) &&
344 R.match(I->getOperand(1))) {
346 *Opcode = I->getOpcode();
349 #if 0 // Doesn't handle constantexprs yet!
350 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
351 return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
352 R.match(CE->getOperand(1));
358 template<typename LHS, typename RHS>
359 inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
360 m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
361 return BinaryOpClass_match<LHS, RHS,
362 BinaryOperator, Instruction::BinaryOps>(Op, L, R);
365 template<typename LHS, typename RHS>
366 inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
367 m_Shift(const LHS &L, const RHS &R) {
368 return BinaryOpClass_match<LHS, RHS,
369 BinaryOperator, Instruction::BinaryOps>(L, R);
372 //===----------------------------------------------------------------------===//
373 // Matchers for CmpInst classes
376 template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
377 struct CmpClass_match {
378 PredicateTy &Predicate;
382 CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
384 : Predicate(Pred), L(LHS), R(RHS) {}
386 template<typename OpTy>
387 bool match(OpTy *V) {
388 if (Class *I = dyn_cast<Class>(V))
389 if (L.match(I->getOperand(0)) &&
390 R.match(I->getOperand(1))) {
391 Predicate = I->getPredicate();
398 template<typename LHS, typename RHS>
399 inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
400 m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
401 return CmpClass_match<LHS, RHS,
402 ICmpInst, ICmpInst::Predicate>(Pred, L, R);
405 template<typename LHS, typename RHS>
406 inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
407 m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
408 return CmpClass_match<LHS, RHS,
409 FCmpInst, FCmpInst::Predicate>(Pred, L, R);
412 //===----------------------------------------------------------------------===//
413 // Matchers for SelectInst classes
416 template<typename Cond_t, typename LHS_t, typename RHS_t>
417 struct SelectClass_match {
422 SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
424 : C(Cond), L(LHS), R(RHS) {}
426 template<typename OpTy>
427 bool match(OpTy *V) {
428 if (SelectInst *I = dyn_cast<SelectInst>(V))
429 return C.match(I->getOperand(0)) &&
430 L.match(I->getOperand(1)) &&
431 R.match(I->getOperand(2));
436 template<typename Cond, typename LHS, typename RHS>
437 inline SelectClass_match<Cond, LHS, RHS>
438 m_Select(const Cond &C, const LHS &L, const RHS &R) {
439 return SelectClass_match<Cond, LHS, RHS>(C, L, R);
442 /// m_SelectCst - This matches a select of two constants, e.g.:
443 /// m_SelectCst<-1, 0>(m_Value(V))
444 template<int64_t L, int64_t R, typename Cond>
445 inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
446 m_SelectCst(const Cond &C) {
447 return SelectClass_match<Cond, constantint_ty<L>,
448 constantint_ty<R> >(C, m_ConstantInt<L>(),
453 //===----------------------------------------------------------------------===//
454 // Matchers for CastInst classes
457 template<typename Op_t, unsigned Opcode>
458 struct CastClass_match {
461 CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
463 template<typename OpTy>
464 bool match(OpTy *V) {
465 if (CastInst *I = dyn_cast<CastInst>(V))
466 return I->getOpcode() == Opcode && Op.match(I->getOperand(0));
467 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
468 return CE->getOpcode() == Opcode && Op.match(CE->getOperand(0));
474 template<typename OpTy>
475 inline CastClass_match<OpTy, Instruction::BitCast>
476 m_BitCast(const OpTy &Op) {
477 return CastClass_match<OpTy, Instruction::BitCast>(Op);
481 template<typename OpTy>
482 inline CastClass_match<OpTy, Instruction::PtrToInt>
483 m_PtrToInt(const OpTy &Op) {
484 return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
488 template<typename OpTy>
489 inline CastClass_match<OpTy, Instruction::Trunc>
490 m_Trunc(const OpTy &Op) {
491 return CastClass_match<OpTy, Instruction::Trunc>(Op);
495 template<typename OpTy>
496 inline CastClass_match<OpTy, Instruction::SExt>
497 m_SExt(const OpTy &Op) {
498 return CastClass_match<OpTy, Instruction::SExt>(Op);
502 template<typename OpTy>
503 inline CastClass_match<OpTy, Instruction::ZExt>
504 m_ZExt(const OpTy &Op) {
505 return CastClass_match<OpTy, Instruction::ZExt>(Op);
509 //===----------------------------------------------------------------------===//
510 // Matchers for unary operators
513 template<typename LHS_t>
517 not_match(const LHS_t &LHS) : L(LHS) {}
519 template<typename OpTy>
520 bool match(OpTy *V) {
521 if (Instruction *I = dyn_cast<Instruction>(V))
522 if (I->getOpcode() == Instruction::Xor)
523 return matchIfNot(I->getOperand(0), I->getOperand(1));
524 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
525 if (CE->getOpcode() == Instruction::Xor)
526 return matchIfNot(CE->getOperand(0), CE->getOperand(1));
530 bool matchIfNot(Value *LHS, Value *RHS) {
531 if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
532 return CI->isAllOnesValue() && L.match(LHS);
533 if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
534 return CI->isAllOnesValue() && L.match(RHS);
535 if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
536 return CV->isAllOnesValue() && L.match(LHS);
537 if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
538 return CV->isAllOnesValue() && L.match(RHS);
543 template<typename LHS>
544 inline not_match<LHS> m_Not(const LHS &L) { return L; }
547 template<typename LHS_t>
551 neg_match(const LHS_t &LHS) : L(LHS) {}
553 template<typename OpTy>
554 bool match(OpTy *V) {
555 if (Instruction *I = dyn_cast<Instruction>(V))
556 if (I->getOpcode() == Instruction::Sub)
557 return matchIfNeg(I->getOperand(0), I->getOperand(1));
558 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
559 if (CE->getOpcode() == Instruction::Sub)
560 return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
564 bool matchIfNeg(Value *LHS, Value *RHS) {
565 return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
570 template<typename LHS>
571 inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
574 template<typename LHS_t>
578 fneg_match(const LHS_t &LHS) : L(LHS) {}
580 template<typename OpTy>
581 bool match(OpTy *V) {
582 if (Instruction *I = dyn_cast<Instruction>(V))
583 if (I->getOpcode() == Instruction::FSub)
584 return matchIfFNeg(I->getOperand(0), I->getOperand(1));
585 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
586 if (CE->getOpcode() == Instruction::FSub)
587 return matchIfFNeg(CE->getOperand(0), CE->getOperand(1));
588 if (ConstantFP *CF = dyn_cast<ConstantFP>(V))
589 return L.match(ConstantExpr::getFNeg(CF));
593 bool matchIfFNeg(Value *LHS, Value *RHS) {
594 return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
599 template<typename LHS>
600 inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
603 //===----------------------------------------------------------------------===//
604 // Matchers for control flow
607 template<typename Cond_t>
611 brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
612 : Cond(C), T(t), F(f) {
615 template<typename OpTy>
616 bool match(OpTy *V) {
617 if (BranchInst *BI = dyn_cast<BranchInst>(V))
618 if (BI->isConditional()) {
619 if (Cond.match(BI->getCondition())) {
620 T = BI->getSuccessor(0);
621 F = BI->getSuccessor(1);
629 template<typename Cond_t>
630 inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
631 return brc_match<Cond_t>(C, T, F);
634 } // end namespace PatternMatch
635 } // end namespace llvm