summaryrefslogtreecommitdiff
path: root/include/llvm/Analysis/VectorUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Analysis/VectorUtils.h')
-rw-r--r--include/llvm/Analysis/VectorUtils.h144
1 files changed, 126 insertions, 18 deletions
diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h
index d93d2bc4570b..4a61c2bc35c7 100644
--- a/include/llvm/Analysis/VectorUtils.h
+++ b/include/llvm/Analysis/VectorUtils.h
@@ -15,18 +15,129 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/CheckedArithmetic.h"
namespace llvm {
+/// Describes the type of Parameters
+enum class VFParamKind {
+ Vector, // No semantic information.
+ OMP_Linear, // declare simd linear(i)
+ OMP_LinearRef, // declare simd linear(ref(i))
+ OMP_LinearVal, // declare simd linear(val(i))
+ OMP_LinearUVal, // declare simd linear(uval(i))
+ OMP_LinearPos, // declare simd linear(i:c) uniform(c)
+ OMP_LinearValPos, // declare simd linear(val(i:c)) uniform(c)
+ OMP_LinearRefPos, // declare simd linear(ref(i:c)) uniform(c)
+ OMP_LinearUValPos, // declare simd linear(uval(i:c)) uniform(c
+ OMP_Uniform, // declare simd uniform(i)
+ GlobalPredicate, // Global logical predicate that acts on all lanes
+ // of the input and output mask concurrently. For
+ // example, it is implied by the `M` token in the
+ // Vector Function ABI mangled name.
+ Unknown
+};
+
+/// Describes the type of Instruction Set Architecture
+enum class VFISAKind {
+ AdvancedSIMD, // AArch64 Advanced SIMD (NEON)
+ SVE, // AArch64 Scalable Vector Extension
+ SSE, // x86 SSE
+ AVX, // x86 AVX
+ AVX2, // x86 AVX2
+ AVX512, // x86 AVX512
+ Unknown // Unknown ISA
+};
+
+/// Encapsulates information needed to describe a parameter.
+///
+/// The description of the parameter is not linked directly to
+/// OpenMP or any other vector function description. This structure
+/// is extendible to handle other paradigms that describe vector
+/// functions and their parameters.
+struct VFParameter {
+ unsigned ParamPos; // Parameter Position in Scalar Function.
+ VFParamKind ParamKind; // Kind of Parameter.
+ int LinearStepOrPos = 0; // Step or Position of the Parameter.
+ Align Alignment = Align(); // Optional aligment in bytes, defaulted to 1.
+
+ // Comparison operator.
+ bool operator==(const VFParameter &Other) const {
+ return std::tie(ParamPos, ParamKind, LinearStepOrPos, Alignment) ==
+ std::tie(Other.ParamPos, Other.ParamKind, Other.LinearStepOrPos,
+ Other.Alignment);
+ }
+};
+
+/// Contains the information about the kind of vectorization
+/// available.
+///
+/// This object in independent on the paradigm used to
+/// represent vector functions. in particular, it is not attached to
+/// any target-specific ABI.
+struct VFShape {
+ unsigned VF; // Vectorization factor.
+ bool IsScalable; // True if the function is a scalable function.
+ VFISAKind ISA; // Instruction Set Architecture.
+ SmallVector<VFParameter, 8> Parameters; // List of parameter informations.
+ // Comparison operator.
+ bool operator==(const VFShape &Other) const {
+ return std::tie(VF, IsScalable, ISA, Parameters) ==
+ std::tie(Other.VF, Other.IsScalable, Other.ISA, Other.Parameters);
+ }
+};
+
+/// Holds the VFShape for a specific scalar to vector function mapping.
+struct VFInfo {
+ VFShape Shape; // Classification of the vector function.
+ StringRef ScalarName; // Scalar Function Name.
+ StringRef VectorName; // Vector Function Name associated to this VFInfo.
+
+ // Comparison operator.
+ bool operator==(const VFInfo &Other) const {
+ return std::tie(Shape, ScalarName, VectorName) ==
+ std::tie(Shape, Other.ScalarName, Other.VectorName);
+ }
+};
+
+namespace VFABI {
+/// Function to contruct a VFInfo out of a mangled names in the
+/// following format:
+///
+/// <VFABI_name>{(<redirection>)}
+///
+/// where <VFABI_name> is the name of the vector function, mangled according
+/// to the rules described in the Vector Function ABI of the target vector
+/// extentsion (or <isa> from now on). The <VFABI_name> is in the following
+/// format:
+///
+/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
+///
+/// This methods support demangling rules for the following <isa>:
+///
+/// * AArch64: https://developer.arm.com/docs/101129/latest
+///
+/// * x86 (libmvec): https://sourceware.org/glibc/wiki/libmvec and
+/// https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt
+///
+///
+///
+/// \param MangledName -> input string in the format
+/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
+Optional<VFInfo> tryDemangleForVFABI(StringRef MangledName);
+
+/// Retrieve the `VFParamKind` from a string token.
+VFParamKind getVFParamKindFromString(const StringRef Token);
+} // end namespace VFABI
+
template <typename T> class ArrayRef;
class DemandedBits;
class GetElementPtrInst;
template <typename InstTy> class InterleaveGroup;
class Loop;
class ScalarEvolution;
+class TargetLibraryInfo;
class TargetTransformInfo;
class Type;
class Value;
@@ -270,13 +381,12 @@ APInt possiblyDemandedEltsInMask(Value *Mask);
/// the interleaved store group doesn't allow gaps.
template <typename InstTy> class InterleaveGroup {
public:
- InterleaveGroup(uint32_t Factor, bool Reverse, uint32_t Align)
- : Factor(Factor), Reverse(Reverse), Align(Align), InsertPos(nullptr) {}
-
- InterleaveGroup(InstTy *Instr, int32_t Stride, uint32_t Align)
- : Align(Align), InsertPos(Instr) {
- assert(Align && "The alignment should be non-zero");
+ InterleaveGroup(uint32_t Factor, bool Reverse, Align Alignment)
+ : Factor(Factor), Reverse(Reverse), Alignment(Alignment),
+ InsertPos(nullptr) {}
+ InterleaveGroup(InstTy *Instr, int32_t Stride, Align Alignment)
+ : Alignment(Alignment), InsertPos(Instr) {
Factor = std::abs(Stride);
assert(Factor > 1 && "Invalid interleave factor");
@@ -286,7 +396,7 @@ public:
bool isReverse() const { return Reverse; }
uint32_t getFactor() const { return Factor; }
- uint32_t getAlignment() const { return Align; }
+ uint32_t getAlignment() const { return Alignment.value(); }
uint32_t getNumMembers() const { return Members.size(); }
/// Try to insert a new member \p Instr with index \p Index and
@@ -294,9 +404,7 @@ public:
/// negative if it is the new leader.
///
/// \returns false if the instruction doesn't belong to the group.
- bool insertMember(InstTy *Instr, int32_t Index, uint32_t NewAlign) {
- assert(NewAlign && "The new member's alignment should be non-zero");
-
+ bool insertMember(InstTy *Instr, int32_t Index, Align NewAlign) {
// Make sure the key fits in an int32_t.
Optional<int32_t> MaybeKey = checkedAdd(Index, SmallestKey);
if (!MaybeKey)
@@ -328,7 +436,7 @@ public:
}
// It's always safe to select the minimum alignment.
- Align = std::min(Align, NewAlign);
+ Alignment = std::min(Alignment, NewAlign);
Members[Key] = Instr;
return true;
}
@@ -387,7 +495,7 @@ public:
private:
uint32_t Factor; // Interleave Factor.
bool Reverse;
- uint32_t Align;
+ Align Alignment;
DenseMap<int32_t, InstTy *> Members;
int32_t SmallestKey = 0;
int32_t LargestKey = 0;
@@ -504,8 +612,8 @@ private:
struct StrideDescriptor {
StrideDescriptor() = default;
StrideDescriptor(int64_t Stride, const SCEV *Scev, uint64_t Size,
- unsigned Align)
- : Stride(Stride), Scev(Scev), Size(Size), Align(Align) {}
+ Align Alignment)
+ : Stride(Stride), Scev(Scev), Size(Size), Alignment(Alignment) {}
// The access's stride. It is negative for a reverse access.
int64_t Stride = 0;
@@ -517,7 +625,7 @@ private:
uint64_t Size = 0;
// The alignment of this access.
- unsigned Align = 0;
+ Align Alignment;
};
/// A type for holding instructions and their stride descriptors.
@@ -528,11 +636,11 @@ private:
///
/// \returns the newly created interleave group.
InterleaveGroup<Instruction> *
- createInterleaveGroup(Instruction *Instr, int Stride, unsigned Align) {
+ createInterleaveGroup(Instruction *Instr, int Stride, Align Alignment) {
assert(!InterleaveGroupMap.count(Instr) &&
"Already in an interleaved access group");
InterleaveGroupMap[Instr] =
- new InterleaveGroup<Instruction>(Instr, Stride, Align);
+ new InterleaveGroup<Instruction>(Instr, Stride, Alignment);
InterleaveGroups.insert(InterleaveGroupMap[Instr]);
return InterleaveGroupMap[Instr];
}