20#define DEBUG_TYPE "vfabi-demangler"
36 if (MangledName.
empty())
37 return ParseRet::Error;
40 ISA = VFISAKind::LLVM;
43 .
Case(
"n", VFISAKind::AdvancedSIMD)
44 .
Case(
"s", VFISAKind::SVE)
45 .
Case(
"b", VFISAKind::SSE)
46 .
Case(
"c", VFISAKind::AVX)
47 .
Case(
"d", VFISAKind::AVX2)
48 .
Case(
"e", VFISAKind::AVX512)
59static ParseRet tryParseMask(
StringRef &MangledName,
bool &IsMasked) {
70 return ParseRet::Error;
79 std::pair<unsigned, bool> &ParsedVF) {
82 if (ISA != VFISAKind::SVE) {
83 LLVM_DEBUG(
dbgs() <<
"Vector function variant declared with scalable VF "
84 <<
"but ISA is not SVE\n");
85 return ParseRet::Error;
97 return ParseRet::Error;
101 return ParseRet::Error;
103 ParsedVF = {VF,
false};
119static ParseRet tryParseLinearTokenWithRuntimeStep(
StringRef &ParseString,
125 return ParseRet::Error;
129 return ParseRet::None;
143static ParseRet tryParseLinearWithRuntimeStep(
StringRef &ParseString,
149 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"ls");
150 if (Ret != ParseRet::None)
154 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Rs");
155 if (Ret != ParseRet::None)
159 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Ls");
160 if (Ret != ParseRet::None)
164 Ret = tryParseLinearTokenWithRuntimeStep(ParseString, PKind, StepOrPos,
"Us");
165 if (Ret != ParseRet::None)
168 return ParseRet::None;
183static ParseRet tryParseCompileTimeLinearToken(
StringRef &ParseString,
197 return ParseRet::None;
209static ParseRet tryParseLinearWithCompileTimeStep(
StringRef &ParseString,
213 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"l") ==
218 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"R") ==
223 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"L") ==
228 if (tryParseCompileTimeLinearToken(ParseString, PKind, StepOrPos,
"U") ==
232 return ParseRet::None;
246 PKind = VFParamKind::Vector;
252 PKind = VFParamKind::OMP_Uniform;
257 const ParseRet HasLinearRuntime =
258 tryParseLinearWithRuntimeStep(ParseString, PKind, StepOrPos);
259 if (HasLinearRuntime != ParseRet::None)
260 return HasLinearRuntime;
262 const ParseRet HasLinearCompileTime =
263 tryParseLinearWithCompileTimeStep(ParseString, PKind, StepOrPos);
264 if (HasLinearCompileTime != ParseRet::None)
265 return HasLinearCompileTime;
267 return ParseRet::None;
278static ParseRet tryParseAlign(
StringRef &ParseString,
Align &Alignment) {
283 return ParseRet::Error;
286 return ParseRet::Error;
288 Alignment =
Align(Val);
293 return ParseRet::None;
302static std::optional<ElementCount> getElementCountForTy(
const VFISAKind ISA,
305 assert(ISA == VFISAKind::SVE &&
306 "Scalable VF decoding only implemented for SVE\n");
322static std::optional<ElementCount>
328 for (
auto &Param : Params) {
331 if (Param.ParamKind == VFParamKind::Vector) {
332 Type *PTy = Signature->getParamType(Param.ParamPos);
334 std::optional<ElementCount> EC = getElementCountForTy(ISA, PTy);
341 if (ElementCount::isKnownLT(*EC, MinEC))
347 Type *
RetTy = Signature->getReturnType();
348 if (!
RetTy->isVoidTy()) {
349 std::optional<ElementCount> ReturnEC = getElementCountForTy(ISA,
RetTy);
353 if (ElementCount::isKnownLT(*ReturnEC, MinEC))
372 const StringRef OriginalName = MangledName;
385 if (tryParseISA(MangledName, ISA) != ParseRet::OK)
390 if (tryParseMask(MangledName, IsMasked) != ParseRet::OK)
394 std::pair<unsigned, bool> ParsedVF;
395 if (tryParseVLEN(MangledName, ISA, ParsedVF) != ParseRet::OK)
402 const unsigned ParameterPos = Parameters.size();
405 ParamFound = tryParseParameter(MangledName, PKind, StepOrPos);
408 if (ParamFound == ParseRet::Error)
411 if (ParamFound == ParseRet::OK) {
414 const ParseRet AlignFound = tryParseAlign(MangledName, Alignment);
416 if (AlignFound == ParseRet::Error)
420 Parameters.push_back({ParameterPos, PKind, StepOrPos, Alignment});
422 }
while (ParamFound == ParseRet::OK);
426 if (Parameters.empty())
439 std::optional<ElementCount> EC;
440 if (ParsedVF.second) {
441 EC = getScalableECFromSignature(FTy, ISA, Parameters);
455 MangledName.
take_while([](
char In) {
return In !=
'('; });
457 if (ScalarName.
empty())
461 MangledName = MangledName.
ltrim(ScalarName);
467 VectorName = MangledName;
469 if (VectorName.
empty())
475 if (ISA == VFISAKind::LLVM && VectorName == OriginalName)
481 const unsigned Pos = Parameters.size();
482 Parameters.push_back({Pos, VFParamKind::GlobalPredicate});
490 const auto NGlobalPreds =
492 return PK.
ParamKind == VFParamKind::GlobalPredicate;
494 assert(NGlobalPreds < 2 &&
"Cannot have more than one global predicate.");
496 assert(Parameters.back().ParamKind == VFParamKind::GlobalPredicate &&
497 "The global predicate must be the last parameter");
499 const VFShape Shape({*EC, Parameters});
500 return VFInfo({Shape, std::string(ScalarName), std::string(VectorName), ISA});
505 .
Case(
"v", VFParamKind::Vector)
506 .
Case(
"l", VFParamKind::OMP_Linear)
507 .
Case(
"R", VFParamKind::OMP_LinearRef)
508 .
Case(
"L", VFParamKind::OMP_LinearVal)
509 .
Case(
"U", VFParamKind::OMP_LinearUVal)
510 .
Case(
"ls", VFParamKind::OMP_LinearPos)
511 .
Case(
"Ls", VFParamKind::OMP_LinearValPos)
512 .
Case(
"Rs", VFParamKind::OMP_LinearRefPos)
513 .
Case(
"Us", VFParamKind::OMP_LinearUValPos)
514 .
Case(
"u", VFParamKind::OMP_Uniform)
515 .
Default(VFParamKind::Unknown);
517 if (ParamKind != VFParamKind::Unknown)
522 " that have a textual representation in the mangled name"
523 " of the Vector Function ABI");
533 S.
split(ListAttr,
",");
536 std::optional<VFInfo>
Info =
539 LLVM_DEBUG(
dbgs() <<
"VFABI: Adding mapping '" << S <<
"' for " << CI
541 VariantMappings.
push_back(std::string(S));
552 int ScalarParamIndex = 0;
553 for (
auto VFParam :
Info.Shape.Parameters) {
554 if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
562 if (VFParam.ParamKind == VFParamKind::Vector)
563 OperandTy = VectorType::get(OperandTy, VF);
568 if (!
RetTy->isVoidTy())
570 return FunctionType::get(
RetTy, VecTypes,
false);
575 if (VariantMappings.
empty())
580 for (
const std::string &VariantMapping : VariantMappings)
581 Out << VariantMapping <<
",";
588 for (
const std::string &VariantMapping : VariantMappings) {
589 LLVM_DEBUG(
dbgs() <<
"VFABI: adding mapping '" << VariantMapping <<
"'\n");
590 std::optional<VFInfo> VI =
592 assert(VI &&
"Cannot add an invalid VFABI name.");
593 assert(M->getNamedValue(VI->VectorName) &&
594 "Cannot add variant to attribute: "
595 "vector function declaration is missing.");
603 for (
unsigned Pos = 0, NumParams =
Parameters.size(); Pos < NumParams;
624 if (
Parameters[Pos].LinearStepOrPos >=
int(NumParams))
631 if (
Parameters[Pos].LinearStepOrPos ==
int(Pos))
637 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)
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.
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.
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...
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