149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===- NVPTXUtilities.cpp - Utility Functions -----------------------------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file contains miscellaneous utility functions 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXUtilities.h" 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTX.h" 150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Operator.h" 2049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <algorithm> 2149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <cstring> 2249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <map> 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <string> 2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <vector> 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/ManagedStatic.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstIterator.h" 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/MutexGuard.h" 2849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm; 3049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskitypedef std::map<std::string, std::vector<unsigned> > key_val_pair_t; 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskitypedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t; 3349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskitypedef std::map<const Module *, global_val_annot_t> per_module_annot_t; 3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3549683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiManagedStatic<per_module_annot_t> annotationCache; 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic sys::Mutex Lock; 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid llvm::clearAnnotationCache(const llvm::Module *Mod) { 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MutexGuard Guard(Lock); 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines annotationCache->erase(Mod); 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MutexGuard Guard(Lock); 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(md && "Invalid mdnode for annotation"); 4649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands"); 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // start index = 1, to skip the global variable key 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // increment = 2, to skip the value for each property-value pairs 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (unsigned i = 1, e = md->getNumOperands(); i != e; i += 2) { 5049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // property 5149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const MDString *prop = dyn_cast<MDString>(md->getOperand(i)); 5249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(prop && "Annotation property not a string"); 5349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // value 553639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski ConstantInt *Val = dyn_cast<ConstantInt>(md->getOperand(i + 1)); 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(Val && "Value operand not a constant int"); 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string keyname = prop->getString().str(); 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (retval.find(keyname) != retval.end()) 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski retval[keyname].push_back(Val->getZExtValue()); 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else { 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> tmp; 6349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski tmp.push_back(Val->getZExtValue()); 6449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski retval[keyname] = tmp; 6549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MutexGuard Guard(Lock); 7149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NamedMDNode *NMD = m->getNamedMetadata(llvm::NamedMDForAnnotations); 7249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!NMD) 7349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 7449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski key_val_pair_t tmp; 7549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { 7649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const MDNode *elem = NMD->getOperand(i); 7749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Value *entity = elem->getOperand(0); 7949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // entity may be null due to DCE 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!entity) 8149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 8249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (entity != gv) 8349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 8449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // accumulate annotations for entity in tmp 8649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cacheAnnotationFromMD(elem, tmp); 8749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 8849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (tmp.empty()) // no annotations for this gv 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 9149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((*annotationCache).find(m) != (*annotationCache).end()) 9349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (*annotationCache)[m][gv] = tmp; 9449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else { 9549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski global_val_annot_t tmp1; 9649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski tmp1[gv] = tmp; 9749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (*annotationCache)[m] = tmp1; 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 9949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::findOneNVVMAnnotation(const GlobalValue *gv, std::string prop, 10249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned &retval) { 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MutexGuard Guard(Lock); 10449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Module *m = gv->getParent(); 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((*annotationCache).find(m) == (*annotationCache).end()) 10649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cacheAnnotationFromMD(m, gv); 10749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 10849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cacheAnnotationFromMD(m, gv); 10949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 11049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 11149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski retval = (*annotationCache)[m][gv][prop][0]; 11249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 11349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 11449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::findAllNVVMAnnotation(const GlobalValue *gv, std::string prop, 11649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> &retval) { 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MutexGuard Guard(Lock); 11849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Module *m = gv->getParent(); 11949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((*annotationCache).find(m) == (*annotationCache).end()) 12049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cacheAnnotationFromMD(m, gv); 12149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) 12249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cacheAnnotationFromMD(m, gv); 12349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) 12449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 12549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski retval = (*annotationCache)[m][gv][prop]; 12649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 12749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 12849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 12949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isTexture(const llvm::Value &val) { 13049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 13149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned annot; 1323639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if (llvm::findOneNVVMAnnotation( 1333639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISTEXTURE], 1343639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 13549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert((annot == 1) && "Unexpected annotation on a texture symbol"); 13649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 13749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 13849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 13949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 14049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 14149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 14249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isSurface(const llvm::Value &val) { 14349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 14449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned annot; 1453639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if (llvm::findOneNVVMAnnotation( 1463639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSURFACE], 1473639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 14849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert((annot == 1) && "Unexpected annotation on a surface symbol"); 14949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 15049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 15149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 15249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 15349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 15449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 15549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isSampler(const llvm::Value &val) { 15649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 15749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned annot; 1583639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if (llvm::findOneNVVMAnnotation( 1593639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski gv, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 1603639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 16149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert((annot == 1) && "Unexpected annotation on a sampler symbol"); 16249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 16349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 16449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 16549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const Argument *arg = dyn_cast<Argument>(&val)) { 16649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Function *func = arg->getParent(); 16749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> annot; 1683639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if (llvm::findAllNVVMAnnotation( 1693639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski func, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISSAMPLER], 1703639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 17149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 17249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 17349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 17449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 17549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 17649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 17749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 17849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isImageReadOnly(const llvm::Value &val) { 17949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const Argument *arg = dyn_cast<Argument>(&val)) { 18049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Function *func = arg->getParent(); 18149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> annot; 18249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (llvm::findAllNVVMAnnotation(func, 1833639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski llvm::PropertyAnnotationNames[ 1843639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski llvm::PROPERTY_ISREADONLY_IMAGE_PARAM], 1853639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 18649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 18749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 18849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 18949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 19049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 19149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 19249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 19349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isImageWriteOnly(const llvm::Value &val) { 19449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const Argument *arg = dyn_cast<Argument>(&val)) { 19549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Function *func = arg->getParent(); 19649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> annot; 19749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (llvm::findAllNVVMAnnotation(func, 1983639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski llvm::PropertyAnnotationNames[ 1993639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski llvm::PROPERTY_ISWRITEONLY_IMAGE_PARAM], 2003639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski annot)) { 20149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 20249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 20349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 20449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 20549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 20649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 20749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool llvm::isImageReadWrite(const llvm::Value &val) { 209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const Argument *arg = dyn_cast<Argument>(&val)) { 210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Function *func = arg->getParent(); 211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::vector<unsigned> annot; 212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (llvm::findAllNVVMAnnotation(func, 213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::PropertyAnnotationNames[ 214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::PROPERTY_ISREADWRITE_IMAGE_PARAM], 215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines annot)) { 216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (std::find(annot.begin(), annot.end(), arg->getArgNo()) != annot.end()) 217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isImage(const llvm::Value &val) { 224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return llvm::isImageReadOnly(val) || llvm::isImageWriteOnly(val) || 225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::isImageReadWrite(val); 226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool llvm::isManaged(const llvm::Value &val) { 229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if(const GlobalValue *gv = dyn_cast<GlobalValue>(&val)) { 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned annot; 231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if(llvm::findOneNVVMAnnotation(gv, 232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::PropertyAnnotationNames[llvm::PROPERTY_MANAGED], 233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines annot)) { 234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((annot == 1) && "Unexpected annotation on a managed symbol"); 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 23949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 24049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 24149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistd::string llvm::getTextureName(const llvm::Value &val) { 24249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(val.hasName() && "Found texture variable with no name"); 24349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return val.getName(); 24449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 24549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 24649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistd::string llvm::getSurfaceName(const llvm::Value &val) { 24749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(val.hasName() && "Found surface variable with no name"); 24849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return val.getName(); 24949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 25049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 25149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistd::string llvm::getSamplerName(const llvm::Value &val) { 25249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski assert(val.hasName() && "Found sampler variable with no name"); 25349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return val.getName(); 25449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 25549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 25649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getMaxNTIDx(const Function &F, unsigned &x) { 2573639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2583639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_X], x)); 25949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 26049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 26149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getMaxNTIDy(const Function &F, unsigned &y) { 2623639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2633639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Y], y)); 26449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 26549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 26649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getMaxNTIDz(const Function &F, unsigned &z) { 2673639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2683639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MAXNTID_Z], z)); 26949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 27049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 27149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getReqNTIDx(const Function &F, unsigned &x) { 2723639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2733639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_X], x)); 27449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 27549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 27649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getReqNTIDy(const Function &F, unsigned &y) { 2773639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2783639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Y], y)); 27949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 28049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 28149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getReqNTIDz(const Function &F, unsigned &z) { 2823639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2833639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_REQNTID_Z], z)); 28449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 28549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 28649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getMinCTASm(const Function &F, unsigned &x) { 2873639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (llvm::findOneNVVMAnnotation( 2883639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_MINNCTAPERSM], x)); 28949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 29049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 29149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isKernelFunction(const Function &F) { 29249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned x = 0; 2933639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski bool retval = llvm::findOneNVVMAnnotation( 2943639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ISKERNEL_FUNCTION], x); 29549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (retval == false) { 29649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // There is no NVVM metadata, check the calling convention 29749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (F.getCallingConv() == llvm::CallingConv::PTX_Kernel) 29849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 29949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 30049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 30149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 3023639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski return (x == 1); 30349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 30449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 30549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getAlign(const Function &F, unsigned index, unsigned &align) { 30649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<unsigned> Vs; 3073639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski bool retval = llvm::findAllNVVMAnnotation( 3083639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski &F, llvm::PropertyAnnotationNames[llvm::PROPERTY_ALIGN], Vs); 30949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (retval == false) 31049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 3113639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (int i = 0, e = Vs.size(); i < e; i++) { 31249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned v = Vs[i]; 3133639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if ((v >> 16) == index) { 3143639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski align = v & 0xFFFF; 31549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 31649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 31749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 31849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 31949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 32049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 32149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::getAlign(const CallInst &I, unsigned index, unsigned &align) { 32249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (MDNode *alignNode = I.getMetadata("callalign")) { 3233639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) { 32449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const ConstantInt *CI = 3253639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski dyn_cast<ConstantInt>(alignNode->getOperand(i))) { 32649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned v = CI->getZExtValue(); 3273639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if ((v >> 16) == index) { 32849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski align = v & 0xFFFF; 32949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 33049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 3313639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski if ((v >> 16) > index) { 33249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 33349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 33449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 33549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 33649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 33749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 33849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 33949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 34049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isBarrierIntrinsic(Intrinsic::ID id) { 34149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((id == Intrinsic::nvvm_barrier0) || 34249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (id == Intrinsic::nvvm_barrier0_popc) || 34349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (id == Intrinsic::nvvm_barrier0_and) || 34449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (id == Intrinsic::nvvm_barrier0_or) || 34549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (id == Intrinsic::cuda_syncthreads)) 34649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 34749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 34849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 34949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 35049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Interface for checking all memory space transfer related intrinsics 35149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool llvm::isMemorySpaceTransferIntrinsic(Intrinsic::ID id) { 35249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (id == Intrinsic::nvvm_ptr_local_to_gen || 35349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_shared_to_gen || 35449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_global_to_gen || 35549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_constant_to_gen || 35649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_gen_to_global || 35749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_gen_to_shared || 35849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_gen_to_local || 35949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_gen_to_constant || 36049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski id == Intrinsic::nvvm_ptr_gen_to_param) { 36149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 36249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 36349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 36449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 36549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 36649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 36749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// consider several special intrinsics in striping pointer casts, and 36849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// provide an option to ignore GEP indicies for find out the base address only 36949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// which could be used in simple alias disambigurate. 3703639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskiconst Value * 3713639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskillvm::skipPointerTransfer(const Value *V, bool ignore_GEP_indices) { 37249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = V->stripPointerCasts(); 37349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski while (true) { 37449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 37549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 37649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = IS->getArgOperand(0)->stripPointerCasts(); 37749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 37849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 37949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (ignore_GEP_indices) 38049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 38149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = GEP->getPointerOperand()->stripPointerCasts(); 38249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 38349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 38449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski break; 38549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 38649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return V; 38749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 38849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 38949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// consider several special intrinsics in striping pointer casts, and 39049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// - ignore GEP indicies for find out the base address only, and 39149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// - tracking PHINode 39249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// which could be used in simple alias disambigurate. 3933639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskiconst Value * 3943639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskillvm::skipPointerTransfer(const Value *V, std::set<const Value *> &processed) { 39549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (processed.find(V) != processed.end()) 396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 39749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski processed.insert(V); 39849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 39949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Value *V2 = V->stripPointerCasts(); 40049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (V2 != V && processed.find(V2) != processed.end()) 401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 40249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski processed.insert(V2); 40349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 40449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = V2; 40549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 40649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski while (true) { 40749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const IntrinsicInst *IS = dyn_cast<IntrinsicInst>(V)) { 40849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (isMemorySpaceTransferIntrinsic(IS->getIntrinsicID())) { 40949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = IS->getArgOperand(0)->stripPointerCasts(); 41049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 41149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 41249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { 41349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = GEP->getPointerOperand()->stripPointerCasts(); 41449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski continue; 41549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (const PHINode *PN = dyn_cast<PHINode>(V)) { 41649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (V != V2 && processed.find(V) != processed.end()) 417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 41849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski processed.insert(PN); 419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Value *common = nullptr; 42049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { 42149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Value *pv = PN->getIncomingValue(i); 42249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Value *base = skipPointerTransfer(pv, processed); 42349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (base) { 424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!common) 42549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski common = base; 42649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (common != base) 42749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return PN; 42849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 42949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!common) 43149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return PN; 43249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski V = common; 43349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 43449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski break; 43549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 43649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return V; 43749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 43849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 43949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The following are some useful utilities for debuggung 44049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 44149683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiBasicBlock *llvm::getParentBlock(Value *v) { 44249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 44349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return B; 44449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 44549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Instruction *I = dyn_cast<Instruction>(v)) 44649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return I->getParent(); 44749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 44949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 45049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 45149683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiFunction *llvm::getParentFunction(Value *v) { 45249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Function *F = dyn_cast<Function>(v)) 45349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return F; 45449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 45549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Instruction *I = dyn_cast<Instruction>(v)) 45649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return I->getParent()->getParent(); 45749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 45849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (BasicBlock *B = dyn_cast<BasicBlock>(v)) 45949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return B->getParent(); 46049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 46249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 46349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 46449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Dump a block by name 46549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid llvm::dumpBlock(Value *v, char *blockName) { 46649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Function *F = getParentFunction(v); 467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!F) 46849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 46949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 47049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (Function::iterator it = F->begin(), ie = F->end(); it != ie; ++it) { 47149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski BasicBlock *B = it; 47249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (strcmp(B->getName().data(), blockName) == 0) { 47349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski B->dump(); 47449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 47549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 47649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 47749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 47849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 47949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Find an instruction by name 48049683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiInstruction *llvm::getInst(Value *base, char *instName) { 48149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Function *F = getParentFunction(base); 482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!F) 483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 48449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 48549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (inst_iterator it = inst_begin(F), ie = inst_end(F); it != ie; ++it) { 48649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Instruction *I = &*it; 48749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (strcmp(I->getName().data(), instName) == 0) { 48849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return I; 48949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 49049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 49149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 49349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 49449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 49549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Dump an instruction by nane 49649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid llvm::dumpInst(Value *base, char *instName) { 49749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Instruction *I = getInst(base, instName); 49849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (I) 49949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->dump(); 50049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 50149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 50249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Dump an instruction and all dependent instructions 50349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid llvm::dumpInstRec(Value *v, std::set<Instruction *> *visited) { 50449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Instruction *I = dyn_cast<Instruction>(v)) { 50549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 50649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (visited->find(I) != visited->end()) 50749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 50849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 50949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski visited->insert(I); 51049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 51149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) 51249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski dumpInstRec(I->getOperand(i), visited); 51349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 51449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->dump(); 51549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 51649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 51749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 51849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Dump an instruction and all dependent instructions 51949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid llvm::dumpInstRec(Value *v) { 52049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::set<Instruction *> visited; 52149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 52249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski //BasicBlock *B = getParentBlock(v); 52349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 52449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski dumpInstRec(v, &visited); 52549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 52649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 52749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Dump the parent for Instruction, block or function 52849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid llvm::dumpParent(Value *v) { 52949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Instruction *I = dyn_cast<Instruction>(v)) { 53049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski I->getParent()->dump(); 53149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 53249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 53349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 53449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (BasicBlock *B = dyn_cast<BasicBlock>(v)) { 53549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski B->getParent()->dump(); 53649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 53749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 53849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 53949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Function *F = dyn_cast<Function>(v)) { 54049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski F->getParent()->dump(); 54149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return; 54249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 54349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 544