aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h238
1 files changed, 206 insertions, 32 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
index 50f34abd6630..fa4a3bb1c82e 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
@@ -1,4 +1,4 @@
-//===--- SPIR.h - Declare SPIR target feature support -----------*- C++ -*-===//
+//===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,21 +6,25 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares SPIR TargetInfo objects.
+// This file declares SPIR and SPIR-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
+#include "Targets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsPrivMap[] = {
0, // Default
1, // opencl_global
@@ -41,9 +45,14 @@ static const unsigned SPIRDefIsPrivMap[] = {
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsGenMap[] = {
4, // Default
// OpenCL address space values for this map are dummy and they can't be used
@@ -54,9 +63,14 @@ static const unsigned SPIRDefIsGenMap[] = {
0, // opencl_generic
0, // opencl_global_device
0, // opencl_global_host
- 0, // cuda_device
- 0, // cuda_constant
- 0, // cuda_shared
+ // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
+ // translation). This mapping is enabled when the language mode is HIP.
+ 1, // cuda_device
+ // cuda_constant pointer can be casted to default/"flat" pointer, but in
+ // SPIR-V casts between constant and generic pointers are not allowed. For
+ // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
+ 1, // cuda_constant
+ 3, // cuda_shared
1, // sycl_global
5, // sycl_global_device
6, // sycl_global_host
@@ -64,17 +78,22 @@ static const unsigned SPIRDefIsGenMap[] = {
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
-class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
-public:
- SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+// Base class for SPIR and SPIR-V target info.
+class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
+ std::unique_ptr<TargetInfo> HostTarget;
+
+protected:
+ BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: TargetInfo(Triple) {
- assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
- "SPIR target must use unknown OS");
- assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
- "SPIR target must use unknown environment type");
+ assert((Triple.isSPIR() || Triple.isSPIRV()) &&
+ "Invalid architecture for SPIR or SPIR-V.");
TLSSupported = false;
VLASupported = false;
LongWidth = LongAlign = 64;
@@ -85,24 +104,68 @@ public:
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
- }
- void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const override;
+ llvm::Triple HostTriple(Opts.HostTriple);
+ if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
+ HostTriple.getArch() != llvm::Triple::UnknownArch) {
+ HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
- bool hasFeature(StringRef Feature) const override {
- return Feature == "spir";
+ // Copy properties from host target.
+ BoolWidth = HostTarget->getBoolWidth();
+ BoolAlign = HostTarget->getBoolAlign();
+ IntWidth = HostTarget->getIntWidth();
+ IntAlign = HostTarget->getIntAlign();
+ HalfWidth = HostTarget->getHalfWidth();
+ HalfAlign = HostTarget->getHalfAlign();
+ FloatWidth = HostTarget->getFloatWidth();
+ FloatAlign = HostTarget->getFloatAlign();
+ DoubleWidth = HostTarget->getDoubleWidth();
+ DoubleAlign = HostTarget->getDoubleAlign();
+ LongWidth = HostTarget->getLongWidth();
+ LongAlign = HostTarget->getLongAlign();
+ LongLongWidth = HostTarget->getLongLongWidth();
+ LongLongAlign = HostTarget->getLongLongAlign();
+ MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
+ NewAlign = HostTarget->getNewAlign();
+ DefaultAlignForAttributeAligned =
+ HostTarget->getDefaultAlignForAttributeAligned();
+ IntMaxType = HostTarget->getIntMaxType();
+ WCharType = HostTarget->getWCharType();
+ WIntType = HostTarget->getWIntType();
+ Char16Type = HostTarget->getChar16Type();
+ Char32Type = HostTarget->getChar32Type();
+ Int64Type = HostTarget->getInt64Type();
+ SigAtomicType = HostTarget->getSigAtomicType();
+ ProcessIDType = HostTarget->getProcessIDType();
+
+ UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
+ UseZeroLengthBitfieldAlignment =
+ HostTarget->useZeroLengthBitfieldAlignment();
+ UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
+ ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
+
+ // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
+ // we need those macros to be identical on host and device, because (among
+ // other things) they affect which standard library classes are defined,
+ // and we need all classes to be defined on both the host and device.
+ MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
+ }
}
+public:
// SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
// memcpy as per section 3 of the SPIR spec.
bool useFP16ConversionIntrinsics() const override { return false; }
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
- ArrayRef<const char *> getGCCRegNames() const override { return None; }
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override {
@@ -110,14 +173,14 @@ public:
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
- Optional<unsigned>
+ std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace) const override {
return AddressSpace;
}
@@ -140,28 +203,56 @@ public:
// FIXME: SYCL specification considers unannotated pointers and references
// to be pointing to the generic address space. See section 5.9.3 of
// SYCL 2020 specification.
- // Currently, there is no way of representing SYCL's default address space
- // language semantic along with the semantics of embedded C's default
- // address space in the same address space map. Hence the map needs to be
- // reset to allow mapping to the desired value of 'Default' entry for SYCL.
- setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice);
+ // Currently, there is no way of representing SYCL's and HIP/CUDA's default
+ // address space language semantic along with the semantics of embedded C's
+ // default address space in the same address space map. Hence the map needs
+ // to be reset to allow mapping to the desired value of 'Default' entry for
+ // SYCL and HIP/CUDA.
+ setAddressSpaceMap(
+ /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
+ // The address mapping from HIP/CUDA language for device code is only
+ // defined for SPIR-V.
+ (getTriple().isSPIRV() && Opts.CUDAIsDevice));
}
void setSupportedOpenCLOpts() override {
// Assume all OpenCL extensions and optional core features are supported
- // for SPIR since it is a generic target.
+ // for SPIR and SPIR-V since they are generic targets.
supportAllOpenCLOpts();
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
bool hasInt128Type() const override { return false; }
};
+class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
+public:
+ SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "SPIR target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "SPIR target must use unknown environment type");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spir";
+ }
+
+ bool checkArithmeticFenceSupported() const override { return true; }
+};
+
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
public:
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: SPIRTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spir &&
+ "Invalid architecture for 32-bit SPIR.");
PointerWidth = PointerAlign = 32;
SizeType = TargetInfo::UnsignedInt;
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
@@ -177,6 +268,8 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
public:
SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: SPIRTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spir64 &&
+ "Invalid architecture for 64-bit SPIR.");
PointerWidth = PointerAlign = 64;
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
@@ -187,6 +280,87 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
+public:
+ BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
+ }
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spirv";
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv &&
+ "Invalid architecture for Logical SPIR-V.");
+ assert(Triple.getOS() == llvm::Triple::Vulkan &&
+ Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
+ "Logical SPIR-V requires a valid Vulkan environment.");
+ assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
+ Triple.getEnvironment() <= llvm::Triple::Amplification &&
+ "Logical SPIR-V environment must be a valid shader stage.");
+
+ // SPIR-V IDs are represented with a single 32-bit word.
+ SizeType = TargetInfo::UnsignedInt;
+ resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv32 &&
+ "Invalid architecture for 32-bit SPIR-V.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "32-bit SPIR-V target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "32-bit SPIR-V target must use unknown environment type");
+ PointerWidth = PointerAlign = 32;
+ SizeType = TargetInfo::UnsignedInt;
+ PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+ resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv64 &&
+ "Invalid architecture for 64-bit SPIR-V.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "64-bit SPIR-V target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "64-bit SPIR-V target must use unknown environment type");
+ PointerWidth = PointerAlign = 64;
+ SizeType = TargetInfo::UnsignedLong;
+ PtrDiffType = IntPtrType = TargetInfo::SignedLong;
+ resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H