Mercurial > hg > CbC > CbC_llvm
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 |