X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FPatternMatch.h;h=f0acbcbaa6e009cbd7f53c03e53e29bc64a51f0b;hb=6b6b6ef1677fa71b1072c2911b4c1f9524a558c9;hp=ae1d30cc088517d6ae9b468c1df06874b097d52e;hpb=f17ffcce18ad8e3da3b1e7a3a8b1ac19ac301c80;p=oota-llvm.git diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index ae1d30cc088..f0acbcbaa6e 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -1,16 +1,16 @@ //===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file provides a simple and efficient mechanism for performing general // tree-based pattern matches on the LLVM IR. The power of these routines is // that it allows you to write concise patterns that are expressive and easy to -// understand. The other major advantage of this is that is allows to you +// understand. The other major advantage of this is that it allows you to // trivially capture/bind elements in the pattern to variables. For example, // you can do something like this: // @@ -33,7 +33,7 @@ #include "llvm/Instructions.h" namespace llvm { -namespace PatternMatch { +namespace PatternMatch { template bool match(Val *V, const Pattern &P) { @@ -68,10 +68,11 @@ inline bind_ty m_Value(Value *&V) { return V; } inline bind_ty m_ConstantInt(ConstantInt *&CI) { return CI; } //===----------------------------------------------------------------------===// -// Matchers for specific binary operators +// Matchers for specific binary operators. // -template +template struct BinaryOp_match { LHS_t L; RHS_t R; @@ -80,15 +81,17 @@ struct BinaryOp_match { template bool match(OpTy *V) { - if (Instruction *I = dyn_cast(V)) + if (V->getValueType() == Value::InstructionVal + Opcode) { + ConcreteTy *I = cast(V); return I->getOpcode() == Opcode && L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + } if (ConstantExpr *CE = dyn_cast(V)) return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); return false; } -}; +}; template inline BinaryOp_match m_Add(const LHS &L, @@ -109,15 +112,39 @@ inline BinaryOp_match m_Mul(const LHS &L, } template -inline BinaryOp_match m_Div(const LHS &L, +inline BinaryOp_match m_UDiv(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_SDiv(const LHS &L, const RHS &R) { - return BinaryOp_match(L, R); + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_FDiv(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_URem(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_SRem(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Rem(const LHS &L, +inline BinaryOp_match m_FRem(const LHS &L, const RHS &R) { - return BinaryOp_match(L, R); + return BinaryOp_match(L, R); } template @@ -127,8 +154,8 @@ inline BinaryOp_match m_And(const LHS &L, } template -inline BinaryOp_match m_Or(const LHS &L, - const RHS &R) { +inline BinaryOp_match m_Or(const LHS &L, + const RHS &R) { return BinaryOp_match(L, R); } @@ -139,28 +166,68 @@ inline BinaryOp_match m_Xor(const LHS &L, } template -inline BinaryOp_match m_Shl(const LHS &L, - const RHS &R) { - return BinaryOp_match(L, R); +inline BinaryOp_match m_Shl(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Shr(const LHS &L, - const RHS &R) { - return BinaryOp_match(L, R); +inline BinaryOp_match m_LShr(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match m_AShr(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); +} + +//===----------------------------------------------------------------------===// +// Matchers for either AShr or LShr .. for convenience +// +template +struct Shr_match { + LHS_t L; + RHS_t R; + + Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} + + template + bool match(OpTy *V) { + if (V->getValueType() == Value::InstructionVal + Instruction::LShr || + V->getValueType() == Value::InstructionVal + Instruction::AShr) { + ConcreteTy *I = cast(V); + return (I->getOpcode() == Instruction::AShr || + I->getOpcode() == Instruction::LShr) && + L.match(I->getOperand(0)) && + R.match(I->getOperand(1)); + } + if (ConstantExpr *CE = dyn_cast(V)) + return (CE->getOpcode() == Instruction::LShr || + CE->getOpcode() == Instruction::AShr) && + L.match(CE->getOperand(0)) && + R.match(CE->getOperand(1)); + return false; + } +}; + +template +inline Shr_match m_Shr(const LHS &L, const RHS &R) { + return Shr_match(L, R); } //===----------------------------------------------------------------------===// // Matchers for binary classes // -template +template struct BinaryOpClass_match { - Instruction::BinaryOps &Opcode; + OpcType &Opcode; LHS_t L; RHS_t R; - BinaryOpClass_match(Instruction::BinaryOps &Op, const LHS_t &LHS, + BinaryOpClass_match(OpcType &Op, const LHS_t &LHS, const RHS_t &RHS) : Opcode(Op), L(LHS), R(RHS) {} @@ -178,14 +245,61 @@ struct BinaryOpClass_match { #endif return false; } -}; +}; template -inline BinaryOpClass_match -m_SetCond(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) { - return BinaryOpClass_match(Op, L, R); +inline BinaryOpClass_match +m_Shift(Instruction::OtherOps &Op, const LHS &L, const RHS &R) { + return BinaryOpClass_match(Op, L, R); } +template +inline BinaryOpClass_match +m_Shift(const LHS &L, const RHS &R) { + Instruction::OtherOps Op; + return BinaryOpClass_match(Op, L, R); +} + +//===----------------------------------------------------------------------===// +// Matchers for CmpInst classes +// + +template +struct CmpClass_match { + PredicateTy &Predicate; + LHS_t L; + RHS_t R; + + CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, + const RHS_t &RHS) + : Predicate(Pred), L(LHS), R(RHS) {} + + template + bool match(OpTy *V) { + if (Class *I = dyn_cast(V)) + if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { + Predicate = I->getPredicate(); + return true; + } + return false; + } +}; + +template +inline CmpClass_match +m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) { + return CmpClass_match(Pred, L, R); +} + +template +inline CmpClass_match +m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) { + return CmpClass_match(Pred, L, R); +} //===----------------------------------------------------------------------===// // Matchers for unary operators @@ -216,7 +330,7 @@ private: else return LHS == ConstantFP::get(LHS->getType(), -0.0) && L.match(RHS); } -}; +}; template inline neg_match m_Neg(const LHS &L) { return L; } @@ -242,9 +356,9 @@ struct not_match { } private: bool matchIfNot(Value *LHS, Value *RHS) { - if (ConstantIntegral *CI = dyn_cast(RHS)) + if (ConstantInt *CI = dyn_cast(RHS)) return CI->isAllOnesValue() && L.match(LHS); - else if (ConstantIntegral *CI = dyn_cast(LHS)) + else if (ConstantInt *CI = dyn_cast(LHS)) return CI->isAllOnesValue() && L.match(RHS); return false; } @@ -253,6 +367,7 @@ private: template inline not_match m_Not(const LHS &L) { return L; } + //===----------------------------------------------------------------------===// // Matchers for control flow //