@@ -52,29 +52,46 @@ void clearAnnotationCache(const Module *Mod) {
52
52
AC.Cache .erase (Mod);
53
53
}
54
54
55
- static void cacheAnnotationFromMD (const MDNode *md, key_val_pair_t &retval) {
55
+ static void readIntVecFromMDNode (const MDNode *MetadataNode,
56
+ std::vector<unsigned > &Vec) {
57
+ for (unsigned i = 0 , e = MetadataNode->getNumOperands (); i != e; ++i) {
58
+ ConstantInt *Val =
59
+ mdconst::extract<ConstantInt>(MetadataNode->getOperand (i));
60
+ Vec.push_back (Val->getZExtValue ());
61
+ }
62
+ }
63
+
64
+ static void cacheAnnotationFromMD (const MDNode *MetadataNode,
65
+ key_val_pair_t &retval) {
56
66
auto &AC = getAnnotationCache ();
57
67
std::lock_guard<sys::Mutex> Guard (AC.Lock );
58
- assert (md && " Invalid mdnode for annotation" );
59
- assert ((md->getNumOperands () % 2 ) == 1 && " Invalid number of operands" );
68
+ assert (MetadataNode && " Invalid mdnode for annotation" );
69
+ assert ((MetadataNode->getNumOperands () % 2 ) == 1 &&
70
+ " Invalid number of operands" );
60
71
// start index = 1, to skip the global variable key
61
72
// increment = 2, to skip the value for each property-value pairs
62
- for (unsigned i = 1 , e = md ->getNumOperands (); i != e; i += 2 ) {
73
+ for (unsigned i = 1 , e = MetadataNode ->getNumOperands (); i != e; i += 2 ) {
63
74
// property
64
- const MDString *prop = dyn_cast<MDString>(md ->getOperand (i));
75
+ const MDString *prop = dyn_cast<MDString>(MetadataNode ->getOperand (i));
65
76
assert (prop && " Annotation property not a string" );
77
+ std::string Key = prop->getString ().str ();
66
78
67
79
// value
68
- ConstantInt *Val = mdconst::dyn_extract<ConstantInt>(md->getOperand (i + 1 ));
69
- assert (Val && " Value operand not a constant int" );
70
-
71
- std::string keyname = prop->getString ().str ();
72
- if (retval.find (keyname) != retval.end ())
73
- retval[keyname].push_back (Val->getZExtValue ());
74
- else {
75
- std::vector<unsigned > tmp;
76
- tmp.push_back (Val->getZExtValue ());
77
- retval[keyname] = tmp;
80
+ if (ConstantInt *Val = mdconst::dyn_extract<ConstantInt>(
81
+ MetadataNode->getOperand (i + 1 ))) {
82
+ retval[Key].push_back (Val->getZExtValue ());
83
+ } else if (MDNode *VecMd =
84
+ dyn_cast<MDNode>(MetadataNode->getOperand (i + 1 ))) {
85
+ // note: only "grid_constant" annotations support vector MDNodes.
86
+ // assert: there can only exist one unique key value pair of
87
+ // the form (string key, MDNode node). Operands of such a node
88
+ // shall always be unsigned ints.
89
+ if (retval.find (Key) == retval.end ()) {
90
+ readIntVecFromMDNode (VecMd, retval[Key]);
91
+ continue ;
92
+ }
93
+ } else {
94
+ llvm_unreachable (" Value operand not a constant int or an mdnode" );
78
95
}
79
96
}
80
97
}
@@ -153,9 +170,9 @@ bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
153
170
154
171
bool isTexture (const Value &val) {
155
172
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
156
- unsigned annot ;
157
- if (findOneNVVMAnnotation (gv, " texture" , annot )) {
158
- assert ((annot == 1 ) && " Unexpected annotation on a texture symbol" );
173
+ unsigned Annot ;
174
+ if (findOneNVVMAnnotation (gv, " texture" , Annot )) {
175
+ assert ((Annot == 1 ) && " Unexpected annotation on a texture symbol" );
159
176
return true ;
160
177
}
161
178
}
@@ -164,70 +181,67 @@ bool isTexture(const Value &val) {
164
181
165
182
bool isSurface (const Value &val) {
166
183
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
167
- unsigned annot ;
168
- if (findOneNVVMAnnotation (gv, " surface" , annot )) {
169
- assert ((annot == 1 ) && " Unexpected annotation on a surface symbol" );
184
+ unsigned Annot ;
185
+ if (findOneNVVMAnnotation (gv, " surface" , Annot )) {
186
+ assert ((Annot == 1 ) && " Unexpected annotation on a surface symbol" );
170
187
return true ;
171
188
}
172
189
}
173
190
return false ;
174
191
}
175
192
176
- bool isSampler (const Value &val) {
177
- const char *AnnotationName = " sampler" ;
178
-
179
- if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
180
- unsigned annot;
181
- if (findOneNVVMAnnotation (gv, AnnotationName, annot)) {
182
- assert ((annot == 1 ) && " Unexpected annotation on a sampler symbol" );
183
- return true ;
184
- }
185
- }
186
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
187
- const Function *func = arg->getParent ();
188
- std::vector<unsigned > annot;
189
- if (findAllNVVMAnnotation (func, AnnotationName, annot)) {
190
- if (is_contained (annot, arg->getArgNo ()))
193
+ static bool argHasNVVMAnnotation (const Value &Val,
194
+ const std::string &Annotation,
195
+ const bool StartArgIndexAtOne = false ) {
196
+ if (const Argument *Arg = dyn_cast<Argument>(&Val)) {
197
+ const Function *Func = Arg->getParent ();
198
+ std::vector<unsigned > Annot;
199
+ if (findAllNVVMAnnotation (Func, Annotation, Annot)) {
200
+ const unsigned BaseOffset = StartArgIndexAtOne ? 1 : 0 ;
201
+ if (is_contained (Annot, BaseOffset + Arg->getArgNo ())) {
191
202
return true ;
203
+ }
192
204
}
193
205
}
194
206
return false ;
195
207
}
196
208
197
- bool isImageReadOnly (const Value &val) {
198
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
199
- const Function *func = arg->getParent ();
200
- std::vector<unsigned > annot;
201
- if (findAllNVVMAnnotation (func, " rdoimage" , annot)) {
202
- if (is_contained (annot, arg->getArgNo ()))
203
- return true ;
209
+ bool isParamGridConstant (const Value &V) {
210
+ if (const Argument *Arg = dyn_cast<Argument>(&V)) {
211
+ // "grid_constant" counts argument indices starting from 1
212
+ if (Arg->hasByValAttr () &&
213
+ argHasNVVMAnnotation (*Arg, " grid_constant" , /* StartArgIndexAtOne*/ true )) {
214
+ assert (isKernelFunction (*Arg->getParent ()) &&
215
+ " only kernel arguments can be grid_constant" );
216
+ return true ;
204
217
}
205
218
}
206
219
return false ;
207
220
}
208
221
209
- bool isImageWriteOnly (const Value &val) {
210
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
211
- const Function *func = arg->getParent ();
212
- std::vector<unsigned > annot;
213
- if (findAllNVVMAnnotation (func, " wroimage" , annot)) {
214
- if (is_contained (annot, arg->getArgNo ()))
215
- return true ;
222
+ bool isSampler (const Value &val) {
223
+ const char *AnnotationName = " sampler" ;
224
+
225
+ if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
226
+ unsigned Annot;
227
+ if (findOneNVVMAnnotation (gv, AnnotationName, Annot)) {
228
+ assert ((Annot == 1 ) && " Unexpected annotation on a sampler symbol" );
229
+ return true ;
216
230
}
217
231
}
218
- return false ;
232
+ return argHasNVVMAnnotation (val, AnnotationName);
233
+ }
234
+
235
+ bool isImageReadOnly (const Value &val) {
236
+ return argHasNVVMAnnotation (val, " rdoimage" );
237
+ }
238
+
239
+ bool isImageWriteOnly (const Value &val) {
240
+ return argHasNVVMAnnotation (val, " wroimage" );
219
241
}
220
242
221
243
bool isImageReadWrite (const Value &val) {
222
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
223
- const Function *func = arg->getParent ();
224
- std::vector<unsigned > annot;
225
- if (findAllNVVMAnnotation (func, " rdwrimage" , annot)) {
226
- if (is_contained (annot, arg->getArgNo ()))
227
- return true ;
228
- }
229
- }
230
- return false ;
244
+ return argHasNVVMAnnotation (val, " rdwrimage" );
231
245
}
232
246
233
247
bool isImage (const Value &val) {
@@ -236,9 +250,9 @@ bool isImage(const Value &val) {
236
250
237
251
bool isManaged (const Value &val) {
238
252
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
239
- unsigned annot ;
240
- if (findOneNVVMAnnotation (gv, " managed" , annot )) {
241
- assert ((annot == 1 ) && " Unexpected annotation on a managed symbol" );
253
+ unsigned Annot ;
254
+ if (findOneNVVMAnnotation (gv, " managed" , Annot )) {
255
+ assert ((Annot == 1 ) && " Unexpected annotation on a managed symbol" );
242
256
return true ;
243
257
}
244
258
}
@@ -323,8 +337,7 @@ bool getMaxNReg(const Function &F, unsigned &x) {
323
337
324
338
bool isKernelFunction (const Function &F) {
325
339
unsigned x = 0 ;
326
- bool retval = findOneNVVMAnnotation (&F, " kernel" , x);
327
- if (!retval) {
340
+ if (!findOneNVVMAnnotation (&F, " kernel" , x)) {
328
341
// There is no NVVM metadata, check the calling convention
329
342
return F.getCallingConv () == CallingConv::PTX_Kernel;
330
343
}
0 commit comments