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