121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski//===- NVVMReflect.cpp - NVVM Emulate conditional compilation -------------===// 221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// 321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// The LLVM Compiler Infrastructure 421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// 521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// This file is distributed under the University of Illinois Open Source 621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// License. See LICENSE.TXT for details. 721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// 821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski//===----------------------------------------------------------------------===// 921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This pass replaces occurrences of __nvvm_reflect("string") with an 1121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// integer based on -nvvm-reflect-list string=<int> option given to this pass. 12d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski// If an undefined string value is seen in a call to __nvvm_reflect("string"), 13d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski// a default value of 0 will be used. 1421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski// 1521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski//===----------------------------------------------------------------------===// 1621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 17d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski#include "NVPTX.h" 18d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski#include "llvm/ADT/DenseMap.h" 19d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski#include "llvm/ADT/SmallVector.h" 2021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/ADT/StringMap.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Constants.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DerivedTypes.h" 2321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/IR/Function.h" 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Instructions.h" 25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/IR/Intrinsics.h" 2621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/IR/Module.h" 2721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/IR/Type.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Pass.h" 2921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/Support/CommandLine.h" 3021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/Support/Debug.h" 3121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/Support/raw_os_ostream.h" 324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 3321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include "llvm/Transforms/Scalar.h" 3421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include <map> 3521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include <sstream> 3621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include <string> 3721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#include <vector> 3821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 3921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski#define NVVM_REFLECT_FUNCTION "__nvvm_reflect" 4021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 4121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskiusing namespace llvm; 4221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "nvptx-reflect" 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 4521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskinamespace llvm { void initializeNVVMReflectPass(PassRegistry &); } 4621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 4721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskinamespace { 48d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinskiclass NVVMReflect : public ModulePass { 4921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskiprivate: 5021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski StringMap<int> VarMap; 51d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski typedef DenseMap<std::string, int>::iterator VarMapIter; 5221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 5321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskipublic: 5421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski static char ID; 55c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines NVVMReflect() : ModulePass(ID) { 56d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski initializeNVVMReflectPass(*PassRegistry::getPassRegistry()); 5721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski VarMap.clear(); 58d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski } 59d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski 60d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski NVVMReflect(const StringMap<int> &Mapping) 61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines : ModulePass(ID) { 62d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski initializeNVVMReflectPass(*PassRegistry::getPassRegistry()); 63d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski for (StringMap<int>::const_iterator I = Mapping.begin(), E = Mapping.end(); 64d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski I != E; ++I) { 65d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski VarMap[(*I).getKey()] = (*I).getValue(); 66d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski } 6721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski } 6821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AU.setPreservesAll(); 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnModule(Module &) override; 7321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesprivate: 75c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool handleFunction(Function *ReflectFunction); 7621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski void setVarMap(); 7721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski}; 7821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski} 7921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 80d22367559300c77c73e0ad9e193a33451bf8bf6cJustin HolewinskiModulePass *llvm::createNVVMReflectPass() { 81d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski return new NVVMReflect(); 82d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski} 83d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski 84d22367559300c77c73e0ad9e193a33451bf8bf6cJustin HolewinskiModulePass *llvm::createNVVMReflectPass(const StringMap<int>& Mapping) { 85d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski return new NVVMReflect(Mapping); 86d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski} 87d22367559300c77c73e0ad9e193a33451bf8bf6cJustin Holewinski 8821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskistatic cl::opt<bool> 89fe16848601bdde6e3a5e0860199169dd171222a4Nadav RotemNVVMReflectEnabled("nvvm-reflect-enable", cl::init(true), cl::Hidden, 9021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski cl::desc("NVVM reflection, enabled by default")); 9121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 9221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskichar NVVMReflect::ID = 0; 9321fdcb02716f5eae097abfd2f44e40563e90180aJustin HolewinskiINITIALIZE_PASS(NVVMReflect, "nvvm-reflect", 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Replace occurrences of __nvvm_reflect() calls with 0/1", false, 9521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski false) 9621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 9721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskistatic cl::list<std::string> 98fe16848601bdde6e3a5e0860199169dd171222a4Nadav RotemReflectList("nvvm-reflect-list", cl::value_desc("name=<int>"), cl::Hidden, 99d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski cl::desc("A list of string=num assignments"), 10021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski cl::ValueRequired); 10121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 10221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski/// The command line can look as follows : 103d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski/// -nvvm-reflect-list a=1,b=2 -nvvm-reflect-list c=3,d=0 -R e=2 10421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski/// The strings "a=1,b=2", "c=3,d=0", "e=2" are available in the 10521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski/// ReflectList vector. First, each of ReflectList[i] is 'split' 10621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski/// using "," as the delimiter. Then each of this part is split 10721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski/// using "=" as the delimiter. 10821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskivoid NVVMReflect::setVarMap() { 10921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski for (unsigned i = 0, e = ReflectList.size(); i != e; ++i) { 110d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski DEBUG(dbgs() << "Option : " << ReflectList[i] << "\n"); 111d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski SmallVector<StringRef, 4> NameValList; 112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StringRef(ReflectList[i]).split(NameValList, ','); 113d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski for (unsigned j = 0, ej = NameValList.size(); j != ej; ++j) { 114d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski SmallVector<StringRef, 2> NameValPair; 115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar NameValList[j].split(NameValPair, '='); 116d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert(NameValPair.size() == 2 && "name=val expected"); 117d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski std::stringstream ValStream(NameValPair[1]); 118d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski int Val; 119d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ValStream >> Val; 120d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert((!(ValStream.fail())) && "integer value expected"); 121d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski VarMap[NameValPair[0]] = Val; 12221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski } 12321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski } 12421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski} 12521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool NVVMReflect::handleFunction(Function *ReflectFunction) { 12721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // Validate _reflect function 128d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert(ReflectFunction->isDeclaration() && 12921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "_reflect function should not have a body"); 130d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert(ReflectFunction->getReturnType()->isIntegerTy() && 13121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "_reflect's return type should be integer"); 13221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 133d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski std::vector<Instruction *> ToRemove; 13421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 135d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski // Go through the uses of ReflectFunction in this Function. 13621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // Each of them should a CallInst with a ConstantArray argument. 13721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // First validate that. If the c-string corresponding to the 13821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // ConstantArray can be found successfully, see if it can be 13921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // found in VarMap. If so, replace the uses of CallInst with the 14021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // value found in VarMap. If not, replace the use with value 0. 1414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // IR for __nvvm_reflect calls differs between CUDA versions: 1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // CUDA 6.5 and earlier uses this sequence: 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // %ptr = tail call i8* @llvm.nvvm.ptr.constant.to.gen.p0i8.p4i8 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (i8 addrspace(4)* getelementptr inbounds 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // ([8 x i8], [8 x i8] addrspace(4)* @str, i32 0, i32 0)) 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // %reflect = tail call i32 @__nvvm_reflect(i8* %ptr) 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // 1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Value returned by Sym->getOperand(0) is a Constant with a 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // ConstantDataSequential operand which can be converted to string and used 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // for lookup. 1524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // CUDA 7.0 does it slightly differently: 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // %reflect = call i32 @__nvvm_reflect(i8* addrspacecast 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (i8 addrspace(1)* getelementptr inbounds 1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // ([8 x i8], [8 x i8] addrspace(1)* @str, i32 0, i32 0) to i8*)) 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // 1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // In this case, we get a Constant with a GlobalVariable operand and we need 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // to dig deeper to find its initializer with the string we'll use for lookup. 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (User *U : ReflectFunction->users()) { 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isa<CallInst>(U) && "Only a call instruction can use _reflect"); 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallInst *Reflect = cast<CallInst>(U); 16421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 165d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert((Reflect->getNumOperands() == 2) && 16621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "Only one operand expect for _reflect function"); 16721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // In cuda, we will have an extra constant-to-generic conversion of 16821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // the string. 169c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const Value *Str = Reflect->getArgOperand(0); 170c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (isa<CallInst>(Str)) { 171c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // CUDA path 172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const CallInst *ConvCall = cast<CallInst>(Str); 173c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Str = ConvCall->getArgOperand(0); 174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(isa<ConstantExpr>(Str) && 17621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "Format of _reflect function not recognized"); 177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const ConstantExpr *GEP = cast<ConstantExpr>(Str); 17821fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 179d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski const Value *Sym = GEP->getOperand(0); 180d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski assert(isa<Constant>(Sym) && "Format of _reflect function not recognized"); 18121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 1824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const Value *Operand = cast<Constant>(Sym)->getOperand(0); 1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand)) { 1844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // For CUDA-7.0 style __nvvm_reflect calls we need to find operand's 1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // initializer. 1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(GV->hasInitializer() && 1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "Format of _reflect function not recognized"); 1884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const Constant *Initializer = GV->getInitializer(); 1894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Operand = Initializer; 1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 19121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(isa<ConstantDataSequential>(Operand) && 19321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "Format of _reflect function not recognized"); 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar assert(cast<ConstantDataSequential>(Operand)->isCString() && 19521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski "Format of _reflect function not recognized"); 19621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 197d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski std::string ReflectArg = 1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cast<ConstantDataSequential>(Operand)->getAsString(); 19921fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 200d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ReflectArg = ReflectArg.substr(0, ReflectArg.size() - 1); 201d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski DEBUG(dbgs() << "Arg of _reflect : " << ReflectArg << "\n"); 20221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 203d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski int ReflectVal = 0; // The default value is 0 204d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski if (VarMap.find(ReflectArg) != VarMap.end()) { 205d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ReflectVal = VarMap[ReflectArg]; 20621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski } 207d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski Reflect->replaceAllUsesWith( 208d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ConstantInt::get(Reflect->getType(), ReflectVal)); 209d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ToRemove.push_back(Reflect); 21021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski } 211d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski if (ToRemove.size() == 0) 21221fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski return false; 21321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 214d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski for (unsigned i = 0, e = ToRemove.size(); i != e; ++i) 215d4ab1926af982e4334978fd9bf9156c7c087f6f5Justin Holewinski ToRemove[i]->eraseFromParent(); 21621fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski return true; 21721fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski} 218c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 219c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool NVVMReflect::runOnModule(Module &M) { 220c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!NVVMReflectEnabled) 221c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return false; 222c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 223c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines setVarMap(); 224c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 225c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 226c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool Res = false; 227c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::string Name; 228c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Type *Tys[1]; 229c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Type *I8Ty = Type::getInt8Ty(M.getContext()); 230c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Function *ReflectFunction; 231c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Check for standard overloaded versions of llvm.nvvm.reflect 233c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 234c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned i = 0; i != 5; ++i) { 235c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Tys[0] = PointerType::get(I8Ty, i); 236c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Name = Intrinsic::getName(Intrinsic::nvvm_reflect, Tys); 237c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ReflectFunction = M.getFunction(Name); 238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if(ReflectFunction != 0) { 239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Res |= handleFunction(ReflectFunction); 240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 241c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 242c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 243c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ReflectFunction = M.getFunction(NVVM_REFLECT_FUNCTION); 244c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If reflect function is not used, then there will be 245c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // no entry in the module. 246c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ReflectFunction != 0) 247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Res |= handleFunction(ReflectFunction); 248c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 249c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Res; 250c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 251