13#ifndef LLVM_ANALYSIS_VECTORUTILS_H
14#define LLVM_ANALYSIS_VECTORUTILS_H
46 static void getVFABIMappings(
const CallInst &CI,
48 if (!CI.getCalledFunction())
51 const StringRef ScalarName = CI.getCalledFunction()->getName();
57 if (ListOfStrings.
empty())
59 for (
const auto &MangledName : ListOfStrings) {
60 const std::optional<VFInfo> Shape =
66 if (Shape && (Shape->ScalarName == ScalarName)) {
67 assert(CI.getModule()->getFunction(Shape->VectorName) &&
68 "Vector function is missing.");
80 getVFABIMappings(CI, Ret);
88 std::optional<ElementCount> VF = std::nullopt) {
93 for (
VFInfo Info : Mappings)
94 if (!VF || Info.Shape.VF == *VF)
103 : M(CI.getModule()), CI(CI),
112 return CI.getCalledFunction();
114 for (
const auto &Info : ScalarToVectorMappings)
115 if (Info.Shape == Shape)
123template <
typename T>
class ArrayRef;
125template <
typename InstTy>
class InterleaveGroup;
128class TargetTransformInfo;
219 const APInt &DemandedElts,
221 bool AllowUndefElts =
false);
230 std::array<std::pair<int, int>, 2> &SrcInfo);
297 ArrayRef<int> Mask,
unsigned NumOfSrcRegs,
unsigned NumOfDestRegs,
298 unsigned NumOfUsedRegs,
function_ref<
void()> NoInputAction,
316 const APInt &DemandedElts,
528 : Factor(Factor), Reverse(Reverse), Alignment(Alignment),
529 InsertPos(nullptr) {}
532 : Alignment(Alignment), InsertPos(Instr) {
533 Factor = std::abs(Stride);
534 assert(Factor > 1 &&
"Invalid interleave factor");
536 Reverse = Stride < 0;
552 std::optional<int32_t> MaybeKey =
checkedAdd(Index, SmallestKey);
555 int32_t
Key = *MaybeKey;
563 if (Members.contains(
Key))
566 if (
Key > LargestKey) {
568 if (Index >=
static_cast<int32_t
>(Factor))
572 }
else if (
Key < SmallestKey) {
575 std::optional<int32_t> MaybeLargestIndex =
checkedSub(LargestKey,
Key);
576 if (!MaybeLargestIndex)
580 if (*MaybeLargestIndex >=
static_cast<int64_t
>(Factor))
587 Alignment = std::min(Alignment, NewAlign);
588 Members[
Key] = Instr;
596 int32_t
Key = SmallestKey + Index;
597 return Members.lookup(
Key);
606 [](InstTy *
I) {
return I !=
nullptr; });
612 for (
auto I : Members) {
613 if (
I.second == Instr)
614 return I.first - SmallestKey;
654 int32_t SmallestKey = 0;
655 int32_t LargestKey = 0;
684 : PSE(PSE), TheLoop(L), DT(DT), LI(LI), LAI(LAI) {}
700 if (InterleaveGroups.empty()) {
702 !RequiresScalarEpilogue &&
703 "RequiresScalarEpilog should not be set without interleave groups");
707 InterleaveGroupMap.clear();
708 for (
auto *Ptr : InterleaveGroups)
710 InterleaveGroups.clear();
711 RequiresScalarEpilogue =
false;
717 return InterleaveGroupMap.contains(Instr);
725 return InterleaveGroupMap.lookup(Instr);
730 return make_range(InterleaveGroups.begin(), InterleaveGroups.end());
743 bool hasGroups()
const {
return !InterleaveGroups.empty(); }
760 bool RequiresScalarEpilogue =
false;
772 struct StrideDescriptor {
773 StrideDescriptor() =
default;
776 : Stride(Stride), Scev(Scev),
Size(
Size), Alignment(Alignment) {}
782 const SCEV *Scev =
nullptr;
792 using StrideEntry = std::pair<Instruction *, StrideDescriptor>;
798 InterleaveGroup<Instruction> *
799 createInterleaveGroup(Instruction *Instr,
int Stride, Align Alignment) {
800 auto [It,
Inserted] = InterleaveGroupMap.try_emplace(Instr);
801 assert(Inserted &&
"Already in an interleaved access group");
802 It->second =
new InterleaveGroup<Instruction>(Instr, Stride, Alignment);
803 InterleaveGroups.insert(It->second);
808 void releaseGroup(InterleaveGroup<Instruction> *Group) {
809 InterleaveGroups.erase(Group);
810 releaseGroupWithoutRemovingFromSet(Group);
815 void releaseGroupWithoutRemovingFromSet(InterleaveGroup<Instruction> *Group) {
816 for (
unsigned i = 0; i < Group->getFactor(); i++)
817 if (Instruction *Member = Group->getMember(i))
818 InterleaveGroupMap.erase(Member);
824 void collectConstStrideAccesses(
825 MapVector<Instruction *, StrideDescriptor> &AccessStrideInfo,
826 const DenseMap<Value *, const SCEV *> &Strides);
829 LLVM_ABI static bool isStrided(
int Stride);
832 bool isPredicated(BasicBlock *BB)
const {
837 bool areDependencesValid()
const {
838 return LAI && LAI->getDepChecker().getDependences();
846 bool canReorderMemAccessesForInterleavedGroups(StrideEntry *
A,
847 StrideEntry *
B)
const {
863 auto *Src =
A->first;
864 auto SrcDes =
A->second;
867 auto *
Sink =
B->first;
868 auto SinkDes =
B->second;
872 if (!Src->mayWriteToMemory())
876 if (!isStrided(SrcDes.Stride) && !isStrided(SinkDes.Stride))
881 if (!areDependencesValid())
886 return !Dependences.contains(Src) || !Dependences.lookup(Src).count(Sink);
893 void collectDependences() {
894 if (!areDependencesValid())
896 const auto &DepChecker = LAI->getDepChecker();
897 auto *Deps = DepChecker.getDependences();
898 for (
auto Dep : *Deps)
899 Dependences[Dep.getSource(DepChecker)].insert(
900 Dep.getDestination(DepChecker));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
This file implements a map that provides insertion order iteration.
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallVector class.
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
const Function & getFunction() const
Common base class shared among various IRBuilders.
The group of interleaved loads/stores sharing the same stride and close to each other.
auto members() const
Return an iterator range over the non-null members of this group, in index order.
bool requiresScalarEpilogue() const
Returns true if this Group requires a scalar iteration to handle gaps.
uint32_t getFactor() const
InstTy * getMember(uint32_t Index) const
Get the member with the given index Index.
InterleaveGroup(uint32_t Factor, bool Reverse, Align Alignment)
bool isFull() const
Return true if this group is full, i.e. it has no gaps.
uint32_t getIndex(const InstTy *Instr) const
Get the index for the given member.
void setInsertPos(InstTy *Inst)
InstTy * getInsertPos() const
void addMetadata(InstTy *NewInst) const
Add metadata (e.g.
InterleaveGroup(InstTy *Instr, int32_t Stride, Align Alignment)
bool insertMember(InstTy *Instr, int32_t Index, Align NewAlign)
Try to insert a new member Instr with index Index and alignment NewAlign.
uint32_t getNumMembers() const
InterleaveGroup< Instruction > * getInterleaveGroup(const Instruction *Instr) const
Get the interleave group that Instr belongs to.
bool requiresScalarEpilogue() const
Returns true if an interleaved group that may access memory out-of-bounds requires a scalar epilogue ...
bool hasGroups() const
Returns true if we have any interleave groups.
bool isInterleaved(Instruction *Instr) const
Check if Instr belongs to any interleave group.
bool invalidateGroups()
Invalidate groups, e.g., in case all blocks in loop will be predicated contrary to original assumptio...
iterator_range< SmallPtrSetIterator< llvm::InterleaveGroup< Instruction > * > > getInterleaveGroups()
LLVM_ABI void analyzeInterleaving(bool EnableMaskedInterleavedGroup)
Analyze the interleaved accesses and collect them in interleave groups.
LLVM_ABI void invalidateGroupsRequiringScalarEpilogue()
Invalidate groups that require a scalar epilogue (due to gaps).
InterleavedAccessInfo(PredicatedScalarEvolution &PSE, Loop *L, DominatorTree *DT, LoopInfo *LI, const LoopAccessInfo *LAI)
A wrapper class for inspecting calls to intrinsic functions.
Drive the analysis of memory accesses in the loop.
static LLVM_ABI bool blockNeedsPredication(const BasicBlock *BB, const Loop *TheLoop, const DominatorTree *DT)
Return true if the block BB needs to be predicated in order for the loop to be vectorized.
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
A Module instance is used to store all the information related to an LLVM module.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
This class represents an analyzed expression in the program.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Provides information about what library functions are available for the current target.
VFDatabase(CallInst &CI)
Constructor, requires a CallInst instance.
static bool hasMaskedVariant(const CallInst &CI, std::optional< ElementCount > VF=std::nullopt)
static SmallVector< VFInfo, 8 > getMappings(const CallInst &CI)
Retrieve all the VFInfo instances associated to the CallInst CI.
LLVM Value Representation.
Base class of all SIMD vector types.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
Function * getVectorizedFunction(const VFShape &Shape) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
LLVM_ABI std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
LLVM_ABI void getVectorVariantNames(const CallInst &CI, SmallVectorImpl< std::string > &VariantMappings)
Populates a set of strings representing the Vector Function ABI variants associated to the CallInst C...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
LLVM_ABI APInt possiblyDemandedEltsInMask(Value *Mask)
Given a mask vector of the form <Y x i1>, return an APInt (of bitwidth Y) for each lane which may be ...
LLVM_ABI llvm::SmallVector< int, 16 > createUnaryMask(ArrayRef< int > Mask, unsigned NumElts)
Given a shuffle mask for a binary shuffle, create the equivalent shuffle mask assuming both operands ...
LLVM_ABI void getMetadataToPropagate(Instruction *Inst, SmallVectorImpl< std::pair< unsigned, MDNode * > > &Metadata)
Add metadata from Inst to Metadata, if it can be preserved after vectorization.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI Value * concatenateVectors(IRBuilderBase &Builder, ArrayRef< Value * > Vecs)
Concatenate a list of vectors.
LLVM_ABI bool widenShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Try to transform a shuffle mask by replacing elements with the scaled index for an equivalent mask of...
LLVM_ABI Instruction * propagateMetadata(Instruction *I, ArrayRef< Value * > VL)
Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath, MD_nontemporal,...
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
LLVM_ABI MDNode * intersectAccessGroups(const Instruction *Inst1, const Instruction *Inst2)
Compute the access-group list of access groups that Inst1 and Inst2 are both in.
LLVM_ABI bool getShuffleDemandedElts(int SrcWidth, ArrayRef< int > Mask, const APInt &DemandedElts, APInt &DemandedLHS, APInt &DemandedRHS, bool AllowUndefElts=false)
Transform a shuffle mask's output demanded element mask into demanded element masks for the 2 operand...
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI Constant * createBitMaskForGaps(IRBuilderBase &Builder, unsigned VF, const InterleaveGroup< Instruction > &Group)
Create a mask that filters the members of an interleave group where there are gaps.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
LLVM_ABI void getHorizDemandedEltsForFirstOperand(unsigned VectorBitWidth, const APInt &DemandedElts, APInt &DemandedLHS, APInt &DemandedRHS)
Compute the demanded elements mask of horizontal binary operations.
LLVM_ABI llvm::SmallVector< int, 16 > createReplicatedMask(unsigned ReplicationFactor, unsigned VF)
Create a mask with replicated elements.
LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
LLVM_ABI unsigned getInterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.interleaveN intrinsics.
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...
LLVM_ABI bool maskIsAllOneOrUndef(Value *Mask)
Given a mask vector of i1, Return true if all of the elements of this predicate mask are known to be ...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isTriviallyScalarizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially scalarizable.
LLVM_ABI bool isVectorIntrinsicWithStructReturnOverloadAtField(Intrinsic::ID ID, int RetIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic that returns a struct is overloaded at the struct elem...
LLVM_ABI void narrowShuffleMaskElts(int Scale, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Replace each shuffle mask index with the scaled sequential indices for an equivalent mask of narrowed...
LLVM_ABI bool isMaskedSlidePair(ArrayRef< int > Mask, int NumElts, std::array< std::pair< int, int >, 2 > &SrcInfo)
Does this shuffle mask represent either one slide shuffle or a pair of two slide shuffles,...
LLVM_ABI VectorType * getDeinterleavedVectorType(IntrinsicInst *DI)
Given a deinterleaveN intrinsic, return the (narrow) vector type of each factor.
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
LLVM_ABI bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
LLVM_ABI Value * findScalarElement(Value *V, unsigned EltNo)
Given a vector and an element number, see if the scalar value is already around as a register,...
LLVM_ABI MDNode * uniteAccessGroups(MDNode *AccGroups1, MDNode *AccGroups2)
Compute the union of two access-group lists.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool maskIsAllZeroOrUndef(Value *Mask)
Given a mask vector of i1, Return true if all of the elements of this predicate mask are known to be ...
std::enable_if_t< std::is_signed_v< T >, std::optional< T > > checkedSub(T LHS, T RHS)
Subtract two signed integers LHS and RHS.
LLVM_ABI void getShuffleMaskWithWidestElts(ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Repetitively apply widenShuffleMaskElts() for as long as it succeeds, to get the shuffle mask with wi...
std::enable_if_t< std::is_signed_v< T >, std::optional< T > > checkedAdd(T LHS, T RHS)
Add two signed integers LHS and RHS.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
LLVM_ABI bool maskContainsAllOneOrUndef(Value *Mask)
Given a mask vector of i1, Return true if any of the elements of this predicate mask are known to be ...
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
LLVM_ABI llvm::SmallVector< int, 16 > createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs)
Create a sequential shuffle mask.
LLVM_ABI bool isVectorIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID, int OpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic is overloaded on the type of the operand at index OpdI...
LLVM_ABI MapVector< Instruction *, uint64_t > computeMinimumValueSizes(ArrayRef< BasicBlock * > Blocks, DemandedBits &DB, const TargetTransformInfo *TTI=nullptr)
Compute a map of integer instructions to their minimum legal type size.
LLVM_ABI bool scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef< int > Mask, SmallVectorImpl< int > &ScaledMask)
Attempt to narrow/widen the Mask shuffle mask to the NumDstElts target width.
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
An information struct used to provide DenseMap with the various necessary components for a given valu...
Holds the VFShape for a specific scalar to vector function mapping.
Contains the information about the kind of vectorization available.
static VFShape getScalarShape(const FunctionType *FTy)
Retrieve the VFShape that can be used to map a scalar function to itself, with VF = 1.