Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
35266 views
//===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file declares SPIR and SPIR-V TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H13#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H1415#include "Targets.h"16#include "clang/Basic/TargetInfo.h"17#include "clang/Basic/TargetOptions.h"18#include "llvm/Support/Compiler.h"19#include "llvm/Support/VersionTuple.h"20#include "llvm/TargetParser/Triple.h"21#include <optional>2223namespace clang {24namespace targets {2526// Used by both the SPIR and SPIR-V targets.27static const unsigned SPIRDefIsPrivMap[] = {280, // Default291, // opencl_global303, // opencl_local312, // opencl_constant320, // opencl_private334, // opencl_generic345, // opencl_global_device356, // opencl_global_host360, // cuda_device370, // cuda_constant380, // cuda_shared39// SYCL address space values for this map are dummy400, // sycl_global410, // sycl_global_device420, // sycl_global_host430, // sycl_local440, // sycl_private450, // ptr32_sptr460, // ptr32_uptr470, // ptr64480, // hlsl_groupshared49// Wasm address space values for this target are dummy values,50// as it is only enabled for Wasm targets.5120, // wasm_funcref52};5354// Used by both the SPIR and SPIR-V targets.55static const unsigned SPIRDefIsGenMap[] = {564, // Default57// OpenCL address space values for this map are dummy and they can't be used580, // opencl_global590, // opencl_local600, // opencl_constant610, // opencl_private620, // opencl_generic630, // opencl_global_device640, // opencl_global_host65// cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V66// translation). This mapping is enabled when the language mode is HIP.671, // cuda_device68// cuda_constant pointer can be casted to default/"flat" pointer, but in69// SPIR-V casts between constant and generic pointers are not allowed. For70// this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.711, // cuda_constant723, // cuda_shared731, // sycl_global745, // sycl_global_device756, // sycl_global_host763, // sycl_local770, // sycl_private780, // ptr32_sptr790, // ptr32_uptr800, // ptr64810, // hlsl_groupshared82// Wasm address space values for this target are dummy values,83// as it is only enabled for Wasm targets.8420, // wasm_funcref85};8687// Base class for SPIR and SPIR-V target info.88class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {89std::unique_ptr<TargetInfo> HostTarget;9091protected:92BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)93: TargetInfo(Triple) {94assert((Triple.isSPIR() || Triple.isSPIRV()) &&95"Invalid architecture for SPIR or SPIR-V.");96TLSSupported = false;97VLASupported = false;98LongWidth = LongAlign = 64;99AddrSpaceMap = &SPIRDefIsPrivMap;100UseAddrSpaceMapMangling = true;101HasLegalHalfType = true;102HasFloat16 = true;103// Define available target features104// These must be defined in sorted order!105NoAsmVariants = true;106107llvm::Triple HostTriple(Opts.HostTriple);108if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&109HostTriple.getArch() != llvm::Triple::UnknownArch) {110HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);111112// Copy properties from host target.113BoolWidth = HostTarget->getBoolWidth();114BoolAlign = HostTarget->getBoolAlign();115IntWidth = HostTarget->getIntWidth();116IntAlign = HostTarget->getIntAlign();117HalfWidth = HostTarget->getHalfWidth();118HalfAlign = HostTarget->getHalfAlign();119FloatWidth = HostTarget->getFloatWidth();120FloatAlign = HostTarget->getFloatAlign();121DoubleWidth = HostTarget->getDoubleWidth();122DoubleAlign = HostTarget->getDoubleAlign();123LongWidth = HostTarget->getLongWidth();124LongAlign = HostTarget->getLongAlign();125LongLongWidth = HostTarget->getLongLongWidth();126LongLongAlign = HostTarget->getLongLongAlign();127MinGlobalAlign =128HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,129/* HasNonWeakDef = */ true);130NewAlign = HostTarget->getNewAlign();131DefaultAlignForAttributeAligned =132HostTarget->getDefaultAlignForAttributeAligned();133IntMaxType = HostTarget->getIntMaxType();134WCharType = HostTarget->getWCharType();135WIntType = HostTarget->getWIntType();136Char16Type = HostTarget->getChar16Type();137Char32Type = HostTarget->getChar32Type();138Int64Type = HostTarget->getInt64Type();139SigAtomicType = HostTarget->getSigAtomicType();140ProcessIDType = HostTarget->getProcessIDType();141142UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();143UseZeroLengthBitfieldAlignment =144HostTarget->useZeroLengthBitfieldAlignment();145UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();146ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();147148// This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and149// we need those macros to be identical on host and device, because (among150// other things) they affect which standard library classes are defined,151// and we need all classes to be defined on both the host and device.152MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();153}154}155156public:157// SPIR supports the half type and the only llvm intrinsic allowed in SPIR is158// memcpy as per section 3 of the SPIR spec.159bool useFP16ConversionIntrinsics() const override { return false; }160161ArrayRef<Builtin::Info> getTargetBuiltins() const override {162return std::nullopt;163}164165std::string_view getClobbers() const override { return ""; }166167ArrayRef<const char *> getGCCRegNames() const override {168return std::nullopt;169}170171bool validateAsmConstraint(const char *&Name,172TargetInfo::ConstraintInfo &info) const override {173return true;174}175176ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {177return std::nullopt;178}179180BuiltinVaListKind getBuiltinVaListKind() const override {181return TargetInfo::VoidPtrBuiltinVaList;182}183184std::optional<unsigned>185getDWARFAddressSpace(unsigned AddressSpace) const override {186return AddressSpace;187}188189CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {190return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK191: CCCR_Warning;192}193194CallingConv getDefaultCallingConv() const override {195return CC_SpirFunction;196}197198void setAddressSpaceMap(bool DefaultIsGeneric) {199AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;200}201202void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {203TargetInfo::adjust(Diags, Opts);204// FIXME: SYCL specification considers unannotated pointers and references205// to be pointing to the generic address space. See section 5.9.3 of206// SYCL 2020 specification.207// Currently, there is no way of representing SYCL's and HIP/CUDA's default208// address space language semantic along with the semantics of embedded C's209// default address space in the same address space map. Hence the map needs210// to be reset to allow mapping to the desired value of 'Default' entry for211// SYCL and HIP/CUDA.212setAddressSpaceMap(213/*DefaultIsGeneric=*/Opts.SYCLIsDevice ||214// The address mapping from HIP/CUDA language for device code is only215// defined for SPIR-V.216(getTriple().isSPIRV() && Opts.CUDAIsDevice));217}218219void setSupportedOpenCLOpts() override {220// Assume all OpenCL extensions and optional core features are supported221// for SPIR and SPIR-V since they are generic targets.222supportAllOpenCLOpts();223}224225bool hasBitIntType() const override { return true; }226227bool hasInt128Type() const override { return false; }228};229230class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {231public:232SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)233: BaseSPIRTargetInfo(Triple, Opts) {234assert(Triple.isSPIR() && "Invalid architecture for SPIR.");235assert(getTriple().getOS() == llvm::Triple::UnknownOS &&236"SPIR target must use unknown OS");237assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&238"SPIR target must use unknown environment type");239}240241void getTargetDefines(const LangOptions &Opts,242MacroBuilder &Builder) const override;243244bool hasFeature(StringRef Feature) const override {245return Feature == "spir";246}247248bool checkArithmeticFenceSupported() const override { return true; }249};250251class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {252public:253SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)254: SPIRTargetInfo(Triple, Opts) {255assert(Triple.getArch() == llvm::Triple::spir &&256"Invalid architecture for 32-bit SPIR.");257PointerWidth = PointerAlign = 32;258SizeType = TargetInfo::UnsignedInt;259PtrDiffType = IntPtrType = TargetInfo::SignedInt;260resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"261"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");262}263264void getTargetDefines(const LangOptions &Opts,265MacroBuilder &Builder) const override;266};267268class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {269public:270SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)271: SPIRTargetInfo(Triple, Opts) {272assert(Triple.getArch() == llvm::Triple::spir64 &&273"Invalid architecture for 64-bit SPIR.");274PointerWidth = PointerAlign = 64;275SizeType = TargetInfo::UnsignedLong;276PtrDiffType = IntPtrType = TargetInfo::SignedLong;277resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"278"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");279}280281void getTargetDefines(const LangOptions &Opts,282MacroBuilder &Builder) const override;283};284285class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {286public:287BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)288: BaseSPIRTargetInfo(Triple, Opts) {289assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");290}291292bool hasFeature(StringRef Feature) const override {293return Feature == "spirv";294}295296void getTargetDefines(const LangOptions &Opts,297MacroBuilder &Builder) const override;298};299300class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {301public:302SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)303: BaseSPIRVTargetInfo(Triple, Opts) {304assert(Triple.getArch() == llvm::Triple::spirv &&305"Invalid architecture for Logical SPIR-V.");306assert(Triple.getOS() == llvm::Triple::Vulkan &&307Triple.getVulkanVersion() != llvm::VersionTuple(0) &&308"Logical SPIR-V requires a valid Vulkan environment.");309assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&310Triple.getEnvironment() <= llvm::Triple::Amplification &&311"Logical SPIR-V environment must be a valid shader stage.");312PointerWidth = PointerAlign = 64;313314// SPIR-V IDs are represented with a single 32-bit word.315SizeType = TargetInfo::UnsignedInt;316resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"317"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");318}319320void getTargetDefines(const LangOptions &Opts,321MacroBuilder &Builder) const override;322};323324class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {325public:326SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)327: BaseSPIRVTargetInfo(Triple, Opts) {328assert(Triple.getArch() == llvm::Triple::spirv32 &&329"Invalid architecture for 32-bit SPIR-V.");330assert(getTriple().getOS() == llvm::Triple::UnknownOS &&331"32-bit SPIR-V target must use unknown OS");332assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&333"32-bit SPIR-V target must use unknown environment type");334PointerWidth = PointerAlign = 32;335SizeType = TargetInfo::UnsignedInt;336PtrDiffType = IntPtrType = TargetInfo::SignedInt;337resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"338"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");339}340341void getTargetDefines(const LangOptions &Opts,342MacroBuilder &Builder) const override;343};344345class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {346public:347SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)348: BaseSPIRVTargetInfo(Triple, Opts) {349assert(Triple.getArch() == llvm::Triple::spirv64 &&350"Invalid architecture for 64-bit SPIR-V.");351assert(getTriple().getOS() == llvm::Triple::UnknownOS &&352"64-bit SPIR-V target must use unknown OS");353assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&354"64-bit SPIR-V target must use unknown environment type");355PointerWidth = PointerAlign = 64;356SizeType = TargetInfo::UnsignedLong;357PtrDiffType = IntPtrType = TargetInfo::SignedLong;358resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"359"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");360}361362void getTargetDefines(const LangOptions &Opts,363MacroBuilder &Builder) const override;364};365366class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final367: public BaseSPIRVTargetInfo {368public:369SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)370: BaseSPIRVTargetInfo(Triple, Opts) {371assert(Triple.getArch() == llvm::Triple::spirv64 &&372"Invalid architecture for 64-bit AMDGCN SPIR-V.");373assert(Triple.getVendor() == llvm::Triple::VendorType::AMD &&374"64-bit AMDGCN SPIR-V target must use AMD vendor");375assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA &&376"64-bit AMDGCN SPIR-V target must use AMDHSA OS");377assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&378"64-bit SPIR-V target must use unknown environment type");379PointerWidth = PointerAlign = 64;380SizeType = TargetInfo::UnsignedLong;381PtrDiffType = IntPtrType = TargetInfo::SignedLong;382383resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"384"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1-P4-A0");385386BFloat16Width = BFloat16Align = 16;387BFloat16Format = &llvm::APFloat::BFloat();388389HasLegalHalfType = true;390HasFloat16 = true;391HalfArgsAndReturns = true;392}393394bool hasBFloat16Type() const override { return true; }395396ArrayRef<const char *> getGCCRegNames() const override;397398bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,399StringRef,400const std::vector<std::string> &) const override;401402bool validateAsmConstraint(const char *&Name,403TargetInfo::ConstraintInfo &Info) const override;404405std::string convertConstraint(const char *&Constraint) const override;406407ArrayRef<Builtin::Info> getTargetBuiltins() const override;408409void getTargetDefines(const LangOptions &Opts,410MacroBuilder &Builder) const override;411412void setAuxTarget(const TargetInfo *Aux) override;413414bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); }415};416417} // namespace targets418} // namespace clang419#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H420421422