@@ -52,29 +52,46 @@ void clearAnnotationCache(const Module *Mod) {
5252 AC.Cache .erase (Mod);
5353}
5454
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) {
5666 auto &AC = getAnnotationCache ();
5767 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" );
6071 // start index = 1, to skip the global variable key
6172 // 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 ) {
6374 // property
64- const MDString *prop = dyn_cast<MDString>(md ->getOperand (i));
75+ const MDString *prop = dyn_cast<MDString>(MetadataNode ->getOperand (i));
6576 assert (prop && " Annotation property not a string" );
77+ std::string Key = prop->getString ().str ();
6678
6779 // 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" );
7895 }
7996 }
8097}
@@ -153,9 +170,9 @@ bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop,
153170
154171bool isTexture (const Value &val) {
155172 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" );
159176 return true ;
160177 }
161178 }
@@ -164,70 +181,67 @@ bool isTexture(const Value &val) {
164181
165182bool isSurface (const Value &val) {
166183 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" );
170187 return true ;
171188 }
172189 }
173190 return false ;
174191}
175192
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 ())) {
191202 return true ;
203+ }
192204 }
193205 }
194206 return false ;
195207}
196208
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 ;
204217 }
205218 }
206219 return false ;
207220}
208221
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 ;
216230 }
217231 }
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" );
219241}
220242
221243bool 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" );
231245}
232246
233247bool isImage (const Value &val) {
@@ -236,9 +250,9 @@ bool isImage(const Value &val) {
236250
237251bool isManaged (const Value &val) {
238252 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" );
242256 return true ;
243257 }
244258 }
@@ -323,8 +337,7 @@ bool getMaxNReg(const Function &F, unsigned &x) {
323337
324338bool isKernelFunction (const Function &F) {
325339 unsigned x = 0 ;
326- bool retval = findOneNVVMAnnotation (&F, " kernel" , x);
327- if (!retval) {
340+ if (!findOneNVVMAnnotation (&F, " kernel" , x)) {
328341 // There is no NVVM metadata, check the calling convention
329342 return F.getCallingConv () == CallingConv::PTX_Kernel;
330343 }
0 commit comments