21#define DEBUG_TYPE "vfabi-demangler"
37 if (MangledName.
empty())
38 return ParseRet::Error;
41 ISA = VFISAKind::LLVM;
44 .
Case(
"n", VFISAKind::AdvancedSIMD)
45 .
Case(
"s", VFISAKind::SVE)
46 .
Case(
"r", VFISAKind::RVV)
47 .
Case(
"b", VFISAKind::SSE)
48 .
Case(
"c", VFISAKind::AVX)
49 .
Case(
"d", VFISAKind::AVX2)
50 .
Case(
"e", VFISAKind::AVX512)
61static ParseRet tryParseMask(
StringRef &MangledName,
bool &IsMasked) {
72 return ParseRet::Error;
81 std::pair<unsigned, bool> &ParsedVF) {
84 if (ISA != VFISAKind::SVE && ISA != VFISAKind::RVV) {
85 LLVM_DEBUG(
dbgs() <<
"Vector function variant declared with scalable VF "
86 <<
"but ISA supported for SVE and RVV only\n");
87 return ParseRet::Error;
99 return ParseRet::Error;
103 return ParseRet::Error;
105 ParsedVF = {VF,
false};
121static ParseRet tryParseLinearTokenWithRuntimeStep(
StringRef &ParseString,
127 return ParseRet::Error;
131 return ParseRet::None;
145static ParseRet tryParseLinearWithRuntimeStep(
StringRef &ParseString,
151 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"ls");
152 if (Ret != ParseRet::None)
156 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Rs");
157 if (Ret != ParseRet::None)
161 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Ls");
162 if (Ret != ParseRet::None)
166 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Us");
167 if (Ret != ParseRet::None)
170 return ParseRet::None;
185static ParseRet tryParseCompileTimeLinearToken(
StringRef &ParseString,
199 return ParseRet::None;
211static ParseRet tryParseLinearWithCompileTimeStep(
StringRef &ParseString,
215 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"l") ==
220 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"R") ==
225 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"L") ==
230 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"U") ==
234 return ParseRet::None;
248 PKind = VFParamKind::Vector;
254 PKind = VFParamKind::OMP_Uniform;
259 const ParseRet HasLinearRuntime =
260 tryParseLinearWithRuntimeStep(ParseString, PKind, StepOrPos);
261 if (HasLinearRuntime != ParseRet::None)
262 return HasLinearRuntime;
264 const ParseRet HasLinearCompileTime =
265 tryParseLinearWithCompileTimeStep(ParseString, PKind, StepOrPos);
266 if (HasLinearCompileTime != ParseRet::None)
267 return HasLinearCompileTime;
269 return ParseRet::None;
280static ParseRet tryParseAlign(
StringRef &ParseString,
Align &Alignment) {
285 return ParseRet::Error;
288 return ParseRet::Error;
290 Alignment =
Align(Val);
295 return ParseRet::None;
304static std::optional<ElementCount> getElementCountForTy(
const VFISAKind ISA,
306 assert((ISA == VFISAKind::SVE || ISA == VFISAKind::RVV) &&
307 "Scalable VF decoding only implemented for SVE and RVV\n");
323static std::optional<ElementCount>
329 for (
auto &Param : Params) {
332 if (Param.ParamKind == VFParamKind::Vector) {
333 Type *PTy = Signature->getParamType(Param.ParamPos);
335 std::optional<ElementCount> EC = getElementCountForTy(ISA, PTy);
342 if (ElementCount::isKnownLT(*EC, MinEC))
348 Type *
RetTy = Signature->getReturnType();
349 if (!
RetTy->isVoidTy()) {
356 std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA,
RetTy);
361 if (ElementCount::isKnownLT(*ReturnEC, MinEC))
381 const StringRef OriginalName = MangledName;
394 if (tryParseISA(MangledName, ISA) != ParseRet::OK)
399 if (tryParseMask(MangledName, IsMasked) != ParseRet::OK)
403 std::pair<unsigned, bool> ParsedVF;
404 if (tryParseVLEN(MangledName, ISA, ParsedVF) != ParseRet::OK)
411 const unsigned ParameterPos = Parameters.size();
414 ParamFound = tryParseParameter(MangledName, PKind, StepOrPos);
417 if (ParamFound == ParseRet::Error)
420 if (ParamFound == ParseRet::OK) {
423 const ParseRet AlignFound = tryParseAlign(MangledName, Alignment);
425 if (AlignFound == ParseRet::Error)
429 Parameters.push_back({ParameterPos, PKind, StepOrPos, Alignment});
431 }
while (ParamFound == ParseRet::OK);
435 if (Parameters.empty())
448 std::optional<ElementCount> EC;
449 if (ParsedVF.second) {
450 EC = getScalableECFromSignature(FTy, ISA, Parameters);
464 MangledName.
take_while([](
char In) {
return In !=
'('; });
466 if (ScalarName.
empty())
470 MangledName = MangledName.
ltrim(ScalarName);
476 VectorName = MangledName;
478 if (VectorName.
empty())
484 if (ISA == VFISAKind::LLVM && VectorName == OriginalName)
490 const unsigned Pos = Parameters.size();
491 Parameters.push_back({Pos, VFParamKind::GlobalPredicate});
499 const auto NGlobalPreds =
501 return PK.
ParamKind == VFParamKind::GlobalPredicate;
503 assert(NGlobalPreds < 2 &&
"Cannot have more than one global predicate.");
505 assert(Parameters.back().ParamKind == VFParamKind::GlobalPredicate &&
506 "The global predicate must be the last parameter");
508 const VFShape Shape({*EC, Parameters});
509 return VFInfo({Shape, std::string(ScalarName), std::string(VectorName), ISA});
514 .
Case(
"v", VFParamKind::Vector)
515 .
Case(
"l", VFParamKind::OMP_Linear)
516 .
Case(
"R", VFParamKind::OMP_LinearRef)
517 .
Case(
"L", VFParamKind::OMP_LinearVal)
518 .
Case(
"U", VFParamKind::OMP_LinearUVal)
519 .
Case(
"ls", VFParamKind::OMP_LinearPos)
520 .
Case(
"Ls", VFParamKind::OMP_LinearValPos)
521 .
Case(
"Rs", VFParamKind::OMP_LinearRefPos)
522 .
Case(
"Us", VFParamKind::OMP_LinearUValPos)
523 .
Case(
"u", VFParamKind::OMP_Uniform)
524 .
Default(VFParamKind::Unknown);
526 if (ParamKind != VFParamKind::Unknown)
531 " that have a textual representation in the mangled name"
532 " of the Vector Function ABI");
542 S.
split(ListAttr,
",");
545 std::optional<VFInfo>
Info =
548 LLVM_DEBUG(
dbgs() <<
"VFABI: Adding mapping '" << S <<
"' for " << CI
550 VariantMappings.
push_back(std::string(S));
561 int ScalarParamIndex = 0;
562 for (
auto VFParam :
Info.Shape.Parameters) {
563 if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
571 if (VFParam.ParamKind == VFParamKind::Vector)
572 OperandTy = VectorType::get(OperandTy, VF);
577 if (!
RetTy->isVoidTy())
579 return FunctionType::get(
RetTy, VecTypes,
false);
584 if (VariantMappings.
empty())
589 for (
const std::string &VariantMapping : VariantMappings)
590 Out << VariantMapping <<
",";
597 for (
const std::string &VariantMapping : VariantMappings) {
598 LLVM_DEBUG(
dbgs() <<
"VFABI: adding mapping '" << VariantMapping <<
"'\n");
599 std::optional<VFInfo> VI =
601 assert(VI &&
"Cannot add an invalid VFABI name.");
602 assert(M->getNamedValue(VI->VectorName) &&
603 "Cannot add variant to attribute: "
604 "vector function declaration is missing.");
612 for (
unsigned Pos = 0, NumParams =
Parameters.size(); Pos < NumParams;
633 if (
Parameters[Pos].LinearStepOrPos >=
int(NumParams))
640 if (
Parameters[Pos].LinearStepOrPos ==
int(Pos))
646 for (
unsigned NextPos = Pos + 1; NextPos < NumParams; ++NextPos)
Analysis containing CSE Info
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallString class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
StringRef getValueAsString() const
Return the attribute's value as a string.
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
FunctionType * getFunctionType() const
This class represents a function call, abstracting a target machine's calling convention.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount getFixed(ScalarTy MinVal)
Lightweight error class with error context and mandatory checking.
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
A Module instance is used to store all the information related to an LLVM module.
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
A vector that has set insertion semantics.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
constexpr bool empty() const
empty - Check if the string is empty.
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...
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
static IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool is16bitFPTy() const
Return true if this is a 16-bit float type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Base class of all SIMD vector types.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr char const * MappingsAttrName
std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
FunctionType * createFunctionType(const VFInfo &Info, const FunctionType *ScalarFTy)
Constructs a FunctionType by applying vector function information to the type of a matching scalar fu...
void getVectorVariantNames(const CallInst &CI, SmallVectorImpl< std::string > &VariantMappings)
Populates a set of strings representing the Vector Function ABI variants associated to the CallInst C...
void setVectorVariantNames(CallInst *CI, ArrayRef< std::string > VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.
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.
This is an optimization pass for GlobalISel generic memory operations.
bool isUnpackedStructLiteral(StructType *StructTy)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Type * toVectorizedTy(Type *Ty, ElementCount EC)
A helper for converting to vectorized types.
VFISAKind
Describes the type of Instruction Set Architecture.
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...
ArrayRef< Type * > getContainedTypes(Type *const &Ty)
Returns the types contained in Ty.
VFParamKind
Describes the type of Parameters.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Holds the VFShape for a specific scalar to vector function mapping.
Encapsulates information needed to describe a parameter.
Contains the information about the kind of vectorization available.
bool hasValidParameterList() const
Validation check on the Parameters in the VFShape.
SmallVector< VFParameter, 8 > Parameters