LLVM: lib/Target/NVPTX/NVPTXUtilities.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23#include
24#include
25#include
26#include
27#include
28#include
29
30namespace llvm {
31
32namespace {
33typedef std::map<std::string, std::vector> key_val_pair_t;
34typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t;
35
36struct AnnotationCache {
38 std::map<const Module *, global_val_annot_t> Cache;
39};
40
41AnnotationCache &getAnnotationCache() {
42 static AnnotationCache AC;
43 return AC;
44}
45}
46
48 auto &AC = getAnnotationCache();
49 std::lock_guardsys::Mutex Guard(AC.Lock);
50 AC.Cache.erase(Mod);
51}
52
54 std::vector &Vec) {
55 for (unsigned i = 0, e = MetadataNode->getNumOperands(); i != e; ++i) {
57 mdconst::extract(MetadataNode->getOperand(i));
59 }
60}
61
63 key_val_pair_t &retval) {
64 auto &AC = getAnnotationCache();
65 std::lock_guardsys::Mutex Guard(AC.Lock);
66 assert(MetadataNode && "Invalid mdnode for annotation");
68 "Invalid number of operands");
69
70
71 for (unsigned i = 1, e = MetadataNode->getNumOperands(); i != e; i += 2) {
72
73 const MDString *prop = dyn_cast(MetadataNode->getOperand(i));
74 assert(prop && "Annotation property not a string");
76
77
78 if (ConstantInt *Val = mdconst::dyn_extract(
80 retval[Key].push_back(Val->getZExtValue());
81 } else if (MDNode *VecMd =
82 dyn_cast(MetadataNode->getOperand(i + 1))) {
83
84
85
86
87 auto [It, Inserted] = retval.try_emplace(Key);
88 if (Inserted) {
90 continue;
91 }
92 } else {
93 llvm_unreachable("Value operand not a constant int or an mdnode");
94 }
95 }
96}
97
99 auto &AC = getAnnotationCache();
100 std::lock_guardsys::Mutex Guard(AC.Lock);
102 if (!NMD)
103 return;
104 key_val_pair_t tmp;
105 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
107
109 mdconst::dyn_extract_or_null(elem->getOperand(0));
110
111 if (!entity)
112 continue;
113 if (entity != gv)
114 continue;
115
116
118 }
119
120 if (tmp.empty())
121 return;
122
123 AC.Cache[m][gv] = std::move(tmp);
124}
125
127 const std::string &prop) {
128 auto &AC = getAnnotationCache();
129 std::lock_guardsys::Mutex Guard(AC.Lock);
131 if (AC.Cache.find(m) == AC.Cache.end())
133 else if (AC.Cache[m].find(gv) == AC.Cache[m].end())
135 if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end())
136 return std::nullopt;
137 return AC.Cache[m][gv][prop][0];
138}
139
141 const std::string &prop,
142 std::vector &retval) {
143 auto &AC = getAnnotationCache();
144 std::lock_guardsys::Mutex Guard(AC.Lock);
146 if (AC.Cache.find(m) == AC.Cache.end())
148 else if (AC.Cache[m].find(gv) == AC.Cache[m].end())
150 if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end())
151 return false;
152 retval = AC.Cache[m][gv][prop];
153 return true;
154}
155
157 if (const auto *GV = dyn_cast(&V))
159 assert((*Annot == 1) && "Unexpected annotation on a symbol");
160 return true;
161 }
162
163 return false;
164}
165
167 const std::string &Annotation,
168 const bool StartArgIndexAtOne = false) {
169 if (const Argument *Arg = dyn_cast(&Val)) {
170 const Function *Func = Arg->getParent();
171 std::vector Annot;
173 const unsigned BaseOffset = StartArgIndexAtOne ? 1 : 0;
174 if (is_contained(Annot, BaseOffset + Arg->getArgNo())) {
175 return true;
176 }
177 }
178 }
179 return false;
180}
181
183 if (const Argument *Arg = dyn_cast(&V)) {
184
185 if (Arg->hasByValAttr() &&
187 true)) {
189 "only kernel arguments can be grid_constant");
190 return true;
191 }
192 }
193 return false;
194}
195
197
199
201 const char *AnnotationName = "sampler";
202
205}
206
209}
210
213}
214
217}
218
221}
222
224
226 assert(V.hasName() && "Found texture variable with no name");
227 return V.getName();
228}
229
231 assert(V.hasName() && "Found surface variable with no name");
232 return V.getName();
233}
234
236 assert(V.hasName() && "Found sampler variable with no name");
237 return V.getName();
238}
239
242}
243
246}
247
250}
251
253
254
255
256
257
258
259 std::optional MaxNTIDx = getMaxNTIDx(F);
260 std::optional MaxNTIDy = getMaxNTIDy(F);
261 std::optional MaxNTIDz = getMaxNTIDz(F);
262 if (MaxNTIDx || MaxNTIDy || MaxNTIDz)
263 return MaxNTIDx.value_or(1) * MaxNTIDy.value_or(1) * MaxNTIDz.value_or(1);
264 return std::nullopt;
265}
266
269}
270
273}
274
277}
278
281}
282
285}
286
289}
290
293}
294
296
297 std::optional ReqNTIDx = getReqNTIDx(F);
298 std::optional ReqNTIDy = getReqNTIDy(F);
299 std::optional ReqNTIDz = getReqNTIDz(F);
300 if (ReqNTIDx || ReqNTIDy || ReqNTIDz)
301 return ReqNTIDx.value_or(1) * ReqNTIDy.value_or(1) * ReqNTIDz.value_or(1);
302 return std::nullopt;
303}
304
307}
308
311}
312
315 return true;
316
318 return (*X == 1);
319
320 return false;
321}
322
324
326 F.getAttributes().getAttributes(Index).getStackAlignment())
327 return StackAlign;
328
329
330 std::vector Vs;
332 if (!retval)
333 return std::nullopt;
334 for (unsigned V : Vs)
335 if ((V >> 16) == Index)
336 return Align(V & 0xFFFF);
337
338 return std::nullopt;
339}
340
342
344 I.getAttributes().getAttributes(Index).getStackAlignment())
345 return StackAlign;
346
347
348 if (MDNode *alignNode = I.getMetadata("callalign")) {
349 for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) {
351 mdconst::dyn_extract(alignNode->getOperand(i))) {
352 unsigned V = CI->getZExtValue();
353 if ((V >> 16) == Index)
354 return Align(V & 0xFFFF);
355 if ((V >> 16) > Index)
356 return std::nullopt;
357 }
358 }
359 }
360 return std::nullopt;
361}
362
365}
366
368 const auto &ST =
370 if (!ST.hasNoReturn())
371 return false;
372
373 assert((isa(V) || isa(V)) &&
374 "Expect either a call instruction or a function");
375
376 if (const CallInst *CallI = dyn_cast(V))
377 return CallI->doesNotReturn() &&
378 CallI->getFunctionType()->getReturnType()->isVoidTy();
379
380 const Function *F = cast(V);
381 return F->doesNotReturn() &&
382 F->getFunctionType()->getReturnType()->isVoidTy() &&
384}
385
387 return (VT == MVT::v2f16 || VT == MVT::v2bf16 || VT == MVT::v2i16);
388}
389
390}
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an incoming formal argument to a Function.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Module * getParent()
Get the module that this global value is contained inside of...
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
StringRef getString() const
A Module instance is used to store all the information related to an LLVM module.
NamedMDNode * getNamedMetadata(StringRef Name) const
Return the first NamedMDNode in the module with the specified name.
MDNode * getOperand(unsigned i) const
unsigned getNumOperands() const
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
Primary interface to the complete machine description for the target machine.
LLVM Value Representation.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ PTX_Kernel
Call to a PTX kernel. Passes all arguments in parameter space.
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
This is an optimization pass for GlobalISel generic memory operations.
bool isManaged(const Value &V)
bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM)
static bool globalHasNVVMAnnotation(const Value &V, const std::string &Prop)
std::optional< unsigned > getMaxNReg(const Function &F)
std::optional< unsigned > getMaxNTIDy(const Function &F)
static void readIntVecFromMDNode(const MDNode *MetadataNode, std::vector< unsigned > &Vec)
bool isParamGridConstant(const Value &V)
StringRef getSamplerName(const Value &V)
bool isImageReadWrite(const Value &V)
bool isImageReadOnly(const Value &V)
std::optional< unsigned > getMaxNTIDz(const Function &F)
MaybeAlign getAlign(const Function &F, unsigned Index)
std::optional< unsigned > getMaxNTIDx(const Function &F)
std::optional< unsigned > getMinCTASm(const Function &F)
bool isImage(const Value &V)
bool isSampler(const Value &V)
static void cacheAnnotationFromMD(const MDNode *MetadataNode, key_val_pair_t &retval)
void clearAnnotationCache(const Module *Mod)
std::optional< unsigned > getReqNTIDy(const Function &F)
bool isSurface(const Value &V)
static bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop, std::vector< unsigned > &retval)
std::optional< unsigned > getMaxClusterRank(const Function &F)
StringRef getTextureName(const Value &V)
std::optional< unsigned > getClusterDimx(const Function &F)
@ Mod
The access may modify the value stored in memory.
static bool argHasNVVMAnnotation(const Value &Val, const std::string &Annotation, const bool StartArgIndexAtOne=false)
StringRef getSurfaceName(const Value &V)
std::optional< unsigned > getClusterDimy(const Function &F)
static std::optional< unsigned > findOneNVVMAnnotation(const GlobalValue *gv, const std::string &prop)
bool isKernelFunction(const Function &F)
bool isTexture(const Value &V)
Function * getMaybeBitcastedCallee(const CallBase *CB)
bool isImageWriteOnly(const Value &V)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::optional< unsigned > getReqNTIDz(const Function &F)
std::optional< unsigned > getReqNTIDx(const Function &F)
std::optional< unsigned > getClusterDimz(const Function &F)
std::optional< unsigned > getReqNTID(const Function &F)
std::optional< unsigned > getMaxNTID(const Function &F)
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.