llvm.org GIT mirror llvm / b47f06e
Merging r182254: ------------------------------------------------------------------------ r182254 | jholewinski | 2013-05-20 05:13:32 -0700 (Mon, 20 May 2013) | 12 lines [NVPTX] Add GenericToNVVM IR converter to better handle idiomatic LLVM IR inputs This converter currently only handles global variables in address space 0. For these variables, they are promoted to address space 1 (global memory), and all uses are updated to point to the result of a cvta.global instruction on the new variable. The motivation for this is address space 0 global variables are illegal since we cannot declare variables in the generic address space. Instead, we place the variables in address space 1 and explicitly convert the pointer to address space 0. This is primarily intended to help new users who expect to be able to place global variables in the default address space. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_33@182826 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 7 years ago
8 changed file(s) with 550 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
2222 NVPTXAsmPrinter.cpp
2323 NVPTXUtilities.cpp
2424 NVVMReflect.cpp
25 NVPTXGenericToNVVM.cpp
2526 )
2627
2728 add_llvm_target(NVPTXCodeGen ${NVPTXCodeGen_sources})
6161 FunctionPass *createLowerStructArgsPass(NVPTXTargetMachine &);
6262 FunctionPass *createNVPTXReMatPass(NVPTXTargetMachine &);
6363 FunctionPass *createNVPTXReMatBlockPass(NVPTXTargetMachine &);
64 ModulePass *createGenericToNVVMPass();
6465
6566 bool isImageOrSamplerVal(const Value *, const Module *);
6667
6767 namespace {
6868 /// DiscoverDependentGlobals - Return a set of GlobalVariables on which \p V
6969 /// depends.
70 void DiscoverDependentGlobals(Value *V, DenseSet &Globals) {
71 if (GlobalVariable *GV = dyn_cast(V))
70 void DiscoverDependentGlobals(const Value *V,
71 DenseSet &Globals) {
72 if (const GlobalVariable *GV = dyn_cast(V))
7273 Globals.insert(GV);
7374 else {
74 if (User *U = dyn_cast(V)) {
75 if (const User *U = dyn_cast(V)) {
7576 for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
7677 DiscoverDependentGlobals(U->getOperand(i), Globals);
7778 }
8384 /// instances to be emitted, but only after any dependents have been added
8485 /// first.
8586 void VisitGlobalVariableForEmission(
86 GlobalVariable *GV, SmallVectorImpl &Order,
87 DenseSet &Visited, DenseSet &Visiting) {
87 const GlobalVariable *GV, SmallVectorImpl &Order,
88 DenseSet &Visited,
89 DenseSet &Visiting) {
8890 // Have we already visited this one?
8991 if (Visited.count(GV))
9092 return;
9799 Visiting.insert(GV);
98100
99101 // Make sure we visit all dependents first
100 DenseSet<GlobalVariable *> Others;
102 DenseSet<const GlobalVariable *> Others;
101103 for (unsigned i = 0, e = GV->getNumOperands(); i != e; ++i)
102104 DiscoverDependentGlobals(GV->getOperand(i), Others);
103105
104 for (DenseSet::iterator I = Others.begin(),
105 E = Others.end();
106 for (DenseSet::iterator I = Others.begin(),
107 E = Others.end();
106108 I != E; ++I)
107109 VisitGlobalVariableForEmission(*I, Order, Visited, Visiting);
108110
404406 SmallString<128> Str;
405407 raw_svector_ostream O(Str);
406408
409 if (!GlobalsEmitted) {
410 emitGlobals(*MF->getFunction()->getParent());
411 GlobalsEmitted = true;
412 }
413
407414 // Set up
408415 MRI = &MF->getRegInfo();
409416 F = MF->getFunction();
794801 return false;
795802 }
796803
797 void NVPTXAsmPrinter::emitDeclarations(Module &M, raw_ostream &O) {
804 void NVPTXAsmPrinter::emitDeclarations(const Module &M, raw_ostream &O) {
798805 llvm::DenseMap seenMap;
799806 for (Module::const_iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
800807 const Function *F = FI;
920927 if (nvptxSubtarget.getDrvInterface() == NVPTX::CUDA)
921928 recordAndEmitFilenames(M);
922929
930 GlobalsEmitted = false;
931
932 return false; // success
933 }
934
935 void NVPTXAsmPrinter::emitGlobals(const Module &M) {
923936 SmallString<128> Str2;
924937 raw_svector_ostream OS2(Str2);
925938
930943 // global variable in order, and ensure that we emit it *after* its dependent
931944 // globals. We use a little extra memory maintaining both a set and a list to
932945 // have fast searches while maintaining a strict ordering.
933 SmallVector Globals;
934 DenseSet GVVisited;
935 DenseSet GVVisiting;
946 SmallVector Globals;
947 DenseSet GVVisited;
948 DenseSet GVVisiting;
936949
937950 // Visit each global variable, in order
938 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E;
939 ++I)
951 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
952 I != E; ++I)
940953 VisitGlobalVariableForEmission(I, Globals, GVVisited, GVVisiting);
941954
942955 assert(GVVisited.size() == M.getGlobalList().size() &&
950963 OS2 << '\n';
951964
952965 OutStreamer.EmitRawText(OS2.str());
953 return false; // success
954966 }
955967
956968 void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O) {
9881000 }
9891001
9901002 bool NVPTXAsmPrinter::doFinalization(Module &M) {
1003
1004 // If we did not emit any functions, then the global declarations have not
1005 // yet been emitted.
1006 if (!GlobalsEmitted) {
1007 emitGlobals(M);
1008 GlobalsEmitted = true;
1009 }
1010
9911011 // XXX Temproarily remove global variables so that doFinalization() will not
9921012 // emit them again (global variables are emitted at beginning).
9931013
10621082 }
10631083 }
10641084
1065 void NVPTXAsmPrinter::printModuleLevelGV(GlobalVariable *GVar, raw_ostream &O,
1085 void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar,
1086 raw_ostream &O,
10661087 bool processDemoted) {
10671088
10681089 // Skip meta data
11061127 if (llvm::isSampler(*GVar)) {
11071128 O << ".global .samplerref " << llvm::getSamplerName(*GVar);
11081129
1109 Constant *Initializer = NULL;
1130 const Constant *Initializer = NULL;
11101131 if (GVar->hasInitializer())
11111132 Initializer = GVar->getInitializer();
1112 ConstantInt *CI = NULL;
1133 const ConstantInt *CI = NULL;
11131134 if (Initializer)
11141135 CI = dyn_cast(Initializer);
11151136 if (CI) {
11821203 if (localDecls.find(demotedFunc) != localDecls.end())
11831204 localDecls[demotedFunc].push_back(GVar);
11841205 else {
1185 std::vector<GlobalVariable *> temp;
1206 std::vector<const GlobalVariable *> temp;
11861207 temp.push_back(GVar);
11871208 localDecls[demotedFunc] = temp;
11881209 }
12121233 (PTy->getAddressSpace() == llvm::ADDRESS_SPACE_CONST_NOT_GEN) ||
12131234 (PTy->getAddressSpace() == llvm::ADDRESS_SPACE_CONST)) &&
12141235 GVar->hasInitializer()) {
1215 Constant *Initializer = GVar->getInitializer();
1236 const Constant *Initializer = GVar->getInitializer();
12161237 if (!Initializer->isNullValue()) {
12171238 O << " = ";
12181239 printScalarConstant(Initializer, O);
12361257 (PTy->getAddressSpace() == llvm::ADDRESS_SPACE_CONST_NOT_GEN) ||
12371258 (PTy->getAddressSpace() == llvm::ADDRESS_SPACE_CONST)) &&
12381259 GVar->hasInitializer()) {
1239 Constant *Initializer = GVar->getInitializer();
1260 const Constant *Initializer = GVar->getInitializer();
12401261 if (!isa(Initializer) && !Initializer->isNullValue()) {
12411262 AggBuffer aggBuffer(ElementSize, O, *this);
12421263 bufferAggregateConstant(Initializer, &aggBuffer);
12861307 if (localDecls.find(f) == localDecls.end())
12871308 return;
12881309
1289 std::vector<GlobalVariable *> &gvars = localDecls[f];
1310 std::vector<const GlobalVariable *> &gvars = localDecls[f];
12901311
12911312 for (unsigned i = 0, e = gvars.size(); i != e; ++i) {
12921313 O << "\t// demoted variable\n\t";
17601781 O << utohexstr(API.getZExtValue());
17611782 }
17621783
1763 void NVPTXAsmPrinter::printScalarConstant(Constant *CPV, raw_ostream &O) {
1764 if (ConstantInt *CI = dyn_cast(CPV)) {
1784 void NVPTXAsmPrinter::printScalarConstant(const Constant *CPV, raw_ostream &O) {
1785 if (const ConstantInt *CI = dyn_cast(CPV)) {
17651786 O << CI->getValue();
17661787 return;
17671788 }
1768 if (ConstantFP *CFP = dyn_cast(CPV)) {
1789 if (const ConstantFP *CFP = dyn_cast(CPV)) {
17691790 printFPConstant(CFP, O);
17701791 return;
17711792 }
17731794 O << "0";
17741795 return;
17751796 }
1776 if (GlobalValue *GVar = dyn_cast(CPV)) {
1797 if (const GlobalValue *GVar = dyn_cast(CPV)) {
17771798 O << *Mang->getSymbol(GVar);
17781799 return;
17791800 }
1780 if (ConstantExpr *Cexpr = dyn_cast(CPV)) {
1781 Value *v = Cexpr->stripPointerCasts();
1782 if (GlobalValue *GVar = dyn_cast(v)) {
1801 if (const ConstantExpr *Cexpr = dyn_cast(CPV)) {
1802 const Value *v = Cexpr->stripPointerCasts();
1803 if (const GlobalValue *GVar = dyn_cast(v)) {
17831804 O << *Mang->getSymbol(GVar);
17841805 return;
17851806 } else {
17901811 llvm_unreachable("Not scalar type found in printScalarConstant()");
17911812 }
17921813
1793 void NVPTXAsmPrinter::bufferLEByte(Constant *CPV, int Bytes,
1814 void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
17941815 AggBuffer *aggBuffer) {
17951816
17961817 const DataLayout *TD = TM.getDataLayout();
18181839 ptr = (unsigned char *)&int16;
18191840 aggBuffer->addBytes(ptr, 2, Bytes);
18201841 } else if (ETy == Type::getInt32Ty(CPV->getContext())) {
1821 if (ConstantInt *constInt = dyn_cast(CPV)) {
1842 if (const ConstantInt *constInt = dyn_cast(CPV)) {
18221843 int int32 = (int)(constInt->getZExtValue());
18231844 ptr = (unsigned char *)&int32;
18241845 aggBuffer->addBytes(ptr, 4, Bytes);
18251846 break;
1826 } else if (ConstantExpr *Cexpr = dyn_cast(CPV)) {
1827 if (ConstantInt *constInt = dyn_cast(
1847 } else if (const ConstantExpr *Cexpr = dyn_cast(CPV)) {
1848 if (const ConstantInt *constInt = dyn_cast(
18281849 ConstantFoldConstantExpression(Cexpr, TD))) {
18291850 int int32 = (int)(constInt->getZExtValue());
18301851 ptr = (unsigned char *)&int32;
18401861 }
18411862 llvm_unreachable("unsupported integer const type");
18421863 } else if (ETy == Type::getInt64Ty(CPV->getContext())) {
1843 if (ConstantInt *constInt = dyn_cast(CPV)) {
1864 if (const ConstantInt *constInt = dyn_cast(CPV)) {
18441865 long long int64 = (long long)(constInt->getZExtValue());
18451866 ptr = (unsigned char *)&int64;
18461867 aggBuffer->addBytes(ptr, 8, Bytes);
18471868 break;
1848 } else if (ConstantExpr *Cexpr = dyn_cast(CPV)) {
1849 if (ConstantInt *constInt = dyn_cast(
1869 } else if (const ConstantExpr *Cexpr = dyn_cast(CPV)) {
1870 if (const ConstantInt *constInt = dyn_cast(
18501871 ConstantFoldConstantExpression(Cexpr, TD))) {
18511872 long long int64 = (long long)(constInt->getZExtValue());
18521873 ptr = (unsigned char *)&int64;
18671888 }
18681889 case Type::FloatTyID:
18691890 case Type::DoubleTyID: {
1870 ConstantFP *CFP = dyn_cast(CPV);
1891 const ConstantFP *CFP = dyn_cast(CPV);
18711892 const Type *Ty = CFP->getType();
18721893 if (Ty == Type::getFloatTy(CPV->getContext())) {
18731894 float float32 = (float) CFP->getValueAPF().convertToFloat();
18831904 break;
18841905 }
18851906 case Type::PointerTyID: {
1886 if (GlobalValue *GVar = dyn_cast(CPV)) {
1907 if (const GlobalValue *GVar = dyn_cast(CPV)) {
18871908 aggBuffer->addSymbol(GVar);
1888 } else if (ConstantExpr *Cexpr = dyn_cast(CPV)) {
1889 Value *v = Cexpr->stripPointerCasts();
1909 } else if (const ConstantExpr *Cexpr = dyn_cast(CPV)) {
1910 const Value *v = Cexpr->stripPointerCasts();
18901911 aggBuffer->addSymbol(v);
18911912 }
18921913 unsigned int s = TD->getTypeAllocSize(CPV->getType());
19151936 }
19161937 }
19171938
1918 void NVPTXAsmPrinter::bufferAggregateConstant(Constant *CPV,
1939 void NVPTXAsmPrinter::bufferAggregateConstant(const Constant *CPV,
19191940 AggBuffer *aggBuffer) {
19201941 const DataLayout *TD = TM.getDataLayout();
19211942 int Bytes;
9090 unsigned char *buffer; // the buffer
9191 unsigned numSymbols; // number of symbol addresses
9292 SmallVector symbolPosInBuffer;
93 SmallVector<Value *, 4> Symbols;
93 SmallVector<const Value *, 4> Symbols;
9494
9595 private:
9696 unsigned curpos;
127127 }
128128 return curpos;
129129 }
130 void addSymbol(Value *GVar) {
130 void addSymbol(const Value *GVar) {
131131 symbolPosInBuffer.push_back(curpos);
132132 Symbols.push_back(GVar);
133133 numSymbols++;
152152 if (pos)
153153 O << ", ";
154154 if (pos == nextSymbolPos) {
155 Value *v = Symbols[nSym];
156 if (GlobalValue *GVar = dyn_cast(v)) {
155 const Value *v = Symbols[nSym];
156 if (const GlobalValue *GVar = dyn_cast(v)) {
157157 MCSymbol *Name = AP.Mang->getSymbol(GVar);
158158 O << *Name;
159 } else if (ConstantExpr *Cexpr = dyn_cast(v)) {
159 } else if (const ConstantExpr *Cexpr = dyn_cast(v)) {
160160 O << *nvptx::LowerConstant(Cexpr, AP);
161161 } else
162162 llvm_unreachable("symbol type unknown");
204204 void printImplicitDef(const MachineInstr *MI, raw_ostream &O) const;
205205 // definition autogenerated.
206206 void printInstruction(const MachineInstr *MI, raw_ostream &O);
207 void printModuleLevelGV(GlobalVariable *GVar, raw_ostream &O, bool = false);
207 void printModuleLevelGV(const GlobalVariable *GVar, raw_ostream &O,
208 bool = false);
208209 void printParamName(int paramIndex, raw_ostream &O);
209210 void printParamName(Function::const_arg_iterator I, int paramIndex,
210211 raw_ostream &O);
212 void emitGlobals(const Module &M);
211213 void emitHeader(Module &M, raw_ostream &O);
212214 void emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const;
213215 void emitVirtualRegister(unsigned int vr, bool isVec, raw_ostream &O);
233235 private:
234236 std::string CurrentBankselLabelInBasicBlock;
235237
238 bool GlobalsEmitted;
239
236240 // This is specific per MachineFunction.
237241 const MachineRegisterInfo *MRI;
238242 // The contents are specific for each
246250 std::map TypeNameMap;
247251
248252 // List of variables demoted to a function scope.
249 std::mapGlobalVariable *> > localDecls;
253 std::mapconst GlobalVariable *> > localDecls;
250254
251255 // To record filename to ID mapping
252256 std::map filenameMap;
255259 void emitPTXGlobalVariable(const GlobalVariable *GVar, raw_ostream &O);
256260 void emitPTXAddressSpace(unsigned int AddressSpace, raw_ostream &O) const;
257261 std::string getPTXFundamentalTypeStr(const Type *Ty, bool = true) const;
258 void printScalarConstant(Constant *CPV, raw_ostream &O);
262 void printScalarConstant(const Constant *CPV, raw_ostream &O);
259263 void printFPConstant(const ConstantFP *Fp, raw_ostream &O);
260 void bufferLEByte(Constant *CPV, int Bytes, AggBuffer *aggBuffer);
261 void bufferAggregateConstant(Constant *CV, AggBuffer *aggBuffer);
264 void bufferLEByte(const Constant *CPV, int Bytes, AggBuffer *aggBuffer);
265 void bufferAggregateConstant(const Constant *CV, AggBuffer *aggBuffer);
262266
263267 void printOperandProper(const MachineOperand &MO);
264268
265269 void emitLinkageDirective(const GlobalValue *V, raw_ostream &O);
266 void emitDeclarations(Module &, raw_ostream &O);
270 void emitDeclarations(const Module &, raw_ostream &O);
267271 void emitDeclaration(const Function *, raw_ostream &O);
268272
269273 static const char *getRegisterName(unsigned RegNo);
0 //===-- GenericToNVVM.cpp - Convert generic module to NVVM module - C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Convert generic global variables into either .global or .const access based
10 // on the variable's "constant" qualifier.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "NVPTX.h"
15 #include "NVPTXUtilities.h"
16 #include "MCTargetDesc/NVPTXBaseInfo.h"
17
18 #include "llvm/PassManager.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/Intrinsics.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/IR/Operator.h"
25 #include "llvm/ADT/ValueMap.h"
26 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
27 #include "llvm/CodeGen/ValueTypes.h"
28 #include "llvm/IR/IRBuilder.h"
29
30 using namespace llvm;
31
32 namespace llvm {
33 void initializeGenericToNVVMPass(PassRegistry &);
34 }
35
36 namespace {
37 class GenericToNVVM : public ModulePass {
38 public:
39 static char ID;
40
41 GenericToNVVM() : ModulePass(ID) {}
42
43 virtual bool runOnModule(Module &M);
44
45 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
46 }
47
48 private:
49 Value *getOrInsertCVTA(Module *M, Function *F, GlobalVariable *GV,
50 IRBuilder<> &Builder);
51 Value *remapConstant(Module *M, Function *F, Constant *C,
52 IRBuilder<> &Builder);
53 Value *remapConstantVectorOrConstantAggregate(Module *M, Function *F,
54 Constant *C,
55 IRBuilder<> &Builder);
56 Value *remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
57 IRBuilder<> &Builder);
58 void remapNamedMDNode(Module *M, NamedMDNode *N);
59 MDNode *remapMDNode(Module *M, MDNode *N);
60
61 typedef ValueMap GVMapTy;
62 typedef ValueMap ConstantToValueMapTy;
63 GVMapTy GVMap;
64 ConstantToValueMapTy ConstantToValueMap;
65 };
66 }
67
68 char GenericToNVVM::ID = 0;
69
70 ModulePass *llvm::createGenericToNVVMPass() { return new GenericToNVVM(); }
71
72 INITIALIZE_PASS(
73 GenericToNVVM, "generic-to-nvvm",
74 "Ensure that the global variables are in the global address space", false,
75 false)
76
77 bool GenericToNVVM::runOnModule(Module &M) {
78 // Create a clone of each global variable that has the default address space.
79 // The clone is created with the global address space specifier, and the pair
80 // of original global variable and its clone is placed in the GVMap for later
81 // use.
82
83 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
84 I != E;) {
85 GlobalVariable *GV = I++;
86 if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
87 !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
88 !GV->getName().startswith("llvm.")) {
89 GlobalVariable *NewGV = new GlobalVariable(
90 M, GV->getType()->getElementType(), GV->isConstant(),
91 GV->getLinkage(), GV->hasInitializer() ? GV->getInitializer() : NULL,
92 "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
93 NewGV->copyAttributesFrom(GV);
94 GVMap[GV] = NewGV;
95 }
96 }
97
98 // Return immediately, if every global variable has a specific address space
99 // specifier.
100 if (GVMap.empty()) {
101 return false;
102 }
103
104 // Walk through the instructions in function defitinions, and replace any use
105 // of original global variables in GVMap with a use of the corresponding
106 // copies in GVMap. If necessary, promote constants to instructions.
107 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
108 if (I->isDeclaration()) {
109 continue;
110 }
111 IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
112 for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
113 ++BBI) {
114 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
115 ++II) {
116 for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
117 Value *Operand = II->getOperand(i);
118 if (isa(Operand)) {
119 II->setOperand(
120 i, remapConstant(&M, I, cast(Operand), Builder));
121 }
122 }
123 }
124 }
125 ConstantToValueMap.clear();
126 }
127
128 // Walk through the metadata section and update the debug information
129 // associated with the global variables in the default address space.
130 for (Module::named_metadata_iterator I = M.named_metadata_begin(),
131 E = M.named_metadata_end();
132 I != E; I++) {
133 remapNamedMDNode(&M, I);
134 }
135
136 // Walk through the global variable initializers, and replace any use of
137 // original global variables in GVMap with a use of the corresponding copies
138 // in GVMap. The copies need to be bitcast to the original global variable
139 // types, as we cannot use cvta in global variable initializers.
140 for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
141 GlobalVariable *GV = I->first;
142 GlobalVariable *NewGV = I->second;
143 ++I;
144 Constant *BitCastNewGV = ConstantExpr::getBitCast(NewGV, GV->getType());
145 // At this point, the remaining uses of GV should be found only in global
146 // variable initializers, as other uses have been already been removed
147 // while walking through the instructions in function definitions.
148 for (Value::use_iterator UI = GV->use_begin(), UE = GV->use_end();
149 UI != UE;) {
150 Use &U = (UI++).getUse();
151 U.set(BitCastNewGV);
152 }
153 std::string Name = GV->getName();
154 GV->removeDeadConstantUsers();
155 GV->eraseFromParent();
156 NewGV->setName(Name);
157 }
158 GVMap.clear();
159
160 return true;
161 }
162
163 Value *GenericToNVVM::getOrInsertCVTA(Module *M, Function *F,
164 GlobalVariable *GV,
165 IRBuilder<> &Builder) {
166 PointerType *GVType = GV->getType();
167 Value *CVTA = NULL;
168
169 // See if the address space conversion requires the operand to be bitcast
170 // to i8 addrspace(n)* first.
171 EVT ExtendedGVType = EVT::getEVT(GVType->getElementType(), true);
172 if (!ExtendedGVType.isInteger() && !ExtendedGVType.isFloatingPoint()) {
173 // A bitcast to i8 addrspace(n)* on the operand is needed.
174 LLVMContext &Context = M->getContext();
175 unsigned int AddrSpace = GVType->getAddressSpace();
176 Type *DestTy = PointerType::get(Type::getInt8Ty(Context), AddrSpace);
177 CVTA = Builder.CreateBitCast(GV, DestTy, "cvta");
178 // Insert the address space conversion.
179 Type *ResultType =
180 PointerType::get(Type::getInt8Ty(Context), llvm::ADDRESS_SPACE_GENERIC);
181 SmallVector ParamTypes;
182 ParamTypes.push_back(ResultType);
183 ParamTypes.push_back(DestTy);
184 Function *CVTAFunction = Intrinsic::getDeclaration(
185 M, Intrinsic::nvvm_ptr_global_to_gen, ParamTypes);
186 CVTA = Builder.CreateCall(CVTAFunction, CVTA, "cvta");
187 // Another bitcast from i8 * to * is
188 // required.
189 DestTy =
190 PointerType::get(GVType->getElementType(), llvm::ADDRESS_SPACE_GENERIC);
191 CVTA = Builder.CreateBitCast(CVTA, DestTy, "cvta");
192 } else {
193 // A simple CVTA is enough.
194 SmallVector ParamTypes;
195 ParamTypes.push_back(PointerType::get(GVType->getElementType(),
196 llvm::ADDRESS_SPACE_GENERIC));
197 ParamTypes.push_back(GVType);
198 Function *CVTAFunction = Intrinsic::getDeclaration(
199 M, Intrinsic::nvvm_ptr_global_to_gen, ParamTypes);
200 CVTA = Builder.CreateCall(CVTAFunction, GV, "cvta");
201 }
202
203 return CVTA;
204 }
205
206 Value *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C,
207 IRBuilder<> &Builder) {
208 // If the constant C has been converted already in the given function F, just
209 // return the converted value.
210 ConstantToValueMapTy::iterator CTII = ConstantToValueMap.find(C);
211 if (CTII != ConstantToValueMap.end()) {
212 return CTII->second;
213 }
214
215 Value *NewValue = C;
216 if (isa(C)) {
217 // If the constant C is a global variable and is found in GVMap, generate a
218 // set set of instructions that convert the clone of C with the global
219 // address space specifier to a generic pointer.
220 // The constant C cannot be used here, as it will be erased from the
221 // module eventually. And the clone of C with the global address space
222 // specifier cannot be used here either, as it will affect the types of
223 // other instructions in the function. Hence, this address space conversion
224 // is required.
225 GVMapTy::iterator I = GVMap.find(cast(C));
226 if (I != GVMap.end()) {
227 NewValue = getOrInsertCVTA(M, F, I->second, Builder);
228 }
229 } else if (isa(C) || isa(C) ||
230 isa(C)) {
231 // If any element in the constant vector or aggregate C is or uses a global
232 // variable in GVMap, the constant C needs to be reconstructed, using a set
233 // of instructions.
234 NewValue = remapConstantVectorOrConstantAggregate(M, F, C, Builder);
235 } else if (isa(C)) {
236 // If any operand in the constant expression C is or uses a global variable
237 // in GVMap, the constant expression C needs to be reconstructed, using a
238 // set of instructions.
239 NewValue = remapConstantExpr(M, F, cast(C), Builder);
240 }
241
242 ConstantToValueMap[C] = NewValue;
243 return NewValue;
244 }
245
246 Value *GenericToNVVM::remapConstantVectorOrConstantAggregate(
247 Module *M, Function *F, Constant *C, IRBuilder<> &Builder) {
248 bool OperandChanged = false;
249 SmallVector NewOperands;
250 unsigned NumOperands = C->getNumOperands();
251
252 // Check if any element is or uses a global variable in GVMap, and thus
253 // converted to another value.
254 for (unsigned i = 0; i < NumOperands; ++i) {
255 Value *Operand = C->getOperand(i);
256 Value *NewOperand = remapConstant(M, F, cast(Operand), Builder);
257 OperandChanged |= Operand != NewOperand;
258 NewOperands.push_back(NewOperand);
259 }
260
261 // If none of the elements has been modified, return C as it is.
262 if (!OperandChanged) {
263 return C;
264 }
265
266 // If any of the elements has been modified, construct the equivalent
267 // vector or aggregate value with a set instructions and the converted
268 // elements.
269 Value *NewValue = UndefValue::get(C->getType());
270 if (isa(C)) {
271 for (unsigned i = 0; i < NumOperands; ++i) {
272 Value *Idx = ConstantInt::get(Type::getInt32Ty(M->getContext()), i);
273 NewValue = Builder.CreateInsertElement(NewValue, NewOperands[i], Idx);
274 }
275 } else {
276 for (unsigned i = 0; i < NumOperands; ++i) {
277 NewValue =
278 Builder.CreateInsertValue(NewValue, NewOperands[i], makeArrayRef(i));
279 }
280 }
281
282 return NewValue;
283 }
284
285 Value *GenericToNVVM::remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
286 IRBuilder<> &Builder) {
287 bool OperandChanged = false;
288 SmallVector NewOperands;
289 unsigned NumOperands = C->getNumOperands();
290
291 // Check if any operand is or uses a global variable in GVMap, and thus
292 // converted to another value.
293 for (unsigned i = 0; i < NumOperands; ++i) {
294 Value *Operand = C->getOperand(i);
295 Value *NewOperand = remapConstant(M, F, cast(Operand), Builder);
296 OperandChanged |= Operand != NewOperand;
297 NewOperands.push_back(NewOperand);
298 }
299
300 // If none of the operands has been modified, return C as it is.
301 if (!OperandChanged) {
302 return C;
303 }
304
305 // If any of the operands has been modified, construct the instruction with
306 // the converted operands.
307 unsigned Opcode = C->getOpcode();
308 switch (Opcode) {
309 case Instruction::ICmp:
310 // CompareConstantExpr (icmp)
311 return Builder.CreateICmp(CmpInst::Predicate(C->getPredicate()),
312 NewOperands[0], NewOperands[1]);
313 case Instruction::FCmp:
314 // CompareConstantExpr (fcmp)
315 assert(false && "Address space conversion should have no effect "
316 "on float point CompareConstantExpr (fcmp)!");
317 return C;
318 case Instruction::ExtractElement:
319 // ExtractElementConstantExpr
320 return Builder.CreateExtractElement(NewOperands[0], NewOperands[1]);
321 case Instruction::InsertElement:
322 // InsertElementConstantExpr
323 return Builder.CreateInsertElement(NewOperands[0], NewOperands[1],
324 NewOperands[2]);
325 case Instruction::ShuffleVector:
326 // ShuffleVector
327 return Builder.CreateShuffleVector(NewOperands[0], NewOperands[1],
328 NewOperands[2]);
329 case Instruction::ExtractValue:
330 // ExtractValueConstantExpr
331 return Builder.CreateExtractValue(NewOperands[0], C->getIndices());
332 case Instruction::InsertValue:
333 // InsertValueConstantExpr
334 return Builder.CreateInsertValue(NewOperands[0], NewOperands[1],
335 C->getIndices());
336 case Instruction::GetElementPtr:
337 // GetElementPtrConstantExpr
338 return cast(C)->isInBounds()
339 ? Builder.CreateGEP(
340 NewOperands[0],
341 makeArrayRef(&NewOperands[1], NumOperands - 1))
342 : Builder.CreateInBoundsGEP(
343 NewOperands[0],
344 makeArrayRef(&NewOperands[1], NumOperands - 1));
345 case Instruction::Select:
346 // SelectConstantExpr
347 return Builder.CreateSelect(NewOperands[0], NewOperands[1], NewOperands[2]);
348 default:
349 // BinaryConstantExpr
350 if (Instruction::isBinaryOp(Opcode)) {
351 return Builder.CreateBinOp(Instruction::BinaryOps(C->getOpcode()),
352 NewOperands[0], NewOperands[1]);
353 }
354 // UnaryConstantExpr
355 if (Instruction::isCast(Opcode)) {
356 return Builder.CreateCast(Instruction::CastOps(C->getOpcode()),
357 NewOperands[0], C->getType());
358 }
359 assert(false && "GenericToNVVM encountered an unsupported ConstantExpr");
360 return C;
361 }
362 }
363
364 void GenericToNVVM::remapNamedMDNode(Module *M, NamedMDNode *N) {
365
366 bool OperandChanged = false;
367 SmallVector NewOperands;
368 unsigned NumOperands = N->getNumOperands();
369
370 // Check if any operand is or contains a global variable in GVMap, and thus
371 // converted to another value.
372 for (unsigned i = 0; i < NumOperands; ++i) {
373 MDNode *Operand = N->getOperand(i);
374 MDNode *NewOperand = remapMDNode(M, Operand);
375 OperandChanged |= Operand != NewOperand;
376 NewOperands.push_back(NewOperand);
377 }
378
379 // If none of the operands has been modified, return immediately.
380 if (!OperandChanged) {
381 return;
382 }
383
384 // Replace the old operands with the new operands.
385 N->dropAllReferences();
386 for (SmallVector::iterator I = NewOperands.begin(),
387 E = NewOperands.end();
388 I != E; ++I) {
389 N->addOperand(*I);
390 }
391 }
392
393 MDNode *GenericToNVVM::remapMDNode(Module *M, MDNode *N) {
394
395 bool OperandChanged = false;
396 SmallVector NewOperands;
397 unsigned NumOperands = N->getNumOperands();
398
399 // Check if any operand is or contains a global variable in GVMap, and thus
400 // converted to another value.
401 for (unsigned i = 0; i < NumOperands; ++i) {
402 Value *Operand = N->getOperand(i);
403 Value *NewOperand = Operand;
404 if (Operand) {
405 if (isa(Operand)) {
406 GVMapTy::iterator I = GVMap.find(cast(Operand));
407 if (I != GVMap.end()) {
408 NewOperand = I->second;
409 if (++i < NumOperands) {
410 NewOperands.push_back(NewOperand);
411 // Address space of the global variable follows the global variable
412 // in the global variable debug info (see createGlobalVariable in
413 // lib/Analysis/DIBuilder.cpp).
414 NewOperand =
415 ConstantInt::get(Type::getInt32Ty(M->getContext()),
416 I->second->getType()->getAddressSpace());
417 }
418 }
419 } else if (isa(Operand)) {
420 NewOperand = remapMDNode(M, cast(Operand));
421 }
422 }
423 OperandChanged |= Operand != NewOperand;
424 NewOperands.push_back(NewOperand);
425 }
426
427 // If none of the operands has been modified, return N as it is.
428 if (!OperandChanged) {
429 return N;
430 }
431
432 // If any of the operands has been modified, create a new MDNode with the new
433 // operands.
434 return MDNode::get(M->getContext(), makeArrayRef(NewOperands));
435 }
15091509 defm cvta_local : NG_TO_G<"local", int_nvvm_ptr_local_to_gen>;
15101510 defm cvta_shared : NG_TO_G<"shared", int_nvvm_ptr_shared_to_gen>;
15111511 defm cvta_global : NG_TO_G<"global", int_nvvm_ptr_global_to_gen>;
1512 defm cvta_const : NG_TO_G<"const", int_nvvm_ptr_constant_to_gen>;
15121513
15131514 defm cvta_to_local : G_TO_NG<"local", int_nvvm_ptr_gen_to_local>;
15141515 defm cvta_to_shared : G_TO_NG<"shared", int_nvvm_ptr_gen_to_shared>;
15151516 defm cvta_to_global : G_TO_NG<"global", int_nvvm_ptr_gen_to_global>;
1516
1517 def cvta_const : NVPTXInst<(outs Int32Regs:$result), (ins Int32Regs:$src),
1518 "mov.u32 \t$result, $src;",
1519 [(set Int32Regs:$result, (int_nvvm_ptr_constant_to_gen Int32Regs:$src))]>;
1520 def cvta_const_64 : NVPTXInst<(outs Int64Regs:$result), (ins Int64Regs:$src),
1521 "mov.u64 \t$result, $src;",
1522 [(set Int64Regs:$result, (int_nvvm_ptr_constant_to_gen Int64Regs:$src))]>;
1523
1524
1525
1526 // @TODO: Revisit this. There is a type
1527 // contradiction between iPTRAny and iPTR for the def.
1528 /*def cvta_const_addr : NVPTXInst<(outs Int32Regs:$result), (ins imemAny:$src),
1529 "mov.u32 \t$result, $src;",
1530 [(set Int32Regs:$result, (int_nvvm_ptr_constant_to_gen
1531 (Wrapper tglobaladdr:$src)))]>;
1532 def cvta_const_addr_64 : NVPTXInst<(outs Int64Regs:$result), (ins imemAny:$src),
1533 "mov.u64 \t$result, $src;",
1534 [(set Int64Regs:$result, (int_nvvm_ptr_constant_to_gen
1535 (Wrapper tglobaladdr:$src)))]>;*/
1536
1537
1538 def cvta_to_const : NVPTXInst<(outs Int32Regs:$result), (ins Int32Regs:$src),
1539 "mov.u32 \t$result, $src;",
1540 [(set Int32Regs:$result, (int_nvvm_ptr_gen_to_constant Int32Regs:$src))]>;
1541 def cvta_to_const_64 : NVPTXInst<(outs Int64Regs:$result), (ins Int64Regs:$src),
1542 "mov.u64 \t$result, $src;",
1543 [(set Int64Regs:$result, (int_nvvm_ptr_gen_to_constant Int64Regs:$src))]>;
1517 defm cvta_to_const : G_TO_NG<"const", int_nvvm_ptr_gen_to_constant>;
15441518
15451519
15461520 // nvvm.ptr.gen.to.param
4848
4949 namespace llvm {
5050 void initializeNVVMReflectPass(PassRegistry&);
51 void initializeGenericToNVVMPass(PassRegistry&);
5152 }
5253
5354 extern "C" void LLVMInitializeNVPTXTarget() {
6162 // FIXME: This pass is really intended to be invoked during IR optimization,
6263 // but it's very NVPTX-specific.
6364 initializeNVVMReflectPass(*PassRegistry::getPassRegistry());
65 initializeGenericToNVVMPass(*PassRegistry::getPassRegistry());
6466 }
6567
6668 NVPTXTargetMachine::NVPTXTargetMachine(
99101 return getTM();
100102 }
101103
104 virtual void addIRPasses();
102105 virtual bool addInstSelector();
103106 virtual bool addPreRegAlloc();
104107 };
107110 TargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) {
108111 NVPTXPassConfig *PassConfig = new NVPTXPassConfig(this, PM);
109112 return PassConfig;
113 }
114
115 void NVPTXPassConfig::addIRPasses() {
116 TargetPassConfig::addIRPasses();
117 addPass(createGenericToNVVMPass());
110118 }
111119
112120 bool NVPTXPassConfig::addInstSelector() {
0 ; RUN: llc < %s -march=nvptx -mcpu=sm_20 -drvcuda | FileCheck %s
1
2 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
3
4 ; Ensure global variables in address space 0 are promoted to address space 1
5
6 ; CHECK: .global .align 4 .u32 myglobal = 42;
7 @myglobal = internal global i32 42, align 4
8 ; CHECK: .global .align 4 .u32 myconst = 42;
9 @myconst = internal constant i32 42, align 4
10
11
12 define void @foo(i32* %a, i32* %b) {
13 ; CHECK: cvta.global.u32
14 %ld1 = load i32* @myglobal
15 ; CHECK: cvta.global.u32
16 %ld2 = load i32* @myconst
17 store i32 %ld1, i32* %a
18 store i32 %ld2, i32* %b
19 ret void
20 }
21
22
23 !nvvm.annotations = !{!0}
24 !0 = metadata !{void (i32*, i32*)* @foo, metadata !"kernel", i32 1}