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