comparison lib/Target/NVPTX/NVVMReflect.cpp @ 95:afa8332a0e37 LLVM3.8

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Tue, 13 Oct 2015 17:48:58 +0900
parents 54457678186b
children 1172e4bd9c6f
comparison
equal deleted inserted replaced
84:f3e34b893a5f 95:afa8332a0e37
27 #include "llvm/IR/Type.h" 27 #include "llvm/IR/Type.h"
28 #include "llvm/Pass.h" 28 #include "llvm/Pass.h"
29 #include "llvm/Support/CommandLine.h" 29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/raw_os_ostream.h" 31 #include "llvm/Support/raw_os_ostream.h"
32 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Transforms/Scalar.h" 33 #include "llvm/Transforms/Scalar.h"
33 #include <map> 34 #include <map>
34 #include <sstream> 35 #include <sstream>
35 #include <string> 36 #include <string>
36 #include <vector> 37 #include <vector>
106 /// using "=" as the delimiter. 107 /// using "=" as the delimiter.
107 void NVVMReflect::setVarMap() { 108 void NVVMReflect::setVarMap() {
108 for (unsigned i = 0, e = ReflectList.size(); i != e; ++i) { 109 for (unsigned i = 0, e = ReflectList.size(); i != e; ++i) {
109 DEBUG(dbgs() << "Option : " << ReflectList[i] << "\n"); 110 DEBUG(dbgs() << "Option : " << ReflectList[i] << "\n");
110 SmallVector<StringRef, 4> NameValList; 111 SmallVector<StringRef, 4> NameValList;
111 StringRef(ReflectList[i]).split(NameValList, ","); 112 StringRef(ReflectList[i]).split(NameValList, ',');
112 for (unsigned j = 0, ej = NameValList.size(); j != ej; ++j) { 113 for (unsigned j = 0, ej = NameValList.size(); j != ej; ++j) {
113 SmallVector<StringRef, 2> NameValPair; 114 SmallVector<StringRef, 2> NameValPair;
114 NameValList[j].split(NameValPair, "="); 115 NameValList[j].split(NameValPair, '=');
115 assert(NameValPair.size() == 2 && "name=val expected"); 116 assert(NameValPair.size() == 2 && "name=val expected");
116 std::stringstream ValStream(NameValPair[1]); 117 std::stringstream ValStream(NameValPair[1]);
117 int Val; 118 int Val;
118 ValStream >> Val; 119 ValStream >> Val;
119 assert((!(ValStream.fail())) && "integer value expected"); 120 assert((!(ValStream.fail())) && "integer value expected");
135 // Each of them should a CallInst with a ConstantArray argument. 136 // Each of them should a CallInst with a ConstantArray argument.
136 // First validate that. If the c-string corresponding to the 137 // First validate that. If the c-string corresponding to the
137 // ConstantArray can be found successfully, see if it can be 138 // ConstantArray can be found successfully, see if it can be
138 // found in VarMap. If so, replace the uses of CallInst with the 139 // found in VarMap. If so, replace the uses of CallInst with the
139 // value found in VarMap. If not, replace the use with value 0. 140 // value found in VarMap. If not, replace the use with value 0.
141
142 // IR for __nvvm_reflect calls differs between CUDA versions:
143 // CUDA 6.5 and earlier uses this sequence:
144 // %ptr = tail call i8* @llvm.nvvm.ptr.constant.to.gen.p0i8.p4i8
145 // (i8 addrspace(4)* getelementptr inbounds
146 // ([8 x i8], [8 x i8] addrspace(4)* @str, i32 0, i32 0))
147 // %reflect = tail call i32 @__nvvm_reflect(i8* %ptr)
148 //
149 // Value returned by Sym->getOperand(0) is a Constant with a
150 // ConstantDataSequential operand which can be converted to string and used
151 // for lookup.
152 //
153 // CUDA 7.0 does it slightly differently:
154 // %reflect = call i32 @__nvvm_reflect(i8* addrspacecast
155 // (i8 addrspace(1)* getelementptr inbounds
156 // ([8 x i8], [8 x i8] addrspace(1)* @str, i32 0, i32 0) to i8*))
157 //
158 // In this case, we get a Constant with a GlobalVariable operand and we need
159 // to dig deeper to find its initializer with the string we'll use for lookup.
160
140 for (User *U : ReflectFunction->users()) { 161 for (User *U : ReflectFunction->users()) {
141 assert(isa<CallInst>(U) && "Only a call instruction can use _reflect"); 162 assert(isa<CallInst>(U) && "Only a call instruction can use _reflect");
142 CallInst *Reflect = cast<CallInst>(U); 163 CallInst *Reflect = cast<CallInst>(U);
143 164
144 assert((Reflect->getNumOperands() == 2) && 165 assert((Reflect->getNumOperands() == 2) &&
156 const ConstantExpr *GEP = cast<ConstantExpr>(Str); 177 const ConstantExpr *GEP = cast<ConstantExpr>(Str);
157 178
158 const Value *Sym = GEP->getOperand(0); 179 const Value *Sym = GEP->getOperand(0);
159 assert(isa<Constant>(Sym) && "Format of _reflect function not recognized"); 180 assert(isa<Constant>(Sym) && "Format of _reflect function not recognized");
160 181
161 const Constant *SymStr = cast<Constant>(Sym); 182 const Value *Operand = cast<Constant>(Sym)->getOperand(0);
162 183 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand)) {
163 assert(isa<ConstantDataSequential>(SymStr->getOperand(0)) && 184 // For CUDA-7.0 style __nvvm_reflect calls we need to find operand's
185 // initializer.
186 assert(GV->hasInitializer() &&
187 "Format of _reflect function not recognized");
188 const Constant *Initializer = GV->getInitializer();
189 Operand = Initializer;
190 }
191
192 assert(isa<ConstantDataSequential>(Operand) &&
164 "Format of _reflect function not recognized"); 193 "Format of _reflect function not recognized");
165 194 assert(cast<ConstantDataSequential>(Operand)->isCString() &&
166 assert(cast<ConstantDataSequential>(SymStr->getOperand(0))->isCString() &&
167 "Format of _reflect function not recognized"); 195 "Format of _reflect function not recognized");
168 196
169 std::string ReflectArg = 197 std::string ReflectArg =
170 cast<ConstantDataSequential>(SymStr->getOperand(0))->getAsString(); 198 cast<ConstantDataSequential>(Operand)->getAsString();
171 199
172 ReflectArg = ReflectArg.substr(0, ReflectArg.size() - 1); 200 ReflectArg = ReflectArg.substr(0, ReflectArg.size() - 1);
173 DEBUG(dbgs() << "Arg of _reflect : " << ReflectArg << "\n"); 201 DEBUG(dbgs() << "Arg of _reflect : " << ReflectArg << "\n");
174 202
175 int ReflectVal = 0; // The default value is 0 203 int ReflectVal = 0; // The default value is 0