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