brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · ec4e40b Raw
334 lines · cpp
1//===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//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 implements NVPTX TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "NVPTX.h"14#include "clang/Basic/Builtins.h"15#include "clang/Basic/MacroBuilder.h"16#include "clang/Basic/TargetBuiltins.h"17#include "llvm/ADT/StringSwitch.h"18 19using namespace clang;20using namespace clang::targets;21 22static constexpr int NumBuiltins =23    clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin;24 25#define GET_BUILTIN_STR_TABLE26#include "clang/Basic/BuiltinsNVPTX.inc"27#undef GET_BUILTIN_STR_TABLE28 29static constexpr Builtin::Info BuiltinInfos[] = {30#define GET_BUILTIN_INFOS31#include "clang/Basic/BuiltinsNVPTX.inc"32#undef GET_BUILTIN_INFOS33};34static_assert(std::size(BuiltinInfos) == NumBuiltins);35 36const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};37 38NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,39                                 const TargetOptions &Opts,40                                 unsigned TargetPointerWidth)41    : TargetInfo(Triple) {42  assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&43         "NVPTX only supports 32- and 64-bit modes.");44 45  PTXVersion = 32;46  for (const StringRef Feature : Opts.FeaturesAsWritten) {47    int PTXV;48    if (!Feature.starts_with("+ptx") ||49        Feature.drop_front(4).getAsInteger(10, PTXV))50      continue;51    PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)?52  }53 54  TLSSupported = false;55  VLASupported = false;56  AddrSpaceMap = &NVPTXAddrSpaceMap;57  UseAddrSpaceMapMangling = true;58  // __bf16 is always available as a load/store only type.59  BFloat16Width = BFloat16Align = 16;60  BFloat16Format = &llvm::APFloat::BFloat();61 62  // Define available target features63  // These must be defined in sorted order!64  NoAsmVariants = true;65  GPU = OffloadArch::UNUSED;66 67  // PTX supports f16 as a fundamental type.68  HasFastHalfType = true;69  HasFloat16 = true;70 71  if (TargetPointerWidth == 32)72    resetDataLayout("e-p:32:32-p6:32:32-p7:32:32-i64:64-i128:128-i256:256-v16:"73                    "16-v32:32-n16:32:64");74  else if (Opts.NVPTXUseShortPointers)75    resetDataLayout("e-p3:32:32-p4:32:32-p5:32:32-p6:32:32-p7:32:32-i64:64-"76                    "i128:128-i256:256-v16:"77                    "16-v32:32-n16:32:64");78  else79    resetDataLayout(80        "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64");81 82  // If possible, get a TargetInfo for our host triple, so we can match its83  // types.84  llvm::Triple HostTriple(Opts.HostTriple);85  if (!HostTriple.isNVPTX())86    HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);87 88  // If no host target, make some guesses about the data layout and return.89  if (!HostTarget) {90    LongWidth = LongAlign = TargetPointerWidth;91    PointerWidth = PointerAlign = TargetPointerWidth;92    switch (TargetPointerWidth) {93    case 32:94      SizeType = TargetInfo::UnsignedInt;95      PtrDiffType = TargetInfo::SignedInt;96      IntPtrType = TargetInfo::SignedInt;97      break;98    case 64:99      SizeType = TargetInfo::UnsignedLong;100      PtrDiffType = TargetInfo::SignedLong;101      IntPtrType = TargetInfo::SignedLong;102      break;103    default:104      llvm_unreachable("TargetPointerWidth must be 32 or 64");105    }106 107    MaxAtomicInlineWidth = TargetPointerWidth;108    return;109  }110 111  // Copy properties from host target.112  PointerWidth = HostTarget->getPointerWidth(LangAS::Default);113  PointerAlign = HostTarget->getPointerAlign(LangAS::Default);114  BoolWidth = HostTarget->getBoolWidth();115  BoolAlign = HostTarget->getBoolAlign();116  IntWidth = HostTarget->getIntWidth();117  IntAlign = HostTarget->getIntAlign();118  HalfWidth = HostTarget->getHalfWidth();119  HalfAlign = HostTarget->getHalfAlign();120  FloatWidth = HostTarget->getFloatWidth();121  FloatAlign = HostTarget->getFloatAlign();122  DoubleWidth = HostTarget->getDoubleWidth();123  DoubleAlign = HostTarget->getDoubleAlign();124  LongWidth = HostTarget->getLongWidth();125  LongAlign = HostTarget->getLongAlign();126  LongLongWidth = HostTarget->getLongLongWidth();127  LongLongAlign = HostTarget->getLongLongAlign();128  MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,129                                                 /* HasNonWeakDef = */ true);130  NewAlign = HostTarget->getNewAlign();131  DefaultAlignForAttributeAligned =132      HostTarget->getDefaultAlignForAttributeAligned();133  SizeType = HostTarget->getSizeType();134  IntMaxType = HostTarget->getIntMaxType();135  PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default);136  IntPtrType = HostTarget->getIntPtrType();137  WCharType = HostTarget->getWCharType();138  WIntType = HostTarget->getWIntType();139  Char16Type = HostTarget->getChar16Type();140  Char32Type = HostTarget->getChar32Type();141  Int64Type = HostTarget->getInt64Type();142  SigAtomicType = HostTarget->getSigAtomicType();143  ProcessIDType = HostTarget->getProcessIDType();144 145  UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();146  UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();147  UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();148  ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();149 150  // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and151  // we need those macros to be identical on host and device, because (among152  // other things) they affect which standard library classes are defined, and153  // we need all classes to be defined on both the host and device.154  MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();155 156  // Properties intentionally not copied from host:157  // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the158  //   host/device boundary.159  // - SuitableAlign: Not visible across the host/device boundary, and may160  //   correctly be different on host/device, e.g. if host has wider vector161  //   types than device.162  // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same163  //   as its double type, but that's not necessarily true on the host.164  //   TODO: nvcc emits a warning when using long double on device; we should165  //   do the same.166}167 168ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {169  return llvm::ArrayRef(GCCRegNames);170}171 172bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {173  return llvm::StringSwitch<bool>(Feature)174      .Cases({"ptx", "nvptx"}, true)175      .Default(false);176}177 178void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,179                                       MacroBuilder &Builder) const {180  Builder.defineMacro("__PTX__");181  Builder.defineMacro("__NVPTX__");182 183  // Skip setting architecture dependent macros if undefined.184  if (GPU == OffloadArch::UNUSED && !HostTarget)185    return;186 187  if (Opts.CUDAIsDevice || Opts.OpenMPIsTargetDevice || !HostTarget) {188    // Set __CUDA_ARCH__ for the GPU specified.189    llvm::StringRef CUDAArchCode = [this] {190      switch (GPU) {191      case OffloadArch::GFX600:192      case OffloadArch::GFX601:193      case OffloadArch::GFX602:194      case OffloadArch::GFX700:195      case OffloadArch::GFX701:196      case OffloadArch::GFX702:197      case OffloadArch::GFX703:198      case OffloadArch::GFX704:199      case OffloadArch::GFX705:200      case OffloadArch::GFX801:201      case OffloadArch::GFX802:202      case OffloadArch::GFX803:203      case OffloadArch::GFX805:204      case OffloadArch::GFX810:205      case OffloadArch::GFX9_GENERIC:206      case OffloadArch::GFX900:207      case OffloadArch::GFX902:208      case OffloadArch::GFX904:209      case OffloadArch::GFX906:210      case OffloadArch::GFX908:211      case OffloadArch::GFX909:212      case OffloadArch::GFX90a:213      case OffloadArch::GFX90c:214      case OffloadArch::GFX9_4_GENERIC:215      case OffloadArch::GFX942:216      case OffloadArch::GFX950:217      case OffloadArch::GFX10_1_GENERIC:218      case OffloadArch::GFX1010:219      case OffloadArch::GFX1011:220      case OffloadArch::GFX1012:221      case OffloadArch::GFX1013:222      case OffloadArch::GFX10_3_GENERIC:223      case OffloadArch::GFX1030:224      case OffloadArch::GFX1031:225      case OffloadArch::GFX1032:226      case OffloadArch::GFX1033:227      case OffloadArch::GFX1034:228      case OffloadArch::GFX1035:229      case OffloadArch::GFX1036:230      case OffloadArch::GFX11_GENERIC:231      case OffloadArch::GFX1100:232      case OffloadArch::GFX1101:233      case OffloadArch::GFX1102:234      case OffloadArch::GFX1103:235      case OffloadArch::GFX1150:236      case OffloadArch::GFX1151:237      case OffloadArch::GFX1152:238      case OffloadArch::GFX1153:239      case OffloadArch::GFX12_GENERIC:240      case OffloadArch::GFX1200:241      case OffloadArch::GFX1201:242      case OffloadArch::GFX1250:243      case OffloadArch::GFX1251:244      case OffloadArch::AMDGCNSPIRV:245      case OffloadArch::Generic:246      case OffloadArch::GRANITERAPIDS:247      case OffloadArch::BMG_G21:248      case OffloadArch::LAST:249        break;250      case OffloadArch::UNKNOWN:251        assert(false && "No GPU arch when compiling CUDA device code.");252        return "";253      case OffloadArch::UNUSED:254      case OffloadArch::SM_20:255        return "200";256      case OffloadArch::SM_21:257        return "210";258      case OffloadArch::SM_30:259        return "300";260      case OffloadArch::SM_32_:261        return "320";262      case OffloadArch::SM_35:263        return "350";264      case OffloadArch::SM_37:265        return "370";266      case OffloadArch::SM_50:267        return "500";268      case OffloadArch::SM_52:269        return "520";270      case OffloadArch::SM_53:271        return "530";272      case OffloadArch::SM_60:273        return "600";274      case OffloadArch::SM_61:275        return "610";276      case OffloadArch::SM_62:277        return "620";278      case OffloadArch::SM_70:279        return "700";280      case OffloadArch::SM_72:281        return "720";282      case OffloadArch::SM_75:283        return "750";284      case OffloadArch::SM_80:285        return "800";286      case OffloadArch::SM_86:287        return "860";288      case OffloadArch::SM_87:289        return "870";290      case OffloadArch::SM_89:291        return "890";292      case OffloadArch::SM_90:293      case OffloadArch::SM_90a:294        return "900";295      case OffloadArch::SM_100:296      case OffloadArch::SM_100a:297        return "1000";298      case OffloadArch::SM_101:299      case OffloadArch::SM_101a:300        return "1010";301      case OffloadArch::SM_103:302      case OffloadArch::SM_103a:303        return "1030";304      case OffloadArch::SM_120:305      case OffloadArch::SM_120a:306        return "1200";307      case OffloadArch::SM_121:308      case OffloadArch::SM_121a:309        return "1210";310      }311      llvm_unreachable("unhandled OffloadArch");312    }();313    Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);314    switch(GPU) {315      case OffloadArch::SM_90a:316      case OffloadArch::SM_100a:317      case OffloadArch::SM_101a:318      case OffloadArch::SM_103a:319      case OffloadArch::SM_120a:320      case OffloadArch::SM_121a:321        Builder.defineMacro("__CUDA_ARCH_FEAT_SM" + CUDAArchCode.drop_back() + "_ALL", "1");322        break;323      default:324        // Do nothing if this is not an enhanced architecture.325        break;326    }327  }328}329 330llvm::SmallVector<Builtin::InfosShard>331NVPTXTargetInfo::getTargetBuiltins() const {332  return {{&BuiltinStrings, BuiltinInfos}};333}334