|
16 | 16 | #include "llvm/ADT/MapVector.h"
|
17 | 17 | #include "llvm/ADT/SmallVector.h"
|
18 | 18 | #include "llvm/Analysis/LoopAccessAnalysis.h"
|
| 19 | +#include "llvm/IR/VFABIDemangler.h" |
19 | 20 | #include "llvm/Support/CheckedArithmetic.h"
|
20 | 21 |
|
21 | 22 | namespace llvm {
|
22 | 23 | class TargetLibraryInfo;
|
23 | 24 |
|
24 |
| -/// Describes the type of Parameters |
25 |
| -enum class VFParamKind { |
26 |
| - Vector, // No semantic information. |
27 |
| - OMP_Linear, // declare simd linear(i) |
28 |
| - OMP_LinearRef, // declare simd linear(ref(i)) |
29 |
| - OMP_LinearVal, // declare simd linear(val(i)) |
30 |
| - OMP_LinearUVal, // declare simd linear(uval(i)) |
31 |
| - OMP_LinearPos, // declare simd linear(i:c) uniform(c) |
32 |
| - OMP_LinearValPos, // declare simd linear(val(i:c)) uniform(c) |
33 |
| - OMP_LinearRefPos, // declare simd linear(ref(i:c)) uniform(c) |
34 |
| - OMP_LinearUValPos, // declare simd linear(uval(i:c)) uniform(c) |
35 |
| - OMP_Uniform, // declare simd uniform(i) |
36 |
| - GlobalPredicate, // Global logical predicate that acts on all lanes |
37 |
| - // of the input and output mask concurrently. For |
38 |
| - // example, it is implied by the `M` token in the |
39 |
| - // Vector Function ABI mangled name. |
40 |
| - Unknown |
41 |
| -}; |
42 |
| - |
43 |
| -/// Describes the type of Instruction Set Architecture |
44 |
| -enum class VFISAKind { |
45 |
| - AdvancedSIMD, // AArch64 Advanced SIMD (NEON) |
46 |
| - SVE, // AArch64 Scalable Vector Extension |
47 |
| - SSE, // x86 SSE |
48 |
| - AVX, // x86 AVX |
49 |
| - AVX2, // x86 AVX2 |
50 |
| - AVX512, // x86 AVX512 |
51 |
| - LLVM, // LLVM internal ISA for functions that are not |
52 |
| - // attached to an existing ABI via name mangling. |
53 |
| - Unknown // Unknown ISA |
54 |
| -}; |
55 |
| - |
56 |
| -/// Encapsulates information needed to describe a parameter. |
57 |
| -/// |
58 |
| -/// The description of the parameter is not linked directly to |
59 |
| -/// OpenMP or any other vector function description. This structure |
60 |
| -/// is extendible to handle other paradigms that describe vector |
61 |
| -/// functions and their parameters. |
62 |
| -struct VFParameter { |
63 |
| - unsigned ParamPos; // Parameter Position in Scalar Function. |
64 |
| - VFParamKind ParamKind; // Kind of Parameter. |
65 |
| - int LinearStepOrPos = 0; // Step or Position of the Parameter. |
66 |
| - Align Alignment = Align(); // Optional alignment in bytes, defaulted to 1. |
67 |
| - |
68 |
| - // Comparison operator. |
69 |
| - bool operator==(const VFParameter &Other) const { |
70 |
| - return std::tie(ParamPos, ParamKind, LinearStepOrPos, Alignment) == |
71 |
| - std::tie(Other.ParamPos, Other.ParamKind, Other.LinearStepOrPos, |
72 |
| - Other.Alignment); |
73 |
| - } |
74 |
| -}; |
75 |
| - |
76 |
| -/// Contains the information about the kind of vectorization |
77 |
| -/// available. |
78 |
| -/// |
79 |
| -/// This object in independent on the paradigm used to |
80 |
| -/// represent vector functions. in particular, it is not attached to |
81 |
| -/// any target-specific ABI. |
82 |
| -struct VFShape { |
83 |
| - ElementCount VF; // Vectorization factor. |
84 |
| - SmallVector<VFParameter, 8> Parameters; // List of parameter information. |
85 |
| - // Comparison operator. |
86 |
| - bool operator==(const VFShape &Other) const { |
87 |
| - return std::tie(VF, Parameters) == std::tie(Other.VF, Other.Parameters); |
88 |
| - } |
89 |
| - |
90 |
| - /// Update the parameter in position P.ParamPos to P. |
91 |
| - void updateParam(VFParameter P) { |
92 |
| - assert(P.ParamPos < Parameters.size() && "Invalid parameter position."); |
93 |
| - Parameters[P.ParamPos] = P; |
94 |
| - assert(hasValidParameterList() && "Invalid parameter list"); |
95 |
| - } |
96 |
| - |
97 |
| - /// Retrieve the VFShape that can be used to map a scalar function to itself, |
98 |
| - /// with VF = 1. |
99 |
| - static VFShape getScalarShape(const FunctionType *FTy) { |
100 |
| - return VFShape::get(FTy, ElementCount::getFixed(1), |
101 |
| - /*HasGlobalPredicate*/ false); |
102 |
| - } |
103 |
| - |
104 |
| - /// Retrieve the basic vectorization shape of the function, where all |
105 |
| - /// parameters are mapped to VFParamKind::Vector with \p EC lanes. Specifies |
106 |
| - /// whether the function has a Global Predicate argument via \p HasGlobalPred. |
107 |
| - static VFShape get(const FunctionType *FTy, ElementCount EC, |
108 |
| - bool HasGlobalPred) { |
109 |
| - SmallVector<VFParameter, 8> Parameters; |
110 |
| - for (unsigned I = 0; I < FTy->getNumParams(); ++I) |
111 |
| - Parameters.push_back(VFParameter({I, VFParamKind::Vector})); |
112 |
| - if (HasGlobalPred) |
113 |
| - Parameters.push_back( |
114 |
| - VFParameter({FTy->getNumParams(), VFParamKind::GlobalPredicate})); |
115 |
| - |
116 |
| - return {EC, Parameters}; |
117 |
| - } |
118 |
| - /// Validation check on the Parameters in the VFShape. |
119 |
| - bool hasValidParameterList() const; |
120 |
| -}; |
121 |
| - |
122 |
| -/// Holds the VFShape for a specific scalar to vector function mapping. |
123 |
| -struct VFInfo { |
124 |
| - VFShape Shape; /// Classification of the vector function. |
125 |
| - std::string ScalarName; /// Scalar Function Name. |
126 |
| - std::string VectorName; /// Vector Function Name associated to this VFInfo. |
127 |
| - VFISAKind ISA; /// Instruction Set Architecture. |
128 |
| - |
129 |
| - /// Returns the index of the first parameter with the kind 'GlobalPredicate', |
130 |
| - /// if any exist. |
131 |
| - std::optional<unsigned> getParamIndexForOptionalMask() const { |
132 |
| - unsigned ParamCount = Shape.Parameters.size(); |
133 |
| - for (unsigned i = 0; i < ParamCount; ++i) |
134 |
| - if (Shape.Parameters[i].ParamKind == VFParamKind::GlobalPredicate) |
135 |
| - return i; |
136 |
| - |
137 |
| - return std::nullopt; |
138 |
| - } |
139 |
| - |
140 |
| - /// Returns true if at least one of the operands to the vectorized function |
141 |
| - /// has the kind 'GlobalPredicate'. |
142 |
| - bool isMasked() const { return getParamIndexForOptionalMask().has_value(); } |
143 |
| -}; |
144 |
| - |
145 |
| -namespace VFABI { |
146 |
| -/// LLVM Internal VFABI ISA token for vector functions. |
147 |
| -static constexpr char const *_LLVM_ = "_LLVM_"; |
148 |
| -/// Prefix for internal name redirection for vector function that |
149 |
| -/// tells the compiler to scalarize the call using the scalar name |
150 |
| -/// of the function. For example, a mangled name like |
151 |
| -/// `_ZGV_LLVM_N2v_foo(_LLVM_Scalarize_foo)` would tell the |
152 |
| -/// vectorizer to vectorize the scalar call `foo`, and to scalarize |
153 |
| -/// it once vectorization is done. |
154 |
| -static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_"; |
155 |
| - |
156 |
| -/// Function to construct a VFInfo out of a mangled names in the |
157 |
| -/// following format: |
158 |
| -/// |
159 |
| -/// <VFABI_name>{(<redirection>)} |
160 |
| -/// |
161 |
| -/// where <VFABI_name> is the name of the vector function, mangled according |
162 |
| -/// to the rules described in the Vector Function ABI of the target vector |
163 |
| -/// extension (or <isa> from now on). The <VFABI_name> is in the following |
164 |
| -/// format: |
165 |
| -/// |
166 |
| -/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)] |
167 |
| -/// |
168 |
| -/// This methods support demangling rules for the following <isa>: |
169 |
| -/// |
170 |
| -/// * AArch64: https://developer.arm.com/docs/101129/latest |
171 |
| -/// |
172 |
| -/// * x86 (libmvec): https://sourceware.org/glibc/wiki/libmvec and |
173 |
| -/// https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt |
174 |
| -/// |
175 |
| -/// \param MangledName -> input string in the format |
176 |
| -/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]. |
177 |
| -/// \param FTy -> FunctionType of the scalar function which we're trying to find |
178 |
| -/// a vectorized variant for. This is required to determine the vectorization |
179 |
| -/// factor for scalable vectors, since the mangled name doesn't encode that; |
180 |
| -/// it needs to be derived from the widest element types of vector arguments |
181 |
| -/// or return values. |
182 |
| -std::optional<VFInfo> tryDemangleForVFABI(StringRef MangledName, |
183 |
| - const FunctionType *FTy); |
184 |
| - |
185 |
| -/// Retrieve the `VFParamKind` from a string token. |
186 |
| -VFParamKind getVFParamKindFromString(const StringRef Token); |
187 |
| - |
188 |
| -// Name of the attribute where the variant mappings are stored. |
189 |
| -static constexpr char const *MappingsAttrName = "vector-function-abi-variant"; |
190 |
| - |
191 |
| -/// Populates a set of strings representing the Vector Function ABI variants |
192 |
| -/// associated to the CallInst CI. If the CI does not contain the |
193 |
| -/// vector-function-abi-variant attribute, we return without populating |
194 |
| -/// VariantMappings, i.e. callers of getVectorVariantNames need not check for |
195 |
| -/// the presence of the attribute (see InjectTLIMappings). |
196 |
| -void getVectorVariantNames(const CallInst &CI, |
197 |
| - SmallVectorImpl<std::string> &VariantMappings); |
198 |
| - |
199 |
| -/// Constructs a FunctionType by applying vector function information to the |
200 |
| -/// type of a matching scalar function. |
201 |
| -/// \param Info gets the vectorization factor (VF) and the VFParamKind of the |
202 |
| -/// parameters. |
203 |
| -/// \param ScalarFTy gets the Type information of parameters, as it is not |
204 |
| -/// stored in \p Info. |
205 |
| -/// \returns a pointer to a newly created vector FunctionType |
206 |
| -FunctionType *createFunctionType(const VFInfo &Info, |
207 |
| - const FunctionType *ScalarFTy); |
208 |
| -} // end namespace VFABI |
209 |
| - |
210 | 25 | /// The Vector Function Database.
|
211 | 26 | ///
|
212 | 27 | /// Helper class used to find the vector functions associated to a
|
|
0 commit comments