brintos

brintos / llvm-project-archived public Read only

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