Home | History | Annotate | Line # | Download | only in AMDGPU
      1 //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef _AMDGPU_LIBFUNC_H_
     10 #define _AMDGPU_LIBFUNC_H_
     11 
     12 #include "llvm/ADT/StringRef.h"
     13 
     14 namespace llvm {
     15 
     16 class FunctionCallee;
     17 class FunctionType;
     18 class Function;
     19 class Module;
     20 
     21 class AMDGPULibFuncBase {
     22 public:
     23   enum EFuncId {
     24     EI_NONE,
     25 
     26     // IMPORTANT: enums below should go in ascending by 1 value order
     27     // because they are used as indexes in the mangling rules table.
     28     // don't use explicit value assignment.
     29     //
     30     // There are two types of library functions: those with mangled
     31     // name and those with unmangled name. The enums for the library
     32     // functions with mangled name are defined before enums for the
     33     // library functions with unmangled name. The enum for the last
     34     // library function with mangled name is EI_LAST_MANGLED.
     35     //
     36     // Library functions with mangled name.
     37     EI_ABS,
     38     EI_ABS_DIFF,
     39     EI_ACOS,
     40     EI_ACOSH,
     41     EI_ACOSPI,
     42     EI_ADD_SAT,
     43     EI_ALL,
     44     EI_ANY,
     45     EI_ASIN,
     46     EI_ASINH,
     47     EI_ASINPI,
     48     EI_ASYNC_WORK_GROUP_COPY,
     49     EI_ASYNC_WORK_GROUP_STRIDED_COPY,
     50     EI_ATAN,
     51     EI_ATAN2,
     52     EI_ATAN2PI,
     53     EI_ATANH,
     54     EI_ATANPI,
     55     EI_ATOMIC_ADD,
     56     EI_ATOMIC_AND,
     57     EI_ATOMIC_CMPXCHG,
     58     EI_ATOMIC_DEC,
     59     EI_ATOMIC_INC,
     60     EI_ATOMIC_MAX,
     61     EI_ATOMIC_MIN,
     62     EI_ATOMIC_OR,
     63     EI_ATOMIC_SUB,
     64     EI_ATOMIC_XCHG,
     65     EI_ATOMIC_XOR,
     66     EI_BITSELECT,
     67     EI_CBRT,
     68     EI_CEIL,
     69     EI_CLAMP,
     70     EI_CLZ,
     71     EI_COMMIT_READ_PIPE,
     72     EI_COMMIT_WRITE_PIPE,
     73     EI_COPYSIGN,
     74     EI_COS,
     75     EI_COSH,
     76     EI_COSPI,
     77     EI_CROSS,
     78     EI_CTZ,
     79     EI_DEGREES,
     80     EI_DISTANCE,
     81     EI_DIVIDE,
     82     EI_DOT,
     83     EI_ERF,
     84     EI_ERFC,
     85     EI_EXP,
     86     EI_EXP10,
     87     EI_EXP2,
     88     EI_EXPM1,
     89     EI_FABS,
     90     EI_FAST_DISTANCE,
     91     EI_FAST_LENGTH,
     92     EI_FAST_NORMALIZE,
     93     EI_FDIM,
     94     EI_FLOOR,
     95     EI_FMA,
     96     EI_FMAX,
     97     EI_FMIN,
     98     EI_FMOD,
     99     EI_FRACT,
    100     EI_FREXP,
    101     EI_GET_IMAGE_ARRAY_SIZE,
    102     EI_GET_IMAGE_CHANNEL_DATA_TYPE,
    103     EI_GET_IMAGE_CHANNEL_ORDER,
    104     EI_GET_IMAGE_DIM,
    105     EI_GET_IMAGE_HEIGHT,
    106     EI_GET_IMAGE_WIDTH,
    107     EI_GET_PIPE_MAX_PACKETS,
    108     EI_GET_PIPE_NUM_PACKETS,
    109     EI_HADD,
    110     EI_HYPOT,
    111     EI_ILOGB,
    112     EI_ISEQUAL,
    113     EI_ISFINITE,
    114     EI_ISGREATER,
    115     EI_ISGREATEREQUAL,
    116     EI_ISINF,
    117     EI_ISLESS,
    118     EI_ISLESSEQUAL,
    119     EI_ISLESSGREATER,
    120     EI_ISNAN,
    121     EI_ISNORMAL,
    122     EI_ISNOTEQUAL,
    123     EI_ISORDERED,
    124     EI_ISUNORDERED,
    125     EI_LDEXP,
    126     EI_LENGTH,
    127     EI_LGAMMA,
    128     EI_LGAMMA_R,
    129     EI_LOG,
    130     EI_LOG10,
    131     EI_LOG1P,
    132     EI_LOG2,
    133     EI_LOGB,
    134     EI_MAD,
    135     EI_MAD24,
    136     EI_MAD_HI,
    137     EI_MAD_SAT,
    138     EI_MAX,
    139     EI_MAXMAG,
    140     EI_MIN,
    141     EI_MINMAG,
    142     EI_MIX,
    143     EI_MODF,
    144     EI_MUL24,
    145     EI_MUL_HI,
    146     EI_NAN,
    147     EI_NEXTAFTER,
    148     EI_NORMALIZE,
    149     EI_POPCOUNT,
    150     EI_POW,
    151     EI_POWN,
    152     EI_POWR,
    153     EI_PREFETCH,
    154     EI_RADIANS,
    155     EI_RECIP,
    156     EI_REMAINDER,
    157     EI_REMQUO,
    158     EI_RESERVE_READ_PIPE,
    159     EI_RESERVE_WRITE_PIPE,
    160     EI_RHADD,
    161     EI_RINT,
    162     EI_ROOTN,
    163     EI_ROTATE,
    164     EI_ROUND,
    165     EI_RSQRT,
    166     EI_SELECT,
    167     EI_SHUFFLE,
    168     EI_SHUFFLE2,
    169     EI_SIGN,
    170     EI_SIGNBIT,
    171     EI_SIN,
    172     EI_SINCOS,
    173     EI_SINH,
    174     EI_SINPI,
    175     EI_SMOOTHSTEP,
    176     EI_SQRT,
    177     EI_STEP,
    178     EI_SUB_GROUP_BROADCAST,
    179     EI_SUB_GROUP_COMMIT_READ_PIPE,
    180     EI_SUB_GROUP_COMMIT_WRITE_PIPE,
    181     EI_SUB_GROUP_REDUCE_ADD,
    182     EI_SUB_GROUP_REDUCE_MAX,
    183     EI_SUB_GROUP_REDUCE_MIN,
    184     EI_SUB_GROUP_RESERVE_READ_PIPE,
    185     EI_SUB_GROUP_RESERVE_WRITE_PIPE,
    186     EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD,
    187     EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX,
    188     EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN,
    189     EI_SUB_GROUP_SCAN_INCLUSIVE_ADD,
    190     EI_SUB_GROUP_SCAN_INCLUSIVE_MAX,
    191     EI_SUB_GROUP_SCAN_INCLUSIVE_MIN,
    192     EI_SUB_SAT,
    193     EI_TAN,
    194     EI_TANH,
    195     EI_TANPI,
    196     EI_TGAMMA,
    197     EI_TRUNC,
    198     EI_UPSAMPLE,
    199     EI_VEC_STEP,
    200     EI_VSTORE,
    201     EI_VSTORE16,
    202     EI_VSTORE2,
    203     EI_VSTORE3,
    204     EI_VSTORE4,
    205     EI_VSTORE8,
    206     EI_WORK_GROUP_COMMIT_READ_PIPE,
    207     EI_WORK_GROUP_COMMIT_WRITE_PIPE,
    208     EI_WORK_GROUP_REDUCE_ADD,
    209     EI_WORK_GROUP_REDUCE_MAX,
    210     EI_WORK_GROUP_REDUCE_MIN,
    211     EI_WORK_GROUP_RESERVE_READ_PIPE,
    212     EI_WORK_GROUP_RESERVE_WRITE_PIPE,
    213     EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD,
    214     EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX,
    215     EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN,
    216     EI_WORK_GROUP_SCAN_INCLUSIVE_ADD,
    217     EI_WORK_GROUP_SCAN_INCLUSIVE_MAX,
    218     EI_WORK_GROUP_SCAN_INCLUSIVE_MIN,
    219     EI_WRITE_IMAGEF,
    220     EI_WRITE_IMAGEI,
    221     EI_WRITE_IMAGEUI,
    222     EI_NCOS,
    223     EI_NEXP2,
    224     EI_NFMA,
    225     EI_NLOG2,
    226     EI_NRCP,
    227     EI_NRSQRT,
    228     EI_NSIN,
    229     EI_NSQRT,
    230     EI_FTZ,
    231     EI_FLDEXP,
    232     EI_CLASS,
    233     EI_RCBRT,
    234     EI_LAST_MANGLED =
    235         EI_RCBRT, /* The last library function with mangled name */
    236 
    237     // Library functions with unmangled name.
    238     EI_READ_PIPE_2,
    239     EI_READ_PIPE_4,
    240     EI_WRITE_PIPE_2,
    241     EI_WRITE_PIPE_4,
    242 
    243     EX_INTRINSICS_COUNT
    244   };
    245 
    246   enum ENamePrefix {
    247     NOPFX,
    248     NATIVE,
    249     HALF
    250   };
    251 
    252   enum EType {
    253     B8  = 1,
    254     B16 = 2,
    255     B32 = 3,
    256     B64 = 4,
    257     SIZE_MASK = 7,
    258     FLOAT = 0x10,
    259     INT   = 0x20,
    260     UINT  = 0x30,
    261     BASE_TYPE_MASK = 0x30,
    262     U8  =  UINT | B8,
    263     U16 =  UINT | B16,
    264     U32 =  UINT | B32,
    265     U64 =  UINT | B64,
    266     I8  =   INT | B8,
    267     I16 =   INT | B16,
    268     I32 =   INT | B32,
    269     I64 =   INT | B64,
    270     F16 = FLOAT | B16,
    271     F32 = FLOAT | B32,
    272     F64 = FLOAT | B64,
    273     IMG1DA = 0x80,
    274     IMG1DB,
    275     IMG2DA,
    276     IMG1D,
    277     IMG2D,
    278     IMG3D,
    279     SAMPLER,
    280     EVENT,
    281     DUMMY
    282   };
    283 
    284   enum EPtrKind {
    285     BYVALUE = 0,
    286     ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF.
    287     CONST      = 0x10,
    288     VOLATILE   = 0x20
    289   };
    290 
    291   struct Param {
    292     unsigned char ArgType;
    293     unsigned char VectorSize;
    294     unsigned char PtrKind;
    295 
    296     unsigned char Reserved;
    297 
    298     void reset() {
    299       ArgType = 0;
    300       VectorSize = 1;
    301       PtrKind = 0;
    302     }
    303     Param() { reset(); }
    304 
    305     template <typename Stream>
    306     void mangleItanium(Stream& os);
    307   };
    308   static bool isMangled(EFuncId Id) {
    309     return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
    310   }
    311 
    312   static unsigned getEPtrKindFromAddrSpace(unsigned AS) {
    313     assert(((AS + 1) & ~ADDR_SPACE) == 0);
    314     return AS + 1;
    315   }
    316 
    317   static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
    318     Kind = Kind & ADDR_SPACE;
    319     assert(Kind >= 1);
    320     return Kind - 1;
    321   }
    322 };
    323 
    324 class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
    325 public:
    326   AMDGPULibFuncImpl() {}
    327   virtual ~AMDGPULibFuncImpl() {}
    328 
    329   /// Get unmangled name for mangled library function and name for unmangled
    330   /// library function.
    331   virtual std::string getName() const = 0;
    332   virtual unsigned getNumArgs() const = 0;
    333   EFuncId getId() const { return FuncId; }
    334   ENamePrefix getPrefix() const { return FKind; }
    335 
    336   bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
    337 
    338   void setId(EFuncId id) { FuncId = id; }
    339   virtual bool parseFuncName(StringRef &mangledName) = 0;
    340 
    341   /// \return The mangled function name for mangled library functions
    342   /// and unmangled function name for unmangled library functions.
    343   virtual std::string mangle() const = 0;
    344 
    345   void setName(StringRef N) { Name = std::string(N); }
    346   void setPrefix(ENamePrefix pfx) { FKind = pfx; }
    347 
    348   virtual FunctionType *getFunctionType(Module &M) const = 0;
    349 
    350 protected:
    351   EFuncId FuncId;
    352   std::string Name;
    353   ENamePrefix FKind;
    354 };
    355 
    356 /// Wrapper class for AMDGPULIbFuncImpl
    357 class AMDGPULibFunc : public AMDGPULibFuncBase {
    358 public:
    359   explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
    360   AMDGPULibFunc(const AMDGPULibFunc &F);
    361   /// Clone a mangled library func with the Id \p Id and argument info from \p
    362   /// CopyFrom.
    363   explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
    364   /// Construct an unmangled library function on the fly.
    365   explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
    366 
    367   AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
    368 
    369   /// Get unmangled name for mangled library function and name for unmangled
    370   /// library function.
    371   std::string getName() const { return Impl->getName(); }
    372   unsigned getNumArgs() const { return Impl->getNumArgs(); }
    373   EFuncId getId() const { return Impl->getId(); }
    374   ENamePrefix getPrefix() const { return Impl->getPrefix(); }
    375   /// Get leading parameters for mangled lib functions.
    376   Param *getLeads();
    377   const Param *getLeads() const;
    378 
    379   bool isMangled() const { return Impl->isMangled(); }
    380   void setId(EFuncId Id) { Impl->setId(Id); }
    381   bool parseFuncName(StringRef &MangledName) {
    382     return Impl->parseFuncName(MangledName);
    383   }
    384 
    385   /// \return The mangled function name for mangled library functions
    386   /// and unmangled function name for unmangled library functions.
    387   std::string mangle() const { return Impl->mangle(); }
    388 
    389   void setName(StringRef N) { Impl->setName(N); }
    390   void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
    391 
    392   FunctionType *getFunctionType(Module &M) const {
    393     return Impl->getFunctionType(M);
    394   }
    395   static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
    396 
    397   static FunctionCallee getOrInsertFunction(llvm::Module *M,
    398                                             const AMDGPULibFunc &fInfo);
    399   static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
    400 
    401 private:
    402   /// Initialize as a mangled library function.
    403   void initMangled();
    404   std::unique_ptr<AMDGPULibFuncImpl> Impl;
    405 };
    406 
    407 class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
    408 public:
    409   Param Leads[2];
    410 
    411   explicit AMDGPUMangledLibFunc();
    412   explicit AMDGPUMangledLibFunc(EFuncId id,
    413                                 const AMDGPUMangledLibFunc &copyFrom);
    414 
    415   std::string getName() const override;
    416   unsigned getNumArgs() const override;
    417   FunctionType *getFunctionType(Module &M) const override;
    418   static StringRef getUnmangledName(StringRef MangledName);
    419 
    420   bool parseFuncName(StringRef &mangledName) override;
    421 
    422   // Methods for support type inquiry through isa, cast, and dyn_cast:
    423   static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
    424 
    425   std::string mangle() const override;
    426 
    427 private:
    428   std::string mangleNameItanium() const;
    429 
    430   std::string mangleName(StringRef Name) const;
    431   bool parseUnmangledName(StringRef MangledName);
    432 
    433   template <typename Stream> void writeName(Stream &OS) const;
    434 };
    435 
    436 class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
    437   FunctionType *FuncTy;
    438 
    439 public:
    440   explicit AMDGPUUnmangledLibFunc();
    441   explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
    442     Name = std::string(FName);
    443     FuncTy = FT;
    444   }
    445   std::string getName() const override { return Name; }
    446   unsigned getNumArgs() const override;
    447   FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
    448 
    449   bool parseFuncName(StringRef &Name) override;
    450 
    451   // Methods for support type inquiry through isa, cast, and dyn_cast:
    452   static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
    453 
    454   std::string mangle() const override { return Name; }
    455 
    456   void setFunctionType(FunctionType *FT) { FuncTy = FT; }
    457 };
    458 }
    459 #endif // _AMDGPU_LIBFUNC_H_
    460