diff options
Diffstat (limited to 'lib/Target/AMDGPU/AMDGPULibFunc.h')
| -rw-r--r-- | lib/Target/AMDGPU/AMDGPULibFunc.h | 459 |
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 ©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 = 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_ |
