Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:11

0001 //===- VFABIDemangler.h - Vector Function ABI demangler ------- -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the VFABI demangling utility.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_IR_VFABIDEMANGLER_H
0014 #define LLVM_IR_VFABIDEMANGLER_H
0015 
0016 #include "llvm/ADT/SmallVector.h"
0017 #include "llvm/IR/DerivedTypes.h"
0018 #include "llvm/IR/Instructions.h"
0019 #include "llvm/Support/Alignment.h"
0020 #include "llvm/Support/TypeSize.h"
0021 
0022 namespace llvm {
0023 
0024 /// Describes the type of Parameters
0025 enum class VFParamKind {
0026   Vector,            // No semantic information.
0027   OMP_Linear,        // declare simd linear(i)
0028   OMP_LinearRef,     // declare simd linear(ref(i))
0029   OMP_LinearVal,     // declare simd linear(val(i))
0030   OMP_LinearUVal,    // declare simd linear(uval(i))
0031   OMP_LinearPos,     // declare simd linear(i:c) uniform(c)
0032   OMP_LinearValPos,  // declare simd linear(val(i:c)) uniform(c)
0033   OMP_LinearRefPos,  // declare simd linear(ref(i:c)) uniform(c)
0034   OMP_LinearUValPos, // declare simd linear(uval(i:c)) uniform(c)
0035   OMP_Uniform,       // declare simd uniform(i)
0036   GlobalPredicate,   // Global logical predicate that acts on all lanes
0037                      // of the input and output mask concurrently. For
0038                      // example, it is implied by the `M` token in the
0039                      // Vector Function ABI mangled name.
0040   Unknown
0041 };
0042 
0043 /// Describes the type of Instruction Set Architecture
0044 enum class VFISAKind {
0045   AdvancedSIMD, // AArch64 Advanced SIMD (NEON)
0046   SVE,          // AArch64 Scalable Vector Extension
0047   RVV,          // RISC-V Vector Extension
0048   SSE,          // x86 SSE
0049   AVX,          // x86 AVX
0050   AVX2,         // x86 AVX2
0051   AVX512,       // x86 AVX512
0052   LLVM,         // LLVM internal ISA for functions that are not
0053   // attached to an existing ABI via name mangling.
0054   Unknown // Unknown ISA
0055 };
0056 
0057 /// Encapsulates information needed to describe a parameter.
0058 ///
0059 /// The description of the parameter is not linked directly to
0060 /// OpenMP or any other vector function description. This structure
0061 /// is extendible to handle other paradigms that describe vector
0062 /// functions and their parameters.
0063 struct VFParameter {
0064   unsigned ParamPos;         // Parameter Position in Scalar Function.
0065   VFParamKind ParamKind;     // Kind of Parameter.
0066   int LinearStepOrPos = 0;   // Step or Position of the Parameter.
0067   Align Alignment = Align(); // Optional alignment in bytes, defaulted to 1.
0068 
0069   // Comparison operator.
0070   bool operator==(const VFParameter &Other) const {
0071     return std::tie(ParamPos, ParamKind, LinearStepOrPos, Alignment) ==
0072            std::tie(Other.ParamPos, Other.ParamKind, Other.LinearStepOrPos,
0073                     Other.Alignment);
0074   }
0075 };
0076 
0077 /// Contains the information about the kind of vectorization
0078 /// available.
0079 ///
0080 /// This object in independent on the paradigm used to
0081 /// represent vector functions. in particular, it is not attached to
0082 /// any target-specific ABI.
0083 struct VFShape {
0084   ElementCount VF;                        // Vectorization factor.
0085   SmallVector<VFParameter, 8> Parameters; // List of parameter information.
0086   // Comparison operator.
0087   bool operator==(const VFShape &Other) const {
0088     return std::tie(VF, Parameters) == std::tie(Other.VF, Other.Parameters);
0089   }
0090 
0091   /// Update the parameter in position P.ParamPos to P.
0092   void updateParam(VFParameter P) {
0093     assert(P.ParamPos < Parameters.size() && "Invalid parameter position.");
0094     Parameters[P.ParamPos] = P;
0095     assert(hasValidParameterList() && "Invalid parameter list");
0096   }
0097 
0098   /// Retrieve the VFShape that can be used to map a scalar function to itself,
0099   /// with VF = 1.
0100   static VFShape getScalarShape(const FunctionType *FTy) {
0101     return VFShape::get(FTy, ElementCount::getFixed(1),
0102                         /*HasGlobalPredicate*/ false);
0103   }
0104 
0105   /// Retrieve the basic vectorization shape of the function, where all
0106   /// parameters are mapped to VFParamKind::Vector with \p EC lanes. Specifies
0107   /// whether the function has a Global Predicate argument via \p HasGlobalPred.
0108   static VFShape get(const FunctionType *FTy, ElementCount EC,
0109                      bool HasGlobalPred) {
0110     SmallVector<VFParameter, 8> Parameters;
0111     for (unsigned I = 0; I < FTy->getNumParams(); ++I)
0112       Parameters.push_back(VFParameter({I, VFParamKind::Vector}));
0113     if (HasGlobalPred)
0114       Parameters.push_back(
0115           VFParameter({FTy->getNumParams(), VFParamKind::GlobalPredicate}));
0116 
0117     return {EC, Parameters};
0118   }
0119   /// Validation check on the Parameters in the VFShape.
0120   bool hasValidParameterList() const;
0121 };
0122 
0123 /// Holds the VFShape for a specific scalar to vector function mapping.
0124 struct VFInfo {
0125   VFShape Shape;          /// Classification of the vector function.
0126   std::string ScalarName; /// Scalar Function Name.
0127   std::string VectorName; /// Vector Function Name associated to this VFInfo.
0128   VFISAKind ISA;          /// Instruction Set Architecture.
0129 
0130   /// Returns the index of the first parameter with the kind 'GlobalPredicate',
0131   /// if any exist.
0132   std::optional<unsigned> getParamIndexForOptionalMask() const {
0133     unsigned ParamCount = Shape.Parameters.size();
0134     for (unsigned i = 0; i < ParamCount; ++i)
0135       if (Shape.Parameters[i].ParamKind == VFParamKind::GlobalPredicate)
0136         return i;
0137 
0138     return std::nullopt;
0139   }
0140 
0141   /// Returns true if at least one of the operands to the vectorized function
0142   /// has the kind 'GlobalPredicate'.
0143   bool isMasked() const { return getParamIndexForOptionalMask().has_value(); }
0144 };
0145 
0146 namespace VFABI {
0147 /// LLVM Internal VFABI ISA token for vector functions.
0148 static constexpr char const *_LLVM_ = "_LLVM_";
0149 /// Prefix for internal name redirection for vector function that
0150 /// tells the compiler to scalarize the call using the scalar name
0151 /// of the function. For example, a mangled name like
0152 /// `_ZGV_LLVM_N2v_foo(_LLVM_Scalarize_foo)` would tell the
0153 /// vectorizer to vectorize the scalar call `foo`, and to scalarize
0154 /// it once vectorization is done.
0155 static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
0156 
0157 /// Function to construct a VFInfo out of a mangled names in the
0158 /// following format:
0159 ///
0160 /// <VFABI_name>{(<redirection>)}
0161 ///
0162 /// where <VFABI_name> is the name of the vector function, mangled according
0163 /// to the rules described in the Vector Function ABI of the target vector
0164 /// extension (or <isa> from now on). The <VFABI_name> is in the following
0165 /// format:
0166 ///
0167 /// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
0168 ///
0169 /// This methods support demangling rules for the following <isa>:
0170 ///
0171 /// * AArch64: https://developer.arm.com/docs/101129/latest
0172 ///
0173 /// * x86 (libmvec): https://sourceware.org/glibc/wiki/libmvec and
0174 ///  https://sourceware.org/glibc/wiki/libmvec?action=AttachFile&do=view&target=VectorABI.txt
0175 ///
0176 /// \param MangledName -> input string in the format
0177 /// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
0178 /// \param FTy -> FunctionType of the scalar function which we're trying to find
0179 /// a vectorized variant for. This is required to determine the vectorization
0180 /// factor for scalable vectors, since the mangled name doesn't encode that;
0181 /// it needs to be derived from the widest element types of vector arguments
0182 /// or return values.
0183 std::optional<VFInfo> tryDemangleForVFABI(StringRef MangledName,
0184                                           const FunctionType *FTy);
0185 
0186 /// Retrieve the `VFParamKind` from a string token.
0187 VFParamKind getVFParamKindFromString(const StringRef Token);
0188 
0189 // Name of the attribute where the variant mappings are stored.
0190 static constexpr char const *MappingsAttrName = "vector-function-abi-variant";
0191 
0192 /// Populates a set of strings representing the Vector Function ABI variants
0193 /// associated to the CallInst CI. If the CI does not contain the
0194 /// vector-function-abi-variant attribute, we return without populating
0195 /// VariantMappings, i.e. callers of getVectorVariantNames need not check for
0196 /// the presence of the attribute (see InjectTLIMappings).
0197 void getVectorVariantNames(const CallInst &CI,
0198                            SmallVectorImpl<std::string> &VariantMappings);
0199 
0200 /// Constructs a FunctionType by applying vector function information to the
0201 /// type of a matching scalar function.
0202 /// \param Info gets the vectorization factor (VF) and the VFParamKind of the
0203 /// parameters.
0204 /// \param ScalarFTy gets the Type information of parameters, as it is not
0205 /// stored in \p Info.
0206 /// \returns a pointer to a newly created vector FunctionType
0207 FunctionType *createFunctionType(const VFInfo &Info,
0208                                  const FunctionType *ScalarFTy);
0209 
0210 /// Overwrite the Vector Function ABI variants attribute with the names provide
0211 /// in \p VariantMappings.
0212 void setVectorVariantNames(CallInst *CI, ArrayRef<std::string> VariantMappings);
0213 
0214 } // end namespace VFABI
0215 
0216 } // namespace llvm
0217 
0218 #endif // LLVM_IR_VFABIDEMANGLER_H