LLVM API Documentation
00001 //===- NVPTXUtilities.cpp - Utility Functions -----------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains miscellaneous utility functions 00011 //===----------------------------------------------------------------------===// 00012 00013 #include "NVPTXUtilities.h" 00014 #include "NVPTX.h" 00015 #include "llvm/IR/Constants.h" 00016 #include "llvm/IR/Function.h" 00017 #include "llvm/IR/GlobalVariable.h" 00018 #include "llvm/IR/Module.h" 00019 #include "llvm/IR/Operator.h" 00020 #include <algorithm> 00021 #include <cstring> 00022 #include <map> 00023 #include <string> 00024 #include <vector> 00025 //#include <iostream> 00026 #include "llvm/Support/ManagedStatic.h" 00027 #include "llvm/Support/InstIterator.h" 00028 00029 using namespace llvm; 00030 00031 typedef std::map<std::string, std::vector<unsigned> > key_val_pair_t; 00032 typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t; 00033 typedef std::map<const Module *, global_val_annot_t> per_module_annot_t; 00034 00035 ManagedStatic<per_module_annot_t> annotationCache; 00036 00037 static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { 00038 assert(md && "Invalid mdnode for annotation"); 00039 assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands"); 00040 // start index = 1, to skip the global variable key 00041 // increment = 2, to skip the value for each property-value pairs 00042 for (unsigned i = 1, e = md->getNumOperands(); i != e; i += 2) { 00043 // property 00044 const MDString *prop = dyn_cast<MDString>(md->getOperand(i)); 00045 assert(prop && "Annotation property not a string"); 00046 00047 // value 00048 ConstantInt *Val = dyn_cast<ConstantInt>(md->getOperand(i + 1)); 00049 assert(Val && "Value operand not a constant int"); 00050 00051 std::string keyname = prop->getString().str(); 00052 if (retval.find(keyname) != retval.end()) 00053 retval[keyname].push_back(Val->getZExtValue()); 00054 else { 00055 std::vector<unsigned> tmp; 00056 tmp.push_back(Val->getZExtValue()); 00057 retval[keyname] = tmp; 00058 } 00059 } 00060 } 00061 00062 static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { 00063 NamedMDNode *NMD = m->getNamedMetadata(llvm::NamedMDForAnnotations); 00064 if (!NMD) 00065 return; 00066 key_val_pair_t tmp; 00067 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { 00068 const MDNode *elem = NMD->getOperand(i); 00069 00070 Value *entity = elem->getOperand(0); 00071 // entity may be null due to DCE 00072 if (!entity) 00073 continue; 00074 if (entity != gv) 00075 continue; 00076 00077 // accumulate annotations for entity in tmp 00078 cacheAnnotationFromMD(elem, tmp); 00079 } 00080 00081 if (tmp.empty()) // no annotations for this gv 00082 return; 00083 00084 if ((*annotationCache).find(m) != (*annotationCache).end()) 00085 (*annotationCache)[m][gv] = tmp; 00086 else { 00087 global_val_annot_t tmp1; 00088 tmp1[gv] = tmp; 00089 (*annotationCache)[m] = tmp1; 00090 } 00091 } 00092 00093 bool llvm::findOneNVVMAnnotation(const GlobalValue *gv, std::string prop, 00094 unsigned &retval) { 00095 const Module *m = gv->getParent(); 00096 if ((*annotationCache).find(m) == (*annotationCache).end()) 00097 cacheAnnotationFromMD(m, gv); 00098 else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 00099 cacheAnnotationFromMD(m, gv); 00100 if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 00101 return false; 00102 retval = (*annotationCache)[m][gv][prop][0]; 00103 return true; 00104 } 00105 00106 bool llvm::findAllNVVMAnnotation(const GlobalValue *gv, std::string prop, 00107 std::vector<unsigned> &retval) { 00108 const Module *m = gv->getParent(); 00109 if ((*annotationCache).find(m) == (*annotationCache).end()) 00110 cacheAnnotationFromMD(m, gv); 00111 else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 00112 cacheAnnotationFromMD(m, gv); 00113 if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 00114 return false; 00115 retval = (*annotationCache)[m][gv][prop]; 00116 return true; 00117 } 00118 00119 bool llvm::isTexture(const llvm::Value &val) { 00120 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 00121 unsigned annot; 00122 if (llvm::findOneNVVMAnnotation( 00123 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISTEXTURE], 00124 annot)) { 00125 assert((annot == 1) && "Unexpected annotation on a texture symbol"); 00126 return true; 00127 } 00128 } 00129 return false; 00130 } 00131 00132 bool llvm::isSurface(const llvm::Value &val) { 00133 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 00134 unsigned annot; 00135 if (llvm::findOneNVVMAnnotation( 00136 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSURFACE], 00137 annot)) { 00138 assert((annot == 1) && "Unexpected annotation on a surface symbol"); 00139 return true; 00140 } 00141 } 00142 return false; 00143 } 00144 00145 bool llvm::isSampler(const llvm::Value &val) { 00146 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 00147 unsigned annot; 00148 if (llvm::findOneNVVMAnnotation( 00149 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 00150 annot)) { 00151 assert((annot == 1) && "Unexpected annotation on a sampler symbol"); 00152 return true; 00153 } 00154 } 00155 if (const Argument *arg = dyn_cast<Argument>(&val)) { 00156 const Function *func = arg->getParent(); 00157 std::vector<unsigned> annot; 00158 if (llvm::findAllNVVMAnnotation( 00159 func, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 00160 annot)) { 00161 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 00162 return true; 00163 } 00164 } 00165 return false; 00166 } 00167 00168 bool llvm::isImageReadOnly(const llvm::Value &val) { 00169 if (const Argument *arg = dyn_cast<Argument>(&val)) { 00170 const Function *func = arg->getParent(); 00171 std::vector<unsigned> annot; 00172 if (llvm::findAllNVVMAnnotation(func, 00173 llvm::PropertyAnnotationNames[ 00174 llvm::PROPERTY_ISREADONLY_IMAGE_PARAM], 00175 annot)) { 00176 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 00177 return true; 00178 } 00179 } 00180 return false; 00181 } 00182 00183 bool llvm::isImageWriteOnly(const llvm::Value &val) { 00184 if (const Argument *arg = dyn_cast<Argument>(&val)) { 00185 const Function *func = arg->getParent(); 00186 std::vector<unsigned> annot; 00187 if (llvm::findAllNVVMAnnotation(func, 00188 llvm::PropertyAnnotationNames[ 00189 llvm::PROPERTY_ISWRITEONLY_IMAGE_PARAM], 00190 annot)) { 00191 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 00192 return true; 00193 } 00194 } 00195 return false; 00196 } 00197 00198 bool llvm::isImage(const llvm::Value &val) { 00199 return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val); 00200 } 00201 00202 std::string llvm::getTextureName(const llvm::Value &val) { 00203 assert(val.hasName() && "Found texture variable with no name"); 00204 return val.getName(); 00205 } 00206 00207 std::string llvm::getSurfaceName(const llvm::Value &val) { 00208 assert(val.hasName() && "Found surface variable with no name"); 00209 return val.getName(); 00210 } 00211 00212 std::string llvm::getSamplerName(const llvm::Value &val) { 00213 assert(val.hasName() && "Found sampler variable with no name"); 00214 return val.getName(); 00215 } 00216 00217 bool llvm::getMaxNTIDx(const Function &F, unsigned &x) { 00218 return (llvm::findOneNVVMAnnotation( 00219 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_X], x)); 00220 } 00221 00222 bool llvm::getMaxNTIDy(const Function &F, unsigned &y) { 00223 return (llvm::findOneNVVMAnnotation( 00224 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Y], y)); 00225 } 00226 00227 bool llvm::getMaxNTIDz(const Function &F, unsigned &z) { 00228 return (llvm::findOneNVVMAnnotation( 00229 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Z], z)); 00230 } 00231 00232 bool llvm::getReqNTIDx(const Function &F, unsigned &x) { 00233 return (llvm::findOneNVVMAnnotation( 00234 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_X], x)); 00235 } 00236 00237 bool llvm::getReqNTIDy(const Function &F, unsigned &y) { 00238 return (llvm::findOneNVVMAnnotation( 00239 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Y], y)); 00240 } 00241 00242 bool llvm::getReqNTIDz(const Function &F, unsigned &z) { 00243 return (llvm::findOneNVVMAnnotation( 00244 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Z], z)); 00245 } 00246 00247 bool llvm::getMinCTASm(const Function &F, unsigned &x) { 00248 return (llvm::findOneNVVMAnnotation( 00249 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MINNCTAPERSM], x)); 00250 } 00251 00252 bool llvm::isKernelFunction(const Function &F) { 00253 unsigned x = 0; 00254 bool retval = llvm::findOneNVVMAnnotation( 00255 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISKERNEL_FUNCTION], x); 00256 if (retval == false) { 00257 // There is no NVVM metadata, check the calling convention 00258 if (F.getCallingConv() == llvm::CallingConv::PTX_Kernel) 00259 return true; 00260 else 00261 return false; 00262 } 00263 return (x == 1); 00264 } 00265 00266 bool llvm::getAlign(const Function &F, unsigned index, unsigned &align) { 00267 std::vector<unsigned> Vs; 00268 bool retval = llvm::findAllNVVMAnnotation( 00269 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ALIGN], Vs); 00270 if (retval == false) 00271 return false; 00272 for (int i = 0, e = Vs.size(); i < e; i++) { 00273 unsigned v = Vs[i]; 00274 if ((v >> 16) == index) { 00275 align = v & 0xFFFF; 00276 return true; 00277 } 00278 } 00279 return false; 00280 } 00281 00282 bool llvm::getAlign(const CallInst &I, unsigned index, unsigned &align) { 00283 if (MDNode *alignNode = I.getMetadata("callalign")) { 00284 for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) { 00285 if (const ConstantInt *CI = 00286 dyn_cast<ConstantInt>(alignNode->getOperand(i))) { 00287 unsigned v = CI->getZExtValue(); 00288 if ((v >> 16) == index) { 00289 align = v & 0xFFFF; 00290 return true; 00291 } 00292 if ((v >> 16) > index) { 00293 return false; 00294 } 00295 } 00296 } 00297 } 00298 return false; 00299 } 00300 00301 bool llvm::isBarrierIntrinsic(Intrinsic::ID id) { 00302 if ((id == Intrinsic::nvvm_barrier0) || 00303 (id == Intrinsic::nvvm_barrier0_popc) || 00304 (id == Intrinsic::nvvm_barrier0_and) || 00305 (id == Intrinsic::nvvm_barrier0_or) || 00306 (id == Intrinsic::cuda_syncthreads)) 00307 return true; 00308 return false; 00309 } 00310 00311 // Interface for checking all memory space transfer related intrinsics 00312 bool llvm::isMemorySpaceTransferIntrinsic(Intrinsic::ID id) { 00313 if (id == Intrinsic::nvvm_ptr_local_to_gen || 00314 id == Intrinsic::nvvm_ptr_shared_to_gen || 00315 id == Intrinsic::nvvm_ptr_global_to_gen || 00316 id == Intrinsic::nvvm_ptr_constant_to_gen || 00317 id == Intrinsic::nvvm_ptr_gen_to_global || 00318 id == Intrinsic::nvvm_ptr_gen_to_shared || 00319 id == Intrinsic::nvvm_ptr_gen_to_local || 00320 id == Intrinsic::nvvm_ptr_gen_to_constant || 00321 id == Intrinsic::nvvm_ptr_gen_to_param) { 00322 return true; 00323 } 00324 00325 return false; 00326 } 00327 00328 // consider several special intrinsics in striping pointer casts, and 00329 // provide an option to ignore GEP indicies for find out the base address only 00330 // which could be used in simple alias disambigurate. 00331 const Value * 00332 llvm::skipPointerTransfer(const Value *V, bool ignore_GEP_indices) { 00333 V = V->stripPointerCasts(); 00334 while (true) { 00335 if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 00336 if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 00337 V = IS->getArgOperand(0)->stripPointerCasts(); 00338 continue; 00339 } 00340 } else if (ignore_GEP_indices) 00341 if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 00342 V = GEP->getPointerOperand()->stripPointerCasts(); 00343 continue; 00344 } 00345 break; 00346 } 00347 return V; 00348 } 00349 00350 // consider several special intrinsics in striping pointer casts, and 00351 // - ignore GEP indicies for find out the base address only, and 00352 // - tracking PHINode 00353 // which could be used in simple alias disambigurate. 00354 const Value * 00355 llvm::skipPointerTransfer(const Value *V, std::set<const Value *> &processed) { 00356 if (processed.find(V) != processed.end()) 00357 return NULL; 00358 processed.insert(V); 00359 00360 const Value *V2 = V->stripPointerCasts(); 00361 if (V2 != V && processed.find(V2) != processed.end()) 00362 return NULL; 00363 processed.insert(V2); 00364 00365 V = V2; 00366 00367 while (true) { 00368 if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 00369 if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 00370 V = IS->getArgOperand(0)->stripPointerCasts(); 00371 continue; 00372 } 00373 } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 00374 V = GEP->getPointerOperand()->stripPointerCasts(); 00375 continue; 00376 } else if (const PHINode *PN = dyn_cast<PHINode>(V)) { 00377 if (V != V2 && processed.find(V) != processed.end()) 00378 return NULL; 00379 processed.insert(PN); 00380 const Value *common = 0; 00381 for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { 00382 const Value *pv = PN->getIncomingValue(i); 00383 const Value *base = skipPointerTransfer(pv, processed); 00384 if (base) { 00385 if (common == 0) 00386 common = base; 00387 else if (common != base) 00388 return PN; 00389 } 00390 } 00391 if (common == 0) 00392 return PN; 00393 V = common; 00394 } 00395 break; 00396 } 00397 return V; 00398 } 00399 00400 // The following are some useful utilities for debuggung 00401 00402 BasicBlock *llvm::getParentBlock(Value *v) { 00403 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 00404 return B; 00405 00406 if (Instruction *I = dyn_cast<Instruction>(v)) 00407 return I->getParent(); 00408 00409 return 0; 00410 } 00411 00412 Function *llvm::getParentFunction(Value *v) { 00413 if (Function *F = dyn_cast<Function>(v)) 00414 return F; 00415 00416 if (Instruction *I = dyn_cast<Instruction>(v)) 00417 return I->getParent()->getParent(); 00418 00419 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 00420 return B->getParent(); 00421 00422 return 0; 00423 } 00424 00425 // Dump a block by name 00426 void llvm::dumpBlock(Value *v, char *blockName) { 00427 Function *F = getParentFunction(v); 00428 if (F == 0) 00429 return; 00430 00431 for (Function::iterator it = F->begin(), ie = F->end(); it != ie; ++it) { 00432 BasicBlock *B = it; 00433 if (strcmp(B->getName().data(), blockName) == 0) { 00434 B->dump(); 00435 return; 00436 } 00437 } 00438 } 00439 00440 // Find an instruction by name 00441 Instruction *llvm::getInst(Value *base, char *instName) { 00442 Function *F = getParentFunction(base); 00443 if (F == 0) 00444 return 0; 00445 00446 for (inst_iterator it = inst_begin(F), ie = inst_end(F); it != ie; ++it) { 00447 Instruction *I = &*it; 00448 if (strcmp(I->getName().data(), instName) == 0) { 00449 return I; 00450 } 00451 } 00452 00453 return 0; 00454 } 00455 00456 // Dump an instruction by nane 00457 void llvm::dumpInst(Value *base, char *instName) { 00458 Instruction *I = getInst(base, instName); 00459 if (I) 00460 I->dump(); 00461 } 00462 00463 // Dump an instruction and all dependent instructions 00464 void llvm::dumpInstRec(Value *v, std::set<Instruction *> *visited) { 00465 if (Instruction *I = dyn_cast<Instruction>(v)) { 00466 00467 if (visited->find(I) != visited->end()) 00468 return; 00469 00470 visited->insert(I); 00471 00472 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) 00473 dumpInstRec(I->getOperand(i), visited); 00474 00475 I->dump(); 00476 } 00477 } 00478 00479 // Dump an instruction and all dependent instructions 00480 void llvm::dumpInstRec(Value *v) { 00481 std::set<Instruction *> visited; 00482 00483 //BasicBlock *B = getParentBlock(v); 00484 00485 dumpInstRec(v, &visited); 00486 } 00487 00488 // Dump the parent for Instruction, block or function 00489 void llvm::dumpParent(Value *v) { 00490 if (Instruction *I = dyn_cast<Instruction>(v)) { 00491 I->getParent()->dump(); 00492 return; 00493 } 00494 00495 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) { 00496 B->getParent()->dump(); 00497 return; 00498 } 00499 00500 if (Function *F = dyn_cast<Function>(v)) { 00501 F->getParent()->dump(); 00502 return; 00503 } 00504 }