Skip to content

Commit 92289db

Browse files
authored
[VFABI] Move the Vector ABI demangling utility to LLVMCore. (#77513)
This fixes #71892 allowing us to check magled names in the IR verifier.
1 parent 53a3c73 commit 92289db

File tree

24 files changed

+393
-379
lines changed

24 files changed

+393
-379
lines changed

llvm/include/llvm/Analysis/VectorUtils.h

Lines changed: 1 addition & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -16,197 +16,12 @@
1616
#include "llvm/ADT/MapVector.h"
1717
#include "llvm/ADT/SmallVector.h"
1818
#include "llvm/Analysis/LoopAccessAnalysis.h"
19+
#include "llvm/IR/VFABIDemangler.h"
1920
#include "llvm/Support/CheckedArithmetic.h"
2021

2122
namespace llvm {
2223
class TargetLibraryInfo;
2324

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-
21025
/// The Vector Function Database.
21126
///
21227
/// Helper class used to find the vector functions associated to a

0 commit comments

Comments
 (0)