1 //===-- NVPTXUtilities - Utilities -----------------------------*- 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the declaration of the NVVM specific utility functions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H 14 #define LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H 15 16 #include "NVPTX.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/CodeGen/ValueTypes.h" 19 #include "llvm/IR/Function.h" 20 #include "llvm/IR/GlobalVariable.h" 21 #include "llvm/IR/IntrinsicInst.h" 22 #include "llvm/IR/Value.h" 23 #include "llvm/Support/Alignment.h" 24 #include "llvm/Support/FormatVariadic.h" 25 #include <cstdarg> 26 #include <set> 27 #include <string> 28 #include <vector> 29 30 namespace llvm { 31 32 class TargetMachine; 33 34 void clearAnnotationCache(const Module *); 35 36 bool isTexture(const Value &); 37 bool isSurface(const Value &); 38 bool isSampler(const Value &); 39 bool isImage(const Value &); 40 bool isImageReadOnly(const Value &); 41 bool isImageWriteOnly(const Value &); 42 bool isImageReadWrite(const Value &); 43 bool isManaged(const Value &); 44 45 StringRef getTextureName(const Value &); 46 StringRef getSurfaceName(const Value &); 47 StringRef getSamplerName(const Value &); 48 49 std::optional<unsigned> getMaxNTIDx(const Function &); 50 std::optional<unsigned> getMaxNTIDy(const Function &); 51 std::optional<unsigned> getMaxNTIDz(const Function &); 52 std::optional<unsigned> getMaxNTID(const Function &); 53 54 std::optional<unsigned> getReqNTIDx(const Function &); 55 std::optional<unsigned> getReqNTIDy(const Function &); 56 std::optional<unsigned> getReqNTIDz(const Function &); 57 std::optional<unsigned> getReqNTID(const Function &); 58 59 std::optional<unsigned> getClusterDimx(const Function &); 60 std::optional<unsigned> getClusterDimy(const Function &); 61 std::optional<unsigned> getClusterDimz(const Function &); 62 63 std::optional<unsigned> getMaxClusterRank(const Function &); 64 std::optional<unsigned> getMinCTASm(const Function &); 65 std::optional<unsigned> getMaxNReg(const Function &); 66 bool isKernelFunction(const Function &); 67 bool isParamGridConstant(const Value &); 68 69 MaybeAlign getAlign(const Function &, unsigned); 70 MaybeAlign getAlign(const CallInst &, unsigned); 71 Function *getMaybeBitcastedCallee(const CallBase *CB); 72 73 // PTX ABI requires all scalar argument/return values to have 74 // bit-size as a power of two of at least 32 bits. 75 inline unsigned promoteScalarArgumentSize(unsigned size) { 76 if (size <= 32) 77 return 32; 78 if (size <= 64) 79 return 64; 80 return size; 81 } 82 83 bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM); 84 85 bool Isv2x16VT(EVT VT); 86 87 namespace NVPTX { 88 inline std::string getValidPTXIdentifier(StringRef Name) { 89 std::string ValidName; 90 ValidName.reserve(Name.size() + 4); 91 for (char C : Name) 92 // While PTX also allows '%' at the start of identifiers, LLVM will throw a 93 // fatal error for '%' in symbol names in MCSymbol::print. Exclude for now. 94 if (isAlnum(C) || C == '_' || C == '$') 95 ValidName.push_back(C); 96 else 97 ValidName.append({'_', '$', '_'}); 98 99 return ValidName; 100 } 101 102 inline std::string OrderingToString(Ordering Order) { 103 switch (Order) { 104 case Ordering::NotAtomic: 105 return "NotAtomic"; 106 case Ordering::Relaxed: 107 return "Relaxed"; 108 case Ordering::Acquire: 109 return "Acquire"; 110 case Ordering::Release: 111 return "Release"; 112 case Ordering::AcquireRelease: 113 return "AcquireRelease"; 114 case Ordering::SequentiallyConsistent: 115 return "SequentiallyConsistent"; 116 case Ordering::Volatile: 117 return "Volatile"; 118 case Ordering::RelaxedMMIO: 119 return "RelaxedMMIO"; 120 } 121 report_fatal_error(formatv("Unknown NVPTX::Ordering \"{}\".", 122 static_cast<OrderingUnderlyingType>(Order))); 123 } 124 125 inline raw_ostream &operator<<(raw_ostream &O, Ordering Order) { 126 O << OrderingToString(Order); 127 return O; 128 } 129 130 inline std::string ScopeToString(Scope S) { 131 switch (S) { 132 case Scope::Thread: 133 return "Thread"; 134 case Scope::System: 135 return "System"; 136 case Scope::Block: 137 return "Block"; 138 case Scope::Cluster: 139 return "Cluster"; 140 case Scope::Device: 141 return "Device"; 142 } 143 report_fatal_error(formatv("Unknown NVPTX::Scope \"{}\".", 144 static_cast<ScopeUnderlyingType>(S))); 145 } 146 147 inline raw_ostream &operator<<(raw_ostream &O, Scope S) { 148 O << ScopeToString(S); 149 return O; 150 } 151 152 inline std::string AddressSpaceToString(AddressSpace A) { 153 switch (A) { 154 case AddressSpace::Generic: 155 return "generic"; 156 case AddressSpace::Global: 157 return "global"; 158 case AddressSpace::Const: 159 return "const"; 160 case AddressSpace::Shared: 161 return "shared"; 162 case AddressSpace::Param: 163 return "param"; 164 case AddressSpace::Local: 165 return "local"; 166 } 167 report_fatal_error(formatv("Unknown NVPTX::AddressSpace \"{}\".", 168 static_cast<AddressSpaceUnderlyingType>(A))); 169 } 170 171 inline raw_ostream &operator<<(raw_ostream &O, AddressSpace A) { 172 O << AddressSpaceToString(A); 173 return O; 174 } 175 176 } // namespace NVPTX 177 } // namespace llvm 178 179 #endif 180