@@ -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
}
@@ -145,9 +162,9 @@ bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
145
162
146
163
bool isTexture (const Value &val) {
147
164
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
148
- unsigned annot ;
149
- if (findOneNVVMAnnotation (gv, " texture" , annot )) {
150
- assert ((annot == 1 ) && " Unexpected annotation on a texture symbol" );
165
+ unsigned Annot ;
166
+ if (findOneNVVMAnnotation (gv, " texture" , Annot )) {
167
+ assert ((Annot == 1 ) && " Unexpected annotation on a texture symbol" );
151
168
return true ;
152
169
}
153
170
}
@@ -156,70 +173,67 @@ bool isTexture(const Value &val) {
156
173
157
174
bool isSurface (const Value &val) {
158
175
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
159
- unsigned annot ;
160
- if (findOneNVVMAnnotation (gv, " surface" , annot )) {
161
- assert ((annot == 1 ) && " Unexpected annotation on a surface symbol" );
176
+ unsigned Annot ;
177
+ if (findOneNVVMAnnotation (gv, " surface" , Annot )) {
178
+ assert ((Annot == 1 ) && " Unexpected annotation on a surface symbol" );
162
179
return true ;
163
180
}
164
181
}
165
182
return false ;
166
183
}
167
184
168
- bool isSampler (const Value &val) {
169
- const char *AnnotationName = " sampler" ;
170
-
171
- if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
172
- unsigned annot;
173
- if (findOneNVVMAnnotation (gv, AnnotationName, annot)) {
174
- assert ((annot == 1 ) && " Unexpected annotation on a sampler symbol" );
175
- return true ;
176
- }
177
- }
178
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
179
- const Function *func = arg->getParent ();
180
- std::vector<unsigned > annot;
181
- if (findAllNVVMAnnotation (func, AnnotationName, annot)) {
182
- if (is_contained (annot, arg->getArgNo ()))
185
+ static bool argHasNVVMAnnotation (const Value &Val,
186
+ const std::string &Annotation,
187
+ const bool StartArgIndexAtOne = false ) {
188
+ if (const Argument *Arg = dyn_cast<Argument>(&Val)) {
189
+ const Function *Func = Arg->getParent ();
190
+ std::vector<unsigned > Annot;
191
+ if (findAllNVVMAnnotation (Func, Annotation, Annot)) {
192
+ const unsigned BaseOffset = StartArgIndexAtOne ? 1 : 0 ;
193
+ if (is_contained (Annot, BaseOffset + Arg->getArgNo ())) {
183
194
return true ;
195
+ }
184
196
}
185
197
}
186
198
return false ;
187
199
}
188
200
189
- bool isImageReadOnly (const Value &val) {
190
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
191
- const Function *func = arg->getParent ();
192
- std::vector<unsigned > annot;
193
- if (findAllNVVMAnnotation (func, " rdoimage" , annot)) {
194
- if (is_contained (annot, arg->getArgNo ()))
195
- return true ;
201
+ bool isParamGridConstant (const Value &V) {
202
+ if (const Argument *Arg = dyn_cast<Argument>(&V)) {
203
+ // "grid_constant" counts argument indices starting from 1
204
+ if (Arg->hasByValAttr () &&
205
+ argHasNVVMAnnotation (*Arg, " grid_constant" , /* StartArgIndexAtOne*/ true )) {
206
+ assert (isKernelFunction (*Arg->getParent ()) &&
207
+ " only kernel arguments can be grid_constant" );
208
+ return true ;
196
209
}
197
210
}
198
211
return false ;
199
212
}
200
213
201
- bool isImageWriteOnly (const Value &val) {
202
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
203
- const Function *func = arg->getParent ();
204
- std::vector<unsigned > annot;
205
- if (findAllNVVMAnnotation (func, " wroimage" , annot)) {
206
- if (is_contained (annot, arg->getArgNo ()))
207
- return true ;
214
+ bool isSampler (const Value &val) {
215
+ const char *AnnotationName = " sampler" ;
216
+
217
+ if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
218
+ unsigned Annot;
219
+ if (findOneNVVMAnnotation (gv, AnnotationName, Annot)) {
220
+ assert ((Annot == 1 ) && " Unexpected annotation on a sampler symbol" );
221
+ return true ;
208
222
}
209
223
}
210
- return false ;
224
+ return argHasNVVMAnnotation (val, AnnotationName);
225
+ }
226
+
227
+ bool isImageReadOnly (const Value &val) {
228
+ return argHasNVVMAnnotation (val, " rdoimage" );
229
+ }
230
+
231
+ bool isImageWriteOnly (const Value &val) {
232
+ return argHasNVVMAnnotation (val, " wroimage" );
211
233
}
212
234
213
235
bool isImageReadWrite (const Value &val) {
214
- if (const Argument *arg = dyn_cast<Argument>(&val)) {
215
- const Function *func = arg->getParent ();
216
- std::vector<unsigned > annot;
217
- if (findAllNVVMAnnotation (func, " rdwrimage" , annot)) {
218
- if (is_contained (annot, arg->getArgNo ()))
219
- return true ;
220
- }
221
- }
222
- return false ;
236
+ return argHasNVVMAnnotation (val, " rdwrimage" );
223
237
}
224
238
225
239
bool isImage (const Value &val) {
@@ -228,9 +242,9 @@ bool isImage(const Value &val) {
228
242
229
243
bool isManaged (const Value &val) {
230
244
if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) {
231
- unsigned annot ;
232
- if (findOneNVVMAnnotation (gv, " managed" , annot )) {
233
- assert ((annot == 1 ) && " Unexpected annotation on a managed symbol" );
245
+ unsigned Annot ;
246
+ if (findOneNVVMAnnotation (gv, " managed" , Annot )) {
247
+ assert ((Annot == 1 ) && " Unexpected annotation on a managed symbol" );
234
248
return true ;
235
249
}
236
250
}
@@ -290,8 +304,7 @@ bool getMaxNReg(const Function &F, unsigned &x) {
290
304
291
305
bool isKernelFunction (const Function &F) {
292
306
unsigned x = 0 ;
293
- bool retval = findOneNVVMAnnotation (&F, " kernel" , x);
294
- if (!retval) {
307
+ if (!findOneNVVMAnnotation (&F, " kernel" , x)) {
295
308
// There is no NVVM metadata, check the calling convention
296
309
return F.getCallingConv () == CallingConv::PTX_Kernel;
297
310
}
0 commit comments