LLVM API Documentation
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.