LLVM API Documentation

PatternMatch.h

Go to the documentation of this file.
00001 //===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file provides a simple and efficient mechanism for performing general
00011 // tree-based pattern matches on the LLVM IR.  The power of these routines is
00012 // that it allows you to write concise patterns that are expressive and easy to
00013 // understand.  The other major advantage of this is that it allows you to
00014 // trivially capture/bind elements in the pattern to variables.  For example,
00015 // you can do something like this:
00016 //
00017 //  Value *Exp = ...
00018 //  Value *X, *Y;  ConstantInt *C1, *C2;      // (X & C1) | (Y & C2)
00019 //  if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
00020 //                      m_And(m_Value(Y), m_ConstantInt(C2))))) {
00021 //    ... Pattern is matched and variables are bound ...
00022 //  }
00023 //
00024 // This is primarily useful to things like the instruction combiner, but can
00025 // also be useful for static analysis tools or code generators.
00026 //
00027 //===----------------------------------------------------------------------===//
00028 
00029 #ifndef LLVM_SUPPORT_PATTERNMATCH_H
00030 #define LLVM_SUPPORT_PATTERNMATCH_H
00031 
00032 #include "llvm/Constants.h"
00033 #include "llvm/Instructions.h"
00034 
00035 namespace llvm {
00036 namespace PatternMatch {
00037 
00038 template<typename Val, typename Pattern>
00039 bool match(Val *V, const Pattern &P) {
00040   return const_cast<Pattern&>(P).match(V);
00041 }
00042 
00043 template<typename Class>
00044 struct leaf_ty {
00045   template<typename ITy>
00046   bool match(ITy *V) { return isa<Class>(V); }
00047 };
00048 
00049 /// m_Value() - Match an arbitrary value and ignore it.
00050 inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
00051 /// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
00052 inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
00053 
00054 template<int64_t Val>
00055 struct constantint_ty {
00056   template<typename ITy>
00057   bool match(ITy *V) {
00058     if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
00059       const APInt &CIV = CI->getValue();
00060       if (Val >= 0)
00061         return CIV == Val;
00062       // If Val is negative, and CI is shorter than it, truncate to the right
00063       // number of bits.  If it is larger, then we have to sign extend.  Just
00064       // compare their negated values.
00065       return -CIV == -Val;
00066     }
00067     return false;
00068   }
00069 };
00070 
00071 /// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value
00072 /// and ignore it.
00073 template<int64_t Val>
00074 inline constantint_ty<Val> m_ConstantInt() {
00075   return constantint_ty<Val>();
00076 }
00077 
00078 struct zero_ty {
00079   template<typename ITy>
00080   bool match(ITy *V) {
00081     if (const Constant *C = dyn_cast<Constant>(V))
00082       return C->isNullValue();
00083     return false;
00084   }
00085 };
00086 
00087 /// m_Zero() - Match an arbitrary zero/null constant.
00088 inline zero_ty m_Zero() { return zero_ty(); }
00089 
00090 
00091 template<typename Class>
00092 struct bind_ty {
00093   Class *&VR;
00094   bind_ty(Class *&V) : VR(V) {}
00095 
00096   template<typename ITy>
00097   bool match(ITy *V) {
00098     if (Class *CV = dyn_cast<Class>(V)) {
00099       VR = CV;
00100       return true;
00101     }
00102     return false;
00103   }
00104 };
00105 
00106 /// m_Value - Match a value, capturing it if we match.
00107 inline bind_ty<Value> m_Value(Value *&V) { return V; }
00108 
00109 /// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
00110 inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
00111   
00112 /// specificval_ty - Match a specified Value*.
00113 struct specificval_ty {
00114   const Value *Val;
00115   specificval_ty(const Value *V) : Val(V) {}
00116   
00117   template<typename ITy>
00118   bool match(ITy *V) {
00119     return V == Val;
00120   }
00121 };
00122   
00123 /// m_Specific - Match if we have a specific specified value.
00124 inline specificval_ty m_Specific(const Value *V) { return V; }
00125   
00126 
00127 //===----------------------------------------------------------------------===//
00128 // Matchers for specific binary operators.
00129 //
00130 
00131 template<typename LHS_t, typename RHS_t, 
00132          unsigned Opcode, typename ConcreteTy = BinaryOperator>
00133 struct BinaryOp_match {
00134   LHS_t L;
00135   RHS_t R;
00136 
00137   BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
00138 
00139   template<typename OpTy>
00140   bool match(OpTy *V) {
00141     if (V->getValueID() == Value::InstructionVal + Opcode) {
00142       ConcreteTy *I = cast<ConcreteTy>(V);
00143       return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
00144              R.match(I->getOperand(1));
00145     }
00146     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
00147       return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
00148              R.match(CE->getOperand(1));
00149     return false;
00150   }
00151 };
00152 
00153 template<typename LHS, typename RHS>
00154 inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
00155                                                         const RHS &R) {
00156   return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
00157 }
00158 
00159 template<typename LHS, typename RHS>
00160 inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
00161                                                         const RHS &R) {
00162   return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
00163 }
00164 
00165 template<typename LHS, typename RHS>
00166 inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
00167                                                         const RHS &R) {
00168   return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
00169 }
00170 
00171 template<typename LHS, typename RHS>
00172 inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
00173                                                         const RHS &R) {
00174   return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
00175 }
00176 
00177 template<typename LHS, typename RHS>
00178 inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
00179                                                         const RHS &R) {
00180   return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
00181 }
00182 
00183 template<typename LHS, typename RHS>
00184 inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
00185                                                         const RHS &R) {
00186   return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
00187 }
00188 
00189 template<typename LHS, typename RHS>
00190 inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
00191                                                           const RHS &R) {
00192   return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
00193 }
00194 
00195 template<typename LHS, typename RHS>
00196 inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
00197                                                           const RHS &R) {
00198   return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
00199 }
00200 
00201 template<typename LHS, typename RHS>
00202 inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
00203                                                         const RHS &R) {
00204   return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
00205 }
00206 
00207 template<typename LHS, typename RHS>
00208 inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
00209                                                         const RHS &R) {
00210   return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
00211 }
00212 
00213 template<typename LHS, typename RHS>
00214 inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
00215                                                       const RHS &R) {
00216   return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
00217 }
00218 
00219 template<typename LHS, typename RHS>
00220 inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
00221                                                         const RHS &R) {
00222   return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
00223 }
00224 
00225 template<typename LHS, typename RHS>
00226 inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L, 
00227                                                         const RHS &R) {
00228   return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
00229 }
00230 
00231 template<typename LHS, typename RHS>
00232 inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L, 
00233                                                           const RHS &R) {
00234   return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
00235 }
00236 
00237 template<typename LHS, typename RHS>
00238 inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L, 
00239                                                           const RHS &R) {
00240   return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
00241 }
00242 
00243 //===----------------------------------------------------------------------===//
00244 // Matchers for either AShr or LShr .. for convenience
00245 //
00246 template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
00247 struct Shr_match {
00248   LHS_t L;
00249   RHS_t R;
00250 
00251   Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
00252 
00253   template<typename OpTy>
00254   bool match(OpTy *V) {
00255     if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
00256         V->getValueID() == Value::InstructionVal + Instruction::AShr) {
00257       ConcreteTy *I = cast<ConcreteTy>(V);
00258       return (I->getOpcode() == Instruction::AShr ||
00259               I->getOpcode() == Instruction::LShr) &&
00260              L.match(I->getOperand(0)) &&
00261              R.match(I->getOperand(1));
00262     }
00263     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
00264       return (CE->getOpcode() == Instruction::LShr ||
00265               CE->getOpcode() == Instruction::AShr) &&
00266              L.match(CE->getOperand(0)) &&
00267              R.match(CE->getOperand(1));
00268     return false;
00269   }
00270 };
00271 
00272 template<typename LHS, typename RHS>
00273 inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
00274   return Shr_match<LHS, RHS>(L, R);
00275 }
00276 
00277 //===----------------------------------------------------------------------===//
00278 // Matchers for binary classes
00279 //
00280 
00281 template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
00282 struct BinaryOpClass_match {
00283   OpcType *Opcode;
00284   LHS_t L;
00285   RHS_t R;
00286 
00287   BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
00288                       const RHS_t &RHS)
00289     : Opcode(&Op), L(LHS), R(RHS) {}
00290   BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
00291     : Opcode(0), L(LHS), R(RHS) {}
00292 
00293   template<typename OpTy>
00294   bool match(OpTy *V) {
00295     if (Class *I = dyn_cast<Class>(V))
00296       if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
00297         if (Opcode)
00298           *Opcode = I->getOpcode();
00299         return true;
00300       }
00301 #if 0  // Doesn't handle constantexprs yet!
00302     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
00303       return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
00304              R.match(CE->getOperand(1));
00305 #endif
00306     return false;
00307   }
00308 };
00309 
00310 template<typename LHS, typename RHS>
00311 inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
00312 m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
00313   return BinaryOpClass_match<LHS, RHS, 
00314                              BinaryOperator, Instruction::BinaryOps>(Op, L, R);
00315 }
00316 
00317 template<typename LHS, typename RHS>
00318 inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
00319 m_Shift(const LHS &L, const RHS &R) {
00320   return BinaryOpClass_match<LHS, RHS, 
00321                              BinaryOperator, Instruction::BinaryOps>(L, R);
00322 }
00323 
00324 //===----------------------------------------------------------------------===//
00325 // Matchers for CmpInst classes
00326 //
00327 
00328 template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
00329 struct CmpClass_match {
00330   PredicateTy &Predicate;
00331   LHS_t L;
00332   RHS_t R;
00333 
00334   CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
00335                  const RHS_t &RHS)
00336     : Predicate(Pred), L(LHS), R(RHS) {}
00337 
00338   template<typename OpTy>
00339   bool match(OpTy *V) {
00340     if (Class *I = dyn_cast<Class>(V))
00341       if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
00342         Predicate = I->getPredicate();
00343         return true;
00344       }
00345     return false;
00346   }
00347 };
00348 
00349 template<typename LHS, typename RHS>
00350 inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
00351 m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
00352   return CmpClass_match<LHS, RHS,
00353                         ICmpInst, ICmpInst::Predicate>(Pred, L, R);
00354 }
00355 
00356 template<typename LHS, typename RHS>
00357 inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
00358 m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
00359   return CmpClass_match<LHS, RHS,
00360                         FCmpInst, FCmpInst::Predicate>(Pred, L, R);
00361 }
00362 
00363 //===----------------------------------------------------------------------===//
00364 // Matchers for SelectInst classes
00365 //
00366 
00367 template<typename Cond_t, typename LHS_t, typename RHS_t>
00368 struct SelectClass_match {
00369   Cond_t C;
00370   LHS_t L;
00371   RHS_t R;
00372 
00373   SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
00374                     const RHS_t &RHS)
00375     : C(Cond), L(LHS), R(RHS) {}
00376 
00377   template<typename OpTy>
00378   bool match(OpTy *V) {
00379     if (SelectInst *I = dyn_cast<SelectInst>(V))
00380       return C.match(I->getOperand(0)) &&
00381              L.match(I->getOperand(1)) &&
00382              R.match(I->getOperand(2));
00383     return false;
00384   }
00385 };
00386 
00387 template<typename Cond, typename LHS, typename RHS>
00388 inline SelectClass_match<Cond, RHS, LHS>
00389 m_Select(const Cond &C, const LHS &L, const RHS &R) {
00390   return SelectClass_match<Cond, LHS, RHS>(C, L, R);
00391 }
00392 
00393 /// m_SelectCst - This matches a select of two constants, e.g.:
00394 ///    m_SelectCst(m_Value(V), -1, 0)
00395 template<int64_t L, int64_t R, typename Cond>
00396 inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
00397 m_SelectCst(const Cond &C) {
00398   return SelectClass_match<Cond, constantint_ty<L>, 
00399                            constantint_ty<R> >(C, m_ConstantInt<L>(),
00400                                            m_ConstantInt<R>());
00401 }
00402 
00403 
00404 //===----------------------------------------------------------------------===//
00405 // Matchers for CastInst classes
00406 //
00407 
00408 template<typename Op_t, typename Class>
00409 struct CastClass_match {
00410   Op_t Op;
00411   
00412   CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
00413   
00414   template<typename OpTy>
00415   bool match(OpTy *V) {
00416     if (Class *I = dyn_cast<Class>(V))
00417       return Op.match(I->getOperand(0));
00418     return false;
00419   }
00420 };
00421 
00422 template<typename Class, typename OpTy>
00423 inline CastClass_match<OpTy, Class> m_Cast(const OpTy &Op) {
00424   return CastClass_match<OpTy, Class>(Op);
00425 }
00426 
00427   
00428 //===----------------------------------------------------------------------===//
00429 // Matchers for unary operators
00430 //
00431 
00432 template<typename LHS_t>
00433 struct not_match {
00434   LHS_t L;
00435 
00436   not_match(const LHS_t &LHS) : L(LHS) {}
00437 
00438   template<typename OpTy>
00439   bool match(OpTy *V) {
00440     if (Instruction *I = dyn_cast<Instruction>(V))
00441       if (I->getOpcode() == Instruction::Xor)
00442         return matchIfNot(I->getOperand(0), I->getOperand(1));
00443     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
00444       if (CE->getOpcode() == Instruction::Xor)
00445         return matchIfNot(CE->getOperand(0), CE->getOperand(1));
00446     if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
00447       return L.match(ConstantExpr::getNot(CI));
00448     return false;
00449   }
00450 private:
00451   bool matchIfNot(Value *LHS, Value *RHS) {
00452     if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
00453       return CI->isAllOnesValue() && L.match(LHS);
00454     if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
00455       return CI->isAllOnesValue() && L.match(RHS);
00456     if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
00457       return CV->isAllOnesValue() && L.match(LHS);
00458     if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
00459       return CV->isAllOnesValue() && L.match(RHS);
00460     return false;
00461   }
00462 };
00463 
00464 template<typename LHS>
00465 inline not_match<LHS> m_Not(const LHS &L) { return L; }
00466 
00467 
00468 template<typename LHS_t>
00469 struct neg_match {
00470   LHS_t L;
00471   
00472   neg_match(const LHS_t &LHS) : L(LHS) {}
00473   
00474   template<typename OpTy>
00475   bool match(OpTy *V) {
00476     if (Instruction *I = dyn_cast<Instruction>(V))
00477       if (I->getOpcode() == Instruction::Sub)
00478         return matchIfNeg(I->getOperand(0), I->getOperand(1));
00479     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
00480       if (CE->getOpcode() == Instruction::Sub)
00481         return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
00482     if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
00483       return L.match(ConstantExpr::getNeg(CI));
00484     return false;
00485   }
00486 private:
00487   bool matchIfNeg(Value *LHS, Value *RHS) {
00488     return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
00489            L.match(RHS);
00490   }
00491 };
00492 
00493 template<typename LHS>
00494 inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
00495 
00496 
00497 //===----------------------------------------------------------------------===//
00498 // Matchers for control flow
00499 //
00500 
00501 template<typename Cond_t>
00502 struct brc_match {
00503   Cond_t Cond;
00504   BasicBlock *&T, *&F;
00505   brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
00506     : Cond(C), T(t), F(f) {
00507   }
00508 
00509   template<typename OpTy>
00510   bool match(OpTy *V) {
00511     if (BranchInst *BI = dyn_cast<BranchInst>(V))
00512       if (BI->isConditional()) {
00513         if (Cond.match(BI->getCondition())) {
00514           T = BI->getSuccessor(0);
00515           F = BI->getSuccessor(1);
00516           return true;
00517         }
00518       }
00519     return false;
00520   }
00521 };
00522 
00523 template<typename Cond_t>
00524 inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
00525   return brc_match<Cond_t>(C, T, F);
00526 }
00527 
00528 } // end namespace PatternMatch
00529 } // end namespace llvm
00530 
00531 #endif



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.