1 //===- NVPTXUtilities.cpp - Utility Functions -----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains miscellaneous utility functions 11 //===----------------------------------------------------------------------===// 12 13 #include "NVPTXUtilities.h" 14 #include "NVPTX.h" 15 #include "llvm/IR/Constants.h" 16 #include "llvm/IR/Function.h" 17 #include "llvm/IR/GlobalVariable.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/IR/Operator.h" 20 #include <algorithm> 21 #include <cstring> 22 #include <map> 23 #include <string> 24 #include <vector> 25 #include "llvm/Support/ManagedStatic.h" 26 #include "llvm/IR/InstIterator.h" 27 #include "llvm/Support/MutexGuard.h" 28 29 using namespace llvm; 30 31 typedef std::map<std::string, std::vector<unsigned> > key_val_pair_t; 32 typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t; 33 typedef std::map<const Module *, global_val_annot_t> per_module_annot_t; 34 35 ManagedStatic<per_module_annot_t> annotationCache; 36 static sys::Mutex Lock; 37 38 void llvm::clearAnnotationCache(const llvm::Module *Mod) { 39 MutexGuard Guard(Lock); 40 annotationCache->erase(Mod); 41 } 42 43 static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { 44 MutexGuard Guard(Lock); 45 assert(md && "Invalid mdnode for annotation"); 46 assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands"); 47 // start index = 1, to skip the global variable key 48 // increment = 2, to skip the value for each property-value pairs 49 for (unsigned i = 1, e = md->getNumOperands(); i != e; i += 2) { 50 // property 51 const MDString *prop = dyn_cast<MDString>(md->getOperand(i)); 52 assert(prop && "Annotation property not a string"); 53 54 // value 55 ConstantInt *Val = dyn_cast<ConstantInt>(md->getOperand(i + 1)); 56 assert(Val && "Value operand not a constant int"); 57 58 std::string keyname = prop->getString().str(); 59 if (retval.find(keyname) != retval.end()) 60 retval[keyname].push_back(Val->getZExtValue()); 61 else { 62 std::vector<unsigned> tmp; 63 tmp.push_back(Val->getZExtValue()); 64 retval[keyname] = tmp; 65 } 66 } 67 } 68 69 static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { 70 MutexGuard Guard(Lock); 71 NamedMDNode *NMD = m->getNamedMetadata(llvm::NamedMDForAnnotations); 72 if (!NMD) 73 return; 74 key_val_pair_t tmp; 75 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { 76 const MDNode *elem = NMD->getOperand(i); 77 78 Value *entity = elem->getOperand(0); 79 // entity may be null due to DCE 80 if (!entity) 81 continue; 82 if (entity != gv) 83 continue; 84 85 // accumulate annotations for entity in tmp 86 cacheAnnotationFromMD(elem, tmp); 87 } 88 89 if (tmp.empty()) // no annotations for this gv 90 return; 91 92 if ((*annotationCache).find(m) != (*annotationCache).end()) 93 (*annotationCache)[m][gv] = tmp; 94 else { 95 global_val_annot_t tmp1; 96 tmp1[gv] = tmp; 97 (*annotationCache)[m] = tmp1; 98 } 99 } 100 101 bool llvm::findOneNVVMAnnotation(const GlobalValue *gv, std::string prop, 102 unsigned &retval) { 103 MutexGuard Guard(Lock); 104 const Module *m = gv->getParent(); 105 if ((*annotationCache).find(m) == (*annotationCache).end()) 106 cacheAnnotationFromMD(m, gv); 107 else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 108 cacheAnnotationFromMD(m, gv); 109 if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 110 return false; 111 retval = (*annotationCache)[m][gv][prop][0]; 112 return true; 113 } 114 115 bool llvm::findAllNVVMAnnotation(const GlobalValue *gv, std::string prop, 116 std::vector<unsigned> &retval) { 117 MutexGuard Guard(Lock); 118 const Module *m = gv->getParent(); 119 if ((*annotationCache).find(m) == (*annotationCache).end()) 120 cacheAnnotationFromMD(m, gv); 121 else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 122 cacheAnnotationFromMD(m, gv); 123 if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 124 return false; 125 retval = (*annotationCache)[m][gv][prop]; 126 return true; 127 } 128 129 bool llvm::isTexture(const llvm::Value &val) { 130 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 131 unsigned annot; 132 if (llvm::findOneNVVMAnnotation( 133 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISTEXTURE], 134 annot)) { 135 assert((annot == 1) && "Unexpected annotation on a texture symbol"); 136 return true; 137 } 138 } 139 return false; 140 } 141 142 bool llvm::isSurface(const llvm::Value &val) { 143 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 144 unsigned annot; 145 if (llvm::findOneNVVMAnnotation( 146 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSURFACE], 147 annot)) { 148 assert((annot == 1) && "Unexpected annotation on a surface symbol"); 149 return true; 150 } 151 } 152 return false; 153 } 154 155 bool llvm::isSampler(const llvm::Value &val) { 156 if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 157 unsigned annot; 158 if (llvm::findOneNVVMAnnotation( 159 gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 160 annot)) { 161 assert((annot == 1) && "Unexpected annotation on a sampler symbol"); 162 return true; 163 } 164 } 165 if (const Argument *arg = dyn_cast<Argument>(&val)) { 166 const Function *func = arg->getParent(); 167 std::vector<unsigned> annot; 168 if (llvm::findAllNVVMAnnotation( 169 func, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 170 annot)) { 171 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 172 return true; 173 } 174 } 175 return false; 176 } 177 178 bool llvm::isImageReadOnly(const llvm::Value &val) { 179 if (const Argument *arg = dyn_cast<Argument>(&val)) { 180 const Function *func = arg->getParent(); 181 std::vector<unsigned> annot; 182 if (llvm::findAllNVVMAnnotation(func, 183 llvm::PropertyAnnotationNames[ 184 llvm::PROPERTY_ISREADONLY_IMAGE_PARAM], 185 annot)) { 186 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 187 return true; 188 } 189 } 190 return false; 191 } 192 193 bool llvm::isImageWriteOnly(const llvm::Value &val) { 194 if (const Argument *arg = dyn_cast<Argument>(&val)) { 195 const Function *func = arg->getParent(); 196 std::vector<unsigned> annot; 197 if (llvm::findAllNVVMAnnotation(func, 198 llvm::PropertyAnnotationNames[ 199 llvm::PROPERTY_ISWRITEONLY_IMAGE_PARAM], 200 annot)) { 201 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 202 return true; 203 } 204 } 205 return false; 206 } 207 208 bool llvm::isImageReadWrite(const llvm::Value &val) { 209 if (const Argument *arg = dyn_cast<Argument>(&val)) { 210 const Function *func = arg->getParent(); 211 std::vector<unsigned> annot; 212 if (llvm::findAllNVVMAnnotation(func, 213 llvm::PropertyAnnotationNames[ 214 llvm::PROPERTY_ISREADWRITE_IMAGE_PARAM], 215 annot)) { 216 if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 217 return true; 218 } 219 } 220 return false; 221 } 222 223 bool llvm::isImage(const llvm::Value &val) { 224 return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val) || 225 llvm::isImageReadWrite(val); 226 } 227 228 bool llvm::isManaged(const llvm::Value &val) { 229 if(const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 230 unsigned annot; 231 if(llvm::findOneNVVMAnnotation(gv, 232 llvm::PropertyAnnotationNames[llvm::PROPERTY_MANAGED], 233 annot)) { 234 assert((annot == 1) && "Unexpected annotation on a managed symbol"); 235 return true; 236 } 237 } 238 return false; 239 } 240 241 std::string llvm::getTextureName(const llvm::Value &val) { 242 assert(val.hasName() && "Found texture variable with no name"); 243 return val.getName(); 244 } 245 246 std::string llvm::getSurfaceName(const llvm::Value &val) { 247 assert(val.hasName() && "Found surface variable with no name"); 248 return val.getName(); 249 } 250 251 std::string llvm::getSamplerName(const llvm::Value &val) { 252 assert(val.hasName() && "Found sampler variable with no name"); 253 return val.getName(); 254 } 255 256 bool llvm::getMaxNTIDx(const Function &F, unsigned &x) { 257 return (llvm::findOneNVVMAnnotation( 258 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_X], x)); 259 } 260 261 bool llvm::getMaxNTIDy(const Function &F, unsigned &y) { 262 return (llvm::findOneNVVMAnnotation( 263 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Y], y)); 264 } 265 266 bool llvm::getMaxNTIDz(const Function &F, unsigned &z) { 267 return (llvm::findOneNVVMAnnotation( 268 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Z], z)); 269 } 270 271 bool llvm::getReqNTIDx(const Function &F, unsigned &x) { 272 return (llvm::findOneNVVMAnnotation( 273 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_X], x)); 274 } 275 276 bool llvm::getReqNTIDy(const Function &F, unsigned &y) { 277 return (llvm::findOneNVVMAnnotation( 278 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Y], y)); 279 } 280 281 bool llvm::getReqNTIDz(const Function &F, unsigned &z) { 282 return (llvm::findOneNVVMAnnotation( 283 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Z], z)); 284 } 285 286 bool llvm::getMinCTASm(const Function &F, unsigned &x) { 287 return (llvm::findOneNVVMAnnotation( 288 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MINNCTAPERSM], x)); 289 } 290 291 bool llvm::isKernelFunction(const Function &F) { 292 unsigned x = 0; 293 bool retval = llvm::findOneNVVMAnnotation( 294 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISKERNEL_FUNCTION], x); 295 if (retval == false) { 296 // There is no NVVM metadata, check the calling convention 297 if (F.getCallingConv() == llvm::CallingConv::PTX_Kernel) 298 return true; 299 else 300 return false; 301 } 302 return (x == 1); 303 } 304 305 bool llvm::getAlign(const Function &F, unsigned index, unsigned &align) { 306 std::vector<unsigned> Vs; 307 bool retval = llvm::findAllNVVMAnnotation( 308 &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ALIGN], Vs); 309 if (retval == false) 310 return false; 311 for (int i = 0, e = Vs.size(); i < e; i++) { 312 unsigned v = Vs[i]; 313 if ((v >> 16) == index) { 314 align = v & 0xFFFF; 315 return true; 316 } 317 } 318 return false; 319 } 320 321 bool llvm::getAlign(const CallInst &I, unsigned index, unsigned &align) { 322 if (MDNode *alignNode = I.getMetadata("callalign")) { 323 for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) { 324 if (const ConstantInt *CI = 325 dyn_cast<ConstantInt>(alignNode->getOperand(i))) { 326 unsigned v = CI->getZExtValue(); 327 if ((v >> 16) == index) { 328 align = v & 0xFFFF; 329 return true; 330 } 331 if ((v >> 16) > index) { 332 return false; 333 } 334 } 335 } 336 } 337 return false; 338 } 339 340 bool llvm::isBarrierIntrinsic(Intrinsic::ID id) { 341 if ((id == Intrinsic::nvvm_barrier0) || 342 (id == Intrinsic::nvvm_barrier0_popc) || 343 (id == Intrinsic::nvvm_barrier0_and) || 344 (id == Intrinsic::nvvm_barrier0_or) || 345 (id == Intrinsic::cuda_syncthreads)) 346 return true; 347 return false; 348 } 349 350 // Interface for checking all memory space transfer related intrinsics 351 bool llvm::isMemorySpaceTransferIntrinsic(Intrinsic::ID id) { 352 if (id == Intrinsic::nvvm_ptr_local_to_gen || 353 id == Intrinsic::nvvm_ptr_shared_to_gen || 354 id == Intrinsic::nvvm_ptr_global_to_gen || 355 id == Intrinsic::nvvm_ptr_constant_to_gen || 356 id == Intrinsic::nvvm_ptr_gen_to_global || 357 id == Intrinsic::nvvm_ptr_gen_to_shared || 358 id == Intrinsic::nvvm_ptr_gen_to_local || 359 id == Intrinsic::nvvm_ptr_gen_to_constant || 360 id == Intrinsic::nvvm_ptr_gen_to_param) { 361 return true; 362 } 363 364 return false; 365 } 366 367 // consider several special intrinsics in striping pointer casts, and 368 // provide an option to ignore GEP indicies for find out the base address only 369 // which could be used in simple alias disambigurate. 370 const Value * 371 llvm::skipPointerTransfer(const Value *V, bool ignore_GEP_indices) { 372 V = V->stripPointerCasts(); 373 while (true) { 374 if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 375 if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 376 V = IS->getArgOperand(0)->stripPointerCasts(); 377 continue; 378 } 379 } else if (ignore_GEP_indices) 380 if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 381 V = GEP->getPointerOperand()->stripPointerCasts(); 382 continue; 383 } 384 break; 385 } 386 return V; 387 } 388 389 // consider several special intrinsics in striping pointer casts, and 390 // - ignore GEP indicies for find out the base address only, and 391 // - tracking PHINode 392 // which could be used in simple alias disambigurate. 393 const Value * 394 llvm::skipPointerTransfer(const Value *V, std::set<const Value *> &processed) { 395 if (processed.find(V) != processed.end()) 396 return nullptr; 397 processed.insert(V); 398 399 const Value *V2 = V->stripPointerCasts(); 400 if (V2 != V && processed.find(V2) != processed.end()) 401 return nullptr; 402 processed.insert(V2); 403 404 V = V2; 405 406 while (true) { 407 if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 408 if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 409 V = IS->getArgOperand(0)->stripPointerCasts(); 410 continue; 411 } 412 } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 413 V = GEP->getPointerOperand()->stripPointerCasts(); 414 continue; 415 } else if (const PHINode *PN = dyn_cast<PHINode>(V)) { 416 if (V != V2 && processed.find(V) != processed.end()) 417 return nullptr; 418 processed.insert(PN); 419 const Value *common = nullptr; 420 for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { 421 const Value *pv = PN->getIncomingValue(i); 422 const Value *base = skipPointerTransfer(pv, processed); 423 if (base) { 424 if (!common) 425 common = base; 426 else if (common != base) 427 return PN; 428 } 429 } 430 if (!common) 431 return PN; 432 V = common; 433 } 434 break; 435 } 436 return V; 437 } 438 439 // The following are some useful utilities for debuggung 440 441 BasicBlock *llvm::getParentBlock(Value *v) { 442 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 443 return B; 444 445 if (Instruction *I = dyn_cast<Instruction>(v)) 446 return I->getParent(); 447 448 return nullptr; 449 } 450 451 Function *llvm::getParentFunction(Value *v) { 452 if (Function *F = dyn_cast<Function>(v)) 453 return F; 454 455 if (Instruction *I = dyn_cast<Instruction>(v)) 456 return I->getParent()->getParent(); 457 458 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 459 return B->getParent(); 460 461 return nullptr; 462 } 463 464 // Dump a block by name 465 void llvm::dumpBlock(Value *v, char *blockName) { 466 Function *F = getParentFunction(v); 467 if (!F) 468 return; 469 470 for (Function::iterator it = F->begin(), ie = F->end(); it != ie; ++it) { 471 BasicBlock *B = it; 472 if (strcmp(B->getName().data(), blockName) == 0) { 473 B->dump(); 474 return; 475 } 476 } 477 } 478 479 // Find an instruction by name 480 Instruction *llvm::getInst(Value *base, char *instName) { 481 Function *F = getParentFunction(base); 482 if (!F) 483 return nullptr; 484 485 for (inst_iterator it = inst_begin(F), ie = inst_end(F); it != ie; ++it) { 486 Instruction *I = &*it; 487 if (strcmp(I->getName().data(), instName) == 0) { 488 return I; 489 } 490 } 491 492 return nullptr; 493 } 494 495 // Dump an instruction by nane 496 void llvm::dumpInst(Value *base, char *instName) { 497 Instruction *I = getInst(base, instName); 498 if (I) 499 I->dump(); 500 } 501 502 // Dump an instruction and all dependent instructions 503 void llvm::dumpInstRec(Value *v, std::set<Instruction *> *visited) { 504 if (Instruction *I = dyn_cast<Instruction>(v)) { 505 506 if (visited->find(I) != visited->end()) 507 return; 508 509 visited->insert(I); 510 511 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) 512 dumpInstRec(I->getOperand(i), visited); 513 514 I->dump(); 515 } 516 } 517 518 // Dump an instruction and all dependent instructions 519 void llvm::dumpInstRec(Value *v) { 520 std::set<Instruction *> visited; 521 522 //BasicBlock *B = getParentBlock(v); 523 524 dumpInstRec(v, &visited); 525 } 526 527 // Dump the parent for Instruction, block or function 528 void llvm::dumpParent(Value *v) { 529 if (Instruction *I = dyn_cast<Instruction>(v)) { 530 I->getParent()->dump(); 531 return; 532 } 533 534 if (BasicBlock *B = dyn_cast<BasicBlock>(v)) { 535 B->getParent()->dump(); 536 return; 537 } 538 539 if (Function *F = dyn_cast<Function>(v)) { 540 F->getParent()->dump(); 541 return; 542 } 543 } 544