17536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski//===-- GenericToNVVM.cpp - Convert generic module to NVVM module - C++ -*-===// 27536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// 37536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// The LLVM Compiler Infrastructure 47536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// 57536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// This file is distributed under the University of Illinois Open Source 67536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// License. See LICENSE.TXT for details. 77536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// 87536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski//===----------------------------------------------------------------------===// 97536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// 107536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// Convert generic global variables into either .global or .const access based 117536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// on the variable's "constant" qualifier. 127536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski// 137536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski//===----------------------------------------------------------------------===// 147536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 157536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "NVPTX.h" 167536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "MCTargetDesc/NVPTXBaseInfo.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "NVPTXUtilities.h" 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFunctionAnalysis.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/ValueTypes.h" 207536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/Constants.h" 217536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/DerivedTypes.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/IRBuilder.h" 237536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/Instructions.h" 247536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/Intrinsics.h" 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h" 267536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/Module.h" 277536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski#include "llvm/IR/Operator.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueMap.h" 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Transforms/Utils/ValueMapper.h" 307536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 317536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskiusing namespace llvm; 327536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 337536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskinamespace llvm { 347536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskivoid initializeGenericToNVVMPass(PassRegistry &); 357536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 367536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 377536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskinamespace { 387536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskiclass GenericToNVVM : public ModulePass { 397536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskipublic: 407536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski static char ID; 417536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 427536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GenericToNVVM() : ModulePass(ID) {} 437536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnModule(Module &M) override; 457536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override {} 477536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 487536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskiprivate: 497536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *getOrInsertCVTA(Module *M, Function *F, GlobalVariable *GV, 507536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder); 517536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *remapConstant(Module *M, Function *F, Constant *C, 527536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder); 537536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *remapConstantVectorOrConstantAggregate(Module *M, Function *F, 547536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Constant *C, 557536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder); 567536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *remapConstantExpr(Module *M, Function *F, ConstantExpr *C, 577536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder); 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void remapNamedMDNode(ValueToValueMapTy &VM, NamedMDNode *N); 597536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 607536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski typedef ValueMap<GlobalVariable *, GlobalVariable *> GVMapTy; 617536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski typedef ValueMap<Constant *, Value *> ConstantToValueMapTy; 627536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GVMapTy GVMap; 637536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ConstantToValueMapTy ConstantToValueMap; 647536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski}; 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end namespace 667536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 677536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskichar GenericToNVVM::ID = 0; 687536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 697536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiModulePass *llvm::createGenericToNVVMPass() { return new GenericToNVVM(); } 707536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 717536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiINITIALIZE_PASS( 727536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GenericToNVVM, "generic-to-nvvm", 737536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski "Ensure that the global variables are in the global address space", false, 747536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski false) 757536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 767536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskibool GenericToNVVM::runOnModule(Module &M) { 777536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Create a clone of each global variable that has the default address space. 787536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // The clone is created with the global address space specifier, and the pair 797536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // of original global variable and its clone is placed in the GVMap for later 807536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // use. 817536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 827536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 837536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski I != E;) { 84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GlobalVariable *GV = &*I++; 857536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC && 867536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski !llvm::isTexture(*GV) && !llvm::isSurface(*GV) && 87c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) { 887536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GlobalVariable *NewGV = new GlobalVariable( 897536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski M, GV->getType()->getElementType(), GV->isConstant(), 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines GV->getLinkage(), 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines GV->hasInitializer() ? GV->getInitializer() : nullptr, 927536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL); 937536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewGV->copyAttributesFrom(GV); 947536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GVMap[GV] = NewGV; 957536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 967536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 977536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 987536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Return immediately, if every global variable has a specific address space 997536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // specifier. 1007536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (GVMap.empty()) { 1017536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return false; 1027536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1037536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 1047536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Walk through the instructions in function defitinions, and replace any use 1057536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // of original global variables in GVMap with a use of the corresponding 1067536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // copies in GVMap. If necessary, promote constants to instructions. 1077536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 1087536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (I->isDeclaration()) { 1097536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski continue; 1107536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1117536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg()); 1127536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE; 1137536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ++BBI) { 1147536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; 1157536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ++II) { 1167536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) { 1177536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *Operand = II->getOperand(i); 1187536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (isa<Constant>(Operand)) { 1197536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski II->setOperand( 120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder)); 1217536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1227536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1237536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1247536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1257536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ConstantToValueMap.clear(); 1267536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1277536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Copy GVMap over to a standard value map. 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValueToValueMapTy VM; 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I) 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VM[I->first] = I->second; 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1337536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Walk through the metadata section and update the debug information 1347536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // associated with the global variables in the default address space. 135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (NamedMDNode &I : M.named_metadata()) { 136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar remapNamedMDNode(VM, &I); 1377536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 1387536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 1397536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Walk through the global variable initializers, and replace any use of 1407536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // original global variables in GVMap with a use of the corresponding copies 1417536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // in GVMap. The copies need to be bitcast to the original global variable 1427536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // types, as we cannot use cvta in global variable initializers. 1437536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) { 1447536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GlobalVariable *GV = I->first; 1457536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GlobalVariable *NewGV = I->second; 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Remove GV from the map so that it can be RAUWed. Note that 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // DenseMap::erase() won't invalidate any iterators but this one. 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Next = std::next(I); 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GVMap.erase(I); 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines I = Next; 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 15359d3ae6cdc4316ad338cd848251f33a236ccb36cMatt Arsenault Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType()); 1547536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // At this point, the remaining uses of GV should be found only in global 1557536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // variable initializers, as other uses have been already been removed 1567536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // while walking through the instructions in function definitions. 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->replaceAllUsesWith(BitCastNewGV); 1587536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski std::string Name = GV->getName(); 1597536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GV->eraseFromParent(); 1607536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewGV->setName(Name); 1617536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(GVMap.empty() && "Expected it to be empty by now"); 1637536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 1647536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return true; 1657536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 1667536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 1677536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiValue *GenericToNVVM::getOrInsertCVTA(Module *M, Function *F, 1687536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GlobalVariable *GV, 1697536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder) { 1707536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski PointerType *GVType = GV->getType(); 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *CVTA = nullptr; 1727536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 1737536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // See if the address space conversion requires the operand to be bitcast 1747536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // to i8 addrspace(n)* first. 1757536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski EVT ExtendedGVType = EVT::getEVT(GVType->getElementType(), true); 1767536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (!ExtendedGVType.isInteger() && !ExtendedGVType.isFloatingPoint()) { 1777536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // A bitcast to i8 addrspace(n)* on the operand is needed. 1787536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski LLVMContext &Context = M->getContext(); 1797536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski unsigned int AddrSpace = GVType->getAddressSpace(); 1807536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Type *DestTy = PointerType::get(Type::getInt8Ty(Context), AddrSpace); 1817536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski CVTA = Builder.CreateBitCast(GV, DestTy, "cvta"); 1827536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Insert the address space conversion. 1837536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Type *ResultType = 1847536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski PointerType::get(Type::getInt8Ty(Context), llvm::ADDRESS_SPACE_GENERIC); 1857536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski SmallVector<Type *, 2> ParamTypes; 1867536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ParamTypes.push_back(ResultType); 1877536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ParamTypes.push_back(DestTy); 1887536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Function *CVTAFunction = Intrinsic::getDeclaration( 1897536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski M, Intrinsic::nvvm_ptr_global_to_gen, ParamTypes); 1907536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski CVTA = Builder.CreateCall(CVTAFunction, CVTA, "cvta"); 1917536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Another bitcast from i8 * to <the element type of GVType> * is 1927536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // required. 1937536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski DestTy = 1947536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski PointerType::get(GVType->getElementType(), llvm::ADDRESS_SPACE_GENERIC); 1957536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski CVTA = Builder.CreateBitCast(CVTA, DestTy, "cvta"); 1967536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } else { 1977536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // A simple CVTA is enough. 1987536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski SmallVector<Type *, 2> ParamTypes; 1997536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ParamTypes.push_back(PointerType::get(GVType->getElementType(), 2007536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski llvm::ADDRESS_SPACE_GENERIC)); 2017536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ParamTypes.push_back(GVType); 2027536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Function *CVTAFunction = Intrinsic::getDeclaration( 2037536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski M, Intrinsic::nvvm_ptr_global_to_gen, ParamTypes); 2047536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski CVTA = Builder.CreateCall(CVTAFunction, GV, "cvta"); 2057536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2067536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2077536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return CVTA; 2087536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 2097536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2107536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiValue *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C, 2117536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder) { 2127536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If the constant C has been converted already in the given function F, just 2137536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // return the converted value. 2147536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ConstantToValueMapTy::iterator CTII = ConstantToValueMap.find(C); 2157536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (CTII != ConstantToValueMap.end()) { 2167536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return CTII->second; 2177536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2187536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2197536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *NewValue = C; 2207536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (isa<GlobalVariable>(C)) { 2217536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If the constant C is a global variable and is found in GVMap, generate a 2227536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // set set of instructions that convert the clone of C with the global 2237536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // address space specifier to a generic pointer. 2247536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // The constant C cannot be used here, as it will be erased from the 2257536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // module eventually. And the clone of C with the global address space 2267536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // specifier cannot be used here either, as it will affect the types of 2277536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // other instructions in the function. Hence, this address space conversion 2287536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // is required. 2297536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski GVMapTy::iterator I = GVMap.find(cast<GlobalVariable>(C)); 2307536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (I != GVMap.end()) { 2317536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewValue = getOrInsertCVTA(M, F, I->second, Builder); 2327536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2337536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } else if (isa<ConstantVector>(C) || isa<ConstantArray>(C) || 2347536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski isa<ConstantStruct>(C)) { 2357536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If any element in the constant vector or aggregate C is or uses a global 2367536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // variable in GVMap, the constant C needs to be reconstructed, using a set 2377536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // of instructions. 2387536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewValue = remapConstantVectorOrConstantAggregate(M, F, C, Builder); 2397536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } else if (isa<ConstantExpr>(C)) { 2407536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If any operand in the constant expression C is or uses a global variable 2417536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // in GVMap, the constant expression C needs to be reconstructed, using a 2427536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // set of instructions. 2437536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewValue = remapConstantExpr(M, F, cast<ConstantExpr>(C), Builder); 2447536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2457536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2467536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ConstantToValueMap[C] = NewValue; 2477536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return NewValue; 2487536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 2497536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2507536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiValue *GenericToNVVM::remapConstantVectorOrConstantAggregate( 2517536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Module *M, Function *F, Constant *C, IRBuilder<> &Builder) { 2527536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski bool OperandChanged = false; 2537536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski SmallVector<Value *, 4> NewOperands; 2547536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski unsigned NumOperands = C->getNumOperands(); 2557536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2567536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Check if any element is or uses a global variable in GVMap, and thus 2577536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // converted to another value. 2587536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0; i < NumOperands; ++i) { 2597536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *Operand = C->getOperand(i); 2607536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder); 2617536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski OperandChanged |= Operand != NewOperand; 2627536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands.push_back(NewOperand); 2637536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2647536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2657536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If none of the elements has been modified, return C as it is. 2667536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (!OperandChanged) { 2677536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return C; 2687536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2697536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2707536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If any of the elements has been modified, construct the equivalent 2717536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // vector or aggregate value with a set instructions and the converted 2727536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // elements. 2737536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *NewValue = UndefValue::get(C->getType()); 2747536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (isa<ConstantVector>(C)) { 2757536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0; i < NumOperands; ++i) { 2767536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *Idx = ConstantInt::get(Type::getInt32Ty(M->getContext()), i); 2777536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewValue = Builder.CreateInsertElement(NewValue, NewOperands[i], Idx); 2787536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2797536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } else { 2807536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0; i < NumOperands; ++i) { 2817536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewValue = 2827536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Builder.CreateInsertValue(NewValue, NewOperands[i], makeArrayRef(i)); 2837536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2847536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 2857536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2867536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return NewValue; 2877536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 2887536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2897536ecf2916a6a986f0d328069e3a210f34d5ea7Justin HolewinskiValue *GenericToNVVM::remapConstantExpr(Module *M, Function *F, ConstantExpr *C, 2907536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski IRBuilder<> &Builder) { 2917536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski bool OperandChanged = false; 2927536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski SmallVector<Value *, 4> NewOperands; 2937536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski unsigned NumOperands = C->getNumOperands(); 2947536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 2957536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Check if any operand is or uses a global variable in GVMap, and thus 2967536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // converted to another value. 2977536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0; i < NumOperands; ++i) { 2987536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *Operand = C->getOperand(i); 2997536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder); 3007536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski OperandChanged |= Operand != NewOperand; 3017536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands.push_back(NewOperand); 3027536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3037536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3047536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If none of the operands has been modified, return C as it is. 3057536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (!OperandChanged) { 3067536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return C; 3077536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3087536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3097536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If any of the operands has been modified, construct the instruction with 3107536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // the converted operands. 3117536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski unsigned Opcode = C->getOpcode(); 3127536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski switch (Opcode) { 3137536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::ICmp: 3147536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // CompareConstantExpr (icmp) 3157536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateICmp(CmpInst::Predicate(C->getPredicate()), 3167536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[0], NewOperands[1]); 3177536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::FCmp: 3187536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // CompareConstantExpr (fcmp) 319cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar llvm_unreachable("Address space conversion should have no effect " 320cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "on float point CompareConstantExpr (fcmp)!"); 3217536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::ExtractElement: 3227536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // ExtractElementConstantExpr 3237536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateExtractElement(NewOperands[0], NewOperands[1]); 3247536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::InsertElement: 3257536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // InsertElementConstantExpr 3267536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateInsertElement(NewOperands[0], NewOperands[1], 3277536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[2]); 3287536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::ShuffleVector: 3297536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // ShuffleVector 3307536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateShuffleVector(NewOperands[0], NewOperands[1], 3317536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[2]); 3327536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::ExtractValue: 3337536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // ExtractValueConstantExpr 3347536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateExtractValue(NewOperands[0], C->getIndices()); 3357536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::InsertValue: 3367536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // InsertValueConstantExpr 3377536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateInsertValue(NewOperands[0], NewOperands[1], 3387536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski C->getIndices()); 3397536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::GetElementPtr: 3407536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // GetElementPtrConstantExpr 3417536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return cast<GEPOperator>(C)->isInBounds() 3427536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski ? Builder.CreateGEP( 3434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cast<GEPOperator>(C)->getSourceElementType(), 3447536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[0], 3457536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski makeArrayRef(&NewOperands[1], NumOperands - 1)) 3467536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski : Builder.CreateInBoundsGEP( 3470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar cast<GEPOperator>(C)->getSourceElementType(), 3487536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[0], 3497536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski makeArrayRef(&NewOperands[1], NumOperands - 1)); 3507536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski case Instruction::Select: 3517536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // SelectConstantExpr 3527536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateSelect(NewOperands[0], NewOperands[1], NewOperands[2]); 3537536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski default: 3547536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // BinaryConstantExpr 3557536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (Instruction::isBinaryOp(Opcode)) { 3567536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateBinOp(Instruction::BinaryOps(C->getOpcode()), 3577536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[0], NewOperands[1]); 3587536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3597536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // UnaryConstantExpr 3607536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (Instruction::isCast(Opcode)) { 3617536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return Builder.CreateCast(Instruction::CastOps(C->getOpcode()), 3627536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands[0], C->getType()); 3637536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 364cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar llvm_unreachable("GenericToNVVM encountered an unsupported ConstantExpr"); 3657536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3667536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 3677536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid GenericToNVVM::remapNamedMDNode(ValueToValueMapTy &VM, NamedMDNode *N) { 3697536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3707536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski bool OperandChanged = false; 3717536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski SmallVector<MDNode *, 16> NewOperands; 3727536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski unsigned NumOperands = N->getNumOperands(); 3737536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3747536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Check if any operand is or contains a global variable in GVMap, and thus 3757536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // converted to another value. 3767536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski for (unsigned i = 0; i < NumOperands; ++i) { 3777536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski MDNode *Operand = N->getOperand(i); 378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MDNode *NewOperand = MapMetadata(Operand, VM); 3797536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski OperandChanged |= Operand != NewOperand; 3807536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski NewOperands.push_back(NewOperand); 3817536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3827536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3837536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // If none of the operands has been modified, return immediately. 3847536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (!OperandChanged) { 3857536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski return; 3867536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3877536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 3887536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski // Replace the old operands with the new operands. 3897536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski N->dropAllReferences(); 3906227d5c690504c7ada5780c00a635b282c46e275Craig Topper for (SmallVectorImpl<MDNode *>::iterator I = NewOperands.begin(), 3917536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski E = NewOperands.end(); 3927536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski I != E; ++I) { 3937536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski N->addOperand(*I); 3947536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } 3957536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 396