xref: /aosp_15_r20/external/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- NVPTXUtilities.cpp - Utility Functions -----------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains miscellaneous utility functions
11*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
12*9880d681SAndroid Build Coastguard Worker 
13*9880d681SAndroid Build Coastguard Worker #include "NVPTXUtilities.h"
14*9880d681SAndroid Build Coastguard Worker #include "NVPTX.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Operator.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MutexGuard.h"
23*9880d681SAndroid Build Coastguard Worker #include <algorithm>
24*9880d681SAndroid Build Coastguard Worker #include <cstring>
25*9880d681SAndroid Build Coastguard Worker #include <map>
26*9880d681SAndroid Build Coastguard Worker #include <string>
27*9880d681SAndroid Build Coastguard Worker #include <vector>
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker typedef std::map<std::string, std::vector<unsigned> > key_val_pair_t;
32*9880d681SAndroid Build Coastguard Worker typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t;
33*9880d681SAndroid Build Coastguard Worker typedef std::map<const Module *, global_val_annot_t> per_module_annot_t;
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker ManagedStatic<per_module_annot_t> annotationCache;
36*9880d681SAndroid Build Coastguard Worker static sys::Mutex Lock;
37*9880d681SAndroid Build Coastguard Worker 
clearAnnotationCache(const llvm::Module * Mod)38*9880d681SAndroid Build Coastguard Worker void llvm::clearAnnotationCache(const llvm::Module *Mod) {
39*9880d681SAndroid Build Coastguard Worker   MutexGuard Guard(Lock);
40*9880d681SAndroid Build Coastguard Worker   annotationCache->erase(Mod);
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker 
cacheAnnotationFromMD(const MDNode * md,key_val_pair_t & retval)43*9880d681SAndroid Build Coastguard Worker static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) {
44*9880d681SAndroid Build Coastguard Worker   MutexGuard Guard(Lock);
45*9880d681SAndroid Build Coastguard Worker   assert(md && "Invalid mdnode for annotation");
46*9880d681SAndroid Build Coastguard Worker   assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands");
47*9880d681SAndroid Build Coastguard Worker   // start index = 1, to skip the global variable key
48*9880d681SAndroid Build Coastguard Worker   // increment = 2, to skip the value for each property-value pairs
49*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1, e = md->getNumOperands(); i != e; i += 2) {
50*9880d681SAndroid Build Coastguard Worker     // property
51*9880d681SAndroid Build Coastguard Worker     const MDString *prop = dyn_cast<MDString>(md->getOperand(i));
52*9880d681SAndroid Build Coastguard Worker     assert(prop && "Annotation property not a string");
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker     // value
55*9880d681SAndroid Build Coastguard Worker     ConstantInt *Val = mdconst::dyn_extract<ConstantInt>(md->getOperand(i + 1));
56*9880d681SAndroid Build Coastguard Worker     assert(Val && "Value operand not a constant int");
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker     std::string keyname = prop->getString().str();
59*9880d681SAndroid Build Coastguard Worker     if (retval.find(keyname) != retval.end())
60*9880d681SAndroid Build Coastguard Worker       retval[keyname].push_back(Val->getZExtValue());
61*9880d681SAndroid Build Coastguard Worker     else {
62*9880d681SAndroid Build Coastguard Worker       std::vector<unsigned> tmp;
63*9880d681SAndroid Build Coastguard Worker       tmp.push_back(Val->getZExtValue());
64*9880d681SAndroid Build Coastguard Worker       retval[keyname] = tmp;
65*9880d681SAndroid Build Coastguard Worker     }
66*9880d681SAndroid Build Coastguard Worker   }
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker 
cacheAnnotationFromMD(const Module * m,const GlobalValue * gv)69*9880d681SAndroid Build Coastguard Worker static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) {
70*9880d681SAndroid Build Coastguard Worker   MutexGuard Guard(Lock);
71*9880d681SAndroid Build Coastguard Worker   NamedMDNode *NMD = m->getNamedMetadata(llvm::NamedMDForAnnotations);
72*9880d681SAndroid Build Coastguard Worker   if (!NMD)
73*9880d681SAndroid Build Coastguard Worker     return;
74*9880d681SAndroid Build Coastguard Worker   key_val_pair_t tmp;
75*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
76*9880d681SAndroid Build Coastguard Worker     const MDNode *elem = NMD->getOperand(i);
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker     GlobalValue *entity =
79*9880d681SAndroid Build Coastguard Worker         mdconst::dyn_extract_or_null<GlobalValue>(elem->getOperand(0));
80*9880d681SAndroid Build Coastguard Worker     // entity may be null due to DCE
81*9880d681SAndroid Build Coastguard Worker     if (!entity)
82*9880d681SAndroid Build Coastguard Worker       continue;
83*9880d681SAndroid Build Coastguard Worker     if (entity != gv)
84*9880d681SAndroid Build Coastguard Worker       continue;
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker     // accumulate annotations for entity in tmp
87*9880d681SAndroid Build Coastguard Worker     cacheAnnotationFromMD(elem, tmp);
88*9880d681SAndroid Build Coastguard Worker   }
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   if (tmp.empty()) // no annotations for this gv
91*9880d681SAndroid Build Coastguard Worker     return;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   if ((*annotationCache).find(m) != (*annotationCache).end())
94*9880d681SAndroid Build Coastguard Worker     (*annotationCache)[m][gv] = std::move(tmp);
95*9880d681SAndroid Build Coastguard Worker   else {
96*9880d681SAndroid Build Coastguard Worker     global_val_annot_t tmp1;
97*9880d681SAndroid Build Coastguard Worker     tmp1[gv] = std::move(tmp);
98*9880d681SAndroid Build Coastguard Worker     (*annotationCache)[m] = std::move(tmp1);
99*9880d681SAndroid Build Coastguard Worker   }
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker 
findOneNVVMAnnotation(const GlobalValue * gv,const std::string & prop,unsigned & retval)102*9880d681SAndroid Build Coastguard Worker bool llvm::findOneNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
103*9880d681SAndroid Build Coastguard Worker                                  unsigned &retval) {
104*9880d681SAndroid Build Coastguard Worker   MutexGuard Guard(Lock);
105*9880d681SAndroid Build Coastguard Worker   const Module *m = gv->getParent();
106*9880d681SAndroid Build Coastguard Worker   if ((*annotationCache).find(m) == (*annotationCache).end())
107*9880d681SAndroid Build Coastguard Worker     cacheAnnotationFromMD(m, gv);
108*9880d681SAndroid Build Coastguard Worker   else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end())
109*9880d681SAndroid Build Coastguard Worker     cacheAnnotationFromMD(m, gv);
110*9880d681SAndroid Build Coastguard Worker   if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end())
111*9880d681SAndroid Build Coastguard Worker     return false;
112*9880d681SAndroid Build Coastguard Worker   retval = (*annotationCache)[m][gv][prop][0];
113*9880d681SAndroid Build Coastguard Worker   return true;
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker 
findAllNVVMAnnotation(const GlobalValue * gv,const std::string & prop,std::vector<unsigned> & retval)116*9880d681SAndroid Build Coastguard Worker bool llvm::findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
117*9880d681SAndroid Build Coastguard Worker                                  std::vector<unsigned> &retval) {
118*9880d681SAndroid Build Coastguard Worker   MutexGuard Guard(Lock);
119*9880d681SAndroid Build Coastguard Worker   const Module *m = gv->getParent();
120*9880d681SAndroid Build Coastguard Worker   if ((*annotationCache).find(m) == (*annotationCache).end())
121*9880d681SAndroid Build Coastguard Worker     cacheAnnotationFromMD(m, gv);
122*9880d681SAndroid Build Coastguard Worker   else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end())
123*9880d681SAndroid Build Coastguard Worker     cacheAnnotationFromMD(m, gv);
124*9880d681SAndroid Build Coastguard Worker   if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end())
125*9880d681SAndroid Build Coastguard Worker     return false;
126*9880d681SAndroid Build Coastguard Worker   retval = (*annotationCache)[m][gv][prop];
127*9880d681SAndroid Build Coastguard Worker   return true;
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker 
isTexture(const llvm::Value & val)130*9880d681SAndroid Build Coastguard Worker bool llvm::isTexture(const llvm::Value &val) {
131*9880d681SAndroid Build Coastguard Worker   if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
132*9880d681SAndroid Build Coastguard Worker     unsigned annot;
133*9880d681SAndroid Build Coastguard Worker     if (llvm::findOneNVVMAnnotation(
134*9880d681SAndroid Build Coastguard Worker             gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISTEXTURE],
135*9880d681SAndroid Build Coastguard Worker             annot)) {
136*9880d681SAndroid Build Coastguard Worker       assert((annot == 1) && "Unexpected annotation on a texture symbol");
137*9880d681SAndroid Build Coastguard Worker       return true;
138*9880d681SAndroid Build Coastguard Worker     }
139*9880d681SAndroid Build Coastguard Worker   }
140*9880d681SAndroid Build Coastguard Worker   return false;
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker 
isSurface(const llvm::Value & val)143*9880d681SAndroid Build Coastguard Worker bool llvm::isSurface(const llvm::Value &val) {
144*9880d681SAndroid Build Coastguard Worker   if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
145*9880d681SAndroid Build Coastguard Worker     unsigned annot;
146*9880d681SAndroid Build Coastguard Worker     if (llvm::findOneNVVMAnnotation(
147*9880d681SAndroid Build Coastguard Worker             gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSURFACE],
148*9880d681SAndroid Build Coastguard Worker             annot)) {
149*9880d681SAndroid Build Coastguard Worker       assert((annot == 1) && "Unexpected annotation on a surface symbol");
150*9880d681SAndroid Build Coastguard Worker       return true;
151*9880d681SAndroid Build Coastguard Worker     }
152*9880d681SAndroid Build Coastguard Worker   }
153*9880d681SAndroid Build Coastguard Worker   return false;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker 
isSampler(const llvm::Value & val)156*9880d681SAndroid Build Coastguard Worker bool llvm::isSampler(const llvm::Value &val) {
157*9880d681SAndroid Build Coastguard Worker   if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
158*9880d681SAndroid Build Coastguard Worker     unsigned annot;
159*9880d681SAndroid Build Coastguard Worker     if (llvm::findOneNVVMAnnotation(
160*9880d681SAndroid Build Coastguard Worker             gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER],
161*9880d681SAndroid Build Coastguard Worker             annot)) {
162*9880d681SAndroid Build Coastguard Worker       assert((annot == 1) && "Unexpected annotation on a sampler symbol");
163*9880d681SAndroid Build Coastguard Worker       return true;
164*9880d681SAndroid Build Coastguard Worker     }
165*9880d681SAndroid Build Coastguard Worker   }
166*9880d681SAndroid Build Coastguard Worker   if (const Argument *arg = dyn_cast<Argument>(&val)) {
167*9880d681SAndroid Build Coastguard Worker     const Function *func = arg->getParent();
168*9880d681SAndroid Build Coastguard Worker     std::vector<unsigned> annot;
169*9880d681SAndroid Build Coastguard Worker     if (llvm::findAllNVVMAnnotation(
170*9880d681SAndroid Build Coastguard Worker             func, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER],
171*9880d681SAndroid Build Coastguard Worker             annot)) {
172*9880d681SAndroid Build Coastguard Worker       if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end())
173*9880d681SAndroid Build Coastguard Worker         return true;
174*9880d681SAndroid Build Coastguard Worker     }
175*9880d681SAndroid Build Coastguard Worker   }
176*9880d681SAndroid Build Coastguard Worker   return false;
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
isImageReadOnly(const llvm::Value & val)179*9880d681SAndroid Build Coastguard Worker bool llvm::isImageReadOnly(const llvm::Value &val) {
180*9880d681SAndroid Build Coastguard Worker   if (const Argument *arg = dyn_cast<Argument>(&val)) {
181*9880d681SAndroid Build Coastguard Worker     const Function *func = arg->getParent();
182*9880d681SAndroid Build Coastguard Worker     std::vector<unsigned> annot;
183*9880d681SAndroid Build Coastguard Worker     if (llvm::findAllNVVMAnnotation(func,
184*9880d681SAndroid Build Coastguard Worker                                     llvm::PropertyAnnotationNames[
185*9880d681SAndroid Build Coastguard Worker                                         llvm::PROPERTY_ISREADONLY_IMAGE_PARAM],
186*9880d681SAndroid Build Coastguard Worker                                     annot)) {
187*9880d681SAndroid Build Coastguard Worker       if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end())
188*9880d681SAndroid Build Coastguard Worker         return true;
189*9880d681SAndroid Build Coastguard Worker     }
190*9880d681SAndroid Build Coastguard Worker   }
191*9880d681SAndroid Build Coastguard Worker   return false;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker 
isImageWriteOnly(const llvm::Value & val)194*9880d681SAndroid Build Coastguard Worker bool llvm::isImageWriteOnly(const llvm::Value &val) {
195*9880d681SAndroid Build Coastguard Worker   if (const Argument *arg = dyn_cast<Argument>(&val)) {
196*9880d681SAndroid Build Coastguard Worker     const Function *func = arg->getParent();
197*9880d681SAndroid Build Coastguard Worker     std::vector<unsigned> annot;
198*9880d681SAndroid Build Coastguard Worker     if (llvm::findAllNVVMAnnotation(func,
199*9880d681SAndroid Build Coastguard Worker                                     llvm::PropertyAnnotationNames[
200*9880d681SAndroid Build Coastguard Worker                                         llvm::PROPERTY_ISWRITEONLY_IMAGE_PARAM],
201*9880d681SAndroid Build Coastguard Worker                                     annot)) {
202*9880d681SAndroid Build Coastguard Worker       if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end())
203*9880d681SAndroid Build Coastguard Worker         return true;
204*9880d681SAndroid Build Coastguard Worker     }
205*9880d681SAndroid Build Coastguard Worker   }
206*9880d681SAndroid Build Coastguard Worker   return false;
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker 
isImageReadWrite(const llvm::Value & val)209*9880d681SAndroid Build Coastguard Worker bool llvm::isImageReadWrite(const llvm::Value &val) {
210*9880d681SAndroid Build Coastguard Worker   if (const Argument *arg = dyn_cast<Argument>(&val)) {
211*9880d681SAndroid Build Coastguard Worker     const Function *func = arg->getParent();
212*9880d681SAndroid Build Coastguard Worker     std::vector<unsigned> annot;
213*9880d681SAndroid Build Coastguard Worker     if (llvm::findAllNVVMAnnotation(func,
214*9880d681SAndroid Build Coastguard Worker                                     llvm::PropertyAnnotationNames[
215*9880d681SAndroid Build Coastguard Worker                                         llvm::PROPERTY_ISREADWRITE_IMAGE_PARAM],
216*9880d681SAndroid Build Coastguard Worker                                     annot)) {
217*9880d681SAndroid Build Coastguard Worker       if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end())
218*9880d681SAndroid Build Coastguard Worker         return true;
219*9880d681SAndroid Build Coastguard Worker     }
220*9880d681SAndroid Build Coastguard Worker   }
221*9880d681SAndroid Build Coastguard Worker   return false;
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker 
isImage(const llvm::Value & val)224*9880d681SAndroid Build Coastguard Worker bool llvm::isImage(const llvm::Value &val) {
225*9880d681SAndroid Build Coastguard Worker   return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val) ||
226*9880d681SAndroid Build Coastguard Worker          llvm::isImageReadWrite(val);
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker 
isManaged(const llvm::Value & val)229*9880d681SAndroid Build Coastguard Worker bool llvm::isManaged(const llvm::Value &val) {
230*9880d681SAndroid Build Coastguard Worker   if(const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
231*9880d681SAndroid Build Coastguard Worker     unsigned annot;
232*9880d681SAndroid Build Coastguard Worker     if(llvm::findOneNVVMAnnotation(gv,
233*9880d681SAndroid Build Coastguard Worker                           llvm::PropertyAnnotationNames[llvm::PROPERTY_MANAGED],
234*9880d681SAndroid Build Coastguard Worker                                    annot)) {
235*9880d681SAndroid Build Coastguard Worker       assert((annot == 1) && "Unexpected annotation on a managed symbol");
236*9880d681SAndroid Build Coastguard Worker       return true;
237*9880d681SAndroid Build Coastguard Worker     }
238*9880d681SAndroid Build Coastguard Worker   }
239*9880d681SAndroid Build Coastguard Worker   return false;
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker 
getTextureName(const llvm::Value & val)242*9880d681SAndroid Build Coastguard Worker std::string llvm::getTextureName(const llvm::Value &val) {
243*9880d681SAndroid Build Coastguard Worker   assert(val.hasName() && "Found texture variable with no name");
244*9880d681SAndroid Build Coastguard Worker   return val.getName();
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker 
getSurfaceName(const llvm::Value & val)247*9880d681SAndroid Build Coastguard Worker std::string llvm::getSurfaceName(const llvm::Value &val) {
248*9880d681SAndroid Build Coastguard Worker   assert(val.hasName() && "Found surface variable with no name");
249*9880d681SAndroid Build Coastguard Worker   return val.getName();
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker 
getSamplerName(const llvm::Value & val)252*9880d681SAndroid Build Coastguard Worker std::string llvm::getSamplerName(const llvm::Value &val) {
253*9880d681SAndroid Build Coastguard Worker   assert(val.hasName() && "Found sampler variable with no name");
254*9880d681SAndroid Build Coastguard Worker   return val.getName();
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker 
getMaxNTIDx(const Function & F,unsigned & x)257*9880d681SAndroid Build Coastguard Worker bool llvm::getMaxNTIDx(const Function &F, unsigned &x) {
258*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
259*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_X], x));
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker 
getMaxNTIDy(const Function & F,unsigned & y)262*9880d681SAndroid Build Coastguard Worker bool llvm::getMaxNTIDy(const Function &F, unsigned &y) {
263*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
264*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Y], y));
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker 
getMaxNTIDz(const Function & F,unsigned & z)267*9880d681SAndroid Build Coastguard Worker bool llvm::getMaxNTIDz(const Function &F, unsigned &z) {
268*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
269*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Z], z));
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker 
getReqNTIDx(const Function & F,unsigned & x)272*9880d681SAndroid Build Coastguard Worker bool llvm::getReqNTIDx(const Function &F, unsigned &x) {
273*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
274*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_X], x));
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker 
getReqNTIDy(const Function & F,unsigned & y)277*9880d681SAndroid Build Coastguard Worker bool llvm::getReqNTIDy(const Function &F, unsigned &y) {
278*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
279*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Y], y));
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker 
getReqNTIDz(const Function & F,unsigned & z)282*9880d681SAndroid Build Coastguard Worker bool llvm::getReqNTIDz(const Function &F, unsigned &z) {
283*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
284*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Z], z));
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
getMinCTASm(const Function & F,unsigned & x)287*9880d681SAndroid Build Coastguard Worker bool llvm::getMinCTASm(const Function &F, unsigned &x) {
288*9880d681SAndroid Build Coastguard Worker   return (llvm::findOneNVVMAnnotation(
289*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MINNCTAPERSM], x));
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker 
isKernelFunction(const Function & F)292*9880d681SAndroid Build Coastguard Worker bool llvm::isKernelFunction(const Function &F) {
293*9880d681SAndroid Build Coastguard Worker   unsigned x = 0;
294*9880d681SAndroid Build Coastguard Worker   bool retval = llvm::findOneNVVMAnnotation(
295*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISKERNEL_FUNCTION], x);
296*9880d681SAndroid Build Coastguard Worker   if (!retval) {
297*9880d681SAndroid Build Coastguard Worker     // There is no NVVM metadata, check the calling convention
298*9880d681SAndroid Build Coastguard Worker     return F.getCallingConv() == llvm::CallingConv::PTX_Kernel;
299*9880d681SAndroid Build Coastguard Worker   }
300*9880d681SAndroid Build Coastguard Worker   return (x == 1);
301*9880d681SAndroid Build Coastguard Worker }
302*9880d681SAndroid Build Coastguard Worker 
getAlign(const Function & F,unsigned index,unsigned & align)303*9880d681SAndroid Build Coastguard Worker bool llvm::getAlign(const Function &F, unsigned index, unsigned &align) {
304*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> Vs;
305*9880d681SAndroid Build Coastguard Worker   bool retval = llvm::findAllNVVMAnnotation(
306*9880d681SAndroid Build Coastguard Worker       &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ALIGN], Vs);
307*9880d681SAndroid Build Coastguard Worker   if (!retval)
308*9880d681SAndroid Build Coastguard Worker     return false;
309*9880d681SAndroid Build Coastguard Worker   for (int i = 0, e = Vs.size(); i < e; i++) {
310*9880d681SAndroid Build Coastguard Worker     unsigned v = Vs[i];
311*9880d681SAndroid Build Coastguard Worker     if ((v >> 16) == index) {
312*9880d681SAndroid Build Coastguard Worker       align = v & 0xFFFF;
313*9880d681SAndroid Build Coastguard Worker       return true;
314*9880d681SAndroid Build Coastguard Worker     }
315*9880d681SAndroid Build Coastguard Worker   }
316*9880d681SAndroid Build Coastguard Worker   return false;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker 
getAlign(const CallInst & I,unsigned index,unsigned & align)319*9880d681SAndroid Build Coastguard Worker bool llvm::getAlign(const CallInst &I, unsigned index, unsigned &align) {
320*9880d681SAndroid Build Coastguard Worker   if (MDNode *alignNode = I.getMetadata("callalign")) {
321*9880d681SAndroid Build Coastguard Worker     for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) {
322*9880d681SAndroid Build Coastguard Worker       if (const ConstantInt *CI =
323*9880d681SAndroid Build Coastguard Worker               mdconst::dyn_extract<ConstantInt>(alignNode->getOperand(i))) {
324*9880d681SAndroid Build Coastguard Worker         unsigned v = CI->getZExtValue();
325*9880d681SAndroid Build Coastguard Worker         if ((v >> 16) == index) {
326*9880d681SAndroid Build Coastguard Worker           align = v & 0xFFFF;
327*9880d681SAndroid Build Coastguard Worker           return true;
328*9880d681SAndroid Build Coastguard Worker         }
329*9880d681SAndroid Build Coastguard Worker         if ((v >> 16) > index) {
330*9880d681SAndroid Build Coastguard Worker           return false;
331*9880d681SAndroid Build Coastguard Worker         }
332*9880d681SAndroid Build Coastguard Worker       }
333*9880d681SAndroid Build Coastguard Worker     }
334*9880d681SAndroid Build Coastguard Worker   }
335*9880d681SAndroid Build Coastguard Worker   return false;
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker 
338*9880d681SAndroid Build Coastguard Worker // The following are some useful utilities for debugging
339*9880d681SAndroid Build Coastguard Worker 
getParentBlock(Value * v)340*9880d681SAndroid Build Coastguard Worker BasicBlock *llvm::getParentBlock(Value *v) {
341*9880d681SAndroid Build Coastguard Worker   if (BasicBlock *B = dyn_cast<BasicBlock>(v))
342*9880d681SAndroid Build Coastguard Worker     return B;
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(v))
345*9880d681SAndroid Build Coastguard Worker     return I->getParent();
346*9880d681SAndroid Build Coastguard Worker 
347*9880d681SAndroid Build Coastguard Worker   return nullptr;
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker 
getParentFunction(Value * v)350*9880d681SAndroid Build Coastguard Worker Function *llvm::getParentFunction(Value *v) {
351*9880d681SAndroid Build Coastguard Worker   if (Function *F = dyn_cast<Function>(v))
352*9880d681SAndroid Build Coastguard Worker     return F;
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(v))
355*9880d681SAndroid Build Coastguard Worker     return I->getParent()->getParent();
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker   if (BasicBlock *B = dyn_cast<BasicBlock>(v))
358*9880d681SAndroid Build Coastguard Worker     return B->getParent();
359*9880d681SAndroid Build Coastguard Worker 
360*9880d681SAndroid Build Coastguard Worker   return nullptr;
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker // Dump a block by name
dumpBlock(Value * v,char * blockName)364*9880d681SAndroid Build Coastguard Worker void llvm::dumpBlock(Value *v, char *blockName) {
365*9880d681SAndroid Build Coastguard Worker   Function *F = getParentFunction(v);
366*9880d681SAndroid Build Coastguard Worker   if (!F)
367*9880d681SAndroid Build Coastguard Worker     return;
368*9880d681SAndroid Build Coastguard Worker 
369*9880d681SAndroid Build Coastguard Worker   for (Function::iterator it = F->begin(), ie = F->end(); it != ie; ++it) {
370*9880d681SAndroid Build Coastguard Worker     BasicBlock *B = &*it;
371*9880d681SAndroid Build Coastguard Worker     if (strcmp(B->getName().data(), blockName) == 0) {
372*9880d681SAndroid Build Coastguard Worker       B->dump();
373*9880d681SAndroid Build Coastguard Worker       return;
374*9880d681SAndroid Build Coastguard Worker     }
375*9880d681SAndroid Build Coastguard Worker   }
376*9880d681SAndroid Build Coastguard Worker }
377*9880d681SAndroid Build Coastguard Worker 
378*9880d681SAndroid Build Coastguard Worker // Find an instruction by name
getInst(Value * base,char * instName)379*9880d681SAndroid Build Coastguard Worker Instruction *llvm::getInst(Value *base, char *instName) {
380*9880d681SAndroid Build Coastguard Worker   Function *F = getParentFunction(base);
381*9880d681SAndroid Build Coastguard Worker   if (!F)
382*9880d681SAndroid Build Coastguard Worker     return nullptr;
383*9880d681SAndroid Build Coastguard Worker 
384*9880d681SAndroid Build Coastguard Worker   for (inst_iterator it = inst_begin(F), ie = inst_end(F); it != ie; ++it) {
385*9880d681SAndroid Build Coastguard Worker     Instruction *I = &*it;
386*9880d681SAndroid Build Coastguard Worker     if (strcmp(I->getName().data(), instName) == 0) {
387*9880d681SAndroid Build Coastguard Worker       return I;
388*9880d681SAndroid Build Coastguard Worker     }
389*9880d681SAndroid Build Coastguard Worker   }
390*9880d681SAndroid Build Coastguard Worker 
391*9880d681SAndroid Build Coastguard Worker   return nullptr;
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker 
394*9880d681SAndroid Build Coastguard Worker // Dump an instruction by name
dumpInst(Value * base,char * instName)395*9880d681SAndroid Build Coastguard Worker void llvm::dumpInst(Value *base, char *instName) {
396*9880d681SAndroid Build Coastguard Worker   Instruction *I = getInst(base, instName);
397*9880d681SAndroid Build Coastguard Worker   if (I)
398*9880d681SAndroid Build Coastguard Worker     I->dump();
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker 
401*9880d681SAndroid Build Coastguard Worker // Dump an instruction and all dependent instructions
dumpInstRec(Value * v,std::set<Instruction * > * visited)402*9880d681SAndroid Build Coastguard Worker void llvm::dumpInstRec(Value *v, std::set<Instruction *> *visited) {
403*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(v)) {
404*9880d681SAndroid Build Coastguard Worker 
405*9880d681SAndroid Build Coastguard Worker     if (visited->find(I) != visited->end())
406*9880d681SAndroid Build Coastguard Worker       return;
407*9880d681SAndroid Build Coastguard Worker 
408*9880d681SAndroid Build Coastguard Worker     visited->insert(I);
409*9880d681SAndroid Build Coastguard Worker 
410*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
411*9880d681SAndroid Build Coastguard Worker       dumpInstRec(I->getOperand(i), visited);
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker     I->dump();
414*9880d681SAndroid Build Coastguard Worker   }
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker 
417*9880d681SAndroid Build Coastguard Worker // Dump an instruction and all dependent instructions
dumpInstRec(Value * v)418*9880d681SAndroid Build Coastguard Worker void llvm::dumpInstRec(Value *v) {
419*9880d681SAndroid Build Coastguard Worker   std::set<Instruction *> visited;
420*9880d681SAndroid Build Coastguard Worker 
421*9880d681SAndroid Build Coastguard Worker   //BasicBlock *B = getParentBlock(v);
422*9880d681SAndroid Build Coastguard Worker 
423*9880d681SAndroid Build Coastguard Worker   dumpInstRec(v, &visited);
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker 
426*9880d681SAndroid Build Coastguard Worker // Dump the parent for Instruction, block or function
dumpParent(Value * v)427*9880d681SAndroid Build Coastguard Worker void llvm::dumpParent(Value *v) {
428*9880d681SAndroid Build Coastguard Worker   if (Instruction *I = dyn_cast<Instruction>(v)) {
429*9880d681SAndroid Build Coastguard Worker     I->getParent()->dump();
430*9880d681SAndroid Build Coastguard Worker     return;
431*9880d681SAndroid Build Coastguard Worker   }
432*9880d681SAndroid Build Coastguard Worker 
433*9880d681SAndroid Build Coastguard Worker   if (BasicBlock *B = dyn_cast<BasicBlock>(v)) {
434*9880d681SAndroid Build Coastguard Worker     B->getParent()->dump();
435*9880d681SAndroid Build Coastguard Worker     return;
436*9880d681SAndroid Build Coastguard Worker   }
437*9880d681SAndroid Build Coastguard Worker 
438*9880d681SAndroid Build Coastguard Worker   if (Function *F = dyn_cast<Function>(v)) {
439*9880d681SAndroid Build Coastguard Worker     F->getParent()->dump();
440*9880d681SAndroid Build Coastguard Worker     return;
441*9880d681SAndroid Build Coastguard Worker   }
442*9880d681SAndroid Build Coastguard Worker }
443