15#ifndef LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPSHUFFLEANALYSIS_H
16#define LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPSHUFFLEANALYSIS_H
52 assert(
V &&
"V cannot be nullptr");
54 "V does not have FixedVectorType");
57 unsigned VNumElements =
59 assert(VNumElements > ScalarTyNumElements &&
60 "the number of elements of V is not large enough");
61 assert(VNumElements % ScalarTyNumElements == 0 &&
62 "the number of elements of V is not a vectorized value");
63 return VNumElements / ScalarTyNumElements;
71 int Limit = Mask.size();
83 if (Limit % VF == 0 &&
all_of(
seq<int>(0, Limit / VF), [=](
int Idx) {
99 unsigned VF = Mask.size();
101 for (
int I = 0, Sz = ExtMask.
size();
I < Sz; ++
I) {
104 int MaskedIdx = Mask[ExtMask[
I] % VF];
145 bool SinglePermute) {
158 if (!IdentityOp || !SinglePermute ||
161 IdentityMask.
size()))) {
166 IdentityMask.
assign(Mask);
186 if (SV->isZeroEltSplat()) {
188 IdentityMask.
assign(Mask);
190 int LocalVF = Mask.size();
193 LocalVF = SVOpTy->getNumElements();
198 static_cast<unsigned>(
P.value()) <
199 SV->getShuffleMask().size();
201 ExtMask[Idx] = SV->getMaskValue(
I);
210 if (!IsOp1Undef && !IsOp2Undef) {
214 if (SV->getMaskValue(
I % SV->getShuffleMask().size()) ==
222 Mask.swap(ShuffleMask);
224 Op = SV->getOperand(0);
226 Op = SV->getOperand(1);
234 "Expected masks of same sizes.");
239 Mask.swap(IdentityMask);
241 return SinglePermute &&
244 (Shuffle && Mask.size() == Shuffle->getShuffleMask().size() &&
245 Shuffle->isZeroEltSplat() &&
249 Shuffle->getShuffleMask()[
P.index()] == 0;
262 template <
typename T,
typename ShuffleBuilderTy,
typename... Args>
265 [[maybe_unused]]
bool ReVec, Args...
Arguments) {
266 assert(
V1 &&
"Expected at least one vector value.");
269 if (ScalarTyNumElements != 1) {
270 assert(ReVec &&
"FixedVectorType is not expected.");
275 Builder.resizeToMatch(
V1, V2);
276 int VF = Mask.size();
278 VF = FTy->getNumElements();
289 for (
int I = 0,
E = Mask.size();
I <
E; ++
I) {
291 CombinedMask1[
I] = Mask[
I];
293 CombinedMask2[
I] = Mask[
I] - VF;
311 ExtMask1[
P.index()] = SV1->getMaskValue(
P.value());
321 ExtMask2[
P.index()] = SV2->getMaskValue(
P.value());
326 if (SV1->getOperand(0)->getType() ==
327 SV2->getOperand(0)->getType() &&
328 SV1->getOperand(0)->getType() != SV1->getType() &&
335 Op1 = SV1->getOperand(0);
336 Op2 = SV2->getOperand(0);
338 int LocalVF = ShuffleMask1.
size();
340 LocalVF = FTy->getNumElements();
342 CombinedMask1.
swap(ShuffleMask1);
344 LocalVF = ShuffleMask2.
size();
346 LocalVF = FTy->getNumElements();
348 CombinedMask2.
swap(ShuffleMask2);
351 }
while (PrevOp1 != Op1 || PrevOp2 != Op2);
352 Builder.resizeToMatch(Op1, Op2);
358 .getKnownMinValue());
359 for (
int I = 0,
E = Mask.size();
I <
E; ++
I) {
362 "Expected undefined mask element");
363 CombinedMask1[
I] = CombinedMask2[
I] + (Op1 == Op2 ? 0 : VF);
372 return Builder.createIdentity(Op1);
373 return Builder.createShuffleVector(
378 return Builder.createPoison(
381 assert(
V1 &&
"Expected non-null value after looking through shuffles.");
384 return Builder.createShuffleVector(
V1, NewMask,
Arguments...);
385 return Builder.createIdentity(
V1);
416 assert(!ShuffleMask.empty() &&
"Empty list of shuffles for inserts.");
418 auto VMIt = std::next(ShuffleMask.begin());
425 if (!IsBasePoison.
all()) {
427 std::pair<T *, bool> Res =
428 ResizeAction(ShuffleMask.begin()->first, Mask,
false);
429 for (
unsigned Idx = 0, VF = Mask.size(); Idx < VF; ++Idx) {
433 Mask[Idx] = (Res.second ? Idx : Mask[Idx]) + VF;
435 if constexpr (std::is_same_v<T, Value>)
437 "Expected base vector of VF number of elements.");
438 Prev = Action(Mask, {
nullptr, Res.first});
439 }
else if (ShuffleMask.size() == 1) {
442 std::pair<T *, bool> Res = ResizeAction(ShuffleMask.begin()->first, Mask,
448 Prev = Action(Mask, {ShuffleMask.begin()->first});
452 unsigned Vec1VF = GetVF(ShuffleMask.begin()->first);
453 unsigned Vec2VF = GetVF(VMIt->first);
454 if (Vec1VF == Vec2VF) {
458 for (
unsigned I = 0, VF = Mask.size();
I < VF; ++
I) {
461 Mask[
I] = SecMask[
I] + Vec1VF;
464 Prev = Action(Mask, {ShuffleMask.begin()->first, VMIt->first});
467 std::pair<T *, bool> Res1 = ResizeAction(ShuffleMask.begin()->first, Mask,
469 std::pair<T *, bool> Res2 =
470 ResizeAction(VMIt->first, VMIt->second,
false);
472 for (
unsigned I = 0, VF = Mask.size();
I < VF; ++
I) {
479 Mask[
I] = (Res2.second ?
I : SecMask[
I]) + VF;
482 Prev = Action(Mask, {Res1.first, Res2.first});
484 VMIt = std::next(VMIt);
486 [[maybe_unused]]
bool IsBaseNotPoison = !IsBasePoison.
all();
488 for (
auto E = ShuffleMask.end(); VMIt !=
E; ++VMIt) {
490 std::pair<T *, bool> Res =
491 ResizeAction(VMIt->first, VMIt->second,
false);
493 for (
unsigned I = 0, VF = Mask.size();
I < VF; ++
I) {
496 "Multiple uses of scalars.");
497 Mask[
I] = (Res.second ?
I : SecMask[
I]) + VF;
502 Prev = Action(Mask, {Prev, Res.first});
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Provides some synthesis utilities to produce sequences of values.
This file implements the SmallBitVector class.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This instruction constructs a fixed permutation of two input vectors.
static LLVM_ABI bool isZeroEltSplatMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses all elements with the same value as the first element of exa...
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
static LLVM_ABI bool isExtractSubvectorMask(ArrayRef< int > Mask, int NumSrcElts, int &Index)
Return true if this shuffle mask is an extract subvector mask.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
bool all() const
Returns true if all bits are set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void swap(SmallVectorImpl &RHS)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
BaseShuffleAnalysis(Type *ScalarTy)
static bool isIdentityMask(ArrayRef< int > Mask, const FixedVectorType *VecTy, bool IsStrict)
Checks if the mask is an identity mask.
static void transformMaskAfterShuffle(MutableArrayRef< int > CommonMask, ArrayRef< int > Mask)
Transforms mask CommonMask per given Mask to make proper set after shuffle emission.
unsigned getVF(Value *V) const
V is expected to be a vectorized value.
static void combineMasks(unsigned LocalVF, SmallVectorImpl< int > &Mask, ArrayRef< int > ExtMask)
Tries to combine 2 different masks into single one.
static T createShuffle(Value *V1, Value *V2, ArrayRef< int > Mask, ShuffleBuilderTy &Builder, Type *ScalarTy, bool ReVec, Args... Arguments)
Smart shuffle instruction emission, walks through shuffles trees and tries to find the best matching ...
static bool peekThroughShuffles(Value *&V, SmallVectorImpl< int > &Mask, bool SinglePermute)
Looks through shuffles trying to reduce final number of shuffles in the code.
A private "module" namespace for types and utilities used by this pass.
template SmallBitVector isUndefVector< true >(const Value *, const SmallBitVector &)
SmallBitVector isUndefVector(const Value *V, const SmallBitVector &UseMask)
Checks if the given value is actually an undefined constant vector.
unsigned getNumElements(Type *Ty)
T * performExtractsShuffleAction(MutableArrayRef< std::pair< T *, SmallVector< int > > > ShuffleMask, Value *Base, function_ref< unsigned(T *)> GetVF, function_ref< std::pair< T *, bool >(T *, ArrayRef< int >, bool)> ResizeAction, function_ref< T *(ArrayRef< int >, ArrayRef< T * >)> Action)
Does the analysis of the provided shuffle masks and performs the requested actions on the vectors wit...
void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements, SmallVectorImpl< int > &Mask)
SmallBitVector buildUseMask(int VF, ArrayRef< int > Mask, UseMask MaskArg)
Prepares a use bitset for the given mask either for the first argument or for the second.
UseMask
Specifies the way the mask should be analyzed for undefs/poisonous elements in the shuffle mask.
@ SecondArg
The mask is expected to be for permutation of 2 vectors, check for the mask elements for the second a...
@ UndefsAsMask
Consider undef mask elements (-1) as placeholders for future shuffle elements and mark them as ones a...
@ FirstArg
The mask is expected to be for permutation of 1-2 vectors, check for the mask elements for the first ...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr int PoisonMaskElem
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.