From 8ad435fa4809b5a4ad1043435cbafd5c9ddf2d93 Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Thu, 13 Dec 2012 03:13:36 +0000 Subject: Pattern matching code for intrinsics. Provides m_Argument that allows matching against a CallSite's specified argument. Provides m_Intrinsic pattern that can be templatized over the intrinsic id and bind/match arguments similarly to other pattern matchers. Implementations provided for 0 to 4 arguments, though it's very simple to extend for more. Also provides example template specialization for bswap (m_BSwap) and example of code cleanup for its use. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170091 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/PatternMatch.h | 98 +++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'include/llvm/Support/PatternMatch.h') diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index edf997de59..7420fab1a7 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -31,7 +31,9 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Operator.h" +#include "llvm/Support/CallSite.h" namespace llvm { namespace PatternMatch { @@ -897,6 +899,102 @@ m_UMin(const LHS &L, const RHS &R) { return MaxMin_match(L, R); } +template +struct Argument_match { + unsigned OpI; + Opnd_t Val; + Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { } + + template + bool match(OpTy *V) { + CallSite CS(V); + return CS.isCall() && Val.match(CS.getArgument(OpI)); + } +}; + +/// Match an argument +template +inline Argument_match m_Argument(const Opnd_t &Op) { + return Argument_match(OpI, Op); +} + +/// Intrinsic matchers. +struct IntrinsicID_match { + unsigned ID; + IntrinsicID_match(unsigned IntrID) : ID(IntrID) { } + + template + bool match(OpTy *V) { + IntrinsicInst *II = dyn_cast(V); + return II && II->getIntrinsicID() == ID; + } +}; + +/// Intrinsic matches are combinations of ID matchers, and argument +/// matchers. Higher arity matcher are defined recursively in terms of and-ing +/// them with lower arity matchers. Here's some convenient typedefs for up to +/// several arguments, and more can be added as needed +template struct m_Intrinsic_Ty; +template +struct m_Intrinsic_Ty { + typedef match_combine_and > Ty; +}; +template +struct m_Intrinsic_Ty { + typedef match_combine_and::Ty, + Argument_match > Ty; +}; +template +struct m_Intrinsic_Ty { + typedef match_combine_and::Ty, + Argument_match > Ty; +}; +template +struct m_Intrinsic_Ty { + typedef match_combine_and::Ty, + Argument_match > Ty; +}; + +/// Match intrinsic calls like this: +/// m_Intrinsic(m_Value(X)) +template +inline IntrinsicID_match +m_Intrinsic() { return IntrinsicID_match(IntrID); } + +template +inline typename m_Intrinsic_Ty::Ty +m_Intrinsic(const T0 &Op0) { + return m_CombineAnd(m_Intrinsic(), m_Argument<0>(Op0)); +} + +template +inline typename m_Intrinsic_Ty::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1) { + return m_CombineAnd(m_Intrinsic(Op0), m_Argument<1>(Op1)); +} + +template +inline typename m_Intrinsic_Ty::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) { + return m_CombineAnd(m_Intrinsic(Op0, Op1), m_Argument<2>(Op2)); +} + +template +inline typename m_Intrinsic_Ty::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { + return m_CombineAnd(m_Intrinsic(Op0, Op1, Op2), m_Argument<3>(Op3)); +} + +// Helper intrinsic matching specializations +template +inline typename m_Intrinsic_Ty::Ty +m_BSwap(const Opnd0 &Op0) { + return m_Intrinsic(Op0); +} + } // end namespace PatternMatch } // end namespace llvm -- cgit v1.2.3