summaryrefslogtreecommitdiff
path: root/lib/Target/AMDGPU/AMDGPULibFunc.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AMDGPU/AMDGPULibFunc.h')
-rw-r--r--lib/Target/AMDGPU/AMDGPULibFunc.h459
1 files changed, 459 insertions, 0 deletions
diff --git a/lib/Target/AMDGPU/AMDGPULibFunc.h b/lib/Target/AMDGPU/AMDGPULibFunc.h
new file mode 100644
index 000000000000..5405bc645714
--- /dev/null
+++ b/lib/Target/AMDGPU/AMDGPULibFunc.h
@@ -0,0 +1,459 @@
+//===-- AMDGPULibFunc.h ---------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _AMDGPU_LIBFUNC_H_
+#define _AMDGPU_LIBFUNC_H_
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+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 = 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 Function *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 &copyFrom);
+
+ 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 = 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_