diff options
| -rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 97 |
1 files changed, 48 insertions, 49 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 84dc2a1fa48..791dbb8dc86 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -660,50 +660,6 @@ m_NUWShl(const LHS &L, const RHS &R) { } //===----------------------------------------------------------------------===// -// Class that matches two different binary ops. -// -template <typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2> -struct BinOp2_match { - LHS_t L; - RHS_t R; - - BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} - - template <typename OpTy> bool match(OpTy *V) { - if (V->getValueID() == Value::InstructionVal + Opc1 || - V->getValueID() == Value::InstructionVal + Opc2) { - auto *I = cast<BinaryOperator>(V); - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); - } - if (auto *CE = dyn_cast<ConstantExpr>(V)) - return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) && - L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); - return false; - } -}; - -/// \brief Matches LShr or AShr. -template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr> -m_Shr(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R); -} - -/// \brief Matches LShr or Shl. -template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl> -m_LogicalShift(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R); -} - -/// \brief Matches UDiv and SDiv. -template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv> -m_IDiv(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R); -} - -//===----------------------------------------------------------------------===// // Class that matches a group of binary opcodes. // template <typename LHS_t, typename RHS_t, typename Predicate> @@ -715,9 +671,11 @@ struct BinOpPred_match : Predicate { template <typename OpTy> bool match(OpTy *V) { if (auto *I = dyn_cast<Instruction>(V)) - return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) && + R.match(I->getOperand(1)); if (auto *CE = dyn_cast<ConstantExpr>(V)) - return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); + return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) && + R.match(CE->getOperand(1)); return false; } }; @@ -726,17 +684,51 @@ struct is_shift_op { bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); } }; +struct is_right_shift_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::LShr || Opcode == Instruction::AShr; + } +}; + +struct is_logical_shift_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::LShr || Opcode == Instruction::Shl; + } +}; + struct is_bitwiselogic_op { - bool isOpType(unsigned Opcode) { return Instruction::isBitwiseLogicOp(Opcode); } + bool isOpType(unsigned Opcode) { + return Instruction::isBitwiseLogicOp(Opcode); + } +}; + +struct is_idiv_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; + } }; /// \brief Matches shift operations. template <typename LHS, typename RHS> -inline BinOpPred_match<LHS, RHS, is_shift_op> -m_Shift(const LHS &L, const RHS &R) { +inline BinOpPred_match<LHS, RHS, is_shift_op> m_Shift(const LHS &L, + const RHS &R) { return BinOpPred_match<LHS, RHS, is_shift_op>(L, R); } +/// \brief Matches logical shift operations. +template <typename LHS, typename RHS> +inline BinOpPred_match<LHS, RHS, is_right_shift_op> m_Shr(const LHS &L, + const RHS &R) { + return BinOpPred_match<LHS, RHS, is_right_shift_op>(L, R); +} + +/// \brief Matches logical shift operations. +template <typename LHS, typename RHS> +inline BinOpPred_match<LHS, RHS, is_logical_shift_op> +m_LogicalShift(const LHS &L, const RHS &R) { + return BinOpPred_match<LHS, RHS, is_logical_shift_op>(L, R); +} + /// \brief Matches bitwise logic operations. template <typename LHS, typename RHS> inline BinOpPred_match<LHS, RHS, is_bitwiselogic_op> @@ -744,6 +736,13 @@ m_BitwiseLogic(const LHS &L, const RHS &R) { return BinOpPred_match<LHS, RHS, is_bitwiselogic_op>(L, R); } +/// \brief Matches integer division operations. +template <typename LHS, typename RHS> +inline BinOpPred_match<LHS, RHS, is_idiv_op> m_IDiv(const LHS &L, + const RHS &R) { + return BinOpPred_match<LHS, RHS, is_idiv_op>(L, R); +} + //===----------------------------------------------------------------------===// // Class that matches exact binary ops. // |

