You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
460 lines
11 KiB
460 lines
11 KiB
//===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _AMDGPU_LIBFUNC_H_
|
|
#define _AMDGPU_LIBFUNC_H_
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
namespace llvm {
|
|
|
|
class FunctionCallee;
|
|
class FunctionType;
|
|
class Function;
|
|
class Module;
|
|
|
|
class AMDGPULibFuncBase {
|
|
public:
|
|
enum EFuncId {
|
|
EI_NONE,
|
|
|
|
// IMPORTANT: enums below should go in ascending by 1 value order
|
|
// because they are used as indexes in the mangling rules table.
|
|
// don't use explicit value assignment.
|
|
//
|
|
// There are two types of library functions: those with mangled
|
|
// name and those with unmangled name. The enums for the library
|
|
// functions with mangled name are defined before enums for the
|
|
// library functions with unmangled name. The enum for the last
|
|
// library function with mangled name is EI_LAST_MANGLED.
|
|
//
|
|
// Library functions with mangled name.
|
|
EI_ABS,
|
|
EI_ABS_DIFF,
|
|
EI_ACOS,
|
|
EI_ACOSH,
|
|
EI_ACOSPI,
|
|
EI_ADD_SAT,
|
|
EI_ALL,
|
|
EI_ANY,
|
|
EI_ASIN,
|
|
EI_ASINH,
|
|
EI_ASINPI,
|
|
EI_ASYNC_WORK_GROUP_COPY,
|
|
EI_ASYNC_WORK_GROUP_STRIDED_COPY,
|
|
EI_ATAN,
|
|
EI_ATAN2,
|
|
EI_ATAN2PI,
|
|
EI_ATANH,
|
|
EI_ATANPI,
|
|
EI_ATOMIC_ADD,
|
|
EI_ATOMIC_AND,
|
|
EI_ATOMIC_CMPXCHG,
|
|
EI_ATOMIC_DEC,
|
|
EI_ATOMIC_INC,
|
|
EI_ATOMIC_MAX,
|
|
EI_ATOMIC_MIN,
|
|
EI_ATOMIC_OR,
|
|
EI_ATOMIC_SUB,
|
|
EI_ATOMIC_XCHG,
|
|
EI_ATOMIC_XOR,
|
|
EI_BITSELECT,
|
|
EI_CBRT,
|
|
EI_CEIL,
|
|
EI_CLAMP,
|
|
EI_CLZ,
|
|
EI_COMMIT_READ_PIPE,
|
|
EI_COMMIT_WRITE_PIPE,
|
|
EI_COPYSIGN,
|
|
EI_COS,
|
|
EI_COSH,
|
|
EI_COSPI,
|
|
EI_CROSS,
|
|
EI_CTZ,
|
|
EI_DEGREES,
|
|
EI_DISTANCE,
|
|
EI_DIVIDE,
|
|
EI_DOT,
|
|
EI_ERF,
|
|
EI_ERFC,
|
|
EI_EXP,
|
|
EI_EXP10,
|
|
EI_EXP2,
|
|
EI_EXPM1,
|
|
EI_FABS,
|
|
EI_FAST_DISTANCE,
|
|
EI_FAST_LENGTH,
|
|
EI_FAST_NORMALIZE,
|
|
EI_FDIM,
|
|
EI_FLOOR,
|
|
EI_FMA,
|
|
EI_FMAX,
|
|
EI_FMIN,
|
|
EI_FMOD,
|
|
EI_FRACT,
|
|
EI_FREXP,
|
|
EI_GET_IMAGE_ARRAY_SIZE,
|
|
EI_GET_IMAGE_CHANNEL_DATA_TYPE,
|
|
EI_GET_IMAGE_CHANNEL_ORDER,
|
|
EI_GET_IMAGE_DIM,
|
|
EI_GET_IMAGE_HEIGHT,
|
|
EI_GET_IMAGE_WIDTH,
|
|
EI_GET_PIPE_MAX_PACKETS,
|
|
EI_GET_PIPE_NUM_PACKETS,
|
|
EI_HADD,
|
|
EI_HYPOT,
|
|
EI_ILOGB,
|
|
EI_ISEQUAL,
|
|
EI_ISFINITE,
|
|
EI_ISGREATER,
|
|
EI_ISGREATEREQUAL,
|
|
EI_ISINF,
|
|
EI_ISLESS,
|
|
EI_ISLESSEQUAL,
|
|
EI_ISLESSGREATER,
|
|
EI_ISNAN,
|
|
EI_ISNORMAL,
|
|
EI_ISNOTEQUAL,
|
|
EI_ISORDERED,
|
|
EI_ISUNORDERED,
|
|
EI_LDEXP,
|
|
EI_LENGTH,
|
|
EI_LGAMMA,
|
|
EI_LGAMMA_R,
|
|
EI_LOG,
|
|
EI_LOG10,
|
|
EI_LOG1P,
|
|
EI_LOG2,
|
|
EI_LOGB,
|
|
EI_MAD,
|
|
EI_MAD24,
|
|
EI_MAD_HI,
|
|
EI_MAD_SAT,
|
|
EI_MAX,
|
|
EI_MAXMAG,
|
|
EI_MIN,
|
|
EI_MINMAG,
|
|
EI_MIX,
|
|
EI_MODF,
|
|
EI_MUL24,
|
|
EI_MUL_HI,
|
|
EI_NAN,
|
|
EI_NEXTAFTER,
|
|
EI_NORMALIZE,
|
|
EI_POPCOUNT,
|
|
EI_POW,
|
|
EI_POWN,
|
|
EI_POWR,
|
|
EI_PREFETCH,
|
|
EI_RADIANS,
|
|
EI_RECIP,
|
|
EI_REMAINDER,
|
|
EI_REMQUO,
|
|
EI_RESERVE_READ_PIPE,
|
|
EI_RESERVE_WRITE_PIPE,
|
|
EI_RHADD,
|
|
EI_RINT,
|
|
EI_ROOTN,
|
|
EI_ROTATE,
|
|
EI_ROUND,
|
|
EI_RSQRT,
|
|
EI_SELECT,
|
|
EI_SHUFFLE,
|
|
EI_SHUFFLE2,
|
|
EI_SIGN,
|
|
EI_SIGNBIT,
|
|
EI_SIN,
|
|
EI_SINCOS,
|
|
EI_SINH,
|
|
EI_SINPI,
|
|
EI_SMOOTHSTEP,
|
|
EI_SQRT,
|
|
EI_STEP,
|
|
EI_SUB_GROUP_BROADCAST,
|
|
EI_SUB_GROUP_COMMIT_READ_PIPE,
|
|
EI_SUB_GROUP_COMMIT_WRITE_PIPE,
|
|
EI_SUB_GROUP_REDUCE_ADD,
|
|
EI_SUB_GROUP_REDUCE_MAX,
|
|
EI_SUB_GROUP_REDUCE_MIN,
|
|
EI_SUB_GROUP_RESERVE_READ_PIPE,
|
|
EI_SUB_GROUP_RESERVE_WRITE_PIPE,
|
|
EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD,
|
|
EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX,
|
|
EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN,
|
|
EI_SUB_GROUP_SCAN_INCLUSIVE_ADD,
|
|
EI_SUB_GROUP_SCAN_INCLUSIVE_MAX,
|
|
EI_SUB_GROUP_SCAN_INCLUSIVE_MIN,
|
|
EI_SUB_SAT,
|
|
EI_TAN,
|
|
EI_TANH,
|
|
EI_TANPI,
|
|
EI_TGAMMA,
|
|
EI_TRUNC,
|
|
EI_UPSAMPLE,
|
|
EI_VEC_STEP,
|
|
EI_VSTORE,
|
|
EI_VSTORE16,
|
|
EI_VSTORE2,
|
|
EI_VSTORE3,
|
|
EI_VSTORE4,
|
|
EI_VSTORE8,
|
|
EI_WORK_GROUP_COMMIT_READ_PIPE,
|
|
EI_WORK_GROUP_COMMIT_WRITE_PIPE,
|
|
EI_WORK_GROUP_REDUCE_ADD,
|
|
EI_WORK_GROUP_REDUCE_MAX,
|
|
EI_WORK_GROUP_REDUCE_MIN,
|
|
EI_WORK_GROUP_RESERVE_READ_PIPE,
|
|
EI_WORK_GROUP_RESERVE_WRITE_PIPE,
|
|
EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD,
|
|
EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX,
|
|
EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN,
|
|
EI_WORK_GROUP_SCAN_INCLUSIVE_ADD,
|
|
EI_WORK_GROUP_SCAN_INCLUSIVE_MAX,
|
|
EI_WORK_GROUP_SCAN_INCLUSIVE_MIN,
|
|
EI_WRITE_IMAGEF,
|
|
EI_WRITE_IMAGEI,
|
|
EI_WRITE_IMAGEUI,
|
|
EI_NCOS,
|
|
EI_NEXP2,
|
|
EI_NFMA,
|
|
EI_NLOG2,
|
|
EI_NRCP,
|
|
EI_NRSQRT,
|
|
EI_NSIN,
|
|
EI_NSQRT,
|
|
EI_FTZ,
|
|
EI_FLDEXP,
|
|
EI_CLASS,
|
|
EI_RCBRT,
|
|
EI_LAST_MANGLED =
|
|
EI_RCBRT, /* The last library function with mangled name */
|
|
|
|
// Library functions with unmangled name.
|
|
EI_READ_PIPE_2,
|
|
EI_READ_PIPE_4,
|
|
EI_WRITE_PIPE_2,
|
|
EI_WRITE_PIPE_4,
|
|
|
|
EX_INTRINSICS_COUNT
|
|
};
|
|
|
|
enum ENamePrefix {
|
|
NOPFX,
|
|
NATIVE,
|
|
HALF
|
|
};
|
|
|
|
enum EType {
|
|
B8 = 1,
|
|
B16 = 2,
|
|
B32 = 3,
|
|
B64 = 4,
|
|
SIZE_MASK = 7,
|
|
FLOAT = 0x10,
|
|
INT = 0x20,
|
|
UINT = 0x30,
|
|
BASE_TYPE_MASK = 0x30,
|
|
U8 = UINT | B8,
|
|
U16 = UINT | B16,
|
|
U32 = UINT | B32,
|
|
U64 = UINT | B64,
|
|
I8 = INT | B8,
|
|
I16 = INT | B16,
|
|
I32 = INT | B32,
|
|
I64 = INT | B64,
|
|
F16 = FLOAT | B16,
|
|
F32 = FLOAT | B32,
|
|
F64 = FLOAT | B64,
|
|
IMG1DA = 0x80,
|
|
IMG1DB,
|
|
IMG2DA,
|
|
IMG1D,
|
|
IMG2D,
|
|
IMG3D,
|
|
SAMPLER,
|
|
EVENT,
|
|
DUMMY
|
|
};
|
|
|
|
enum EPtrKind {
|
|
BYVALUE = 0,
|
|
ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF.
|
|
CONST = 0x10,
|
|
VOLATILE = 0x20
|
|
};
|
|
|
|
struct Param {
|
|
unsigned char ArgType;
|
|
unsigned char VectorSize;
|
|
unsigned char PtrKind;
|
|
|
|
unsigned char Reserved;
|
|
|
|
void reset() {
|
|
ArgType = 0;
|
|
VectorSize = 1;
|
|
PtrKind = 0;
|
|
}
|
|
Param() { reset(); }
|
|
|
|
template <typename Stream>
|
|
void mangleItanium(Stream& os);
|
|
};
|
|
static bool isMangled(EFuncId Id) {
|
|
return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
|
|
}
|
|
|
|
static unsigned getEPtrKindFromAddrSpace(unsigned AS) {
|
|
assert(((AS + 1) & ~ADDR_SPACE) == 0);
|
|
return AS + 1;
|
|
}
|
|
|
|
static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
|
|
Kind = Kind & ADDR_SPACE;
|
|
assert(Kind >= 1);
|
|
return Kind - 1;
|
|
}
|
|
};
|
|
|
|
class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
|
|
public:
|
|
AMDGPULibFuncImpl() {}
|
|
virtual ~AMDGPULibFuncImpl() {}
|
|
|
|
/// Get unmangled name for mangled library function and name for unmangled
|
|
/// library function.
|
|
virtual std::string getName() const = 0;
|
|
virtual unsigned getNumArgs() const = 0;
|
|
EFuncId getId() const { return FuncId; }
|
|
ENamePrefix getPrefix() const { return FKind; }
|
|
|
|
bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
|
|
|
|
void setId(EFuncId id) { FuncId = id; }
|
|
virtual bool parseFuncName(StringRef &mangledName) = 0;
|
|
|
|
/// \return The mangled function name for mangled library functions
|
|
/// and unmangled function name for unmangled library functions.
|
|
virtual std::string mangle() const = 0;
|
|
|
|
void setName(StringRef N) { Name = std::string(N); }
|
|
void setPrefix(ENamePrefix pfx) { FKind = pfx; }
|
|
|
|
virtual FunctionType *getFunctionType(Module &M) const = 0;
|
|
|
|
protected:
|
|
EFuncId FuncId;
|
|
std::string Name;
|
|
ENamePrefix FKind;
|
|
};
|
|
|
|
/// Wrapper class for AMDGPULIbFuncImpl
|
|
class AMDGPULibFunc : public AMDGPULibFuncBase {
|
|
public:
|
|
explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
|
|
AMDGPULibFunc(const AMDGPULibFunc &F);
|
|
/// Clone a mangled library func with the Id \p Id and argument info from \p
|
|
/// CopyFrom.
|
|
explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
|
|
/// Construct an unmangled library function on the fly.
|
|
explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
|
|
|
|
AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
|
|
|
|
/// Get unmangled name for mangled library function and name for unmangled
|
|
/// library function.
|
|
std::string getName() const { return Impl->getName(); }
|
|
unsigned getNumArgs() const { return Impl->getNumArgs(); }
|
|
EFuncId getId() const { return Impl->getId(); }
|
|
ENamePrefix getPrefix() const { return Impl->getPrefix(); }
|
|
/// Get leading parameters for mangled lib functions.
|
|
Param *getLeads();
|
|
const Param *getLeads() const;
|
|
|
|
bool isMangled() const { return Impl->isMangled(); }
|
|
void setId(EFuncId Id) { Impl->setId(Id); }
|
|
bool parseFuncName(StringRef &MangledName) {
|
|
return Impl->parseFuncName(MangledName);
|
|
}
|
|
|
|
/// \return The mangled function name for mangled library functions
|
|
/// and unmangled function name for unmangled library functions.
|
|
std::string mangle() const { return Impl->mangle(); }
|
|
|
|
void setName(StringRef N) { Impl->setName(N); }
|
|
void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
|
|
|
|
FunctionType *getFunctionType(Module &M) const {
|
|
return Impl->getFunctionType(M);
|
|
}
|
|
static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
|
|
|
|
static FunctionCallee getOrInsertFunction(llvm::Module *M,
|
|
const AMDGPULibFunc &fInfo);
|
|
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
|
|
|
|
private:
|
|
/// Initialize as a mangled library function.
|
|
void initMangled();
|
|
std::unique_ptr<AMDGPULibFuncImpl> Impl;
|
|
};
|
|
|
|
class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
|
|
public:
|
|
Param Leads[2];
|
|
|
|
explicit AMDGPUMangledLibFunc();
|
|
explicit AMDGPUMangledLibFunc(EFuncId id,
|
|
const AMDGPUMangledLibFunc ©From);
|
|
|
|
std::string getName() const override;
|
|
unsigned getNumArgs() const override;
|
|
FunctionType *getFunctionType(Module &M) const override;
|
|
static StringRef getUnmangledName(StringRef MangledName);
|
|
|
|
bool parseFuncName(StringRef &mangledName) override;
|
|
|
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
|
|
|
|
std::string mangle() const override;
|
|
|
|
private:
|
|
std::string mangleNameItanium() const;
|
|
|
|
std::string mangleName(StringRef Name) const;
|
|
bool parseUnmangledName(StringRef MangledName);
|
|
|
|
template <typename Stream> void writeName(Stream &OS) const;
|
|
};
|
|
|
|
class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
|
|
FunctionType *FuncTy;
|
|
|
|
public:
|
|
explicit AMDGPUUnmangledLibFunc();
|
|
explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
|
|
Name = std::string(FName);
|
|
FuncTy = FT;
|
|
}
|
|
std::string getName() const override { return Name; }
|
|
unsigned getNumArgs() const override;
|
|
FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
|
|
|
|
bool parseFuncName(StringRef &Name) override;
|
|
|
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
|
|
|
|
std::string mangle() const override { return Name; }
|
|
|
|
void setFunctionType(FunctionType *FT) { FuncTy = FT; }
|
|
};
|
|
}
|
|
#endif // _AMDGPU_LIBFUNC_H_
|