X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FPatternMatch.h;h=f0acbcbaa6e009cbd7f53c03e53e29bc64a51f0b;hb=6b6b6ef1677fa71b1072c2911b4c1f9524a558c9;hp=d15ae9c498663f1320be340cc12c7a08e7677cd0;hpb=c70cc35ddfe2b938846c3029a7b634c7f8c47978;p=oota-llvm.git diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index d15ae9c4986..f0acbcbaa6e 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -10,7 +10,7 @@ // 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: // @@ -68,7 +68,7 @@ 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 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); + return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Rem(const LHS &L, +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_FRem(const LHS &L, + const RHS &R) { + return BinaryOp_match(L, R); } template @@ -148,22 +172,62 @@ inline BinaryOp_match -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) {} @@ -184,11 +248,58 @@ struct BinaryOpClass_match { }; 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 @@ -245,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; } @@ -256,6 +367,7 @@ private: template inline not_match m_Not(const LHS &L) { return L; } + //===----------------------------------------------------------------------===// // Matchers for control flow //