From: Craig Topper Date: Sat, 24 Jun 2017 06:27:14 +0000 (+0000) Subject: [IR][AssumptionCache] Add m_Shift and m_BitwiseLogic matchers to replace a couple... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=82dfc83ad0c34b6d14e64be07a6a7d857781dc73;p=llvm [IR][AssumptionCache] Add m_Shift and m_BitwiseLogic matchers to replace a couple m_CombineOr Summary: m_CombineOr isn't very efficient. The code using it is also quite verbose. This patch adds m_Shift and m_BitwiseLogic matchers to make the using code more concise and improve the match efficiency. Reviewers: spatel, davide Reviewed By: davide Subscribers: davide, llvm-commits Differential Revision: https://reviews.llvm.org/D34593 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306206 cdac9f57-aa62-4fd3-8940-286f4534e8a0 --- diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 00c431834e3..d8db29e1588 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -152,9 +152,14 @@ public: return getOpcode() == AShr; } + /// Determine if the Opcode is and/or/xor. + static inline bool isBitwiseLogicOp(unsigned Opcode) { + return Opcode == And || Opcode == Or || Opcode == Xor; + } + /// Return true if this is and/or/xor. inline bool isBitwiseLogicOp() const { - return getOpcode() == And || getOpcode() == Or || getOpcode() == Xor; + return isBitwiseLogicOp(getOpcode()); } /// Determine if the OpCode is one of the CastInst instructions. diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 015a17e8e7c..84dc2a1fa48 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -703,6 +703,47 @@ m_IDiv(const LHS &L, const RHS &R) { return BinOp2_match(L, R); } +//===----------------------------------------------------------------------===// +// Class that matches a group of binary opcodes. +// +template +struct BinOpPred_match : Predicate { + LHS_t L; + RHS_t R; + + BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} + + template bool match(OpTy *V) { + if (auto *I = dyn_cast(V)) + return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + if (auto *CE = dyn_cast(V)) + return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); + return false; + } +}; + +struct is_shift_op { + bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); } +}; + +struct is_bitwiselogic_op { + bool isOpType(unsigned Opcode) { return Instruction::isBitwiseLogicOp(Opcode); } +}; + +/// \brief Matches shift operations. +template +inline BinOpPred_match +m_Shift(const LHS &L, const RHS &R) { + return BinOpPred_match(L, R); +} + +/// \brief Matches bitwise logic operations. +template +inline BinOpPred_match +m_BitwiseLogic(const LHS &L, const RHS &R) { + return BinOpPred_match(L, R); +} + //===----------------------------------------------------------------------===// // Class that matches exact binary ops. // diff --git a/lib/Analysis/AssumptionCache.cpp b/lib/Analysis/AssumptionCache.cpp index 0468c794e81..3ff27890dc3 100644 --- a/lib/Analysis/AssumptionCache.cpp +++ b/lib/Analysis/AssumptionCache.cpp @@ -84,18 +84,11 @@ void AssumptionCache::updateAffectedValues(CallInst *CI) { Value *B; ConstantInt *C; // (A & B) or (A | B) or (A ^ B). - if (match(V, - m_CombineOr(m_And(m_Value(A), m_Value(B)), - m_CombineOr(m_Or(m_Value(A), m_Value(B)), - m_Xor(m_Value(A), m_Value(B)))))) { + if (match(V, m_BitwiseLogic(m_Value(A), m_Value(B)))) { AddAffected(A); AddAffected(B); // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant. - } else if (match(V, - m_CombineOr(m_Shl(m_Value(A), m_ConstantInt(C)), - m_CombineOr(m_LShr(m_Value(A), m_ConstantInt(C)), - m_AShr(m_Value(A), - m_ConstantInt(C)))))) { + } else if (match(V, m_Shift(m_Value(A), m_ConstantInt(C)))) { AddAffected(A); } };