20#ifndef LLVM_TRANSFORM_VECTORIZE_VPLANPATTERNMATCH_H
21#define LLVM_TRANSFORM_VECTORIZE_VPLANPATTERNMATCH_H
26namespace VPlanPatternMatch {
28template <
typename Val,
typename Pattern>
bool match(Val *V,
const Pattern &
P) {
33 template <
typename ITy>
bool match(ITy *V) {
return isa<Class>(V); }
44 template <
typename ITy>
bool match(ITy *V) {
45 if (
auto *CV = dyn_cast<Class>(V)) {
65 const auto *CI = dyn_cast<ConstantInt>(V);
66 if (!CI && V->getType()->isVectorTy())
67 if (
const auto *
C = dyn_cast<Constant>(V))
68 CI = dyn_cast_or_null<ConstantInt>(
69 C->getSplatValue(
false));
74 "Trying the match constant with unexpected bitwidth.");
92 template <
typename ITy>
bool match(ITy *V) {
101template <
typename LTy,
typename RTy>
114template <
unsigned Opcode,
typename RecipeTy>
117 auto *DefR = dyn_cast<RecipeTy>(R);
118 return DefR && DefR->getOpcode() == Opcode;
122template <
unsigned Opcode,
typename RecipeTy,
typename... RecipeTys>
131template <
typename Op0_t,
unsigned Opcode,
typename... RecipeTys>
138 auto *DefR = V->getDefiningRecipe();
139 return DefR &&
match(DefR);
145 assert(R->getNumOperands() == 1 &&
146 "recipe with matched opcode does not have 1 operands");
147 return Op0.match(R->getOperand(0));
151template <
typename Op0_t,
unsigned Opcode>
155template <
typename Op0_t,
unsigned Opcode>
160template <
typename Op0_t,
typename Op1_t,
unsigned Opcode,
bool Commutative,
161 typename... RecipeTys>
169 auto *DefR = V->getDefiningRecipe();
170 return DefR &&
match(DefR);
180 assert(R->getNumOperands() == 2 &&
181 "recipe with matched opcode does not have 2 operands");
182 if (
Op0.match(R->getOperand(0)) &&
Op1.match(R->getOperand(1)))
184 return Commutative &&
Op0.match(R->getOperand(1)) &&
185 Op1.match(R->getOperand(0));
189template <
typename Op0_t,
typename Op1_t,
unsigned Opcode>
194template <
typename Op0_t,
typename Op1_t,
unsigned Opcode,
195 bool Commutative =
false>
200template <
unsigned Opcode,
typename Op0_t>
206template <
unsigned Opcode,
typename Op0_t,
typename Op1_t>
207inline BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>
212template <
typename Op0_t>
213inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
215 return m_VPInstruction<VPInstruction::Not>(Op0);
218template <
typename Op0_t>
219inline UnaryVPInstruction_match<Op0_t, VPInstruction::BranchOnCond>
221 return m_VPInstruction<VPInstruction::BranchOnCond>(Op0);
224template <
typename Op0_t,
typename Op1_t>
225inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::ActiveLaneMask>
227 return m_VPInstruction<VPInstruction::ActiveLaneMask>(Op0, Op1);
230template <
typename Op0_t,
typename Op1_t>
231inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::BranchOnCount>
233 return m_VPInstruction<VPInstruction::BranchOnCount>(Op0, Op1);
236template <
unsigned Opcode,
typename Op0_t>
241template <
typename Op0_t>
242inline AllUnaryRecipe_match<Op0_t, Instruction::Trunc>
244 return m_Unary<Instruction::Trunc, Op0_t>(Op0);
247template <
typename Op0_t>
249 return m_Unary<Instruction::ZExt, Op0_t>(Op0);
252template <
typename Op0_t>
254 return m_Unary<Instruction::SExt, Op0_t>(Op0);
257template <
typename Op0_t>
259 AllUnaryRecipe_match<Op0_t, Instruction::SExt>>
264template <
unsigned Opcode,
typename Op0_t,
typename Op1_t,
265 bool Commutative =
false>
266inline AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative>
271template <
typename Op0_t,
typename Op1_t>
272inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Mul>
273m_Mul(
const Op0_t &Op0,
const Op1_t &Op1) {
274 return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1);
277template <
typename Op0_t,
typename Op1_t>
281 return m_Binary<Instruction::Mul, Op0_t, Op1_t, true>(Op0, Op1);
288template <
typename Op0_t,
typename Op1_t,
bool Commutative = false>
289inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or, Commutative>
291 return m_Binary<Instruction::Or, Op0_t, Op1_t, Commutative>(Op0, Op1);
294template <
typename Op0_t,
typename Op1_t>
298 return m_BinaryOr<Op0_t, Op1_t,
true>(Op0, Op1);
301template <
typename Op0_t,
typename Op1_t>
302inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::LogicalAnd>
304 return m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1);
309 auto *DefR = V->getDefiningRecipe();
310 return DefR &&
match(DefR);
327 auto *DefR = V->getDefiningRecipe();
328 return DefR &&
match(DefR);
332 if (!isa<VPScalarIVStepsRecipe>(R))
334 assert(R->getNumOperands() == 2 &&
335 "VPScalarIVSteps must have exactly 2 operands");
336 return Op0.match(R->getOperand(0)) &&
Op1.match(R->getOperand(1));
340template <
typename Op0_t,
typename Op1_t>
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains the declarations of the Vectorization Plan base classes:
Class for arbitrary precision integers.
static bool isSameValue(const APInt &I1, const APInt &I2)
Determine if two APInts have the same value, after zero-extending one of them (if needed!...
This is a concrete Recipe that models a single VPlan-level instruction.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Value * getLiveInIRValue()
Returns the underlying IR value, if this VPValue is defined outside the scope of VPlan.
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
VPWidenCastRecipe is a recipe to create vector cast instructions.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
LLVM Value Representation.
@ C
The default llvm calling convention, compatible with C.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
AllBinaryRecipe_match< Op0_t, Op1_t, Instruction::Or, Commutative > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR operation.
AllUnaryRecipe_match< Op0_t, Opcode > m_Unary(const Op0_t &Op0)
AllBinaryRecipe_match< Op0_t, Op1_t, Instruction::Or, true > m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
BinaryVPInstruction_match< Op0_t, Op1_t, VPInstruction::ActiveLaneMask > m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
UnaryVPInstruction_match< Op0_t, Opcode > m_VPInstruction(const Op0_t &Op0)
AllBinaryRecipe_match< Op0_t, Op1_t, Opcode, Commutative > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
UnaryVPInstruction_match< Op0_t, VPInstruction::Not > m_Not(const Op0_t &Op0)
VPCanonicalIVPHI_match m_CanonicalIV()
AllUnaryRecipe_match< Op0_t, Instruction::Trunc > m_Trunc(const Op0_t &Op0)
VPScalarIVSteps_match< Op0_t, Op1_t > m_ScalarIVSteps(const Op0_t &Op0, const Op1_t &Op1)
AllBinaryRecipe_match< Op0_t, Op1_t, Instruction::Mul, true > m_c_Mul(const Op0_t &Op0, const Op1_t &Op1)
BinaryVPInstruction_match< Op0_t, Op1_t, VPInstruction::BranchOnCount > m_BranchOnCount(const Op0_t &Op0, const Op1_t &Op1)
specific_intval< 1 > m_False()
specific_intval< 0 > m_SpecificInt(uint64_t V)
AllBinaryRecipe_match< Op0_t, Op1_t, Instruction::Mul > m_Mul(const Op0_t &Op0, const Op1_t &Op1)
UnaryVPInstruction_match< Op0_t, VPInstruction::BranchOnCond > m_BranchOnCond(const Op0_t &Op0)
bool match(Val *V, const Pattern &P)
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
BinaryRecipe_match< Op0_t, Op1_t, Opcode, Commutative, VPWidenRecipe, VPReplicateRecipe, VPWidenCastRecipe, VPInstruction > AllBinaryRecipe_match
AllUnaryRecipe_match< Op0_t, Instruction::SExt > m_SExt(const Op0_t &Op0)
AllUnaryRecipe_match< Op0_t, Instruction::ZExt > m_ZExt(const Op0_t &Op0)
match_combine_or< AllUnaryRecipe_match< Op0_t, Instruction::ZExt >, AllUnaryRecipe_match< Op0_t, Instruction::SExt > > m_ZExtOrSExt(const Op0_t &Op0)
This is an optimization pass for GlobalISel generic memory operations.
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
BinaryRecipe_match(Op0_t Op0, Op1_t Op1)
bool match(const VPValue *V)
bool match(const VPRecipeBase *R)
bool match(const VPSingleDefRecipe *R)
bool match(const VPRecipeBase *R)
UnaryRecipe_match(Op0_t Op0)
bool match(const VPValue *V)
bool match(const VPRecipeBase *R)
bool match(const VPValue *V)
bool match(const VPValue *V)
bool match(const VPRecipeBase *R)
VPScalarIVSteps_match(Op0_t Op0, Op1_t Op1)
static bool match(const VPRecipeBase *R)
static bool match(const VPRecipeBase *R)
A helper to match an opcode against multiple recipe types.
match_combine_or(const LTy &Left, const RTy &Right)
Match a specified integer value or vector of all elements of that value.