From cbb70ce070d220642b038ea101d9c0f9fbf860d6 Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 20 Feb 2011 12:57:14 +0000 Subject: Vendor import of llvm trunk r126079: http://llvm.org/svn/llvm-project/llvm/trunk@126079 --- include/llvm/Support/PatternMatch.h | 339 ++++++++++++++++++++---------------- 1 file changed, 190 insertions(+), 149 deletions(-) (limited to 'include/llvm/Support/PatternMatch.h') diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index bee6768..948ae51 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -41,18 +41,62 @@ bool match(Val *V, const Pattern &P) { } template -struct leaf_ty { +struct class_match { template bool match(ITy *V) { return isa(V); } }; /// m_Value() - Match an arbitrary value and ignore it. -inline leaf_ty m_Value() { return leaf_ty(); } +inline class_match m_Value() { return class_match(); } /// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it. -inline leaf_ty m_ConstantInt() { return leaf_ty(); } +inline class_match m_ConstantInt() { + return class_match(); +} +/// m_Undef() - Match an arbitrary undef constant. +inline class_match m_Undef() { return class_match(); } +inline class_match m_Constant() { return class_match(); } + +struct match_zero { + template + bool match(ITy *V) { + if (const Constant *C = dyn_cast(V)) + return C->isNullValue(); + return false; + } +}; + +/// m_Zero() - Match an arbitrary zero/null constant. This includes +/// zero_initializer for vectors and ConstantPointerNull for pointers. +inline match_zero m_Zero() { return match_zero(); } + + +struct apint_match { + const APInt *&Res; + apint_match(const APInt *&R) : Res(R) {} + template + bool match(ITy *V) { + if (ConstantInt *CI = dyn_cast(V)) { + Res = &CI->getValue(); + return true; + } + if (ConstantVector *CV = dyn_cast(V)) + if (ConstantInt *CI = + dyn_cast_or_null(CV->getSplatValue())) { + Res = &CI->getValue(); + return true; + } + return false; + } +}; + +/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the +/// specified pointer to the contained APInt. +inline apint_match m_APInt(const APInt *&Res) { return Res; } + + template -struct constantint_ty { +struct constantint_match { template bool match(ITy *V) { if (const ConstantInt *CI = dyn_cast(V)) { @@ -68,37 +112,82 @@ struct constantint_ty { } }; -/// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value -/// and ignore it. +/// m_ConstantInt - Match a ConstantInt with a specific value. template -inline constantint_ty m_ConstantInt() { - return constantint_ty(); +inline constantint_match m_ConstantInt() { + return constantint_match(); } -struct zero_ty { +/// cst_pred_ty - This helper class is used to match scalar and vector constants +/// that satisfy a specified predicate. +template +struct cst_pred_ty : public Predicate { template bool match(ITy *V) { - if (const Constant *C = dyn_cast(V)) - return C->isNullValue(); + if (const ConstantInt *CI = dyn_cast(V)) + return this->isValue(CI->getValue()); + if (const ConstantVector *CV = dyn_cast(V)) + if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) + return this->isValue(CI->getValue()); return false; } }; - -/// m_Zero() - Match an arbitrary zero/null constant. -inline zero_ty m_Zero() { return zero_ty(); } - -struct one_ty { + +/// api_pred_ty - This helper class is used to match scalar and vector constants +/// that satisfy a specified predicate, and bind them to an APInt. +template +struct api_pred_ty : public Predicate { + const APInt *&Res; + api_pred_ty(const APInt *&R) : Res(R) {} template bool match(ITy *V) { - if (const ConstantInt *C = dyn_cast(V)) - return C->isOne(); + if (const ConstantInt *CI = dyn_cast(V)) + if (this->isValue(CI->getValue())) { + Res = &CI->getValue(); + return true; + } + if (const ConstantVector *CV = dyn_cast(V)) + if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) + if (this->isValue(CI->getValue())) { + Res = &CI->getValue(); + return true; + } return false; } }; + + +struct is_one { + bool isValue(const APInt &C) { return C == 1; } +}; -/// m_One() - Match a an integer 1. -inline one_ty m_One() { return one_ty(); } +/// m_One() - Match an integer 1 or a vector with all elements equal to 1. +inline cst_pred_ty m_One() { return cst_pred_ty(); } +inline api_pred_ty m_One(const APInt *&V) { return V; } + +struct is_all_ones { + bool isValue(const APInt &C) { return C.isAllOnesValue(); } +}; +/// m_AllOnes() - Match an integer or vector with all bits set to true. +inline cst_pred_ty m_AllOnes() {return cst_pred_ty();} +inline api_pred_ty m_AllOnes(const APInt *&V) { return V; } + +struct is_sign_bit { + bool isValue(const APInt &C) { return C.isSignBit(); } +}; + +/// m_SignBit() - Match an integer or vector with only the sign bit(s) set. +inline cst_pred_ty m_SignBit() {return cst_pred_ty();} +inline api_pred_ty m_SignBit(const APInt *&V) { return V; } + +struct is_power2 { + bool isValue(const APInt &C) { return C.isPowerOf2(); } +}; + +/// m_Power2() - Match an integer or vector power of 2. +inline cst_pred_ty m_Power2() { return cst_pred_ty(); } +inline api_pred_ty m_Power2(const APInt *&V) { return V; } template struct bind_ty { @@ -121,6 +210,9 @@ inline bind_ty m_Value(Value *&V) { return V; } /// m_ConstantInt - Match a ConstantInt, capturing the value if we match. inline bind_ty m_ConstantInt(ConstantInt *&CI) { return CI; } +/// m_Constant - Match a Constant, capturing the value if we match. +inline bind_ty m_Constant(Constant *&C) { return C; } + /// specificval_ty - Match a specified Value*. struct specificval_ty { const Value *Val; @@ -140,8 +232,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; } // Matchers for specific binary operators. // -template +template struct BinaryOp_match { LHS_t L; RHS_t R; @@ -151,9 +242,8 @@ struct BinaryOp_match { template bool match(OpTy *V) { if (V->getValueID() == Value::InstructionVal + Opcode) { - ConcreteTy *I = cast(V); - return I->getOpcode() == Opcode && L.match(I->getOperand(0)) && - R.match(I->getOperand(1)); + BinaryOperator *I = cast(V); + return 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)) && @@ -163,193 +253,156 @@ struct BinaryOp_match { }; template -inline BinaryOp_match m_Add(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_Add(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_FAdd(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_FAdd(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Sub(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_Sub(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_FSub(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_FSub(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Mul(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_Mul(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_FMul(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_FMul(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_UDiv(const LHS &L, - const RHS &R) { +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) { +inline BinaryOp_match +m_SDiv(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_FDiv(const LHS &L, - const RHS &R) { +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) { +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) { +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) { +inline BinaryOp_match +m_FRem(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_And(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_And(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } 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); } template -inline BinaryOp_match m_Xor(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_Xor(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_Shl(const LHS &L, - const RHS &R) { +inline BinaryOp_match +m_Shl(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } template -inline BinaryOp_match m_LShr(const LHS &L, - const RHS &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) { +inline BinaryOp_match +m_AShr(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } //===----------------------------------------------------------------------===// -// Matchers for either AShr or LShr .. for convenience +// Class that matches two different binary ops. // -template -struct Shr_match { +template +struct BinOp2_match { LHS_t L; RHS_t R; - Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} + BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template bool match(OpTy *V) { - if (V->getValueID() == Value::InstructionVal + Instruction::LShr || - V->getValueID() == 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 (V->getValueID() == Value::InstructionVal + Opc1 || + V->getValueID() == Value::InstructionVal + Opc2) { + BinaryOperator *I = cast(V); + return 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 (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) && + L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); return false; } }; +/// m_Shr - Matches LShr or AShr. template -inline Shr_match m_Shr(const LHS &L, const RHS &R) { - return Shr_match(L, R); +inline BinOp2_match +m_Shr(const LHS &L, const RHS &R) { + return BinOp2_match(L, R); } -//===----------------------------------------------------------------------===// -// Matchers for binary classes -// - -template -struct BinaryOpClass_match { - OpcType *Opcode; - LHS_t L; - RHS_t R; - - BinaryOpClass_match(OpcType &Op, const LHS_t &LHS, - const RHS_t &RHS) - : Opcode(&Op), L(LHS), R(RHS) {} - BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS) - : Opcode(0), 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))) { - if (Opcode) - *Opcode = I->getOpcode(); - return true; - } -#if 0 // Doesn't handle constantexprs yet! - if (ConstantExpr *CE = dyn_cast(V)) - return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && - R.match(CE->getOperand(1)); -#endif - return false; - } -}; - +/// m_LogicalShift - Matches LShr or Shl. template -inline BinaryOpClass_match -m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) { - return BinaryOpClass_match(Op, L, R); +inline BinOp2_match +m_LogicalShift(const LHS &L, const RHS &R) { + return BinOp2_match(L, R); } +/// m_IDiv - Matches UDiv and SDiv. template -inline BinaryOpClass_match -m_Shift(const LHS &L, const RHS &R) { - return BinaryOpClass_match(L, R); +inline BinOp2_match +m_IDiv(const LHS &L, const RHS &R) { + return BinOp2_match(L, R); } //===----------------------------------------------------------------------===// @@ -362,15 +415,13 @@ struct CmpClass_match { LHS_t L; RHS_t R; - CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, - const RHS_t &RHS) + 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))) { + if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { Predicate = I->getPredicate(); return true; } @@ -425,11 +476,9 @@ m_Select(const Cond &C, const LHS &L, const RHS &R) { /// m_SelectCst - This matches a select of two constants, e.g.: /// m_SelectCst<-1, 0>(m_Value(V)) template -inline SelectClass_match, constantint_ty > +inline SelectClass_match, constantint_match > m_SelectCst(const Cond &C) { - return SelectClass_match, - constantint_ty >(C, m_ConstantInt(), - m_ConstantInt()); + return m_Select(C, m_ConstantInt(), m_ConstantInt()); } @@ -507,20 +556,14 @@ struct not_match { if (ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::Xor) return matchIfNot(CE->getOperand(0), CE->getOperand(1)); - if (ConstantInt *CI = dyn_cast(V)) - return L.match(ConstantExpr::getNot(CI)); return false; } private: bool matchIfNot(Value *LHS, Value *RHS) { if (ConstantInt *CI = dyn_cast(RHS)) return CI->isAllOnesValue() && L.match(LHS); - if (ConstantInt *CI = dyn_cast(LHS)) - return CI->isAllOnesValue() && L.match(RHS); if (ConstantVector *CV = dyn_cast(RHS)) return CV->isAllOnesValue() && L.match(LHS); - if (ConstantVector *CV = dyn_cast(LHS)) - return CV->isAllOnesValue() && L.match(RHS); return false; } }; @@ -543,17 +586,17 @@ struct neg_match { if (ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::Sub) return matchIfNeg(CE->getOperand(0), CE->getOperand(1)); - if (ConstantInt *CI = dyn_cast(V)) - return L.match(ConstantExpr::getNeg(CI)); return false; } private: bool matchIfNeg(Value *LHS, Value *RHS) { - return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) && - L.match(RHS); + if (ConstantInt *C = dyn_cast(LHS)) + return C->isZero() && L.match(RHS); + return false; } }; +/// m_Neg - Match an integer negate. template inline neg_match m_Neg(const LHS &L) { return L; } @@ -572,23 +615,23 @@ struct fneg_match { if (ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::FSub) return matchIfFNeg(CE->getOperand(0), CE->getOperand(1)); - if (ConstantFP *CF = dyn_cast(V)) - return L.match(ConstantExpr::getFNeg(CF)); return false; } private: bool matchIfFNeg(Value *LHS, Value *RHS) { - return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) && - L.match(RHS); + if (ConstantFP *C = dyn_cast(LHS)) + return C->isNegativeZeroValue() && L.match(RHS); + return false; } }; +/// m_FNeg - Match a floating point negate. template inline fneg_match m_FNeg(const LHS &L) { return L; } //===----------------------------------------------------------------------===// -// Matchers for control flow +// Matchers for control flow. // template @@ -602,12 +645,10 @@ struct brc_match { template bool match(OpTy *V) { if (BranchInst *BI = dyn_cast(V)) - if (BI->isConditional()) { - if (Cond.match(BI->getCondition())) { - T = BI->getSuccessor(0); - F = BI->getSuccessor(1); - return true; - } + if (BI->isConditional() && Cond.match(BI->getCondition())) { + T = BI->getSuccessor(0); + F = BI->getSuccessor(1); + return true; } return false; } -- cgit v1.1