xref: /freebsd/contrib/llvm-project/llvm/lib/Target/NVPTX/NVPTXUtilities.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/SmallVector.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/CodeGen/ValueTypes.h"
20 #include "llvm/IR/CallingConv.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Support/Alignment.h"
26 #include "llvm/Support/FormatVariadic.h"
27 #include <cstdarg>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 namespace llvm {
33 
34 class TargetMachine;
35 
36 void clearAnnotationCache(const Module *);
37 
38 bool isTexture(const Value &);
39 bool isSurface(const Value &);
40 bool isSampler(const Value &);
41 bool isImage(const Value &);
42 bool isImageReadOnly(const Value &);
43 bool isImageWriteOnly(const Value &);
44 bool isImageReadWrite(const Value &);
45 bool isManaged(const Value &);
46 
47 StringRef getTextureName(const Value &);
48 StringRef getSurfaceName(const Value &);
49 StringRef getSamplerName(const Value &);
50 
51 SmallVector<unsigned, 3> getMaxNTID(const Function &);
52 SmallVector<unsigned, 3> getReqNTID(const Function &);
53 SmallVector<unsigned, 3> getClusterDim(const Function &);
54 
55 std::optional<uint64_t> getOverallMaxNTID(const Function &);
56 std::optional<uint64_t> getOverallReqNTID(const Function &);
57 std::optional<uint64_t> getOverallClusterRank(const Function &);
58 
59 std::optional<unsigned> getMaxClusterRank(const Function &);
60 std::optional<unsigned> getMinCTASm(const Function &);
61 std::optional<unsigned> getMaxNReg(const Function &);
62 
isKernelFunction(const Function & F)63 inline bool isKernelFunction(const Function &F) {
64   return F.getCallingConv() == CallingConv::PTX_Kernel;
65 }
66 
67 bool isParamGridConstant(const Argument &);
68 
getAlign(const Function & F,unsigned Index)69 inline MaybeAlign getAlign(const Function &F, unsigned Index) {
70   return F.getAttributes().getAttributes(Index).getStackAlignment();
71 }
72 
73 MaybeAlign getAlign(const CallInst &, unsigned);
74 Function *getMaybeBitcastedCallee(const CallBase *CB);
75 
76 // PTX ABI requires all scalar argument/return values to have
77 // bit-size as a power of two of at least 32 bits.
promoteScalarArgumentSize(unsigned size)78 inline unsigned promoteScalarArgumentSize(unsigned size) {
79   if (size <= 32)
80     return 32;
81   if (size <= 64)
82     return 64;
83   return size;
84 }
85 
86 bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM);
87 
shouldPassAsArray(Type * Ty)88 inline bool shouldPassAsArray(Type *Ty) {
89   return Ty->isAggregateType() || Ty->isVectorTy() ||
90          Ty->getScalarSizeInBits() == 128 || Ty->isHalfTy() || Ty->isBFloatTy();
91 }
92 
93 namespace NVPTX {
94 // Returns a list of vector types that we prefer to fit into a single PTX
95 // register. NOTE: This must be kept in sync with the register classes
96 // defined in NVPTXRegisterInfo.td.
packed_types()97 inline auto packed_types() {
98   static const auto PackedTypes = {MVT::v4i8, MVT::v2f16, MVT::v2bf16,
99                                    MVT::v2i16, MVT::v2f32};
100   return PackedTypes;
101 }
102 
103 // Checks if the type VT can fit into a single register.
isPackedVectorTy(EVT VT)104 inline bool isPackedVectorTy(EVT VT) {
105   return any_of(packed_types(), [VT](EVT OVT) { return OVT == VT; });
106 }
107 
108 // Checks if two or more of the type ET can fit into a single register.
isPackedElementTy(EVT ET)109 inline bool isPackedElementTy(EVT ET) {
110   return any_of(packed_types(),
111                 [ET](EVT OVT) { return OVT.getVectorElementType() == ET; });
112 }
113 
getValidPTXIdentifier(StringRef Name)114 inline std::string getValidPTXIdentifier(StringRef Name) {
115   std::string ValidName;
116   ValidName.reserve(Name.size() + 4);
117   for (char C : Name)
118     // While PTX also allows '%' at the start of identifiers, LLVM will throw a
119     // fatal error for '%' in symbol names in MCSymbol::print. Exclude for now.
120     if (isAlnum(C) || C == '_' || C == '$')
121       ValidName.push_back(C);
122     else
123       ValidName.append({'_', '$', '_'});
124 
125   return ValidName;
126 }
127 
OrderingToString(Ordering Order)128 inline std::string OrderingToString(Ordering Order) {
129   switch (Order) {
130   case Ordering::NotAtomic:
131     return "NotAtomic";
132   case Ordering::Relaxed:
133     return "Relaxed";
134   case Ordering::Acquire:
135     return "Acquire";
136   case Ordering::Release:
137     return "Release";
138   case Ordering::AcquireRelease:
139     return "AcquireRelease";
140   case Ordering::SequentiallyConsistent:
141     return "SequentiallyConsistent";
142   case Ordering::Volatile:
143     return "Volatile";
144   case Ordering::RelaxedMMIO:
145     return "RelaxedMMIO";
146   }
147   report_fatal_error(formatv("Unknown NVPTX::Ordering \"{}\".",
148                              static_cast<OrderingUnderlyingType>(Order)));
149 }
150 
151 inline raw_ostream &operator<<(raw_ostream &O, Ordering Order) {
152   O << OrderingToString(Order);
153   return O;
154 }
155 
ScopeToString(Scope S)156 inline std::string ScopeToString(Scope S) {
157   switch (S) {
158   case Scope::Thread:
159     return "Thread";
160   case Scope::System:
161     return "System";
162   case Scope::Block:
163     return "Block";
164   case Scope::Cluster:
165     return "Cluster";
166   case Scope::Device:
167     return "Device";
168   }
169   report_fatal_error(formatv("Unknown NVPTX::Scope \"{}\".",
170                              static_cast<ScopeUnderlyingType>(S)));
171 }
172 
173 inline raw_ostream &operator<<(raw_ostream &O, Scope S) {
174   O << ScopeToString(S);
175   return O;
176 }
177 
AddressSpaceToString(AddressSpace A)178 inline std::string AddressSpaceToString(AddressSpace A) {
179   switch (A) {
180   case AddressSpace::Generic:
181     return "generic";
182   case AddressSpace::Global:
183     return "global";
184   case AddressSpace::Const:
185     return "const";
186   case AddressSpace::Shared:
187     return "shared";
188   case AddressSpace::SharedCluster:
189     return "shared::cluster";
190   case AddressSpace::Param:
191     return "param";
192   case AddressSpace::Local:
193     return "local";
194   }
195   report_fatal_error(formatv("Unknown NVPTX::AddressSpace \"{}\".",
196                              static_cast<AddressSpaceUnderlyingType>(A)));
197 }
198 
199 inline raw_ostream &operator<<(raw_ostream &O, AddressSpace A) {
200   O << AddressSpaceToString(A);
201   return O;
202 }
203 
204 } // namespace NVPTX
205 } // namespace llvm
206 
207 #endif
208