LLVM 18.0.0git
VFABIDemangling.cpp
Go to the documentation of this file.
1//===- VFABIDemangling.cpp - Vector Function ABI demangling utilities. ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/Support/Debug.h"
12#include <limits>
13
14using namespace llvm;
15
16#define DEBUG_TYPE "vfabi-demangling"
17
18namespace {
19/// Utilities for the Vector Function ABI name parser.
20
21/// Return types for the parser functions.
22enum class ParseRet {
23 OK, // Found.
24 None, // Not found.
25 Error // Syntax error.
26};
27
28/// Extracts the `<isa>` information from the mangled string, and
29/// sets the `ISA` accordingly. If successful, the <isa> token is removed
30/// from the input string `MangledName`.
31static ParseRet tryParseISA(StringRef &MangledName, VFISAKind &ISA) {
32 if (MangledName.empty())
33 return ParseRet::Error;
34
35 if (MangledName.startswith(VFABI::_LLVM_)) {
36 MangledName = MangledName.drop_front(strlen(VFABI::_LLVM_));
37 ISA = VFISAKind::LLVM;
38 } else {
39 ISA = StringSwitch<VFISAKind>(MangledName.take_front(1))
40 .Case("n", VFISAKind::AdvancedSIMD)
41 .Case("s", VFISAKind::SVE)
42 .Case("b", VFISAKind::SSE)
43 .Case("c", VFISAKind::AVX)
44 .Case("d", VFISAKind::AVX2)
45 .Case("e", VFISAKind::AVX512)
46 .Default(VFISAKind::Unknown);
47 MangledName = MangledName.drop_front(1);
48 }
49
50 return ParseRet::OK;
51}
52
53/// Extracts the `<mask>` information from the mangled string, and
54/// sets `IsMasked` accordingly. If successful, the <mask> token is removed
55/// from the input string `MangledName`.
56static ParseRet tryParseMask(StringRef &MangledName, bool &IsMasked) {
57 if (MangledName.consume_front("M")) {
58 IsMasked = true;
59 return ParseRet::OK;
60 }
61
62 if (MangledName.consume_front("N")) {
63 IsMasked = false;
64 return ParseRet::OK;
65 }
66
67 return ParseRet::Error;
68}
69
70/// Extract the `<vlen>` information from the mangled string, and
71/// sets `ParsedVF` accordingly. A `<vlen> == "x"` token is interpreted as a
72/// scalable vector length and the boolean is set to true, otherwise a nonzero
73/// unsigned integer will be directly used as a VF. On success, the `<vlen>`
74/// token is removed from the input string `ParseString`.
75static ParseRet tryParseVLEN(StringRef &ParseString, VFISAKind ISA,
76 std::pair<unsigned, bool> &ParsedVF) {
77 if (ParseString.consume_front("x")) {
78 // SVE is the only scalable ISA currently supported.
79 if (ISA != VFISAKind::SVE) {
80 LLVM_DEBUG(dbgs() << "Vector function variant declared with scalable VF "
81 << "but ISA is not SVE\n");
82 return ParseRet::Error;
83 }
84 // We can't determine the VF of a scalable vector by looking at the vlen
85 // string (just 'x'), so say we successfully parsed it but return a 'true'
86 // for the scalable field with an invalid VF field so that we know to look
87 // up the actual VF based on element types from the parameters or return.
88 ParsedVF = {0, true};
89 return ParseRet::OK;
90 }
91
92 unsigned VF = 0;
93 if (ParseString.consumeInteger(10, VF))
94 return ParseRet::Error;
95
96 // The token `0` is invalid for VLEN.
97 if (VF == 0)
98 return ParseRet::Error;
99
100 ParsedVF = {VF, false};
101 return ParseRet::OK;
102}
103
104/// The function looks for the following strings at the beginning of
105/// the input string `ParseString`:
106///
107/// <token> <number>
108///
109/// On success, it removes the parsed parameter from `ParseString`,
110/// sets `PKind` to the correspondent enum value, sets `Pos` to
111/// <number>, and return success. On a syntax error, it return a
112/// parsing error. If nothing is parsed, it returns std::nullopt.
113///
114/// The function expects <token> to be one of "ls", "Rs", "Us" or
115/// "Ls".
116static ParseRet tryParseLinearTokenWithRuntimeStep(StringRef &ParseString,
117 VFParamKind &PKind, int &Pos,
118 const StringRef Token) {
119 if (ParseString.consume_front(Token)) {
120 PKind = VFABI::getVFParamKindFromString(Token);
121 if (ParseString.consumeInteger(10, Pos))
122 return ParseRet::Error;
123 return ParseRet::OK;
124 }
125
126 return ParseRet::None;
127}
128
129/// The function looks for the following stringt at the beginning of
130/// the input string `ParseString`:
131///
132/// <token> <number>
133///
134/// <token> is one of "ls", "Rs", "Us" or "Ls".
135///
136/// On success, it removes the parsed parameter from `ParseString`,
137/// sets `PKind` to the correspondent enum value, sets `StepOrPos` to
138/// <number>, and return success. On a syntax error, it return a
139/// parsing error. If nothing is parsed, it returns std::nullopt.
140static ParseRet tryParseLinearWithRuntimeStep(StringRef &ParseString,
141 VFParamKind &PKind,
142 int &StepOrPos) {
143 ParseRet Ret;
144
145 // "ls" <RuntimeStepPos>
146 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos, "ls");
147 if (Ret != ParseRet::None)
148 return Ret;
149
150 // "Rs" <RuntimeStepPos>
151 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos, "Rs");
152 if (Ret != ParseRet::None)
153 return Ret;
154
155 // "Ls" <RuntimeStepPos>
156 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos, "Ls");
157 if (Ret != ParseRet::None)
158 return Ret;
159
160 // "Us" <RuntimeStepPos>
161 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos, "Us");
162 if (Ret != ParseRet::None)
163 return Ret;
164
165 return ParseRet::None;
166}
167
168/// The function looks for the following strings at the beginning of
169/// the input string `ParseString`:
170///
171/// <token> {"n"} <number>
172///
173/// On success, it removes the parsed parameter from `ParseString`,
174/// sets `PKind` to the correspondent enum value, sets `LinearStep` to
175/// <number>, and return success. On a syntax error, it return a
176/// parsing error. If nothing is parsed, it returns std::nullopt.
177///
178/// The function expects <token> to be one of "l", "R", "U" or
179/// "L".
180static ParseRet tryParseCompileTimeLinearToken(StringRef &ParseString,
181 VFParamKind &PKind,
182 int &LinearStep,
183 const StringRef Token) {
184 if (ParseString.consume_front(Token)) {
185 PKind = VFABI::getVFParamKindFromString(Token);
186 const bool Negate = ParseString.consume_front("n");
187 if (ParseString.consumeInteger(10, LinearStep))
188 LinearStep = 1;
189 if (Negate)
190 LinearStep *= -1;
191 return ParseRet::OK;
192 }
193
194 return ParseRet::None;
195}
196
197/// The function looks for the following strings at the beginning of
198/// the input string `ParseString`:
199///
200/// ["l" | "R" | "U" | "L"] {"n"} <number>
201///
202/// On success, it removes the parsed parameter from `ParseString`,
203/// sets `PKind` to the correspondent enum value, sets `LinearStep` to
204/// <number>, and return success. On a syntax error, it return a
205/// parsing error. If nothing is parsed, it returns std::nullopt.
206static ParseRet tryParseLinearWithCompileTimeStep(StringRef &ParseString,
207 VFParamKind &PKind,
208 int &StepOrPos) {
209 // "l" {"n"} <CompileTimeStep>
210 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos, "l") ==
211 ParseRet::OK)
212 return ParseRet::OK;
213
214 // "R" {"n"} <CompileTimeStep>
215 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos, "R") ==
216 ParseRet::OK)
217 return ParseRet::OK;
218
219 // "L" {"n"} <CompileTimeStep>
220 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos, "L") ==
221 ParseRet::OK)
222 return ParseRet::OK;
223
224 // "U" {"n"} <CompileTimeStep>
225 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos, "U") ==
226 ParseRet::OK)
227 return ParseRet::OK;
228
229 return ParseRet::None;
230}
231
232/// Looks into the <parameters> part of the mangled name in search
233/// for valid paramaters at the beginning of the string
234/// `ParseString`.
235///
236/// On success, it removes the parsed parameter from `ParseString`,
237/// sets `PKind` to the correspondent enum value, sets `StepOrPos`
238/// accordingly, and return success. On a syntax error, it return a
239/// parsing error. If nothing is parsed, it returns std::nullopt.
240static ParseRet tryParseParameter(StringRef &ParseString, VFParamKind &PKind,
241 int &StepOrPos) {
242 if (ParseString.consume_front("v")) {
243 PKind = VFParamKind::Vector;
244 StepOrPos = 0;
245 return ParseRet::OK;
246 }
247
248 if (ParseString.consume_front("u")) {
249 PKind = VFParamKind::OMP_Uniform;
250 StepOrPos = 0;
251 return ParseRet::OK;
252 }
253
254 const ParseRet HasLinearRuntime =
255 tryParseLinearWithRuntimeStep(ParseString, PKind, StepOrPos);
256 if (HasLinearRuntime != ParseRet::None)
257 return HasLinearRuntime;
258
259 const ParseRet HasLinearCompileTime =
260 tryParseLinearWithCompileTimeStep(ParseString, PKind, StepOrPos);
261 if (HasLinearCompileTime != ParseRet::None)
262 return HasLinearCompileTime;
263
264 return ParseRet::None;
265}
266
267/// Looks into the <parameters> part of the mangled name in search
268/// of a valid 'aligned' clause. The function should be invoked
269/// after parsing a parameter via `tryParseParameter`.
270///
271/// On success, it removes the parsed parameter from `ParseString`,
272/// sets `PKind` to the correspondent enum value, sets `StepOrPos`
273/// accordingly, and return success. On a syntax error, it return a
274/// parsing error. If nothing is parsed, it returns std::nullopt.
275static ParseRet tryParseAlign(StringRef &ParseString, Align &Alignment) {
276 uint64_t Val;
277 // "a" <number>
278 if (ParseString.consume_front("a")) {
279 if (ParseString.consumeInteger(10, Val))
280 return ParseRet::Error;
281
282 if (!isPowerOf2_64(Val))
283 return ParseRet::Error;
284
285 Alignment = Align(Val);
286
287 return ParseRet::OK;
288 }
289
290 return ParseRet::None;
291}
292
293// Returns the 'natural' VF for a given scalar element type, based on the
294// current architecture.
295//
296// For SVE (currently the only scalable architecture with a defined name
297// mangling), we assume a minimum vector size of 128b and return a VF based on
298// the number of elements of the given type which would fit in such a vector.
299static std::optional<ElementCount> getElementCountForTy(const VFISAKind ISA,
300 const Type *Ty) {
301 // Only AArch64 SVE is supported at present.
302 assert(ISA == VFISAKind::SVE &&
303 "Scalable VF decoding only implemented for SVE\n");
304
305 if (Ty->isIntegerTy(64) || Ty->isDoubleTy() || Ty->isPointerTy())
307 if (Ty->isIntegerTy(32) || Ty->isFloatTy())
309 if (Ty->isIntegerTy(16) || Ty->is16bitFPTy())
311 if (Ty->isIntegerTy(8))
312 return ElementCount::getScalable(16);
313
314 return std::nullopt;
315}
316
317// Extract the VectorizationFactor from a given function signature, based
318// on the widest scalar element types that will become vector parameters.
319static std::optional<ElementCount>
320getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA,
321 const SmallVectorImpl<VFParameter> &Params) {
322 // Start with a very wide EC and drop when we find smaller ECs based on type.
323 ElementCount MinEC =
324 ElementCount::getScalable(std::numeric_limits<unsigned int>::max());
325 for (auto &Param : Params) {
326 // Only vector parameters are used when determining the VF; uniform or
327 // linear are left as scalars, so do not affect VF.
328 if (Param.ParamKind == VFParamKind::Vector) {
329 // If the scalar function doesn't actually have a corresponding argument,
330 // reject the mapping.
331 if (Param.ParamPos >= Signature->getNumParams())
332 return std::nullopt;
333 Type *PTy = Signature->getParamType(Param.ParamPos);
334
335 std::optional<ElementCount> EC = getElementCountForTy(ISA, PTy);
336 // If we have an unknown scalar element type we can't find a reasonable
337 // VF.
338 if (!EC)
339 return std::nullopt;
340
341 // Find the smallest VF, based on the widest scalar type.
342 if (ElementCount::isKnownLT(*EC, MinEC))
343 MinEC = *EC;
344 }
345 }
346
347 // Also check the return type if not void.
348 Type *RetTy = Signature->getReturnType();
349 if (!RetTy->isVoidTy()) {
350 std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA, RetTy);
351 // If we have an unknown scalar element type we can't find a reasonable VF.
352 if (!ReturnEC)
353 return std::nullopt;
354 if (ElementCount::isKnownLT(*ReturnEC, MinEC))
355 MinEC = *ReturnEC;
356 }
357
358 // The SVE Vector function call ABI bases the VF on the widest element types
359 // present, and vector arguments containing types of that width are always
360 // considered to be packed. Arguments with narrower elements are considered
361 // to be unpacked.
362 if (MinEC.getKnownMinValue() < std::numeric_limits<unsigned int>::max())
363 return MinEC;
364
365 return std::nullopt;
366}
367} // namespace
368
369// Format of the ABI name:
370// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
371std::optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName,
372 const CallInst &CI) {
373 const StringRef OriginalName = MangledName;
374 // Assume there is no custom name <redirection>, and therefore the
375 // vector name consists of
376 // _ZGV<isa><mask><vlen><parameters>_<scalarname>.
377 StringRef VectorName = MangledName;
378
379 // Parse the fixed size part of the manled name
380 if (!MangledName.consume_front("_ZGV"))
381 return std::nullopt;
382
383 // Extract ISA. An unknow ISA is also supported, so we accept all
384 // values.
385 VFISAKind ISA;
386 if (tryParseISA(MangledName, ISA) != ParseRet::OK)
387 return std::nullopt;
388
389 // Extract <mask>.
390 bool IsMasked;
391 if (tryParseMask(MangledName, IsMasked) != ParseRet::OK)
392 return std::nullopt;
393
394 // Parse the variable size, starting from <vlen>.
395 std::pair<unsigned, bool> ParsedVF;
396 if (tryParseVLEN(MangledName, ISA, ParsedVF) != ParseRet::OK)
397 return std::nullopt;
398
399 // Parse the <parameters>.
400 ParseRet ParamFound;
402 do {
403 const unsigned ParameterPos = Parameters.size();
404 VFParamKind PKind;
405 int StepOrPos;
406 ParamFound = tryParseParameter(MangledName, PKind, StepOrPos);
407
408 // Bail off if there is a parsing error in the parsing of the parameter.
409 if (ParamFound == ParseRet::Error)
410 return std::nullopt;
411
412 if (ParamFound == ParseRet::OK) {
413 Align Alignment;
414 // Look for the alignment token "a <number>".
415 const ParseRet AlignFound = tryParseAlign(MangledName, Alignment);
416 // Bail off if there is a syntax error in the align token.
417 if (AlignFound == ParseRet::Error)
418 return std::nullopt;
419
420 // Add the parameter.
421 Parameters.push_back({ParameterPos, PKind, StepOrPos, Alignment});
422 }
423 } while (ParamFound == ParseRet::OK);
424
425 // A valid MangledName must have at least one valid entry in the
426 // <parameters>.
427 if (Parameters.empty())
428 return std::nullopt;
429
430 // Figure out the number of lanes in vectors for this function variant. This
431 // is easy for fixed length, as the vlen encoding just gives us the value
432 // directly. However, if the vlen mangling indicated that this function
433 // variant expects scalable vectors we need to work it out based on the
434 // demangled parameter types and the scalar function signature.
435 std::optional<ElementCount> EC;
436 if (ParsedVF.second) {
437 EC = getScalableECFromSignature(CI.getFunctionType(), ISA, Parameters);
438 if (!EC)
439 return std::nullopt;
440 } else
441 EC = ElementCount::getFixed(ParsedVF.first);
442
443 // Check for the <scalarname> and the optional <redirection>, which
444 // are separated from the prefix with "_"
445 if (!MangledName.consume_front("_"))
446 return std::nullopt;
447
448 // The rest of the string must be in the format:
449 // <scalarname>[(<redirection>)]
450 const StringRef ScalarName =
451 MangledName.take_while([](char In) { return In != '('; });
452
453 if (ScalarName.empty())
454 return std::nullopt;
455
456 // Reduce MangledName to [(<redirection>)].
457 MangledName = MangledName.ltrim(ScalarName);
458 // Find the optional custom name redirection.
459 if (MangledName.consume_front("(")) {
460 if (!MangledName.consume_back(")"))
461 return std::nullopt;
462 // Update the vector variant with the one specified by the user.
463 VectorName = MangledName;
464 // If the vector name is missing, bail out.
465 if (VectorName.empty())
466 return std::nullopt;
467 }
468
469 // LLVM internal mapping via the TargetLibraryInfo (TLI) must be
470 // redirected to an existing name.
471 if (ISA == VFISAKind::LLVM && VectorName == OriginalName)
472 return std::nullopt;
473
474 // When <mask> is "M", we need to add a parameter that is used as
475 // global predicate for the function.
476 if (IsMasked) {
477 const unsigned Pos = Parameters.size();
478 Parameters.push_back({Pos, VFParamKind::GlobalPredicate});
479 }
480
481 // Asserts for parameters of type `VFParamKind::GlobalPredicate`, as
482 // prescribed by the Vector Function ABI specifications supported by
483 // this parser:
484 // 1. Uniqueness.
485 // 2. Must be the last in the parameter list.
486 const auto NGlobalPreds =
487 llvm::count_if(Parameters, [](const VFParameter &PK) {
488 return PK.ParamKind == VFParamKind::GlobalPredicate;
489 });
490 assert(NGlobalPreds < 2 && "Cannot have more than one global predicate.");
491 if (NGlobalPreds)
492 assert(Parameters.back().ParamKind == VFParamKind::GlobalPredicate &&
493 "The global predicate must be the last parameter");
494
495 const VFShape Shape({*EC, Parameters});
496 return VFInfo({Shape, std::string(ScalarName), std::string(VectorName), ISA});
497}
498
500 const VFParamKind ParamKind = StringSwitch<VFParamKind>(Token)
501 .Case("v", VFParamKind::Vector)
502 .Case("l", VFParamKind::OMP_Linear)
503 .Case("R", VFParamKind::OMP_LinearRef)
504 .Case("L", VFParamKind::OMP_LinearVal)
505 .Case("U", VFParamKind::OMP_LinearUVal)
506 .Case("ls", VFParamKind::OMP_LinearPos)
507 .Case("Ls", VFParamKind::OMP_LinearValPos)
508 .Case("Rs", VFParamKind::OMP_LinearRefPos)
509 .Case("Us", VFParamKind::OMP_LinearUValPos)
510 .Case("u", VFParamKind::OMP_Uniform)
511 .Default(VFParamKind::Unknown);
512
513 if (ParamKind != VFParamKind::Unknown)
514 return ParamKind;
515
516 // This function should never be invoked with an invalid input.
517 llvm_unreachable("This fuction should be invoken only on parameters"
518 " that have a textual representation in the mangled name"
519 " of the Vector Function ABI");
520}
return RetTy
#define LLVM_DEBUG(X)
Definition: Debug.h:101
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ None
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1307
This class represents a function call, abstracting a target machine's calling convention.
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition: TypeSize.h:300
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:297
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:659
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:503
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
StringRef take_while(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that every character in the prefix satisfies the given predi...
Definition: StringRef.h:601
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:613
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:795
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:639
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:584
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition: Type.h:154
bool is16bitFPTy() const
Return true if this is a 16-bit float type.
Definition: Type.h:149
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition: Type.h:157
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:169
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const CallInst &CI)
Function to construct a VFInfo out of a mangled names in the following format:
VFParamKind getVFParamKindFromString(const StringRef Token)
Retrieve the VFParamKind from a string token.
static constexpr char const * _LLVM_
LLVM Internal VFABI ISA token for vector functions.
Definition: VectorUtils.h:147
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:269
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
VFISAKind
Describes the type of Instruction Set Architecture.
Definition: VectorUtils.h:44
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition: STLExtras.h:1925
VFParamKind
Describes the type of Parameters.
Definition: VectorUtils.h:25
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Holds the VFShape for a specific scalar to vector function mapping.
Definition: VectorUtils.h:123
Encapsulates information needed to describe a parameter.
Definition: VectorUtils.h:62
VFParamKind ParamKind
Definition: VectorUtils.h:64
Contains the information about the kind of vectorization available.
Definition: VectorUtils.h:82