brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.6 KiB · 332bf79 Raw
485 lines · c
1//===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- 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// This file declares SPIR and SPIR-V TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H15 16#include "Targets.h"17#include "clang/Basic/TargetInfo.h"18#include "clang/Basic/TargetOptions.h"19#include "llvm/Support/Compiler.h"20#include "llvm/Support/VersionTuple.h"21#include "llvm/TargetParser/Triple.h"22#include <optional>23 24namespace clang {25namespace targets {26 27// Used by both the SPIR and SPIR-V targets.28static const unsigned SPIRDefIsPrivMap[] = {29    0, // Default30    1, // opencl_global31    3, // opencl_local32    2, // opencl_constant33    0, // opencl_private34    4, // opencl_generic35    5, // opencl_global_device36    6, // opencl_global_host37    0, // cuda_device38    0, // cuda_constant39    0, // cuda_shared40    // SYCL address space values for this map are dummy41    0,  // sycl_global42    0,  // sycl_global_device43    0,  // sycl_global_host44    0,  // sycl_local45    0,  // sycl_private46    0,  // ptr32_sptr47    0,  // ptr32_uptr48    0,  // ptr6449    3,  // hlsl_groupshared50    12, // hlsl_constant51    10, // hlsl_private52    11, // hlsl_device53    7,  // hlsl_input54    // Wasm address space values for this target are dummy values,55    // as it is only enabled for Wasm targets.56    20, // wasm_funcref57};58 59// Used by both the SPIR and SPIR-V targets.60static const unsigned SPIRDefIsGenMap[] = {61    4, // Default62    1, // opencl_global63    3, // opencl_local64    2, // opencl_constant65    0, // opencl_private66    4, // opencl_generic67    5, // opencl_global_device68    6, // opencl_global_host69    // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V70    // translation). This mapping is enabled when the language mode is HIP.71    1, // cuda_device72    // cuda_constant pointer can be casted to default/"flat" pointer, but in73    // SPIR-V casts between constant and generic pointers are not allowed. For74    // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.75    1,  // cuda_constant76    3,  // cuda_shared77    1,  // sycl_global78    5,  // sycl_global_device79    6,  // sycl_global_host80    3,  // sycl_local81    0,  // sycl_private82    0,  // ptr32_sptr83    0,  // ptr32_uptr84    0,  // ptr6485    3,  // hlsl_groupshared86    0,  // hlsl_constant87    10, // hlsl_private88    11, // hlsl_device89    7,  // hlsl_input90    // Wasm address space values for this target are dummy values,91    // as it is only enabled for Wasm targets.92    20, // wasm_funcref93};94 95// Base class for SPIR and SPIR-V target info.96class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {97  std::unique_ptr<TargetInfo> HostTarget;98 99protected:100  BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)101      : TargetInfo(Triple) {102    assert((Triple.isSPIR() || Triple.isSPIRV()) &&103           "Invalid architecture for SPIR or SPIR-V.");104    TLSSupported = false;105    VLASupported = false;106    LongWidth = LongAlign = 64;107    AddrSpaceMap = &SPIRDefIsPrivMap;108    UseAddrSpaceMapMangling = true;109    HasFastHalfType = true;110    HasFloat16 = true;111    HasBFloat16 = true;112    HasFullBFloat16 = true;113    BFloat16Width = BFloat16Align = 16;114    BFloat16Format = &llvm::APFloat::BFloat();115    // Define available target features116    // These must be defined in sorted order!117    NoAsmVariants = true;118 119    llvm::Triple HostTriple(Opts.HostTriple);120    if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&121        HostTriple.getArch() != llvm::Triple::UnknownArch) {122      HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);123 124      // Copy properties from host target.125      BoolWidth = HostTarget->getBoolWidth();126      BoolAlign = HostTarget->getBoolAlign();127      IntWidth = HostTarget->getIntWidth();128      IntAlign = HostTarget->getIntAlign();129      HalfWidth = HostTarget->getHalfWidth();130      HalfAlign = HostTarget->getHalfAlign();131      FloatWidth = HostTarget->getFloatWidth();132      FloatAlign = HostTarget->getFloatAlign();133      DoubleWidth = HostTarget->getDoubleWidth();134      DoubleAlign = HostTarget->getDoubleAlign();135      LongWidth = HostTarget->getLongWidth();136      LongAlign = HostTarget->getLongAlign();137      LongLongWidth = HostTarget->getLongLongWidth();138      LongLongAlign = HostTarget->getLongLongAlign();139      MinGlobalAlign =140          HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,141                                        /* HasNonWeakDef = */ true);142      NewAlign = HostTarget->getNewAlign();143      DefaultAlignForAttributeAligned =144          HostTarget->getDefaultAlignForAttributeAligned();145      IntMaxType = HostTarget->getIntMaxType();146      WCharType = HostTarget->getWCharType();147      WIntType = HostTarget->getWIntType();148      Char16Type = HostTarget->getChar16Type();149      Char32Type = HostTarget->getChar32Type();150      Int64Type = HostTarget->getInt64Type();151      SigAtomicType = HostTarget->getSigAtomicType();152      ProcessIDType = HostTarget->getProcessIDType();153 154      UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();155      UseZeroLengthBitfieldAlignment =156          HostTarget->useZeroLengthBitfieldAlignment();157      UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();158      ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();159 160      // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and161      // we need those macros to be identical on host and device, because (among162      // other things) they affect which standard library classes are defined,163      // and we need all classes to be defined on both the host and device.164      MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();165    }166  }167 168public:169  // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is170  // memcpy as per section 3 of the SPIR spec.171  bool useFP16ConversionIntrinsics() const override { return false; }172 173  llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {174    return {};175  }176 177  std::string_view getClobbers() const override { return ""; }178 179  ArrayRef<const char *> getGCCRegNames() const override { return {}; }180 181  bool validateAsmConstraint(const char *&Name,182                             TargetInfo::ConstraintInfo &info) const override {183    return true;184  }185 186  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {187    return {};188  }189 190  BuiltinVaListKind getBuiltinVaListKind() const override {191    return TargetInfo::VoidPtrBuiltinVaList;192  }193 194  std::optional<unsigned>195  getDWARFAddressSpace(unsigned AddressSpace) const override {196    return AddressSpace;197  }198 199  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {200    return (CC == CC_SpirFunction || CC == CC_DeviceKernel) ? CCCR_OK201                                                            : CCCR_Warning;202  }203 204  CallingConv getDefaultCallingConv() const override {205    return CC_SpirFunction;206  }207 208  void setAddressSpaceMap(bool DefaultIsGeneric) {209    AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;210  }211 212  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,213              const TargetInfo *Aux) override {214    TargetInfo::adjust(Diags, Opts, Aux);215    // FIXME: SYCL specification considers unannotated pointers and references216    // to be pointing to the generic address space. See section 5.9.3 of217    // SYCL 2020 specification.218    // Currently, there is no way of representing SYCL's and HIP/CUDA's default219    // address space language semantic along with the semantics of embedded C's220    // default address space in the same address space map. Hence the map needs221    // to be reset to allow mapping to the desired value of 'Default' entry for222    // SYCL and HIP/CUDA.223    setAddressSpaceMap(224        /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||225        // The address mapping from HIP/CUDA language for device code is only226        // defined for SPIR-V, and all Intel SPIR-V code should have the default227        // AS as generic.228        (getTriple().isSPIRV() &&229         (Opts.CUDAIsDevice ||230          getTriple().getVendor() == llvm::Triple::Intel)));231  }232 233  void setSupportedOpenCLOpts() override {234    // Assume all OpenCL extensions and optional core features are supported235    // for SPIR and SPIR-V since they are generic targets.236    supportAllOpenCLOpts();237  }238 239  bool hasBitIntType() const override { return true; }240 241  bool hasInt128Type() const override { return false; }242};243 244class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {245public:246  SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)247      : BaseSPIRTargetInfo(Triple, Opts) {248    assert(Triple.isSPIR() && "Invalid architecture for SPIR.");249    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&250           "SPIR target must use unknown OS");251    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&252           "SPIR target must use unknown environment type");253  }254 255  void getTargetDefines(const LangOptions &Opts,256                        MacroBuilder &Builder) const override;257 258  bool hasFeature(StringRef Feature) const override {259    return Feature == "spir";260  }261 262  bool checkArithmeticFenceSupported() const override { return true; }263};264 265class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {266public:267  SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)268      : SPIRTargetInfo(Triple, Opts) {269    assert(Triple.getArch() == llvm::Triple::spir &&270           "Invalid architecture for 32-bit SPIR.");271    PointerWidth = PointerAlign = 32;272    SizeType = TargetInfo::UnsignedInt;273    PtrDiffType = IntPtrType = TargetInfo::SignedInt;274    // SPIR32 has support for atomic ops if atomic extension is enabled.275    // Take the maximum because it's possible the Host supports wider types.276    MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 32);277    resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"278                    "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");279  }280 281  void getTargetDefines(const LangOptions &Opts,282                        MacroBuilder &Builder) const override;283};284 285class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {286public:287  SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)288      : SPIRTargetInfo(Triple, Opts) {289    assert(Triple.getArch() == llvm::Triple::spir64 &&290           "Invalid architecture for 64-bit SPIR.");291    PointerWidth = PointerAlign = 64;292    SizeType = TargetInfo::UnsignedLong;293    PtrDiffType = IntPtrType = TargetInfo::SignedLong;294    // SPIR64 has support for atomic ops if atomic extension is enabled.295    // Take the maximum because it's possible the Host supports wider types.296    MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);297    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"298                    "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");299  }300 301  void getTargetDefines(const LangOptions &Opts,302                        MacroBuilder &Builder) const override;303};304 305class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {306public:307  BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)308      : BaseSPIRTargetInfo(Triple, Opts) {309    assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");310  }311 312  llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;313 314  bool hasFeature(StringRef Feature) const override {315    return Feature == "spirv";316  }317 318  void getTargetDefines(const LangOptions &Opts,319                        MacroBuilder &Builder) const override;320};321 322class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {323public:324  SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)325      : BaseSPIRVTargetInfo(Triple, Opts) {326    assert(Triple.getArch() == llvm::Triple::spirv &&327           "Invalid architecture for Logical SPIR-V.");328    assert(Triple.getOS() == llvm::Triple::Vulkan &&329           Triple.getVulkanVersion() != llvm::VersionTuple(0) &&330           "Logical SPIR-V requires a valid Vulkan environment.");331    assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&332           Triple.getEnvironment() <= llvm::Triple::Amplification &&333           "Logical SPIR-V environment must be a valid shader stage.");334    PointerWidth = PointerAlign = 64;335 336    // SPIR-V IDs are represented with a single 32-bit word.337    SizeType = TargetInfo::UnsignedInt;338    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"339                    "v256:256-v512:512-v1024:1024-n8:16:32:64-G10");340  }341 342  void getTargetDefines(const LangOptions &Opts,343                        MacroBuilder &Builder) const override;344};345 346class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {347public:348  SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)349      : BaseSPIRVTargetInfo(Triple, Opts) {350    assert(Triple.getArch() == llvm::Triple::spirv32 &&351           "Invalid architecture for 32-bit SPIR-V.");352    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&353           "32-bit SPIR-V target must use unknown OS");354    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&355           "32-bit SPIR-V target must use unknown environment type");356    PointerWidth = PointerAlign = 32;357    SizeType = TargetInfo::UnsignedInt;358    PtrDiffType = IntPtrType = TargetInfo::SignedInt;359    // SPIR-V has core support for atomic ops, and Int32 is always available;360    // we take the maximum because it's possible the Host supports wider types.361    MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 32);362    resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-"363                    "v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1");364  }365 366  void getTargetDefines(const LangOptions &Opts,367                        MacroBuilder &Builder) const override;368};369 370class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {371public:372  SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)373      : BaseSPIRVTargetInfo(Triple, Opts) {374    assert(Triple.getArch() == llvm::Triple::spirv64 &&375           "Invalid architecture for 64-bit SPIR-V.");376    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&377           "64-bit SPIR-V target must use unknown OS");378    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&379           "64-bit SPIR-V target must use unknown environment type");380    PointerWidth = PointerAlign = 64;381    SizeType = TargetInfo::UnsignedLong;382    PtrDiffType = IntPtrType = TargetInfo::SignedLong;383    // SPIR-V has core support for atomic ops, and Int64 is always available;384    // we take the maximum because it's possible the Host supports wider types.385    MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);386    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"387                    "v256:256-v512:512-v1024:1024-n8:16:32:64-G1");388  }389 390  void getTargetDefines(const LangOptions &Opts,391                        MacroBuilder &Builder) const override;392 393  const llvm::omp::GV &getGridValue() const override {394    return llvm::omp::SPIRVGridValues;395  }396 397  std::optional<LangAS> getConstantAddressSpace() const override {398    return ConstantAS;399  }400  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,401              const TargetInfo *Aux) override {402    BaseSPIRVTargetInfo::adjust(Diags, Opts, Aux);403    // opencl_constant will map to UniformConstant in SPIR-V404    if (Opts.OpenCL)405      ConstantAS = LangAS::opencl_constant;406  }407 408private:409  // opencl_global will map to CrossWorkgroup in SPIR-V410  LangAS ConstantAS = LangAS::opencl_global;411};412 413class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final414    : public BaseSPIRVTargetInfo {415public:416  SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)417      : BaseSPIRVTargetInfo(Triple, Opts) {418    assert(Triple.getArch() == llvm::Triple::spirv64 &&419           "Invalid architecture for 64-bit AMDGCN SPIR-V.");420    assert(Triple.getVendor() == llvm::Triple::VendorType::AMD &&421           "64-bit AMDGCN SPIR-V target must use AMD vendor");422    assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA &&423           "64-bit AMDGCN SPIR-V target must use AMDHSA OS");424    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&425           "64-bit SPIR-V target must use unknown environment type");426    PointerWidth = PointerAlign = 64;427    SizeType = TargetInfo::UnsignedLong;428    PtrDiffType = IntPtrType = TargetInfo::SignedLong;429    AddrSpaceMap = &SPIRDefIsGenMap;430 431    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"432                    "v256:256-v512:512-v1024:1024-n32:64-S32-G1-P4-A0");433 434    HasFastHalfType = true;435    HasFloat16 = true;436    HalfArgsAndReturns = true;437 438    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;439  }440 441  ArrayRef<const char *> getGCCRegNames() const override;442 443  BuiltinVaListKind getBuiltinVaListKind() const override {444    return TargetInfo::CharPtrBuiltinVaList;445  }446 447  bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,448                      StringRef,449                      const std::vector<std::string> &) const override;450 451  bool validateAsmConstraint(const char *&Name,452                             TargetInfo::ConstraintInfo &Info) const override;453 454  std::string convertConstraint(const char *&Constraint) const override;455 456  llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;457 458  void getTargetDefines(const LangOptions &Opts,459                        MacroBuilder &Builder) const override;460 461  void setAuxTarget(const TargetInfo *Aux) override;462 463  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,464              const TargetInfo *Aux) override {465    TargetInfo::adjust(Diags, Opts, Aux);466  }467 468  bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); }469};470 471class LLVM_LIBRARY_VISIBILITY SPIRV64IntelTargetInfo final472    : public SPIRV64TargetInfo {473public:474  SPIRV64IntelTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)475      : SPIRV64TargetInfo(Triple, Opts) {476    assert(Triple.getVendor() == llvm::Triple::VendorType::Intel &&477           "64-bit Intel SPIR-V target must use Intel vendor");478    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"479                    "v256:256-v512:512-v1024:1024-n8:16:32:64-G1-P9-A0");480  }481};482} // namespace targets483} // namespace clang484#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H485