//===- VFABIDemangler.cpp - Vector Function ABI demangler -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/IR/VFABIDemangler.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include <limits> usingnamespacellvm; #define DEBUG_TYPE … namespace { /// Utilities for the Vector Function ABI name parser. /// Return types for the parser functions. enum class ParseRet { … }; /// Extracts the `<isa>` information from the mangled string, and /// sets the `ISA` accordingly. If successful, the <isa> token is removed /// from the input string `MangledName`. static ParseRet tryParseISA(StringRef &MangledName, VFISAKind &ISA) { … } /// Extracts the `<mask>` information from the mangled string, and /// sets `IsMasked` accordingly. If successful, the <mask> token is removed /// from the input string `MangledName`. static ParseRet tryParseMask(StringRef &MangledName, bool &IsMasked) { … } /// Extract the `<vlen>` information from the mangled string, and /// sets `ParsedVF` accordingly. A `<vlen> == "x"` token is interpreted as a /// scalable vector length and the boolean is set to true, otherwise a nonzero /// unsigned integer will be directly used as a VF. On success, the `<vlen>` /// token is removed from the input string `ParseString`. static ParseRet tryParseVLEN(StringRef &ParseString, VFISAKind ISA, std::pair<unsigned, bool> &ParsedVF) { … } /// The function looks for the following strings at the beginning of /// the input string `ParseString`: /// /// <token> <number> /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `Pos` to /// <number>, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. /// /// The function expects <token> to be one of "ls", "Rs", "Us" or /// "Ls". static ParseRet tryParseLinearTokenWithRuntimeStep(StringRef &ParseString, VFParamKind &PKind, int &Pos, const StringRef Token) { … } /// The function looks for the following string at the beginning of /// the input string `ParseString`: /// /// <token> <number> /// /// <token> is one of "ls", "Rs", "Us" or "Ls". /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `StepOrPos` to /// <number>, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. static ParseRet tryParseLinearWithRuntimeStep(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos) { … } /// The function looks for the following strings at the beginning of /// the input string `ParseString`: /// /// <token> {"n"} <number> /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `LinearStep` to /// <number>, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. /// /// The function expects <token> to be one of "l", "R", "U" or /// "L". static ParseRet tryParseCompileTimeLinearToken(StringRef &ParseString, VFParamKind &PKind, int &LinearStep, const StringRef Token) { … } /// The function looks for the following strings at the beginning of /// the input string `ParseString`: /// /// ["l" | "R" | "U" | "L"] {"n"} <number> /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `LinearStep` to /// <number>, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. static ParseRet tryParseLinearWithCompileTimeStep(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos) { … } /// Looks into the <parameters> part of the mangled name in search /// for valid paramaters at the beginning of the string /// `ParseString`. /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `StepOrPos` /// accordingly, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. static ParseRet tryParseParameter(StringRef &ParseString, VFParamKind &PKind, int &StepOrPos) { … } /// Looks into the <parameters> part of the mangled name in search /// of a valid 'aligned' clause. The function should be invoked /// after parsing a parameter via `tryParseParameter`. /// /// On success, it removes the parsed parameter from `ParseString`, /// sets `PKind` to the correspondent enum value, sets `StepOrPos` /// accordingly, and return success. On a syntax error, it return a /// parsing error. If nothing is parsed, it returns std::nullopt. static ParseRet tryParseAlign(StringRef &ParseString, Align &Alignment) { … } // Returns the 'natural' VF for a given scalar element type, based on the // current architecture. // // For SVE (currently the only scalable architecture with a defined name // mangling), we assume a minimum vector size of 128b and return a VF based on // the number of elements of the given type which would fit in such a vector. static std::optional<ElementCount> getElementCountForTy(const VFISAKind ISA, const Type *Ty) { … } // Extract the VectorizationFactor from a given function signature, based // on the widest scalar element types that will become vector parameters. static std::optional<ElementCount> getScalableECFromSignature(const FunctionType *Signature, const VFISAKind ISA, const SmallVectorImpl<VFParameter> &Params) { … } } // namespace // Format of the ABI name: // _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)] std::optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy) { … } VFParamKind VFABI::getVFParamKindFromString(const StringRef Token) { … } void VFABI::getVectorVariantNames( const CallInst &CI, SmallVectorImpl<std::string> &VariantMappings) { … } FunctionType *VFABI::createFunctionType(const VFInfo &Info, const FunctionType *ScalarFTy) { … } void VFABI::setVectorVariantNames(CallInst *CI, ArrayRef<std::string> VariantMappings) { … } bool VFShape::hasValidParameterList() const { … }