summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
new file mode 100644
index 000000000000..f69e9d84c701
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
@@ -0,0 +1,244 @@
+//===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements NVPTX TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NVPTX.h"
+#include "Targets.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
+ {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+#include "clang/Basic/BuiltinsNVPTX.def"
+};
+
+const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
+
+NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts,
+ unsigned TargetPointerWidth)
+ : TargetInfo(Triple) {
+ assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
+ "NVPTX only supports 32- and 64-bit modes.");
+
+ PTXVersion = 32;
+ for (const StringRef Feature : Opts.FeaturesAsWritten) {
+ if (!Feature.startswith("+ptx"))
+ continue;
+ PTXVersion = llvm::StringSwitch<unsigned>(Feature)
+ .Case("+ptx64", 64)
+ .Case("+ptx63", 63)
+ .Case("+ptx61", 61)
+ .Case("+ptx60", 60)
+ .Case("+ptx50", 50)
+ .Case("+ptx43", 43)
+ .Case("+ptx42", 42)
+ .Case("+ptx41", 41)
+ .Case("+ptx40", 40)
+ .Case("+ptx32", 32)
+ .Default(32);
+ }
+
+ TLSSupported = false;
+ VLASupported = false;
+ AddrSpaceMap = &NVPTXAddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
+
+ // Define available target features
+ // These must be defined in sorted order!
+ NoAsmVariants = true;
+ GPU = CudaArch::SM_20;
+
+ if (TargetPointerWidth == 32)
+ resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
+ else if (Opts.NVPTXUseShortPointers)
+ resetDataLayout(
+ "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
+ else
+ resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
+
+ // If possible, get a TargetInfo for our host triple, so we can match its
+ // types.
+ llvm::Triple HostTriple(Opts.HostTriple);
+ if (!HostTriple.isNVPTX())
+ HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
+
+ // If no host target, make some guesses about the data layout and return.
+ if (!HostTarget) {
+ LongWidth = LongAlign = TargetPointerWidth;
+ PointerWidth = PointerAlign = TargetPointerWidth;
+ switch (TargetPointerWidth) {
+ case 32:
+ SizeType = TargetInfo::UnsignedInt;
+ PtrDiffType = TargetInfo::SignedInt;
+ IntPtrType = TargetInfo::SignedInt;
+ break;
+ case 64:
+ SizeType = TargetInfo::UnsignedLong;
+ PtrDiffType = TargetInfo::SignedLong;
+ IntPtrType = TargetInfo::SignedLong;
+ break;
+ default:
+ llvm_unreachable("TargetPointerWidth must be 32 or 64");
+ }
+ return;
+ }
+
+ // Copy properties from host target.
+ PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
+ PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
+ 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();
+ SizeType = HostTarget->getSizeType();
+ IntMaxType = HostTarget->getIntMaxType();
+ PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
+ IntPtrType = HostTarget->getIntPtrType();
+ 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();
+
+ // Properties intentionally not copied from host:
+ // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
+ // host/device boundary.
+ // - SuitableAlign: Not visible across the host/device boundary, and may
+ // correctly be different on host/device, e.g. if host has wider vector
+ // types than device.
+ // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
+ // as its double type, but that's not necessarily true on the host.
+ // TODO: nvcc emits a warning when using long double on device; we should
+ // do the same.
+}
+
+ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
+ return llvm::makeArrayRef(GCCRegNames);
+}
+
+bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Cases("ptx", "nvptx", true)
+ .Default(false);
+}
+
+void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__PTX__");
+ Builder.defineMacro("__NVPTX__");
+ if (Opts.CUDAIsDevice) {
+ // Set __CUDA_ARCH__ for the GPU specified.
+ std::string CUDAArchCode = [this] {
+ switch (GPU) {
+ case CudaArch::GFX600:
+ case CudaArch::GFX601:
+ case CudaArch::GFX700:
+ case CudaArch::GFX701:
+ case CudaArch::GFX702:
+ case CudaArch::GFX703:
+ case CudaArch::GFX704:
+ case CudaArch::GFX801:
+ case CudaArch::GFX802:
+ case CudaArch::GFX803:
+ case CudaArch::GFX810:
+ case CudaArch::GFX900:
+ case CudaArch::GFX902:
+ case CudaArch::GFX904:
+ case CudaArch::GFX906:
+ case CudaArch::GFX908:
+ case CudaArch::GFX909:
+ case CudaArch::GFX1010:
+ case CudaArch::GFX1011:
+ case CudaArch::GFX1012:
+ case CudaArch::LAST:
+ break;
+ case CudaArch::UNKNOWN:
+ assert(false && "No GPU arch when compiling CUDA device code.");
+ return "";
+ case CudaArch::SM_20:
+ return "200";
+ case CudaArch::SM_21:
+ return "210";
+ case CudaArch::SM_30:
+ return "300";
+ case CudaArch::SM_32:
+ return "320";
+ case CudaArch::SM_35:
+ return "350";
+ case CudaArch::SM_37:
+ return "370";
+ case CudaArch::SM_50:
+ return "500";
+ case CudaArch::SM_52:
+ return "520";
+ case CudaArch::SM_53:
+ return "530";
+ case CudaArch::SM_60:
+ return "600";
+ case CudaArch::SM_61:
+ return "610";
+ case CudaArch::SM_62:
+ return "620";
+ case CudaArch::SM_70:
+ return "700";
+ case CudaArch::SM_72:
+ return "720";
+ case CudaArch::SM_75:
+ return "750";
+ }
+ llvm_unreachable("unhandled CudaArch");
+ }();
+ Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
+ }
+}
+
+ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
+ return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
+}