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 auto *R = dyn_cast<VPRecipeBase>(U);
38 template <
typename ITy>
bool match(ITy *V)
const {
return isa<Class>(V); }
49 template <
typename ITy>
bool match(ITy *V)
const {
50 if (
auto *CV = dyn_cast<Class>(V)) {
83 const auto *CI = dyn_cast<ConstantInt>(V);
84 if (!CI && V->getType()->isVectorTy())
85 if (
const auto *
C = dyn_cast<Constant>(V))
86 CI = dyn_cast_or_null<ConstantInt>(
87 C->getSplatValue(
false));
112 template <
typename ITy>
bool match(ITy *V)
const {
121template <
typename LTy,
typename RTy>
134template <
unsigned Opcode,
typename RecipeTy>
137 auto *DefR = dyn_cast<RecipeTy>(R);
139 if constexpr (std::is_same<RecipeTy, VPScalarIVStepsRecipe>::value ||
140 std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value ||
141 std::is_same<RecipeTy, VPWidenSelectRecipe>::value ||
142 std::is_same<RecipeTy, VPDerivedIVRecipe>::value)
145 return DefR && DefR->getOpcode() == Opcode;
149template <
unsigned Opcode,
typename RecipeTy,
typename... RecipeTys>
156template <
typename TupleTy,
typename Fn, std::size_t... Is>
158 return (
P(std::get<Is>(Ops), Is) && ...);
162template <
typename TupleTy,
typename Fn>
165 Ops,
P, std::make_index_sequence<std::tuple_size<TupleTy>::value>{});
169template <
typename Ops_t,
unsigned Opcode,
bool Commutative,
170 typename... RecipeTys>
175 static_assert(std::tuple_size<Ops_t>::value == 0 &&
176 "constructor can only be used with zero operands");
179 template <
typename A_t,
typename B_t>
181 static_assert(std::tuple_size<Ops_t>::value == 2 &&
182 "constructor can only be used for binary matcher");
186 auto *DefR = V->getDefiningRecipe();
187 return DefR &&
match(DefR);
197 assert(R->getNumOperands() == std::tuple_size<Ops_t>::value &&
198 "recipe with matched opcode the expected number of operands");
201 return Op.match(R->getOperand(
Idx));
205 return Commutative &&
207 return Op.match(R->getOperand(R->getNumOperands() -
Idx - 1));
212template <
typename Op0_t,
unsigned Opcode,
typename... RecipeTys>
216template <
typename Op0_t,
unsigned Opcode>
220template <
typename Op0_t,
unsigned Opcode>
225template <
typename Op0_t,
typename Op1_t,
unsigned Opcode,
bool Commutative,
226 typename... RecipeTys>
230template <
typename Op0_t,
typename Op1_t,
unsigned Opcode>
235template <
typename Op0_t,
typename Op1_t,
unsigned Opcode,
236 bool Commutative =
false>
241template <
unsigned Opcode,
typename Op0_t>
247template <
unsigned Opcode,
typename Op0_t,
typename Op1_t>
248inline BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>
253template <
typename Op0_t>
254inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
256 return m_VPInstruction<VPInstruction::Not>(Op0);
259template <
typename Op0_t>
260inline UnaryVPInstruction_match<Op0_t, VPInstruction::BranchOnCond>
262 return m_VPInstruction<VPInstruction::BranchOnCond>(Op0);
265template <
typename Op0_t,
typename Op1_t>
266inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::ActiveLaneMask>
268 return m_VPInstruction<VPInstruction::ActiveLaneMask>(Op0, Op1);
271template <
typename Op0_t,
typename Op1_t>
272inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::BranchOnCount>
274 return m_VPInstruction<VPInstruction::BranchOnCount>(Op0, Op1);
277template <
unsigned Opcode,
typename Op0_t>
282template <
typename Op0_t>
283inline AllUnaryRecipe_match<Op0_t, Instruction::Trunc>
285 return m_Unary<Instruction::Trunc, Op0_t>(Op0);
288template <
typename Op0_t>
290 return m_Unary<Instruction::ZExt, Op0_t>(Op0);
293template <
typename Op0_t>
295 return m_Unary<Instruction::SExt, Op0_t>(Op0);
298template <
typename Op0_t>
300 AllUnaryRecipe_match<Op0_t, Instruction::SExt>>
305template <
unsigned Opcode,
typename Op0_t,
typename Op1_t,
306 bool Commutative =
false>
307inline AllBinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative>
312template <
typename Op0_t,
typename Op1_t>
313inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Mul>
314m_Mul(
const Op0_t &Op0,
const Op1_t &Op1) {
315 return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1);
318template <
typename Op0_t,
typename Op1_t>
322 return m_Binary<Instruction::Mul, Op0_t, Op1_t, true>(Op0, Op1);
329template <
typename Op0_t,
typename Op1_t,
bool Commutative = false>
330inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or, Commutative>
332 return m_Binary<Instruction::Or, Op0_t, Op1_t, Commutative>(Op0, Op1);
335template <
typename Op0_t,
typename Op1_t>
339 return m_BinaryOr<Op0_t, Op1_t,
true>(Op0, Op1);
342template <
typename Op0_t,
typename Op1_t,
typename Op2_t,
unsigned Opcode>
347template <
typename Op0_t,
typename Op1_t,
typename Op2_t>
349m_Select(
const Op0_t &Op0,
const Op1_t &Op1,
const Op2_t &Op2) {
354template <
typename Op0_t,
typename Op1_t>
356 BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::LogicalAnd>,
357 AllTernaryRecipe_match<Op0_t, Op1_t, specific_intval<1>,
358 Instruction::Select>>
361 m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1),
365template <
typename Op0_t,
typename Op1_t>
366inline AllTernaryRecipe_match<Op0_t, specific_intval<1>, Op1_t,
379template <
typename Op0_t,
typename Op1_t>
383template <
typename Op0_t,
typename Op1_t>
389template <
typename Op0_t,
typename Op1_t,
typename Op2_t>
393template <
typename Op0_t,
typename Op1_t,
typename Op2_t>
395m_DerivedIV(
const Op0_t &Op0,
const Op1_t &Op1,
const Op2_t &Op2) {
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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 class represents an Operation in the Expression.
Canonical scalar induction phi of the vector loop.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
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...
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
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_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
bool CheckTupleElements(const TupleTy &Ops, Fn P, std::index_sequence< Is... >)
bool all_of_tuple_elements(const TupleTy &Ops, Fn P)
Helper to check if predicate P holds on all tuple elements in Ops.
AllBinaryRecipe_match< Op0_t, Op1_t, Instruction::Or, Commutative > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR operation.
AllTernaryRecipe_match< Op0_t, Op1_t, Op2_t, Instruction::Select > m_Select(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
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)
specificval_ty m_Specific(const VPValue *VPV)
specific_intval< 1 > m_False()
VPDerivedIV_match< Op0_t, Op1_t, Op2_t > m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
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)
specific_intval< 1 > m_True()
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)
Recipe_match< std::tuple<>, 0, false, VPCanonicalIVPHIRecipe > VPCanonicalIVPHI_match
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.
A recipe for widening select instructions.
bool match(const VPSingleDefRecipe *R) const
bool match(const VPValue *V) const
Recipe_match(A_t A, B_t B)
bool match(const VPRecipeBase *R) const
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.
bool match(VPValue *VPV) const
Match a specified VPValue.
specificval_ty(const VPValue *V)
bool match(VPValue *VPV) const