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