blob: 30195f74720db5f12b5a03e8490cb067882cc353 [file] [log] [blame]
David Neto22f144c2017-06-12 14:26:21 -04001// Copyright 2017 The Clspv Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifdef _MSC_VER
16#pragma warning(push, 0)
17#endif
18
David Neto156783e2017-07-05 15:39:41 -040019#include <cassert>
David Neto22f144c2017-06-12 14:26:21 -040020#include <clspv/Passes.h>
21
22#include <llvm/ADT/StringSwitch.h>
23#include <llvm/ADT/UniqueVector.h>
24#include <llvm/Analysis/LoopInfo.h>
25#include <llvm/IR/Constants.h>
26#include <llvm/IR/Dominators.h>
27#include <llvm/IR/Instructions.h>
28#include <llvm/IR/Metadata.h>
29#include <llvm/IR/Module.h>
30#include <llvm/Pass.h>
31#include <llvm/Support/raw_ostream.h>
32#include <llvm/Transforms/Utils/Cloning.h>
33
34#include <spirv/1.0/spirv.hpp>
35#include <clspv/AddressSpace.h>
36#include <clspv/spirv_c_strings.hpp>
37#include <clspv/spirv_glsl.hpp>
38
39#include <list>
David Neto0676e6f2017-07-11 18:47:44 -040040#include <iomanip>
41#include <sstream>
David Neto22f144c2017-06-12 14:26:21 -040042
43#if defined(_MSC_VER)
44#pragma warning(pop)
45#endif
46
47using namespace llvm;
48using namespace clspv;
David Neto156783e2017-07-05 15:39:41 -040049using namespace mdconst;
David Neto22f144c2017-06-12 14:26:21 -040050
51namespace {
52enum SPIRVOperandType {
53 NUMBERID,
54 LITERAL_INTEGER,
55 LITERAL_STRING,
56 LITERAL_FLOAT
57};
58
59struct SPIRVOperand {
60 explicit SPIRVOperand(SPIRVOperandType Ty, uint32_t Num)
61 : Type(Ty), LiteralNum(1, Num) {}
62 explicit SPIRVOperand(SPIRVOperandType Ty, const char *Str)
63 : Type(Ty), LiteralStr(Str) {}
64 explicit SPIRVOperand(SPIRVOperandType Ty, StringRef Str)
65 : Type(Ty), LiteralStr(Str) {}
66 explicit SPIRVOperand(SPIRVOperandType Ty, ArrayRef<uint32_t> NumVec)
67 : Type(Ty), LiteralNum(NumVec.begin(), NumVec.end()) {}
68
69 SPIRVOperandType getType() { return Type; };
70 uint32_t getNumID() { return LiteralNum[0]; };
71 std::string getLiteralStr() { return LiteralStr; };
72 ArrayRef<uint32_t> getLiteralNum() { return LiteralNum; };
73
74private:
75 SPIRVOperandType Type;
76 std::string LiteralStr;
77 SmallVector<uint32_t, 4> LiteralNum;
78};
79
80struct SPIRVInstruction {
81 explicit SPIRVInstruction(uint16_t WCount, spv::Op Opc, uint32_t ResID,
82 ArrayRef<SPIRVOperand *> Ops)
83 : WordCount(WCount), Opcode(static_cast<uint16_t>(Opc)), ResultID(ResID),
84 Operands(Ops.begin(), Ops.end()) {}
85
86 uint16_t getWordCount() const { return WordCount; }
87 uint16_t getOpcode() const { return Opcode; }
88 uint32_t getResultID() const { return ResultID; }
89 ArrayRef<SPIRVOperand *> getOperands() const { return Operands; }
90
91private:
92 uint16_t WordCount;
93 uint16_t Opcode;
94 uint32_t ResultID;
95 SmallVector<SPIRVOperand *, 4> Operands;
96};
97
98struct SPIRVProducerPass final : public ModulePass {
99 typedef std::vector<SPIRVOperand *> SPIRVOperandList;
100 typedef DenseMap<Type *, uint32_t> TypeMapType;
101 typedef UniqueVector<Type *> TypeList;
102 typedef DenseMap<Value *, uint32_t> ValueMapType;
103 typedef std::vector<Value *> ValueList;
104 typedef std::vector<std::pair<Value *, uint32_t>> EntryPointVecType;
105 typedef std::list<SPIRVInstruction *> SPIRVInstructionList;
106 typedef std::vector<
107 std::tuple<Value *, SPIRVInstructionList::iterator, uint32_t>>
108 DeferredInstVecType;
109 typedef DenseMap<FunctionType *, std::pair<FunctionType *, uint32_t>>
110 GlobalConstFuncMapType;
111
112 explicit SPIRVProducerPass(raw_pwrite_stream &out,
David Netoc2c368d2017-06-30 16:50:17 -0400113 raw_ostream &descriptor_map_out,
David Neto0676e6f2017-07-11 18:47:44 -0400114 ArrayRef<unsigned> samplerMap, bool outputAsm,
115 bool outputCInitList)
David Netoc2c368d2017-06-30 16:50:17 -0400116 : ModulePass(ID), samplerMap(samplerMap), out(out),
David Neto0676e6f2017-07-11 18:47:44 -0400117 binaryTempOut(binaryTempUnderlyingVector), binaryOut(&out),
David Netoc2c368d2017-06-30 16:50:17 -0400118 descriptorMapOut(descriptor_map_out), outputAsm(outputAsm),
David Neto0676e6f2017-07-11 18:47:44 -0400119 outputCInitList(outputCInitList), patchBoundOffset(0), nextID(1),
120 OpExtInstImportID(0), HasVariablePointers(false), SamplerTy(nullptr) {}
David Neto22f144c2017-06-12 14:26:21 -0400121
122 void getAnalysisUsage(AnalysisUsage &AU) const override {
123 AU.addRequired<DominatorTreeWrapperPass>();
124 AU.addRequired<LoopInfoWrapperPass>();
125 }
126
127 virtual bool runOnModule(Module &module) override;
128
129 // output the SPIR-V header block
130 void outputHeader();
131
132 // patch the SPIR-V header block
133 void patchHeader();
134
135 uint32_t lookupType(Type *Ty) {
136 if (Ty->isPointerTy() &&
137 (Ty->getPointerAddressSpace() != AddressSpace::UniformConstant)) {
138 auto PointeeTy = Ty->getPointerElementType();
139 if (PointeeTy->isStructTy() &&
140 dyn_cast<StructType>(PointeeTy)->isOpaque()) {
141 Ty = PointeeTy;
142 }
143 }
144
145 if (0 == TypeMap.count(Ty)) {
146 Ty->print(errs());
147 llvm_unreachable("Unhandled type!");
148 }
149
150 return TypeMap[Ty];
151 }
152 TypeMapType &getImageTypeMap() { return ImageTypeMap; }
153 TypeList &getTypeList() { return Types; };
154 ValueList &getConstantList() { return Constants; };
155 ValueMapType &getValueMap() { return ValueMap; }
156 ValueMapType &getAllocatedValueMap() { return AllocatedValueMap; }
157 SPIRVInstructionList &getSPIRVInstList() { return SPIRVInsts; };
158 ValueToValueMapTy &getArgumentGVMap() { return ArgumentGVMap; };
159 ValueMapType &getArgumentGVIDMap() { return ArgumentGVIDMap; };
160 EntryPointVecType &getEntryPointVec() { return EntryPointVec; };
161 DeferredInstVecType &getDeferredInstVec() { return DeferredInstVec; };
162 ValueList &getEntryPointInterfacesVec() { return EntryPointInterfacesVec; };
163 uint32_t &getOpExtInstImportID() { return OpExtInstImportID; };
164 std::vector<uint32_t> &getBuiltinDimVec() { return BuiltinDimensionVec; };
165 bool hasVariablePointers() { return true; /* We use StorageBuffer everywhere */ };
166 void setVariablePointers(bool Val) { HasVariablePointers = Val; };
167 ArrayRef<unsigned> &getSamplerMap() { return samplerMap; }
168 GlobalConstFuncMapType &getGlobalConstFuncTypeMap() {
169 return GlobalConstFuncTypeMap;
170 }
171 SmallPtrSet<Value *, 16> &getGlobalConstArgSet() {
172 return GlobalConstArgumentSet;
173 }
David Neto1a1a0582017-07-07 12:01:44 -0400174 TypeList &getPointerTypesNeedingArrayStride() {
175 return PointerTypesNeedingArrayStride;
176 }
David Neto22f144c2017-06-12 14:26:21 -0400177
178 void GenerateLLVMIRInfo(Module &M);
179 bool FindExtInst(Module &M);
180 void FindTypePerGlobalVar(GlobalVariable &GV);
181 void FindTypePerFunc(Function &F);
182 void FindType(Type *Ty);
183 void FindConstantPerGlobalVar(GlobalVariable &GV);
184 void FindConstantPerFunc(Function &F);
185 void FindConstant(Value *V);
186 void GenerateExtInstImport();
187 void GenerateSPIRVTypes(const DataLayout &DL);
188 void GenerateSPIRVConstants();
189 void GenerateModuleInfo();
190 void GenerateGlobalVar(GlobalVariable &GV);
191 void GenerateSamplers(Module &M);
192 void GenerateFuncPrologue(Function &F);
193 void GenerateFuncBody(Function &F);
194 void GenerateInstForArg(Function &F);
195 spv::Op GetSPIRVCmpOpcode(CmpInst *CmpI);
196 spv::Op GetSPIRVCastOpcode(Instruction &I);
197 spv::Op GetSPIRVBinaryOpcode(Instruction &I);
198 void GenerateInstruction(Instruction &I);
199 void GenerateFuncEpilogue();
200 void HandleDeferredInstruction();
David Neto1a1a0582017-07-07 12:01:44 -0400201 void HandleDeferredDecorations(const DataLayout& DL);
David Neto22f144c2017-06-12 14:26:21 -0400202 bool is4xi8vec(Type *Ty) const;
203 spv::StorageClass GetStorageClass(unsigned AddrSpace) const;
204 spv::BuiltIn GetBuiltin(StringRef globalVarName) const;
205 glsl::ExtInst getExtInstEnum(StringRef Name);
206 void PrintResID(SPIRVInstruction *Inst);
207 void PrintOpcode(SPIRVInstruction *Inst);
208 void PrintOperand(SPIRVOperand *Op);
209 void PrintCapability(SPIRVOperand *Op);
210 void PrintExtInst(SPIRVOperand *Op);
211 void PrintAddrModel(SPIRVOperand *Op);
212 void PrintMemModel(SPIRVOperand *Op);
213 void PrintExecModel(SPIRVOperand *Op);
214 void PrintExecMode(SPIRVOperand *Op);
215 void PrintSourceLanguage(SPIRVOperand *Op);
216 void PrintFuncCtrl(SPIRVOperand *Op);
217 void PrintStorageClass(SPIRVOperand *Op);
218 void PrintDecoration(SPIRVOperand *Op);
219 void PrintBuiltIn(SPIRVOperand *Op);
220 void PrintSelectionControl(SPIRVOperand *Op);
221 void PrintLoopControl(SPIRVOperand *Op);
222 void PrintDimensionality(SPIRVOperand *Op);
223 void PrintImageFormat(SPIRVOperand *Op);
224 void PrintMemoryAccess(SPIRVOperand *Op);
225 void PrintImageOperandsType(SPIRVOperand *Op);
226 void WriteSPIRVAssembly();
227 void WriteOneWord(uint32_t Word);
228 void WriteResultID(SPIRVInstruction *Inst);
229 void WriteWordCountAndOpcode(SPIRVInstruction *Inst);
230 void WriteOperand(SPIRVOperand *Op);
231 void WriteSPIRVBinary();
232
233private:
234 static char ID;
235 ArrayRef<unsigned> samplerMap;
236 raw_pwrite_stream &out;
David Neto0676e6f2017-07-11 18:47:44 -0400237
238 // TODO(dneto): Wouldn't it be better to always just emit a binary, and then
239 // convert to other formats on demand?
240
241 // When emitting a C initialization list, the WriteSPIRVBinary method
242 // will actually write its words to this vector via binaryTempOut.
243 SmallVector<char, 100> binaryTempUnderlyingVector;
244 raw_svector_ostream binaryTempOut;
245
246 // Binary output writes to this stream, which might be |out| or
247 // |binaryTempOut|. It's the latter when we really want to write a C
248 // initializer list.
249 raw_pwrite_stream* binaryOut;
David Netoc2c368d2017-06-30 16:50:17 -0400250 raw_ostream &descriptorMapOut;
David Neto22f144c2017-06-12 14:26:21 -0400251 const bool outputAsm;
David Neto0676e6f2017-07-11 18:47:44 -0400252 const bool outputCInitList; // If true, output look like {0x7023, ... , 5}
David Neto22f144c2017-06-12 14:26:21 -0400253 uint64_t patchBoundOffset;
254 uint32_t nextID;
255
256 TypeMapType TypeMap;
257 TypeMapType ImageTypeMap;
258 TypeList Types;
259 ValueList Constants;
260 ValueMapType ValueMap;
261 ValueMapType AllocatedValueMap;
262 SPIRVInstructionList SPIRVInsts;
263 ValueToValueMapTy ArgumentGVMap;
264 ValueMapType ArgumentGVIDMap;
265 EntryPointVecType EntryPointVec;
266 DeferredInstVecType DeferredInstVec;
267 ValueList EntryPointInterfacesVec;
268 uint32_t OpExtInstImportID;
269 std::vector<uint32_t> BuiltinDimensionVec;
270 bool HasVariablePointers;
271 Type *SamplerTy;
272 GlobalConstFuncMapType GlobalConstFuncTypeMap;
273 SmallPtrSet<Value *, 16> GlobalConstArgumentSet;
David Neto1a1a0582017-07-07 12:01:44 -0400274 // An ordered set of pointer types of Base arguments to OpPtrAccessChain,
275 // and which point into transparent memory (StorageBuffer storage class).
276 // These will require an ArrayStride decoration.
277 // See SPV_KHR_variable_pointers rev 13.
278 TypeList PointerTypesNeedingArrayStride;
David Neto22f144c2017-06-12 14:26:21 -0400279};
280
281char SPIRVProducerPass::ID;
282}
283
284namespace clspv {
285ModulePass *createSPIRVProducerPass(raw_pwrite_stream &out,
David Netoc2c368d2017-06-30 16:50:17 -0400286 raw_ostream &descriptor_map_out,
David Neto22f144c2017-06-12 14:26:21 -0400287 ArrayRef<unsigned> samplerMap,
David Neto0676e6f2017-07-11 18:47:44 -0400288 bool outputAsm,
289 bool outputCInitList) {
290 return new SPIRVProducerPass(out, descriptor_map_out, samplerMap, outputAsm, outputCInitList);
David Neto22f144c2017-06-12 14:26:21 -0400291}
David Netoc2c368d2017-06-30 16:50:17 -0400292} // namespace clspv
David Neto22f144c2017-06-12 14:26:21 -0400293
294bool SPIRVProducerPass::runOnModule(Module &module) {
David Neto0676e6f2017-07-11 18:47:44 -0400295 binaryOut = outputCInitList ? &binaryTempOut : &out;
296
David Neto22f144c2017-06-12 14:26:21 -0400297 // SPIR-V always begins with its header information
298 outputHeader();
299
300 // Gather information from the LLVM IR that we require.
301 GenerateLLVMIRInfo(module);
302
303 // If we are using a sampler map, find the type of the sampler.
304 if (0 < getSamplerMap().size()) {
305 auto SamplerStructTy = module.getTypeByName("opencl.sampler_t");
306 if (!SamplerStructTy) {
307 SamplerStructTy =
308 StructType::create(module.getContext(), "opencl.sampler_t");
309 }
310
311 SamplerTy = SamplerStructTy->getPointerTo(AddressSpace::UniformConstant);
312
313 FindType(SamplerTy);
314 }
315
316 // Collect information on global variables too.
317 for (GlobalVariable &GV : module.globals()) {
318 // If the GV is one of our special __spirv_* variables, remove the
319 // initializer as it was only placed there to force LLVM to not throw the
320 // value away.
321 if (GV.getName().startswith("__spirv_")) {
322 GV.setInitializer(nullptr);
323 }
324
325 // Collect types' information from global variable.
326 FindTypePerGlobalVar(GV);
327
328 // Collect constant information from global variable.
329 FindConstantPerGlobalVar(GV);
330
331 // If the variable is an input, entry points need to know about it.
332 if (AddressSpace::Input == GV.getType()->getPointerAddressSpace()) {
333 getEntryPointInterfacesVec().push_back(&GV);
334 }
335 }
336
337 // If there are extended instructions, generate OpExtInstImport.
338 if (FindExtInst(module)) {
339 GenerateExtInstImport();
340 }
341
342 // Generate SPIRV instructions for types.
343 const DataLayout &DL = module.getDataLayout();
344 GenerateSPIRVTypes(DL);
345
346 // Generate SPIRV constants.
347 GenerateSPIRVConstants();
348
349 // If we have a sampler map, we might have literal samplers to generate.
350 if (0 < getSamplerMap().size()) {
351 GenerateSamplers(module);
352 }
353
354 // Generate SPIRV variables.
355 for (GlobalVariable &GV : module.globals()) {
356 GenerateGlobalVar(GV);
357 }
358
359 // Generate SPIRV instructions for each function.
360 for (Function &F : module) {
361 if (F.isDeclaration()) {
362 continue;
363 }
364
365 // Generate Function Prologue.
366 GenerateFuncPrologue(F);
367
368 // Generate SPIRV instructions for function body.
369 GenerateFuncBody(F);
370
371 // Generate Function Epilogue.
372 GenerateFuncEpilogue();
373 }
374
375 HandleDeferredInstruction();
David Neto1a1a0582017-07-07 12:01:44 -0400376 HandleDeferredDecorations(DL);
David Neto22f144c2017-06-12 14:26:21 -0400377
378 // Generate SPIRV module information.
379 GenerateModuleInfo();
380
381 if (outputAsm) {
382 WriteSPIRVAssembly();
383 } else {
384 WriteSPIRVBinary();
385 }
386
387 // We need to patch the SPIR-V header to set bound correctly.
388 patchHeader();
David Neto0676e6f2017-07-11 18:47:44 -0400389
390 if (outputCInitList) {
391 bool first = true;
392 int word_index = 0;
393 std::ostringstream os;
394
395 os << std::hex;
396 auto emit_word = [&os, &word_index, &first](uint32_t word) {
397 if (!first)
398 os << ',';
399 if (word_index > 0)
400 os << ((word_index & 3) ? ' ' : '\n');
401 os << "0x" << word;
402 ++word_index;
403 first = false;
404 };
405
406 os << "{";
407 const StringRef str = binaryTempOut.str();
408 for (unsigned i = 0; i < str.size() / 4; i++) {
409 emit_word(uint32_t(str[4 * i]) | (uint32_t(str[4 * i + 1]) << 8) |
410 (uint32_t(str[4 * i + 2]) << 16) |
411 (uint32_t(str[4 * i + 3]) << 24));
412 }
413 os << "}\n";
414 out << os.str();
415 }
416
David Neto22f144c2017-06-12 14:26:21 -0400417 return false;
418}
419
420void SPIRVProducerPass::outputHeader() {
421 if (outputAsm) {
422 // for ASM output the header goes into 5 comments at the beginning of the
423 // file
424 out << "; SPIR-V\n";
425
426 // the major version number is in the 2nd highest byte
427 const uint32_t major = (spv::Version >> 16) & 0xFF;
428
429 // the minor version number is in the 2nd lowest byte
430 const uint32_t minor = (spv::Version >> 8) & 0xFF;
431 out << "; Version: " << major << "." << minor << "\n";
432
433 // use Codeplay's vendor ID
434 out << "; Generator: Codeplay; 0\n";
435
436 out << "; Bound: ";
437
438 // we record where we need to come back to and patch in the bound value
439 patchBoundOffset = out.tell();
440
441 // output one space per digit for the max size of a 32 bit unsigned integer
442 // (which is the maximum ID we could possibly be using)
443 for (uint32_t i = std::numeric_limits<uint32_t>::max(); 0 != i; i /= 10) {
444 out << " ";
445 }
446
447 out << "\n";
448
449 out << "; Schema: 0\n";
450 } else {
David Neto0676e6f2017-07-11 18:47:44 -0400451 binaryOut->write(reinterpret_cast<const char *>(&spv::MagicNumber),
David Neto22f144c2017-06-12 14:26:21 -0400452 sizeof(spv::MagicNumber));
David Neto0676e6f2017-07-11 18:47:44 -0400453 binaryOut->write(reinterpret_cast<const char *>(&spv::Version),
David Neto22f144c2017-06-12 14:26:21 -0400454 sizeof(spv::Version));
455
456 // use Codeplay's vendor ID
457 const uint32_t vendor = 3 << 16;
David Neto0676e6f2017-07-11 18:47:44 -0400458 binaryOut->write(reinterpret_cast<const char *>(&vendor), sizeof(vendor));
David Neto22f144c2017-06-12 14:26:21 -0400459
460 // we record where we need to come back to and patch in the bound value
David Neto0676e6f2017-07-11 18:47:44 -0400461 patchBoundOffset = binaryOut->tell();
David Neto22f144c2017-06-12 14:26:21 -0400462
463 // output a bad bound for now
David Neto0676e6f2017-07-11 18:47:44 -0400464 binaryOut->write(reinterpret_cast<const char *>(&nextID), sizeof(nextID));
David Neto22f144c2017-06-12 14:26:21 -0400465
466 // output the schema (reserved for use and must be 0)
467 const uint32_t schema = 0;
David Neto0676e6f2017-07-11 18:47:44 -0400468 binaryOut->write(reinterpret_cast<const char *>(&schema), sizeof(schema));
David Neto22f144c2017-06-12 14:26:21 -0400469 }
470}
471
472void SPIRVProducerPass::patchHeader() {
473 if (outputAsm) {
474 // get the string representation of the max bound used (nextID will be the
475 // max ID used)
476 auto asString = std::to_string(nextID);
477 out.pwrite(asString.c_str(), asString.size(), patchBoundOffset);
478 } else {
479 // for a binary we just write the value of nextID over bound
David Neto0676e6f2017-07-11 18:47:44 -0400480 binaryOut->pwrite(reinterpret_cast<char *>(&nextID), sizeof(nextID),
481 patchBoundOffset);
David Neto22f144c2017-06-12 14:26:21 -0400482 }
483}
484
485void SPIRVProducerPass::GenerateLLVMIRInfo(Module &M) {
486 // This function generates LLVM IR for function such as global variable for
487 // argument, constant and pointer type for argument access. These information
488 // is artificial one because we need Vulkan SPIR-V output. This function is
489 // executed ahead of FindType and FindConstant.
490 ValueToValueMapTy &ArgGVMap = getArgumentGVMap();
491 LLVMContext &Context = M.getContext();
492
493 // Map for avoiding to generate struct type with same fields.
494 DenseMap<Type *, Type *> ArgTyMap;
495
496 // Collect global constant variables.
497 SmallVector<GlobalVariable *, 8> GVList;
498 for (GlobalVariable &GV : M.globals()) {
499 if (GV.getType()->getAddressSpace() == AddressSpace::Constant) {
500 GVList.push_back(&GV);
501 }
502 }
503
504 // Change global constant variable's address space to ModuleScopePrivate.
505 auto &GlobalConstFuncTyMap = getGlobalConstFuncTypeMap();
506 for (auto GV : GVList) {
507 // If there is no user of gv, delete gv.
508 if (GV->use_empty()) {
509 GV->eraseFromParent();
510 continue;
511 }
512
513 // Create new gv with ModuleScopePrivate address space.
514 Type *NewGVTy = GV->getType()->getPointerElementType();
515 GlobalVariable *NewGV = new GlobalVariable(
516 M, NewGVTy, false, GV->getLinkage(), GV->getInitializer(), "", nullptr,
517 GV->getThreadLocalMode(), AddressSpace::ModuleScopePrivate);
518 NewGV->takeName(GV);
519
520 const SmallVector<User *, 8> GVUsers(GV->user_begin(), GV->user_end());
521 SmallVector<User*, 8> CandidateUsers;
522
523 for (User *GVU : GVUsers) {
524 if (CallInst *Call = dyn_cast<CallInst>(GVU)) {
525 // Find argument index.
526 unsigned GVCstArgIdx = 0;
527 for (unsigned i = 0; i < Call->getNumArgOperands(); i++) {
528 if (GV == Call->getOperand(i)) {
529 GVCstArgIdx = i;
530 }
531 }
532
533 // Record function with global constant.
534 GlobalConstFuncTyMap[Call->getFunctionType()] =
535 std::make_pair(Call->getFunctionType(), GVCstArgIdx);
536 } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(GVU)) {
537 // Check GEP users.
538 for (User *GEPU : GEP->users()) {
539 if (CallInst *GEPCall = dyn_cast<CallInst>(GEPU)) {
540 // Find argument index.
541 unsigned GVCstArgIdx = 0;
542 for (unsigned i = 0; i < GEPCall->getNumArgOperands(); i++) {
543 if (GEP == GEPCall->getOperand(i)) {
544 GVCstArgIdx = i;
545 }
546 }
547
548 // Record function with global constant.
549 GlobalConstFuncTyMap[GEPCall->getFunctionType()] =
550 std::make_pair(GEPCall->getFunctionType(), GVCstArgIdx);
551 }
552 }
553 }
554
555 CandidateUsers.push_back(GVU);
556 }
557
558 for (User *U : CandidateUsers) {
559 // Update users of gv with new gv.
560 U->replaceUsesOfWith(GV, NewGV);
561 }
562
563 // Delete original gv.
564 GV->eraseFromParent();
565 }
566
567 bool HasWorkGroupBuiltin = false;
568 for (GlobalVariable &GV : M.globals()) {
569 const spv::BuiltIn BuiltinType = GetBuiltin(GV.getName());
570 if (spv::BuiltInWorkgroupSize == BuiltinType) {
571 HasWorkGroupBuiltin = true;
572 }
573 }
574
575
576 for (Function &F : M) {
577 // Handle kernel function first.
578 if (F.isDeclaration() || F.getCallingConv() != CallingConv::SPIR_KERNEL) {
579 continue;
580 }
581
582 for (BasicBlock &BB : F) {
583 for (Instruction &I : BB) {
584 if (I.getOpcode() == Instruction::ZExt ||
585 I.getOpcode() == Instruction::SExt ||
586 I.getOpcode() == Instruction::UIToFP) {
587 // If there is zext with i1 type, it will be changed to OpSelect. The
588 // OpSelect needs constant 0 and 1 so the constants are added here.
589
590 auto OpTy = I.getOperand(0)->getType();
591
592 if (OpTy->isIntegerTy(1) ||
593 (OpTy->isVectorTy() &&
594 OpTy->getVectorElementType()->isIntegerTy(1))) {
595 if (I.getOpcode() == Instruction::ZExt) {
596 APInt One(32, 1);
597 FindConstant(Constant::getNullValue(I.getType()));
598 FindConstant(Constant::getIntegerValue(I.getType(), One));
599 } else if (I.getOpcode() == Instruction::SExt) {
600 APInt MinusOne(32, UINT64_MAX, true);
601 FindConstant(Constant::getNullValue(I.getType()));
602 FindConstant(Constant::getIntegerValue(I.getType(), MinusOne));
603 } else {
604 FindConstant(ConstantFP::get(Context, APFloat(0.0f)));
605 FindConstant(ConstantFP::get(Context, APFloat(1.0f)));
606 }
607 }
608 } else if (CallInst *Call = dyn_cast<CallInst>(&I)) {
609 Function *Callee = Call->getCalledFunction();
610
611 // Handle image type specially.
612 if (Callee->getName().equals(
613 "_Z11read_imagef14ocl_image2d_ro11ocl_samplerDv2_f") ||
614 Callee->getName().equals(
615 "_Z11read_imagef14ocl_image3d_ro11ocl_samplerDv4_f")) {
616 TypeMapType &OpImageTypeMap = getImageTypeMap();
617 Type *ImageTy =
618 Call->getArgOperand(0)->getType()->getPointerElementType();
619 OpImageTypeMap[ImageTy] = 0;
620
621 FindConstant(ConstantFP::get(Context, APFloat(0.0f)));
622 }
623 }
624 }
625 }
626
627 if (M.getTypeByName("opencl.image2d_ro_t") ||
628 M.getTypeByName("opencl.image2d_wo_t") ||
629 M.getTypeByName("opencl.image3d_ro_t") ||
630 M.getTypeByName("opencl.image3d_wo_t")) {
631 // Assume Image type's sampled type is float type.
632 FindType(Type::getFloatTy(Context));
633 }
634
635 if (const MDNode *MD =
636 dyn_cast<Function>(&F)->getMetadata("reqd_work_group_size")) {
637 // We generate constants if the WorkgroupSize builtin is being used.
638 if (HasWorkGroupBuiltin) {
639 // Collect constant information for work group size.
640 FindConstant(mdconst::extract<ConstantInt>(MD->getOperand(0)));
641 FindConstant(mdconst::extract<ConstantInt>(MD->getOperand(1)));
642 FindConstant(mdconst::extract<ConstantInt>(MD->getOperand(2)));
643 }
644 }
645
646 // Wrap up all argument types with struct type and create global variables
647 // with them.
648 bool HasArgUser = false;
649 unsigned Idx = 0;
650
651 for (const Argument &Arg : F.args()) {
652 Type *ArgTy = Arg.getType();
653 Type *GVTy = nullptr;
654
655 // Check argument type whether it is pointer type or not. If it is
656 // pointer type, add its address space to new global variable for
657 // argument.
658 unsigned AddrSpace = AddressSpace::Global;
659 if (PointerType *ArgPTy = dyn_cast<PointerType>(ArgTy)) {
660 AddrSpace = ArgPTy->getAddressSpace();
661 }
662
663 Type *TmpArgTy = ArgTy;
664
665 // sampler_t and image types have pointer type of struct type with
666 // opaque
667 // type as field. Extract the struct type. It will be used by global
668 // variable for argument.
669 bool IsSamplerType = false;
670 bool IsImageType = false;
671 if (PointerType *TmpArgPTy = dyn_cast<PointerType>(TmpArgTy)) {
672 if (StructType *STy =
673 dyn_cast<StructType>(TmpArgPTy->getElementType())) {
674 if (STy->isOpaque()) {
675 if (STy->getName().equals("opencl.sampler_t")) {
676 AddrSpace = AddressSpace::UniformConstant;
677 IsSamplerType = true;
678 TmpArgTy = STy;
679 } else if (STy->getName().equals("opencl.image2d_ro_t") ||
680 STy->getName().equals("opencl.image2d_wo_t") ||
681 STy->getName().equals("opencl.image3d_ro_t") ||
682 STy->getName().equals("opencl.image3d_wo_t")) {
683 AddrSpace = AddressSpace::UniformConstant;
684 IsImageType = true;
685 TmpArgTy = STy;
686 } else {
687 llvm_unreachable("Argument has opaque type unsupported???");
688 }
689 }
690 }
691 }
692
693 // LLVM's pointer type is distinguished by address space but we need to
694 // regard constant and global address space as same here. If pointer
695 // type has constant address space, generate new pointer type
696 // temporarily to check previous struct type for argument.
697 if (PointerType *TmpArgPTy = dyn_cast<PointerType>(TmpArgTy)) {
698 AddrSpace = TmpArgPTy->getAddressSpace();
699 if (AddrSpace == AddressSpace::Constant) {
700 TmpArgTy = PointerType::get(TmpArgPTy->getElementType(),
701 AddressSpace::Global);
702 }
703 }
704
705 if (IsSamplerType || IsImageType) {
706 GVTy = TmpArgTy;
707 } else if (ArgTyMap.count(TmpArgTy)) {
708 // If there are arguments handled previously, use its type.
709 GVTy = ArgTyMap[TmpArgTy];
710 } else {
711 // Wrap up argument type with struct type.
712 StructType *STy = StructType::create(Context);
713
714 SmallVector<Type *, 8> EltTys;
715 EltTys.push_back(ArgTy);
716
717 STy->setBody(EltTys, false);
718
719 GVTy = STy;
720 ArgTyMap[TmpArgTy] = STy;
721 }
722
723 // In order to build type map between llvm type and spirv id, LLVM
724 // global variable is needed. It has llvm type and other instructions
725 // can access it with its type.
726 GlobalVariable *NewGV = new GlobalVariable(
727 M, GVTy, false, GlobalValue::ExternalLinkage, UndefValue::get(GVTy),
728 F.getName() + ".arg." + std::to_string(Idx++), nullptr,
729 GlobalValue::ThreadLocalMode::NotThreadLocal, AddrSpace);
730
731 // Generate type info for argument global variable.
732 FindType(NewGV->getType());
733
734 ArgGVMap[&Arg] = NewGV;
735
736 // Generate pointer type of argument type for OpAccessChain of argument.
737 if (!Arg.use_empty()) {
738 if (!isa<PointerType>(ArgTy)) {
739 FindType(PointerType::get(ArgTy, AddrSpace));
740 }
741 HasArgUser = true;
742 }
743 }
744
745 if (HasArgUser) {
746 // Generate constant 0 for OpAccessChain of argument.
747 Type *IdxTy = Type::getInt32Ty(Context);
748 FindConstant(ConstantInt::get(IdxTy, 0));
749 FindType(IdxTy);
750 }
751
752 // Collect types' information from function.
753 FindTypePerFunc(F);
754
755 // Collect constant information from function.
756 FindConstantPerFunc(F);
757 }
758
759 for (Function &F : M) {
760 // Handle non-kernel functions.
761 if (F.isDeclaration() || F.getCallingConv() == CallingConv::SPIR_KERNEL) {
762 continue;
763 }
764
765 for (BasicBlock &BB : F) {
766 for (Instruction &I : BB) {
767 if (I.getOpcode() == Instruction::ZExt ||
768 I.getOpcode() == Instruction::SExt ||
769 I.getOpcode() == Instruction::UIToFP) {
770 // If there is zext with i1 type, it will be changed to OpSelect. The
771 // OpSelect needs constant 0 and 1 so the constants are added here.
772
773 auto OpTy = I.getOperand(0)->getType();
774
775 if (OpTy->isIntegerTy(1) ||
776 (OpTy->isVectorTy() &&
777 OpTy->getVectorElementType()->isIntegerTy(1))) {
778 if (I.getOpcode() == Instruction::ZExt) {
779 APInt One(32, 1);
780 FindConstant(Constant::getNullValue(I.getType()));
781 FindConstant(Constant::getIntegerValue(I.getType(), One));
782 } else if (I.getOpcode() == Instruction::SExt) {
783 APInt MinusOne(32, UINT64_MAX, true);
784 FindConstant(Constant::getNullValue(I.getType()));
785 FindConstant(Constant::getIntegerValue(I.getType(), MinusOne));
786 } else {
787 FindConstant(ConstantFP::get(Context, APFloat(0.0f)));
788 FindConstant(ConstantFP::get(Context, APFloat(1.0f)));
789 }
790 }
791 } else if (CallInst *Call = dyn_cast<CallInst>(&I)) {
792 Function *Callee = Call->getCalledFunction();
793
794 // Handle image type specially.
795 if (Callee->getName().equals(
796 "_Z11read_imagef14ocl_image2d_ro11ocl_samplerDv2_f") ||
797 Callee->getName().equals(
798 "_Z11read_imagef14ocl_image3d_ro11ocl_samplerDv4_f")) {
799 TypeMapType &OpImageTypeMap = getImageTypeMap();
800 Type *ImageTy =
801 Call->getArgOperand(0)->getType()->getPointerElementType();
802 OpImageTypeMap[ImageTy] = 0;
803
804 FindConstant(ConstantFP::get(Context, APFloat(0.0f)));
805 }
806 }
807 }
808 }
809
810 if (M.getTypeByName("opencl.image2d_ro_t") ||
811 M.getTypeByName("opencl.image2d_wo_t") ||
812 M.getTypeByName("opencl.image3d_ro_t") ||
813 M.getTypeByName("opencl.image3d_wo_t")) {
814 // Assume Image type's sampled type is float type.
815 FindType(Type::getFloatTy(Context));
816 }
817
818 // Collect types' information from function.
819 FindTypePerFunc(F);
820
821 // Collect constant information from function.
822 FindConstantPerFunc(F);
823 }
824}
825
826bool SPIRVProducerPass::FindExtInst(Module &M) {
827 LLVMContext &Context = M.getContext();
828 bool HasExtInst = false;
829
830 for (Function &F : M) {
831 for (BasicBlock &BB : F) {
832 for (Instruction &I : BB) {
833 if (CallInst *Call = dyn_cast<CallInst>(&I)) {
834 Function *Callee = Call->getCalledFunction();
835 // Check whether this call is for extend instructions.
836 glsl::ExtInst EInst = getExtInstEnum(Callee->getName());
837 if (EInst) {
838 // clz needs OpExtInst and OpISub with constant 31. Add constant 31
839 // to constant list here.
840 if (EInst == glsl::ExtInstFindUMsb) {
841 Type *IdxTy = Type::getInt32Ty(Context);
842 FindConstant(ConstantInt::get(IdxTy, 31));
843 FindType(IdxTy);
844 }
845
846 HasExtInst = true;
847 }
848 }
849 }
850 }
851 }
852
853 return HasExtInst;
854}
855
856void SPIRVProducerPass::FindTypePerGlobalVar(GlobalVariable &GV) {
857 // Investigate global variable's type.
858 FindType(GV.getType());
859}
860
861void SPIRVProducerPass::FindTypePerFunc(Function &F) {
862 // Investigate function's type.
863 FunctionType *FTy = F.getFunctionType();
864
865 if (F.getCallingConv() != CallingConv::SPIR_KERNEL) {
866 auto &GlobalConstFuncTyMap = getGlobalConstFuncTypeMap();
867 // Handle function with global constant parameters.
868 if (GlobalConstFuncTyMap.count(FTy)) {
869 uint32_t GVCstArgIdx = GlobalConstFuncTypeMap[FTy].second;
870 SmallVector<Type *, 4> NewFuncParamTys;
871 for (unsigned i = 0; i < FTy->getNumParams(); i++) {
872 Type *ParamTy = FTy->getParamType(i);
873 if (i == GVCstArgIdx) {
874 Type *EleTy = ParamTy->getPointerElementType();
875 ParamTy = PointerType::get(EleTy, AddressSpace::ModuleScopePrivate);
876 }
877
878 NewFuncParamTys.push_back(ParamTy);
879 }
880
881 FunctionType *NewFTy =
882 FunctionType::get(FTy->getReturnType(), NewFuncParamTys, false);
883 GlobalConstFuncTyMap[FTy] = std::make_pair(NewFTy, GVCstArgIdx);
884 FTy = NewFTy;
885 }
886
887 FindType(FTy);
888 } else {
889 // As kernel functions do not have parameters, create new function type and
890 // add it to type map.
891 SmallVector<Type *, 4> NewFuncParamTys;
892 FunctionType *NewFTy =
893 FunctionType::get(FTy->getReturnType(), NewFuncParamTys, false);
894 FindType(NewFTy);
895 }
896
897 // Investigate instructions' type in function body.
898 for (BasicBlock &BB : F) {
899 for (Instruction &I : BB) {
900 if (isa<ShuffleVectorInst>(I)) {
901 for (unsigned i = 0; i < I.getNumOperands(); i++) {
902 // Ignore type for mask of shuffle vector instruction.
903 if (i == 2) {
904 continue;
905 }
906
907 Value *Op = I.getOperand(i);
908 if (!isa<MetadataAsValue>(Op)) {
909 FindType(Op->getType());
910 }
911 }
912
913 FindType(I.getType());
914 continue;
915 }
916
917 // Work through the operands of the instruction.
918 for (unsigned i = 0; i < I.getNumOperands(); i++) {
919 Value *const Op = I.getOperand(i);
920 // If any of the operands is a constant, find the type!
921 if (isa<Constant>(Op) && !isa<GlobalValue>(Op)) {
922 FindType(Op->getType());
923 }
924 }
925
926 for (Use &Op : I.operands()) {
927 if (CallInst *Call = dyn_cast<CallInst>(&I)) {
928 // Avoid to check call instruction's type.
929 break;
930 }
931 if (!isa<MetadataAsValue>(&Op)) {
932 FindType(Op->getType());
933 continue;
934 }
935 }
936
937 CallInst *Call = dyn_cast<CallInst>(&I);
938
939 // We don't want to track the type of this call as we are going to replace
940 // it.
941 if (Call && ("__translate_sampler_initializer" ==
942 Call->getCalledFunction()->getName())) {
943 continue;
944 }
945
946 if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) {
947 // If gep's base operand has ModuleScopePrivate address space, make gep
948 // return ModuleScopePrivate address space.
949 if (GEP->getPointerAddressSpace() == AddressSpace::ModuleScopePrivate) {
950 // Add pointer type with private address space for global constant to
951 // type list.
952 Type *EleTy = I.getType()->getPointerElementType();
953 Type *NewPTy =
954 PointerType::get(EleTy, AddressSpace::ModuleScopePrivate);
955
956 FindType(NewPTy);
957 continue;
958 }
959 }
960
961 FindType(I.getType());
962 }
963 }
964}
965
966void SPIRVProducerPass::FindType(Type *Ty) {
967 TypeList &TyList = getTypeList();
968
969 if (0 != TyList.idFor(Ty)) {
970 return;
971 }
972
973 if (Ty->isPointerTy()) {
974 auto AddrSpace = Ty->getPointerAddressSpace();
975 if ((AddressSpace::Constant == AddrSpace) ||
976 (AddressSpace::Global == AddrSpace)) {
977 auto PointeeTy = Ty->getPointerElementType();
978
979 if (PointeeTy->isStructTy() &&
980 dyn_cast<StructType>(PointeeTy)->isOpaque()) {
981 FindType(PointeeTy);
982 auto ActualPointerTy =
983 PointeeTy->getPointerTo(AddressSpace::UniformConstant);
984 FindType(ActualPointerTy);
985 return;
986 }
987 }
988 }
989
990 // OpTypeArray has constant and we need to support type of the constant.
991 if (isa<ArrayType>(Ty)) {
992 LLVMContext &Context = Ty->getContext();
993 FindType(Type::getInt32Ty(Context));
994 }
995
996 for (Type *SubTy : Ty->subtypes()) {
997 FindType(SubTy);
998 }
999
1000 TyList.insert(Ty);
1001}
1002
1003void SPIRVProducerPass::FindConstantPerGlobalVar(GlobalVariable &GV) {
1004 // If the global variable has a (non undef) initializer.
1005 if (GV.hasInitializer() && !isa<UndefValue>(GV.getInitializer())) {
1006 FindConstant(GV.getInitializer());
1007 }
1008}
1009
1010void SPIRVProducerPass::FindConstantPerFunc(Function &F) {
1011 // Investigate constants in function body.
1012 for (BasicBlock &BB : F) {
1013 for (Instruction &I : BB) {
1014 CallInst *Call = dyn_cast<CallInst>(&I);
1015
1016 if (Call && ("__translate_sampler_initializer" ==
1017 Call->getCalledFunction()->getName())) {
1018 // We've handled these constants elsewhere, so skip it.
1019 continue;
1020 }
1021
1022 if (isa<AllocaInst>(I)) {
1023 // Alloca instruction has constant for the number of element. Ignore it.
1024 continue;
1025 } else if (isa<ShuffleVectorInst>(I)) {
1026 for (unsigned i = 0; i < I.getNumOperands(); i++) {
1027 // Ignore constant for mask of shuffle vector instruction.
1028 if (i == 2) {
1029 continue;
1030 }
1031
1032 if (isa<Constant>(I.getOperand(i)) &&
1033 !isa<GlobalValue>(I.getOperand(i))) {
1034 FindConstant(I.getOperand(i));
1035 }
1036 }
1037
1038 continue;
1039 } else if (isa<InsertElementInst>(I)) {
1040 // Handle InsertElement with <4 x i8> specially.
1041 Type *CompositeTy = I.getOperand(0)->getType();
1042 if (is4xi8vec(CompositeTy)) {
1043 LLVMContext &Context = CompositeTy->getContext();
1044 if (isa<Constant>(I.getOperand(0))) {
1045 FindConstant(I.getOperand(0));
1046 }
1047
1048 if (isa<Constant>(I.getOperand(1))) {
1049 FindConstant(I.getOperand(1));
1050 }
1051
1052 // Add mask constant 0xFF.
1053 Constant *CstFF = ConstantInt::get(Type::getInt32Ty(Context), 0xFF);
1054 FindConstant(CstFF);
1055
1056 // Add shift amount constant.
1057 if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2))) {
1058 uint64_t Idx = CI->getZExtValue();
1059 Constant *CstShiftAmount =
1060 ConstantInt::get(Type::getInt32Ty(Context), Idx * 8);
1061 FindConstant(CstShiftAmount);
1062 }
1063
1064 continue;
1065 }
1066
1067 for (unsigned i = 0; i < I.getNumOperands(); i++) {
1068 // Ignore constant for index of InsertElement instruction.
1069 if (i == 2) {
1070 continue;
1071 }
1072
1073 if (isa<Constant>(I.getOperand(i)) &&
1074 !isa<GlobalValue>(I.getOperand(i))) {
1075 FindConstant(I.getOperand(i));
1076 }
1077 }
1078
1079 continue;
1080 } else if (isa<ExtractElementInst>(I)) {
1081 // Handle ExtractElement with <4 x i8> specially.
1082 Type *CompositeTy = I.getOperand(0)->getType();
1083 if (is4xi8vec(CompositeTy)) {
1084 LLVMContext &Context = CompositeTy->getContext();
1085 if (isa<Constant>(I.getOperand(0))) {
1086 FindConstant(I.getOperand(0));
1087 }
1088
1089 // Add mask constant 0xFF.
1090 Constant *CstFF = ConstantInt::get(Type::getInt32Ty(Context), 0xFF);
1091 FindConstant(CstFF);
1092
1093 // Add shift amount constant.
1094 if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) {
1095 uint64_t Idx = CI->getZExtValue();
1096 Constant *CstShiftAmount =
1097 ConstantInt::get(Type::getInt32Ty(Context), Idx * 8);
1098 FindConstant(CstShiftAmount);
1099 } else {
1100 ConstantInt *Cst8 = ConstantInt::get(Type::getInt32Ty(Context), 8);
1101 FindConstant(Cst8);
1102 }
1103
1104 continue;
1105 }
1106
1107 for (unsigned i = 0; i < I.getNumOperands(); i++) {
1108 // Ignore constant for index of ExtractElement instruction.
1109 if (i == 1) {
1110 continue;
1111 }
1112
1113 if (isa<Constant>(I.getOperand(i)) &&
1114 !isa<GlobalValue>(I.getOperand(i))) {
1115 FindConstant(I.getOperand(i));
1116 }
1117 }
1118
1119 continue;
1120 } else if ((Instruction::Xor == I.getOpcode()) && I.getType()->isIntegerTy(1)) {
1121 // We special case for Xor where the type is i1 and one of the arguments is a constant 1 (true), this is an OpLogicalNot in SPIR-V, and we don't need the constant
1122 bool foundConstantTrue = false;
1123 for (Use &Op : I.operands()) {
1124 if (isa<Constant>(Op) && !isa<GlobalValue>(Op)) {
1125 auto CI = cast<ConstantInt>(Op);
1126
1127 if (CI->isZero() || foundConstantTrue) {
1128 // If we already found the true constant, we might (probably only on -O0) have an OpLogicalNot which is taking a constant argument, so discover it anyway.
1129 FindConstant(Op);
1130 } else {
1131 foundConstantTrue = true;
1132 }
1133 }
1134 }
1135
1136 continue;
1137 }
1138
1139 for (Use &Op : I.operands()) {
1140 if (isa<Constant>(Op) && !isa<GlobalValue>(Op)) {
1141 FindConstant(Op);
1142 }
1143 }
1144 }
1145 }
1146}
1147
1148void SPIRVProducerPass::FindConstant(Value *V) {
1149 ValueMapType &VMap = getValueMap();
1150 ValueList &CstList = getConstantList();
1151
1152 // If V is already in VMap, ignore it.
1153 if (VMap.find_as(V) != VMap.end()) {
1154 return;
1155 }
1156
1157 Constant *Cst = cast<Constant>(V);
1158
1159 // Handle constant with <4 x i8> type specially.
1160 Type *CstTy = Cst->getType();
1161 if (is4xi8vec(CstTy)) {
1162 if (!isa<GlobalValue>(V)) {
1163 CstList.push_back(V);
1164 VMap[V] = static_cast<uint32_t>(CstList.size());
1165 }
1166 }
1167
1168 if (Cst->getNumOperands()) {
1169 for (User::const_op_iterator I = Cst->op_begin(), E = Cst->op_end(); I != E;
1170 ++I) {
1171 FindConstant(*I);
1172 }
1173
1174 CstList.push_back(Cst);
1175 VMap[V] = static_cast<uint32_t>(CstList.size());
1176 return;
1177 } else if (const ConstantDataSequential *CDS =
1178 dyn_cast<ConstantDataSequential>(Cst)) {
1179 // Add constants for each element to constant list.
1180 for (unsigned i = 0; i < CDS->getNumElements(); i++) {
1181 Constant *EleCst = CDS->getElementAsConstant(i);
1182 FindConstant(EleCst);
1183 }
1184 }
1185
1186 if (!isa<GlobalValue>(V)) {
1187 CstList.push_back(V);
1188 VMap[V] = static_cast<uint32_t>(CstList.size());
1189 }
1190}
1191
1192spv::StorageClass SPIRVProducerPass::GetStorageClass(unsigned AddrSpace) const {
1193 switch (AddrSpace) {
1194 default:
1195 llvm_unreachable("Unsupported OpenCL address space");
1196 case AddressSpace::Private:
1197 return spv::StorageClassFunction;
1198 case AddressSpace::Global:
1199 case AddressSpace::Constant:
1200 return spv::StorageClassStorageBuffer;
1201 case AddressSpace::Input:
1202 return spv::StorageClassInput;
1203 case AddressSpace::Local:
1204 return spv::StorageClassWorkgroup;
1205 case AddressSpace::UniformConstant:
1206 return spv::StorageClassUniformConstant;
1207 case AddressSpace::ModuleScopePrivate:
1208 return spv::StorageClassPrivate;
1209 }
1210}
1211
1212spv::BuiltIn SPIRVProducerPass::GetBuiltin(StringRef Name) const {
1213 return StringSwitch<spv::BuiltIn>(Name)
1214 .Case("__spirv_GlobalInvocationId", spv::BuiltInGlobalInvocationId)
1215 .Case("__spirv_LocalInvocationId", spv::BuiltInLocalInvocationId)
1216 .Case("__spirv_WorkgroupSize", spv::BuiltInWorkgroupSize)
1217 .Case("__spirv_NumWorkgroups", spv::BuiltInNumWorkgroups)
1218 .Case("__spirv_WorkgroupId", spv::BuiltInWorkgroupId)
1219 .Default(spv::BuiltInMax);
1220}
1221
1222void SPIRVProducerPass::GenerateExtInstImport() {
1223 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
1224 uint32_t &ExtInstImportID = getOpExtInstImportID();
1225
1226 //
1227 // Generate OpExtInstImport.
1228 //
1229 // Ops[0] ... Ops[n] = Name (Literal String)
1230 SPIRVOperandList Ops;
1231
1232 SPIRVOperand *Name =
1233 new SPIRVOperand(SPIRVOperandType::LITERAL_STRING, "GLSL.std.450");
1234 Ops.push_back(Name);
1235
1236 size_t NameWordSize = (Name->getLiteralStr().size() + 1) / 4;
1237 assert(NameWordSize < (UINT16_MAX - 2));
1238 if ((Name->getLiteralStr().size() + 1) % 4) {
1239 NameWordSize += 1;
1240 }
1241
1242 uint16_t WordCount = static_cast<uint16_t>(2 + NameWordSize);
1243 ExtInstImportID = nextID;
1244
1245 SPIRVInstruction *Inst =
1246 new SPIRVInstruction(WordCount, spv::OpExtInstImport, nextID++, Ops);
1247 SPIRVInstList.push_back(Inst);
1248}
1249
1250void SPIRVProducerPass::GenerateSPIRVTypes(const DataLayout &DL) {
1251 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
1252 ValueMapType &VMap = getValueMap();
1253 ValueMapType &AllocatedVMap = getAllocatedValueMap();
1254 ValueToValueMapTy &ArgGVMap = getArgumentGVMap();
1255
1256 // Map for OpTypeRuntimeArray. If argument has pointer type, 2 spirv type
1257 // instructions are generated. They are OpTypePointer and OpTypeRuntimeArray.
1258 DenseMap<Type *, uint32_t> OpRuntimeTyMap;
1259
1260 for (Type *Ty : getTypeList()) {
1261 // Update TypeMap with nextID for reference later.
1262 TypeMap[Ty] = nextID;
1263
1264 switch (Ty->getTypeID()) {
1265 default: {
1266 Ty->print(errs());
1267 llvm_unreachable("Unsupported type???");
1268 break;
1269 }
1270 case Type::MetadataTyID:
1271 case Type::LabelTyID: {
1272 // Ignore these types.
1273 break;
1274 }
1275 case Type::PointerTyID: {
1276 PointerType *PTy = cast<PointerType>(Ty);
1277 unsigned AddrSpace = PTy->getAddressSpace();
1278
1279 // For the purposes of our Vulkan SPIR-V type system, constant and global
1280 // are conflated.
1281 bool UseExistingOpTypePointer = false;
1282 if (AddressSpace::Constant == AddrSpace) {
1283 AddrSpace = AddressSpace::Global;
1284
1285 // Check to see if we already created this type (for instance, if we had
1286 // a constant <type>* and a global <type>*, the type would be created by
1287 // one of these types, and shared by both).
1288 auto GlobalTy = PTy->getPointerElementType()->getPointerTo(AddrSpace);
1289 if (0 < TypeMap.count(GlobalTy)) {
1290 TypeMap[PTy] = TypeMap[GlobalTy];
1291 break;
1292 }
1293 } else if (AddressSpace::Global == AddrSpace) {
1294 AddrSpace = AddressSpace::Constant;
1295
1296 // Check to see if we already created this type (for instance, if we had
1297 // a constant <type>* and a global <type>*, the type would be created by
1298 // one of these types, and shared by both).
1299 auto ConstantTy = PTy->getPointerElementType()->getPointerTo(AddrSpace);
1300 if (0 < TypeMap.count(ConstantTy)) {
1301 TypeMap[PTy] = TypeMap[ConstantTy];
1302 UseExistingOpTypePointer = true;
1303 }
1304 }
1305
1306 bool IsOpTypeRuntimeArray = false;
1307 bool HasArgUser = false;
1308
1309 for (auto ArgGV : ArgGVMap) {
1310 auto Arg = ArgGV.first;
1311
1312 Type *ArgTy = Arg->getType();
1313 if (ArgTy == PTy) {
1314 if (AddrSpace != AddressSpace::UniformConstant) {
1315 IsOpTypeRuntimeArray = true;
1316 }
1317
1318 for (auto U : Arg->users()) {
1319 if (!isa<GetElementPtrInst>(U) || (U->getType() == PTy)) {
1320 HasArgUser = true;
1321 break;
1322 }
1323 }
1324 }
1325 }
1326
1327 if ((!IsOpTypeRuntimeArray || HasArgUser) && !UseExistingOpTypePointer) {
1328 //
1329 // Generate OpTypePointer.
1330 //
1331
1332 // OpTypePointer
1333 // Ops[0] = Storage Class
1334 // Ops[1] = Element Type ID
1335 SPIRVOperandList Ops;
1336
1337 spv::StorageClass StorageClass = GetStorageClass(AddrSpace);
1338
1339 SPIRVOperand *StorageClassOp =
1340 new SPIRVOperand(SPIRVOperandType::NUMBERID, StorageClass);
1341 Ops.push_back(StorageClassOp);
1342
1343 uint32_t EleTyID = lookupType(PTy->getElementType());
1344 SPIRVOperand *EleTyOp =
1345 new SPIRVOperand(SPIRVOperandType::NUMBERID, EleTyID);
1346 Ops.push_back(EleTyOp);
1347
1348 spv::Op Opcode = spv::OpTypePointer;
1349 uint16_t WordCount = 4;
1350
1351 SPIRVInstruction *Inst =
1352 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
1353 SPIRVInstList.push_back(Inst);
1354 }
1355
1356 if (IsOpTypeRuntimeArray) {
1357 //
1358 // Generate OpTypeRuntimeArray.
1359 //
1360
1361 // OpTypeRuntimeArray
1362 // Ops[0] = Element Type ID
1363 SPIRVOperandList Ops;
1364
1365 uint32_t EleTyID = lookupType(PTy->getElementType());
1366 SPIRVOperand *EleTyOp =
1367 new SPIRVOperand(SPIRVOperandType::NUMBERID, EleTyID);
1368 Ops.push_back(EleTyOp);
1369
1370 spv::Op Opcode = spv::OpTypeRuntimeArray;
1371 uint16_t WordCount = 3;
1372
1373 uint32_t OpTypeRuntimeArrayID = nextID;
1374 assert(0 == OpRuntimeTyMap.count(Ty));
1375 OpRuntimeTyMap[Ty] = nextID;
1376
1377 SPIRVInstruction *Inst =
1378 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
1379 SPIRVInstList.push_back(Inst);
1380
1381 // Generate OpDecorate.
1382 auto DecoInsertPoint =
1383 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
1384 [](SPIRVInstruction *Inst) -> bool {
1385 return Inst->getOpcode() != spv::OpDecorate &&
1386 Inst->getOpcode() != spv::OpMemberDecorate &&
1387 Inst->getOpcode() != spv::OpExtInstImport;
1388 });
1389
1390 // Ops[0] = Target ID
1391 // Ops[1] = Decoration (ArrayStride)
1392 // Ops[2] = Stride Number(Literal Number)
1393 Ops.clear();
1394
1395 SPIRVOperand *PTyIDOp =
1396 new SPIRVOperand(SPIRVOperandType::NUMBERID, OpTypeRuntimeArrayID);
1397 Ops.push_back(PTyIDOp);
1398
1399 SPIRVOperand *DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID,
1400 spv::DecorationArrayStride);
1401 Ops.push_back(DecoOp);
1402
1403 std::vector<uint32_t> LiteralNum;
1404 Type *EleTy = PTy->getElementType();
David Neto25018082017-07-07 13:21:46 -04001405 const unsigned ArrayStride = DL.getTypeAllocSize(EleTy);
David Neto22f144c2017-06-12 14:26:21 -04001406 LiteralNum.push_back(ArrayStride);
1407 SPIRVOperand *ArrayStrideOp =
1408 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1409 Ops.push_back(ArrayStrideOp);
1410
1411 SPIRVInstruction *DecoInst =
1412 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
1413 SPIRVInstList.insert(DecoInsertPoint, DecoInst);
1414 }
1415 break;
1416 }
1417 case Type::StructTyID: {
1418 LLVMContext &Context = Ty->getContext();
1419
1420 StructType *STy = cast<StructType>(Ty);
1421
1422 // Handle sampler type.
1423 if (STy->isOpaque()) {
1424 if (STy->getName().equals("opencl.sampler_t")) {
1425 //
1426 // Generate OpTypeSampler
1427 //
1428 // Empty Ops.
1429 SPIRVOperandList Ops;
1430
1431 SPIRVInstruction *Inst =
1432 new SPIRVInstruction(2, spv::OpTypeSampler, nextID++, Ops);
1433 SPIRVInstList.push_back(Inst);
1434 break;
1435 } else if (STy->getName().equals("opencl.image2d_ro_t") ||
1436 STy->getName().equals("opencl.image2d_wo_t") ||
1437 STy->getName().equals("opencl.image3d_ro_t") ||
1438 STy->getName().equals("opencl.image3d_wo_t")) {
1439 //
1440 // Generate OpTypeImage
1441 //
1442 // Ops[0] = Sampled Type ID
1443 // Ops[1] = Dim ID
1444 // Ops[2] = Depth (Literal Number)
1445 // Ops[3] = Arrayed (Literal Number)
1446 // Ops[4] = MS (Literal Number)
1447 // Ops[5] = Sampled (Literal Number)
1448 // Ops[6] = Image Format ID
1449 //
1450 SPIRVOperandList Ops;
1451
1452 // TODO: Changed Sampled Type according to situations.
1453 uint32_t SampledTyID = lookupType(Type::getFloatTy(Context));
1454 SPIRVOperand *SampledTyIDOp =
1455 new SPIRVOperand(SPIRVOperandType::NUMBERID, SampledTyID);
1456 Ops.push_back(SampledTyIDOp);
1457
1458 spv::Dim DimID = spv::Dim2D;
1459 if (STy->getName().equals("opencl.image3d_ro_t") ||
1460 STy->getName().equals("opencl.image3d_wo_t")) {
1461 DimID = spv::Dim3D;
1462 }
1463 SPIRVOperand *DimIDOp =
1464 new SPIRVOperand(SPIRVOperandType::NUMBERID, DimID);
1465 Ops.push_back(DimIDOp);
1466
1467 // TODO: Set up Depth.
1468 std::vector<uint32_t> LiteralNum;
1469 LiteralNum.push_back(0);
1470 SPIRVOperand *DepthOp =
1471 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1472 Ops.push_back(DepthOp);
1473
1474 // TODO: Set up Arrayed.
1475 LiteralNum.clear();
1476 LiteralNum.push_back(0);
1477 SPIRVOperand *ArrayedOp =
1478 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1479 Ops.push_back(ArrayedOp);
1480
1481 // TODO: Set up MS.
1482 LiteralNum.clear();
1483 LiteralNum.push_back(0);
1484 SPIRVOperand *MSOp =
1485 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1486 Ops.push_back(MSOp);
1487
1488 // TODO: Set up Sampled.
1489 //
1490 // From Spec
1491 //
1492 // 0 indicates this is only known at run time, not at compile time
1493 // 1 indicates will be used with sampler
1494 // 2 indicates will be used without a sampler (a storage image)
1495 uint32_t Sampled = 1;
1496 if (STy->getName().equals("opencl.image2d_wo_t") ||
1497 STy->getName().equals("opencl.image3d_wo_t")) {
1498 Sampled = 2;
1499 }
1500 LiteralNum.clear();
1501 LiteralNum.push_back(Sampled);
1502 SPIRVOperand *SampledOp =
1503 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1504 Ops.push_back(SampledOp);
1505
1506 // TODO: Set up Image Format.
1507 SPIRVOperand *ImageFormatOp = new SPIRVOperand(
1508 SPIRVOperandType::NUMBERID, spv::ImageFormatUnknown);
1509 Ops.push_back(ImageFormatOp);
1510
1511 SPIRVInstruction *Inst =
1512 new SPIRVInstruction(9, spv::OpTypeImage, nextID++, Ops);
1513 SPIRVInstList.push_back(Inst);
1514 break;
1515 }
1516 }
1517
1518 //
1519 // Generate OpTypeStruct
1520 //
1521 // Ops[0] ... Ops[n] = Member IDs
1522 SPIRVOperandList Ops;
1523
1524 for (auto *EleTy : STy->elements()) {
1525 uint32_t EleTyID = lookupType(EleTy);
1526
1527 // Check OpTypeRuntimeArray.
1528 if (isa<PointerType>(EleTy)) {
1529 for (auto ArgGV : ArgGVMap) {
1530 Type *ArgTy = ArgGV.first->getType();
1531 if (ArgTy == EleTy) {
1532 assert(0 != OpRuntimeTyMap.count(EleTy));
1533 EleTyID = OpRuntimeTyMap[EleTy];
1534 }
1535 }
1536 }
1537
1538 SPIRVOperand *EleTyOp =
1539 new SPIRVOperand(SPIRVOperandType::NUMBERID, EleTyID);
1540 Ops.push_back(EleTyOp);
1541 }
1542
1543 uint16_t WordCount = static_cast<uint16_t>(2 + Ops.size());
1544 uint32_t STyID = nextID;
1545
1546 SPIRVInstruction *Inst =
1547 new SPIRVInstruction(WordCount, spv::OpTypeStruct, nextID++, Ops);
1548 SPIRVInstList.push_back(Inst);
1549
1550 // Generate OpMemberDecorate.
1551 auto DecoInsertPoint =
1552 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
1553 [](SPIRVInstruction *Inst) -> bool {
1554 return Inst->getOpcode() != spv::OpDecorate &&
1555 Inst->getOpcode() != spv::OpMemberDecorate &&
1556 Inst->getOpcode() != spv::OpExtInstImport;
1557 });
1558
1559 uint32_t ByteOffset = 0;
1560 for (unsigned MemberIdx = 0; MemberIdx < STy->getNumElements();
1561 MemberIdx++) {
1562 // Ops[0] = Structure Type ID
1563 // Ops[1] = Member Index(Literal Number)
1564 // Ops[2] = Decoration (Offset)
1565 // Ops[3] = Byte Offset (Literal Number)
1566 Ops.clear();
1567
1568 SPIRVOperand *STyIDOp =
1569 new SPIRVOperand(SPIRVOperandType::NUMBERID, STyID);
1570 Ops.push_back(STyIDOp);
1571
1572 std::vector<uint32_t> LiteralNum;
1573 LiteralNum.push_back(MemberIdx);
1574 SPIRVOperand *MemberIdxOp =
1575 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1576 Ops.push_back(MemberIdxOp);
1577
1578 SPIRVOperand *DecoOp =
1579 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::DecorationOffset);
1580 Ops.push_back(DecoOp);
1581
1582 LiteralNum.clear();
1583 LiteralNum.push_back(ByteOffset);
1584 SPIRVOperand *ByteOffsetOp =
1585 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1586 Ops.push_back(ByteOffsetOp);
1587
1588 SPIRVInstruction *DecoInst =
1589 new SPIRVInstruction(5, spv::OpMemberDecorate, 0 /* No id */, Ops);
1590 SPIRVInstList.insert(DecoInsertPoint, DecoInst);
1591
1592 // Update ByteOffset.
1593 Type *EleTy = STy->getElementType(MemberIdx);
1594 ByteOffset += static_cast<uint32_t>(DL.getTypeSizeInBits(EleTy) / 8);
1595 }
1596
1597 // Generate OpDecorate.
1598 for (auto ArgGV : ArgGVMap) {
1599 Type *ArgGVTy = ArgGV.second->getType();
1600 PointerType *PTy = cast<PointerType>(ArgGVTy);
1601 Type *ArgTy = PTy->getElementType();
1602
1603 // Struct type from argument is already distinguished with the other
1604 // struct types on llvm types. As a result, if current processing struct
1605 // type is same with argument type, we can generate OpDecorate with
1606 // Block or BufferBlock.
1607 if (ArgTy == STy) {
1608 // Ops[0] = Target ID
1609 // Ops[1] = Decoration (Block or BufferBlock)
1610 Ops.clear();
1611
1612 SPIRVOperand *STyIDOp =
1613 new SPIRVOperand(SPIRVOperandType::NUMBERID, STyID);
1614 Ops.push_back(STyIDOp);
1615
1616 const spv::Decoration Deco = spv::DecorationBufferBlock;
1617
1618 SPIRVOperand *DecoOp =
1619 new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
1620 Ops.push_back(DecoOp);
1621
1622 SPIRVInstruction *DecoInst =
1623 new SPIRVInstruction(3, spv::OpDecorate, 0 /* No id */, Ops);
1624 SPIRVInstList.insert(DecoInsertPoint, DecoInst);
1625 break;
1626 }
1627 }
1628 break;
1629 }
1630 case Type::IntegerTyID: {
1631 unsigned BitWidth = Ty->getPrimitiveSizeInBits();
1632
1633 if (BitWidth == 1) {
1634 SPIRVInstruction *Inst =
1635 new SPIRVInstruction(2, spv::OpTypeBool, nextID++, {});
1636 SPIRVInstList.push_back(Inst);
1637 } else {
1638 // i8 is added to TypeMap as i32.
1639 if (BitWidth == 8) {
1640 BitWidth = 32;
1641 }
1642
1643 SPIRVOperand *Ops[2] = {
1644 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, BitWidth),
1645 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, 0u)};
1646
1647 SPIRVInstList.push_back(
1648 new SPIRVInstruction(4, spv::OpTypeInt, nextID++, Ops));
1649 }
1650 break;
1651 }
1652 case Type::HalfTyID:
1653 case Type::FloatTyID:
1654 case Type::DoubleTyID: {
1655 SPIRVOperand *WidthOp = new SPIRVOperand(
1656 SPIRVOperandType::LITERAL_INTEGER, Ty->getPrimitiveSizeInBits());
1657
1658 SPIRVInstList.push_back(
1659 new SPIRVInstruction(3, spv::OpTypeFloat, nextID++, WidthOp));
1660 break;
1661 }
1662 case Type::ArrayTyID: {
1663 LLVMContext &Context = Ty->getContext();
1664 ArrayType *ArrTy = cast<ArrayType>(Ty);
1665 //
1666 // Generate OpConstant and OpTypeArray.
1667 //
1668
1669 //
1670 // Generate OpConstant for array length.
1671 //
1672 // Ops[0] = Result Type ID
1673 // Ops[1] .. Ops[n] = Values LiteralNumber
1674 SPIRVOperandList Ops;
1675
1676 Type *LengthTy = Type::getInt32Ty(Context);
1677 uint32_t ResTyID = lookupType(LengthTy);
1678 SPIRVOperand *ResTyOp =
1679 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
1680 Ops.push_back(ResTyOp);
1681
1682 uint64_t Length = ArrTy->getArrayNumElements();
1683 assert(Length < UINT32_MAX);
1684 std::vector<uint32_t> LiteralNum;
1685 LiteralNum.push_back(static_cast<uint32_t>(Length));
1686 SPIRVOperand *ValOp =
1687 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1688 Ops.push_back(ValOp);
1689
1690 // Add constant for length to constant list.
1691 Constant *CstLength = ConstantInt::get(LengthTy, Length);
1692 AllocatedVMap[CstLength] = nextID;
1693 VMap[CstLength] = nextID;
1694 uint32_t LengthID = nextID;
1695
1696 SPIRVInstruction *CstInst =
1697 new SPIRVInstruction(4, spv::OpConstant, nextID++, Ops);
1698 SPIRVInstList.push_back(CstInst);
1699
1700 //
1701 // Generate OpTypeArray.
1702 //
1703 // Ops[0] = Element Type ID
1704 // Ops[1] = Array Length Constant ID
1705 Ops.clear();
1706
1707 uint32_t EleTyID = lookupType(ArrTy->getElementType());
1708 SPIRVOperand *EleTyOp =
1709 new SPIRVOperand(SPIRVOperandType::NUMBERID, EleTyID);
1710 Ops.push_back(EleTyOp);
1711
1712 SPIRVOperand *LengthOp =
1713 new SPIRVOperand(SPIRVOperandType::NUMBERID, LengthID);
1714 Ops.push_back(LengthOp);
1715
1716 // Update TypeMap with nextID.
1717 TypeMap[Ty] = nextID;
1718
1719 SPIRVInstruction *ArrayInst =
1720 new SPIRVInstruction(4, spv::OpTypeArray, nextID++, Ops);
1721 SPIRVInstList.push_back(ArrayInst);
1722 break;
1723 }
1724 case Type::VectorTyID: {
1725 // <4 x i8> is changed to i32.
1726 LLVMContext &Context = Ty->getContext();
1727 if (Ty->getVectorElementType() == Type::getInt8Ty(Context)) {
1728 if (Ty->getVectorNumElements() == 4) {
1729 TypeMap[Ty] = lookupType(Ty->getVectorElementType());
1730 break;
1731 } else {
1732 Ty->print(errs());
1733 llvm_unreachable("Support above i8 vector type");
1734 }
1735 }
1736
1737 // Ops[0] = Component Type ID
1738 // Ops[1] = Component Count (Literal Number)
1739 SPIRVOperand *Ops[2] = {
1740 new SPIRVOperand(SPIRVOperandType::NUMBERID,
1741 lookupType(Ty->getVectorElementType())),
1742 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER,
1743 Ty->getVectorNumElements())};
1744
1745 SPIRVInstList.push_back(
1746 new SPIRVInstruction(4, spv::OpTypeVector, nextID++, Ops));
1747 break;
1748 }
1749 case Type::VoidTyID: {
1750 SPIRVInstruction *Inst =
1751 new SPIRVInstruction(2, spv::OpTypeVoid, nextID++, {});
1752 SPIRVInstList.push_back(Inst);
1753 break;
1754 }
1755 case Type::FunctionTyID: {
1756 // Generate SPIRV instruction for function type.
1757 FunctionType *FTy = cast<FunctionType>(Ty);
1758
1759 // Ops[0] = Return Type ID
1760 // Ops[1] ... Ops[n] = Parameter Type IDs
1761 SPIRVOperandList Ops;
1762
1763 // Find SPIRV instruction for return type
1764 uint32_t RetTyID = lookupType(FTy->getReturnType());
1765
1766 SPIRVOperand *RetTyOp =
1767 new SPIRVOperand(SPIRVOperandType::NUMBERID, RetTyID);
1768 Ops.push_back(RetTyOp);
1769
1770 // Find SPIRV instructions for parameter types
1771 for (unsigned k = 0; k < FTy->getNumParams(); k++) {
1772 // Find SPIRV instruction for parameter type.
1773 auto ParamTy = FTy->getParamType(k);
1774 if (ParamTy->isPointerTy()) {
1775 auto PointeeTy = ParamTy->getPointerElementType();
1776 if (PointeeTy->isStructTy() &&
1777 dyn_cast<StructType>(PointeeTy)->isOpaque()) {
1778 ParamTy = PointeeTy;
1779 }
1780 }
1781
1782 uint32_t ParamTyID = lookupType(ParamTy);
1783 SPIRVOperand *ParamTyOp =
1784 new SPIRVOperand(SPIRVOperandType::NUMBERID, ParamTyID);
1785 Ops.push_back(ParamTyOp);
1786 }
1787
1788 // Return type id is included in operand list.
1789 uint16_t WordCount = static_cast<uint16_t>(2 + Ops.size());
1790
1791 SPIRVInstruction *Inst =
1792 new SPIRVInstruction(WordCount, spv::OpTypeFunction, nextID++, Ops);
1793 SPIRVInstList.push_back(Inst);
1794 break;
1795 }
1796 }
1797 }
1798
1799 // Generate OpTypeSampledImage.
1800 TypeMapType &OpImageTypeMap = getImageTypeMap();
1801 for (auto &ImageType : OpImageTypeMap) {
1802 //
1803 // Generate OpTypeSampledImage.
1804 //
1805 // Ops[0] = Image Type ID
1806 //
1807 SPIRVOperandList Ops;
1808
1809 Type *ImgTy = ImageType.first;
1810 uint32_t ImgTyID = TypeMap[ImgTy];
1811 SPIRVOperand *ImgTyOp =
1812 new SPIRVOperand(SPIRVOperandType::NUMBERID, ImgTyID);
1813 Ops.push_back(ImgTyOp);
1814
1815 // Update OpImageTypeMap.
1816 ImageType.second = nextID;
1817
1818 SPIRVInstruction *Inst =
1819 new SPIRVInstruction(3, spv::OpTypeSampledImage, nextID++, Ops);
1820 SPIRVInstList.push_back(Inst);
1821 }
1822}
1823
1824void SPIRVProducerPass::GenerateSPIRVConstants() {
1825 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
1826 ValueMapType &VMap = getValueMap();
1827 ValueMapType &AllocatedVMap = getAllocatedValueMap();
1828 ValueList &CstList = getConstantList();
1829
1830 for (uint32_t i = 0; i < CstList.size(); i++) {
1831 Constant *Cst = cast<Constant>(CstList[i]);
1832
1833 // OpTypeArray's constant was already generated.
1834 if (AllocatedVMap[Cst]) {
1835 continue;
1836 }
1837
1838 // Update TypeMap with nextID for reference later.
1839 VMap[Cst] = nextID;
1840
1841 //
1842 // Generate OpConstant.
1843 //
1844
1845 // Ops[0] = Result Type ID
1846 // Ops[1] .. Ops[n] = Values LiteralNumber
1847 SPIRVOperandList Ops;
1848
1849 uint32_t ResTyID = lookupType(Cst->getType());
1850 SPIRVOperand *ResTyIDOp =
1851 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
1852 Ops.push_back(ResTyIDOp);
1853
1854 std::vector<uint32_t> LiteralNum;
1855 uint16_t WordCount = 0;
1856 spv::Op Opcode = spv::OpNop;
1857
1858 if (isa<UndefValue>(Cst)) {
1859 // Ops[0] = Result Type ID
1860 Opcode = spv::OpUndef;
1861 WordCount = 3;
1862 } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Cst)) {
1863 unsigned BitWidth = CI->getBitWidth();
1864 if (BitWidth == 1) {
1865 // If the bitwidth of constant is 1, generate OpConstantTrue or
1866 // OpConstantFalse.
1867 if (CI->getZExtValue()) {
1868 // Ops[0] = Result Type ID
1869 Opcode = spv::OpConstantTrue;
1870 } else {
1871 // Ops[0] = Result Type ID
1872 Opcode = spv::OpConstantFalse;
1873 }
1874 WordCount = 3;
1875 } else {
1876 auto V = CI->getZExtValue();
1877 LiteralNum.push_back(V & 0xFFFFFFFF);
1878
1879 if (BitWidth > 32) {
1880 LiteralNum.push_back(V >> 32);
1881 }
1882
1883 Opcode = spv::OpConstant;
1884 WordCount = static_cast<uint16_t>(3 + LiteralNum.size());
1885
1886 SPIRVOperand *CstValue =
1887 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1888 Ops.push_back(CstValue);
1889 }
1890 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Cst)) {
1891 uint64_t FPVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
1892 Type *CFPTy = CFP->getType();
1893 if (CFPTy->isFloatTy()) {
1894 LiteralNum.push_back(FPVal & 0xFFFFFFFF);
1895 } else {
1896 CFPTy->print(errs());
1897 llvm_unreachable("Implement this ConstantFP Type");
1898 }
1899
1900 Opcode = spv::OpConstant;
1901 WordCount = static_cast<uint16_t>(3 + LiteralNum.size());
1902
1903 SPIRVOperand *CstValue =
1904 new SPIRVOperand(SPIRVOperandType::LITERAL_FLOAT, LiteralNum);
1905 Ops.push_back(CstValue);
1906 } else if (isa<ConstantDataSequential>(Cst) &&
1907 cast<ConstantDataSequential>(Cst)->isString()) {
1908 Cst->print(errs());
1909 llvm_unreachable("Implement this Constant");
1910
1911 } else if (const ConstantDataSequential *CDS =
1912 dyn_cast<ConstantDataSequential>(Cst)) {
1913 for (unsigned k = 0; k < CDS->getNumElements(); k++) {
1914 Constant *EleCst = CDS->getElementAsConstant(k);
1915 uint32_t EleCstID = VMap[EleCst];
1916 SPIRVOperand *EleCstIDOp =
1917 new SPIRVOperand(SPIRVOperandType::NUMBERID, EleCstID);
1918 Ops.push_back(EleCstIDOp);
1919 }
1920
1921 Opcode = spv::OpConstantComposite;
1922 WordCount = static_cast<uint16_t>(3 + CDS->getNumElements());
1923 } else if (const ConstantAggregate *CA = dyn_cast<ConstantAggregate>(Cst)) {
1924 // Let's convert <4 x i8> constant to int constant specially.
1925 Type *CstTy = Cst->getType();
1926 if (is4xi8vec(CstTy)) {
1927 LLVMContext &Context = CstTy->getContext();
1928
1929 //
1930 // Generate OpConstant with OpTypeInt 32 0.
1931 //
1932 uint64_t IntValue = 0;
1933 uint32_t Idx = 0;
1934 for (User::const_op_iterator I = Cst->op_begin(), E = Cst->op_end();
1935 I != E; ++I) {
1936 uint64_t Val = 0;
1937 if (ConstantInt *CI2 = dyn_cast<ConstantInt>(I)) {
1938 Val = CI2->getZExtValue();
1939 }
1940 IntValue = (IntValue << Idx) | Val;
1941 }
1942
1943 ConstantInt *CstInt =
1944 ConstantInt::get(Type::getInt32Ty(Context), IntValue);
1945 // If this constant is already registered on VMap, use it.
1946 if (VMap.count(CstInt)) {
1947 uint32_t CstID = VMap[CstInt];
1948 VMap[Cst] = CstID;
1949 return;
1950 }
1951
1952 LiteralNum.push_back(IntValue & 0xFFFFFFFF);
1953 SPIRVOperand *CstValue =
1954 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
1955 Ops.push_back(CstValue);
1956
1957 SPIRVInstruction *CstInst =
1958 new SPIRVInstruction(4, spv::OpConstant, nextID++, Ops);
1959 SPIRVInstList.push_back(CstInst);
1960
1961 return;
1962 }
1963
1964 // We use a constant composite in SPIR-V for our constant aggregate in
1965 // LLVM.
1966 Opcode = spv::OpConstantComposite;
1967 WordCount = static_cast<uint16_t>(3 + CA->getNumOperands());
1968
1969 for (unsigned k = 0; k < CA->getNumOperands(); k++) {
1970 // Look up the ID of the element of this aggregate (which we will
1971 // previously have created a constant for).
1972 uint32_t ElementConstantID = VMap[CA->getAggregateElement(k)];
1973
1974 // And add an operand to the composite we are constructing
1975 Ops.push_back(
1976 new SPIRVOperand(SPIRVOperandType::NUMBERID, ElementConstantID));
1977 }
1978 } else if (Cst->isNullValue()) {
1979 Opcode = spv::OpConstantNull;
1980 WordCount = 3;
1981 } else {
1982 Cst->print(errs());
1983 llvm_unreachable("Unsupported Constant???");
1984 }
1985
1986 SPIRVInstruction *CstInst =
1987 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
1988 SPIRVInstList.push_back(CstInst);
1989 }
1990}
1991
1992void SPIRVProducerPass::GenerateSamplers(Module &M) {
1993 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
1994 ValueMapType &VMap = getValueMap();
1995
1996 DenseMap<unsigned, unsigned> SamplerLiteralToIDMap;
1997
1998 unsigned BindingIdx = 0;
1999
2000 // Generate the sampler map.
2001 for (auto SamplerLiteral : getSamplerMap()) {
2002 // Generate OpVariable.
2003 //
2004 // GIDOps[0] : Result Type ID
2005 // GIDOps[1] : Storage Class
2006 SPIRVOperandList Ops;
2007
2008 Ops.push_back(
2009 new SPIRVOperand(SPIRVOperandType::NUMBERID, lookupType(SamplerTy)));
2010
2011 spv::StorageClass StorageClass = spv::StorageClassUniformConstant;
2012 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, StorageClass));
2013
2014 SPIRVInstruction *Inst = new SPIRVInstruction(
2015 static_cast<uint16_t>(2 + Ops.size()), spv::OpVariable, nextID, Ops);
2016 SPIRVInstList.push_back(Inst);
2017
2018 SamplerLiteralToIDMap[SamplerLiteral] = nextID++;
2019
2020 // Find Insert Point for OpDecorate.
2021 auto DecoInsertPoint =
2022 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
2023 [](SPIRVInstruction *Inst) -> bool {
2024 return Inst->getOpcode() != spv::OpDecorate &&
2025 Inst->getOpcode() != spv::OpMemberDecorate &&
2026 Inst->getOpcode() != spv::OpExtInstImport;
2027 });
2028
2029 // Ops[0] = Target ID
2030 // Ops[1] = Decoration (DescriptorSet)
2031 // Ops[2] = LiteralNumber according to Decoration
2032 Ops.clear();
2033
2034 SPIRVOperand *ArgIDOp = new SPIRVOperand(
2035 SPIRVOperandType::NUMBERID, SamplerLiteralToIDMap[SamplerLiteral]);
2036 Ops.push_back(ArgIDOp);
2037
2038 spv::Decoration Deco = spv::DecorationDescriptorSet;
2039 SPIRVOperand *DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2040 Ops.push_back(DecoOp);
2041
David Netoc2c368d2017-06-30 16:50:17 -04002042 descriptorMapOut << "sampler," << SamplerLiteral << ",descriptorSet,0,binding,"
2043 << BindingIdx << "\n";
2044
David Neto22f144c2017-06-12 14:26:21 -04002045 std::vector<uint32_t> LiteralNum;
2046 LiteralNum.push_back(0);
2047 SPIRVOperand *DescSet =
2048 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2049 Ops.push_back(DescSet);
2050
2051 SPIRVInstruction *DescDecoInst =
2052 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2053 SPIRVInstList.insert(DecoInsertPoint, DescDecoInst);
2054
2055 // Ops[0] = Target ID
2056 // Ops[1] = Decoration (Binding)
2057 // Ops[2] = LiteralNumber according to Decoration
2058 Ops.clear();
2059
2060 Ops.push_back(ArgIDOp);
2061
2062 Deco = spv::DecorationBinding;
2063 DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2064 Ops.push_back(DecoOp);
2065
2066 LiteralNum.clear();
2067 LiteralNum.push_back(BindingIdx++);
2068 SPIRVOperand *Binding =
2069 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2070 Ops.push_back(Binding);
2071
2072 SPIRVInstruction *BindDecoInst =
2073 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2074 SPIRVInstList.insert(DecoInsertPoint, BindDecoInst);
2075 }
2076
2077 const char *TranslateSamplerFunctionName = "__translate_sampler_initializer";
2078
2079 auto SamplerFunction = M.getFunction(TranslateSamplerFunctionName);
2080
2081 // If there are no uses of the sampler function, no work to do!
2082 if (!SamplerFunction) {
2083 return;
2084 }
2085
2086 // Iterate through the users of the sampler function.
2087 for (auto User : SamplerFunction->users()) {
2088 if (auto CI = dyn_cast<CallInst>(User)) {
2089 // Get the literal used to initialize the sampler.
2090 auto Constant = dyn_cast<ConstantInt>(CI->getArgOperand(0));
2091
2092 if (!Constant) {
2093 CI->getArgOperand(0)->print(errs());
2094 llvm_unreachable("Argument of sampler initializer was non-constant!");
2095 }
2096
2097 auto SamplerLiteral = static_cast<unsigned>(Constant->getZExtValue());
2098
2099 if (0 == SamplerLiteralToIDMap.count(SamplerLiteral)) {
2100 Constant->print(errs());
2101 llvm_unreachable("Sampler literal was not found in sampler map!");
2102 }
2103
2104 // Calls to the sampler literal function to initialize a sampler are
2105 // re-routed to the global variables declared for the sampler.
2106 VMap[CI] = SamplerLiteralToIDMap[SamplerLiteral];
2107 }
2108 }
2109}
2110
2111void SPIRVProducerPass::GenerateGlobalVar(GlobalVariable &GV) {
2112 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
2113 ValueMapType &VMap = getValueMap();
2114 std::vector<uint32_t> &BuiltinDimVec = getBuiltinDimVec();
2115
2116 const spv::BuiltIn BuiltinType = GetBuiltin(GV.getName());
2117 Type *Ty = GV.getType();
2118 PointerType *PTy = cast<PointerType>(Ty);
2119
2120 uint32_t InitializerID = 0;
2121
2122 // Workgroup size is handled differently (it goes into a constant)
2123 if (spv::BuiltInWorkgroupSize == BuiltinType) {
2124 std::vector<bool> HasMDVec;
2125 uint32_t PrevXDimCst = 0xFFFFFFFF;
2126 uint32_t PrevYDimCst = 0xFFFFFFFF;
2127 uint32_t PrevZDimCst = 0xFFFFFFFF;
2128 for (Function &Func : *GV.getParent()) {
2129 if (Func.isDeclaration()) {
2130 continue;
2131 }
2132
2133 // We only need to check kernels.
2134 if (Func.getCallingConv() != CallingConv::SPIR_KERNEL) {
2135 continue;
2136 }
2137
2138 if (const MDNode *MD =
2139 dyn_cast<Function>(&Func)->getMetadata("reqd_work_group_size")) {
2140 uint32_t CurXDimCst = static_cast<uint32_t>(
2141 mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue());
2142 uint32_t CurYDimCst = static_cast<uint32_t>(
2143 mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue());
2144 uint32_t CurZDimCst = static_cast<uint32_t>(
2145 mdconst::extract<ConstantInt>(MD->getOperand(2))->getZExtValue());
2146
2147 if (PrevXDimCst == 0xFFFFFFFF && PrevYDimCst == 0xFFFFFFFF &&
2148 PrevZDimCst == 0xFFFFFFFF) {
2149 PrevXDimCst = CurXDimCst;
2150 PrevYDimCst = CurYDimCst;
2151 PrevZDimCst = CurZDimCst;
2152 } else if (CurXDimCst != PrevXDimCst || CurYDimCst != PrevYDimCst ||
2153 CurZDimCst != PrevZDimCst) {
2154 llvm_unreachable(
2155 "reqd_work_group_size must be the same across all kernels");
2156 } else {
2157 continue;
2158 }
2159
2160 //
2161 // Generate OpConstantComposite.
2162 //
2163 // Ops[0] : Result Type ID
2164 // Ops[1] : Constant size for x dimension.
2165 // Ops[2] : Constant size for y dimension.
2166 // Ops[3] : Constant size for z dimension.
2167 SPIRVOperandList Ops;
2168
2169 uint32_t XDimCstID =
2170 VMap[mdconst::extract<ConstantInt>(MD->getOperand(0))];
2171 uint32_t YDimCstID =
2172 VMap[mdconst::extract<ConstantInt>(MD->getOperand(1))];
2173 uint32_t ZDimCstID =
2174 VMap[mdconst::extract<ConstantInt>(MD->getOperand(2))];
2175
2176 InitializerID = nextID;
2177
2178 Ops.push_back(
2179 new SPIRVOperand(SPIRVOperandType::NUMBERID,
2180 lookupType(Ty->getPointerElementType())));
2181
2182 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, XDimCstID));
2183 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, YDimCstID));
2184 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, ZDimCstID));
2185
2186 SPIRVInstruction *Inst =
2187 new SPIRVInstruction(6, spv::OpConstantComposite, nextID++, Ops);
2188 SPIRVInstList.push_back(Inst);
2189
2190 HasMDVec.push_back(true);
2191 } else {
2192 HasMDVec.push_back(false);
2193 }
2194 }
2195
2196 // Check all kernels have same definitions for work_group_size.
2197 bool HasMD = false;
2198 if (!HasMDVec.empty()) {
2199 HasMD = HasMDVec[0];
2200 for (uint32_t i = 1; i < HasMDVec.size(); i++) {
2201 if (HasMD != HasMDVec[i]) {
2202 llvm_unreachable(
2203 "Kernels should have consistent work group size definition");
2204 }
2205 }
2206 }
2207
2208 // If all kernels do not have metadata for reqd_work_group_size, generate
2209 // OpSpecConstants for x/y/z dimension.
2210 if (!HasMD) {
2211 //
2212 // Generate OpSpecConstants for x/y/z dimension.
2213 //
2214 // Ops[0] : Result Type ID
2215 // Ops[1] : Constant size for x/y/z dimension (Literal Number).
2216 uint32_t XDimCstID = 0;
2217 uint32_t YDimCstID = 0;
2218 uint32_t ZDimCstID = 0;
2219
2220 // X Dimension
2221 SPIRVOperandList Ops;
2222
2223 Ops.push_back(new SPIRVOperand(
2224 SPIRVOperandType::NUMBERID,
2225 lookupType(Ty->getPointerElementType()->getSequentialElementType())));
2226
2227 std::vector<uint32_t> LiteralNum;
2228 LiteralNum.push_back(1);
2229 SPIRVOperand *XDim =
2230 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2231 Ops.push_back(XDim);
2232
2233 XDimCstID = nextID;
2234 BuiltinDimVec.push_back(XDimCstID);
2235
2236 SPIRVInstruction *XDimCstInst =
2237 new SPIRVInstruction(4, spv::OpSpecConstant, nextID++, Ops);
2238 SPIRVInstList.push_back(XDimCstInst);
2239
2240 // Y Dimension
2241 Ops.clear();
2242
2243 Ops.push_back(new SPIRVOperand(
2244 SPIRVOperandType::NUMBERID,
2245 lookupType(Ty->getPointerElementType()->getSequentialElementType())));
2246
2247 LiteralNum.clear();
2248 LiteralNum.push_back(1);
2249 SPIRVOperand *YDim =
2250 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2251 Ops.push_back(YDim);
2252
2253 YDimCstID = nextID;
2254 BuiltinDimVec.push_back(YDimCstID);
2255
2256 SPIRVInstruction *YDimCstInst =
2257 new SPIRVInstruction(4, spv::OpSpecConstant, nextID++, Ops);
2258 SPIRVInstList.push_back(YDimCstInst);
2259
2260 // Z Dimension
2261 Ops.clear();
2262
2263 Ops.push_back(new SPIRVOperand(
2264 SPIRVOperandType::NUMBERID,
2265 lookupType(Ty->getPointerElementType()->getSequentialElementType())));
2266
2267 LiteralNum.clear();
2268 LiteralNum.push_back(1);
2269 SPIRVOperand *ZDim =
2270 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2271 Ops.push_back(ZDim);
2272
2273 ZDimCstID = nextID;
2274 BuiltinDimVec.push_back(ZDimCstID);
2275
2276 SPIRVInstruction *ZDimCstInst =
2277 new SPIRVInstruction(4, spv::OpSpecConstant, nextID++, Ops);
2278 SPIRVInstList.push_back(ZDimCstInst);
2279
2280 //
2281 // Generate OpSpecConstantComposite.
2282 //
2283 // Ops[0] : Result Type ID
2284 // Ops[1] : Constant size for x dimension.
2285 // Ops[2] : Constant size for y dimension.
2286 // Ops[3] : Constant size for z dimension.
2287 InitializerID = nextID;
2288
2289 Ops.clear();
2290
2291 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
2292 lookupType(Ty->getPointerElementType())));
2293
2294 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, XDimCstID));
2295 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, YDimCstID));
2296 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, ZDimCstID));
2297
2298 SPIRVInstruction *Inst =
2299 new SPIRVInstruction(6, spv::OpSpecConstantComposite, nextID++, Ops);
2300 SPIRVInstList.push_back(Inst);
2301 }
2302 }
2303
2304 if (GV.hasInitializer()) {
2305 InitializerID = VMap[GV.getInitializer()];
2306 }
2307
2308 VMap[&GV] = nextID;
2309
2310 //
2311 // Generate OpVariable.
2312 //
2313 // GIDOps[0] : Result Type ID
2314 // GIDOps[1] : Storage Class
2315 SPIRVOperandList Ops;
2316
2317 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, lookupType(Ty)));
2318
2319 spv::StorageClass StorageClass = GetStorageClass(PTy->getAddressSpace());
2320 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, StorageClass));
2321
2322 if (0 != InitializerID) {
2323 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, InitializerID));
2324 }
2325
2326 SPIRVInstruction *Inst = new SPIRVInstruction(
2327 static_cast<uint16_t>(2 + Ops.size()), spv::OpVariable, nextID++, Ops);
2328 SPIRVInstList.push_back(Inst);
2329
2330 // If we have a builtin.
2331 if (spv::BuiltInMax != BuiltinType) {
2332 // Find Insert Point for OpDecorate.
2333 auto DecoInsertPoint =
2334 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
2335 [](SPIRVInstruction *Inst) -> bool {
2336 return Inst->getOpcode() != spv::OpDecorate &&
2337 Inst->getOpcode() != spv::OpMemberDecorate &&
2338 Inst->getOpcode() != spv::OpExtInstImport;
2339 });
2340 //
2341 // Generate OpDecorate.
2342 //
2343 // DOps[0] = Target ID
2344 // DOps[1] = Decoration (Builtin)
2345 // DOps[2] = BuiltIn ID
2346 uint32_t ResultID;
2347
2348 // WorkgroupSize is different, we decorate the constant composite that has
2349 // its value, rather than the variable that we use to access the value.
2350 if (spv::BuiltInWorkgroupSize == BuiltinType) {
2351 ResultID = InitializerID;
2352 } else {
2353 ResultID = VMap[&GV];
2354 }
2355
2356 SPIRVOperandList DOps;
2357 SPIRVOperand *ResultIDOp =
2358 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResultID);
2359 DOps.push_back(ResultIDOp);
2360
2361 spv::Decoration Deco = spv::DecorationBuiltIn;
2362 SPIRVOperand *DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2363 DOps.push_back(DecoOp);
2364
2365 SPIRVOperand *Builtin =
2366 new SPIRVOperand(SPIRVOperandType::NUMBERID, BuiltinType);
2367 DOps.push_back(Builtin);
2368
2369 SPIRVInstruction *DescDecoInst =
2370 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, DOps);
2371 SPIRVInstList.insert(DecoInsertPoint, DescDecoInst);
2372 }
2373}
2374
2375void SPIRVProducerPass::GenerateFuncPrologue(Function &F) {
2376 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
2377 ValueMapType &VMap = getValueMap();
2378 EntryPointVecType &EntryPoints = getEntryPointVec();
2379 ValueToValueMapTy &ArgGVMap = getArgumentGVMap();
2380 ValueMapType &ArgGVIDMap = getArgumentGVIDMap();
2381 auto &GlobalConstFuncTyMap = getGlobalConstFuncTypeMap();
2382 auto &GlobalConstArgSet = getGlobalConstArgSet();
David Netoc2c368d2017-06-30 16:50:17 -04002383 const DataLayout& dataLayout(F.getParent()->getDataLayout());
David Neto22f144c2017-06-12 14:26:21 -04002384
2385 FunctionType *FTy = F.getFunctionType();
2386
2387 //
2388 // Generate OpVariable and OpDecorate for kernel function with arguments.
2389 //
2390 if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
2391
2392 // Find Insert Point for OpDecorate.
2393 auto DecoInsertPoint =
2394 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
2395 [](SPIRVInstruction *Inst) -> bool {
2396 return Inst->getOpcode() != spv::OpDecorate &&
2397 Inst->getOpcode() != spv::OpMemberDecorate &&
2398 Inst->getOpcode() != spv::OpExtInstImport;
2399 });
2400
2401 uint32_t DescriptorSetIdx = (0 < getSamplerMap().size()) ? 1u : 0u;
2402 for (Function &Func : *F.getParent()) {
2403 if (Func.isDeclaration()) {
2404 continue;
2405 }
2406
2407 if (Func.getCallingConv() == CallingConv::SPIR_KERNEL) {
2408 if (&Func == &F) {
2409 break;
2410 }
2411 DescriptorSetIdx++;
2412 }
2413 }
2414
David Neto156783e2017-07-05 15:39:41 -04002415 const auto *ArgMap = F.getMetadata("kernel_arg_map");
2416 // Emit descriptor map entries, if there was explicit metadata
2417 // attached.
2418 if (ArgMap) {
2419 for (const auto &arg : ArgMap->operands()) {
2420 const MDNode *arg_node = dyn_cast<MDNode>(arg.get());
2421 assert(arg_node->getNumOperands() == 4);
2422 const auto name =
2423 dyn_cast<MDString>(arg_node->getOperand(0))->getString();
2424 const auto old_index =
2425 dyn_extract<ConstantInt>(arg_node->getOperand(1))->getZExtValue();
2426 const auto new_index =
2427 dyn_extract<ConstantInt>(arg_node->getOperand(2))->getZExtValue();
2428 const auto offset =
2429 dyn_extract<ConstantInt>(arg_node->getOperand(3))->getZExtValue();
2430 descriptorMapOut << "kernel," << F.getName() << ",arg," << name
2431 << ",argOrdinal," << old_index << ",descriptorSet,"
2432 << DescriptorSetIdx << ",binding," << new_index
2433 << ",offset," << offset << "\n";
2434 }
2435 }
2436
David Neto22f144c2017-06-12 14:26:21 -04002437 uint32_t BindingIdx = 0;
2438 for (auto &Arg : F.args()) {
2439 Value *NewGV = ArgGVMap[&Arg];
2440 VMap[&Arg] = VMap[NewGV];
2441 ArgGVIDMap[&Arg] = VMap[&Arg];
2442
David Neto156783e2017-07-05 15:39:41 -04002443 // Emit a descriptor map entry for this arg, in case there was no explicit
2444 // kernel arg mapping metadata.
2445 if (!ArgMap) {
2446 descriptorMapOut << "kernel," << F.getName() << ",arg," << Arg.getName()
2447 << ",argOrdinal," << BindingIdx << ",descriptorSet,"
2448 << DescriptorSetIdx << ",binding," << BindingIdx
2449 << ",offset,0\n";
David Netoc2c368d2017-06-30 16:50:17 -04002450 }
2451
David Neto22f144c2017-06-12 14:26:21 -04002452 // Ops[0] = Target ID
2453 // Ops[1] = Decoration (DescriptorSet)
2454 // Ops[2] = LiteralNumber according to Decoration
2455 SPIRVOperandList Ops;
2456
2457 SPIRVOperand *ArgIDOp =
2458 new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[&Arg]);
2459 Ops.push_back(ArgIDOp);
2460
2461 spv::Decoration Deco = spv::DecorationDescriptorSet;
2462 SPIRVOperand *DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2463 Ops.push_back(DecoOp);
2464
2465 std::vector<uint32_t> LiteralNum;
2466 LiteralNum.push_back(DescriptorSetIdx);
2467 SPIRVOperand *DescSet =
2468 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2469 Ops.push_back(DescSet);
2470
2471 SPIRVInstruction *DescDecoInst =
2472 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2473 SPIRVInstList.insert(DecoInsertPoint, DescDecoInst);
2474
2475 // Ops[0] = Target ID
2476 // Ops[1] = Decoration (Binding)
2477 // Ops[2] = LiteralNumber according to Decoration
2478 Ops.clear();
2479
2480 Ops.push_back(ArgIDOp);
2481
2482 Deco = spv::DecorationBinding;
2483 DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2484 Ops.push_back(DecoOp);
2485
2486 LiteralNum.clear();
2487 LiteralNum.push_back(BindingIdx++);
2488 SPIRVOperand *Binding =
2489 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2490 Ops.push_back(Binding);
2491
2492 SPIRVInstruction *BindDecoInst =
2493 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2494 SPIRVInstList.insert(DecoInsertPoint, BindDecoInst);
2495
2496 // Handle image type argument.
2497 bool HasReadOnlyImageType = false;
2498 bool HasWriteOnlyImageType = false;
2499 if (PointerType *ArgPTy = dyn_cast<PointerType>(Arg.getType())) {
2500 if (StructType *STy = dyn_cast<StructType>(ArgPTy->getElementType())) {
2501 if (STy->isOpaque()) {
2502 if (STy->getName().equals("opencl.image2d_ro_t") ||
2503 STy->getName().equals("opencl.image3d_ro_t")) {
2504 HasReadOnlyImageType = true;
2505 } else if (STy->getName().equals("opencl.image2d_wo_t") ||
2506 STy->getName().equals("opencl.image3d_wo_t")) {
2507 HasWriteOnlyImageType = true;
2508 }
2509 }
2510 }
2511 }
2512
2513 if (HasReadOnlyImageType || HasWriteOnlyImageType) {
2514 // Ops[0] = Target ID
2515 // Ops[1] = Decoration (NonReadable or NonWritable)
2516 Ops.clear();
2517
2518 ArgIDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[&Arg]);
2519 Ops.push_back(ArgIDOp);
2520
2521 Deco = spv::DecorationNonReadable;
2522 if (HasReadOnlyImageType) {
2523 Deco = spv::DecorationNonWritable;
2524 }
2525 DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2526 Ops.push_back(DecoOp);
2527
2528 DescDecoInst =
2529 new SPIRVInstruction(3, spv::OpDecorate, 0 /* No id */, Ops);
2530 SPIRVInstList.insert(DecoInsertPoint, DescDecoInst);
2531 }
2532
2533 // Handle const address space.
2534 if (NewGV->getType()->getPointerAddressSpace() ==
2535 AddressSpace::Constant) {
2536 // Ops[0] = Target ID
2537 // Ops[1] = Decoration (NonWriteable)
2538 Ops.clear();
2539
2540 Ops.push_back(ArgIDOp);
2541
2542 Deco = spv::DecorationNonWritable;
2543 DecoOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Deco);
2544 Ops.push_back(DecoOp);
2545
2546 BindDecoInst =
2547 new SPIRVInstruction(3, spv::OpDecorate, 0 /* No id */, Ops);
2548 SPIRVInstList.insert(DecoInsertPoint, BindDecoInst);
2549 }
2550 }
2551 }
2552
2553 //
2554 // Generate OPFunction.
2555 //
2556
2557 // FOps[0] : Result Type ID
2558 // FOps[1] : Function Control
2559 // FOps[2] : Function Type ID
2560 SPIRVOperandList FOps;
2561
2562 // Find SPIRV instruction for return type.
2563 uint32_t RetTyID = lookupType(FTy->getReturnType());
2564 SPIRVOperand *RetTyOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, RetTyID);
2565 FOps.push_back(RetTyOp);
2566
2567 // Check function attributes for SPIRV Function Control.
2568 uint32_t FuncControl = spv::FunctionControlMaskNone;
2569 if (F.hasFnAttribute(Attribute::AlwaysInline)) {
2570 FuncControl |= spv::FunctionControlInlineMask;
2571 }
2572 if (F.hasFnAttribute(Attribute::NoInline)) {
2573 FuncControl |= spv::FunctionControlDontInlineMask;
2574 }
2575 // TODO: Check llvm attribute for Function Control Pure.
2576 if (F.hasFnAttribute(Attribute::ReadOnly)) {
2577 FuncControl |= spv::FunctionControlPureMask;
2578 }
2579 // TODO: Check llvm attribute for Function Control Const.
2580 if (F.hasFnAttribute(Attribute::ReadNone)) {
2581 FuncControl |= spv::FunctionControlConstMask;
2582 }
2583
2584 SPIRVOperand *FunctionControlOp =
2585 new SPIRVOperand(SPIRVOperandType::NUMBERID, FuncControl);
2586 FOps.push_back(FunctionControlOp);
2587
2588 uint32_t FTyID;
2589 if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
2590 SmallVector<Type *, 4> NewFuncParamTys;
2591 FunctionType *NewFTy =
2592 FunctionType::get(FTy->getReturnType(), NewFuncParamTys, false);
2593 FTyID = lookupType(NewFTy);
2594 } else {
2595 // Handle function with global constant parameters.
2596 if (GlobalConstFuncTyMap.count(FTy)) {
2597 FTyID = lookupType(GlobalConstFuncTyMap[FTy].first);
2598 } else {
2599 FTyID = lookupType(FTy);
2600 }
2601 }
2602
2603 SPIRVOperand *FTyOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, FTyID);
2604 FOps.push_back(FTyOp);
2605
2606 if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
2607 EntryPoints.push_back(std::make_pair(&F, nextID));
2608 }
2609
2610 VMap[&F] = nextID;
2611
2612 // Generate SPIRV instruction for function.
2613 SPIRVInstruction *FuncInst =
2614 new SPIRVInstruction(5, spv::OpFunction, nextID++, FOps);
2615 SPIRVInstList.push_back(FuncInst);
2616
2617 //
2618 // Generate OpFunctionParameter for Normal function.
2619 //
2620
2621 if (F.getCallingConv() != CallingConv::SPIR_KERNEL) {
2622 // Iterate Argument for name instead of param type from function type.
2623 unsigned ArgIdx = 0;
2624 for (Argument &Arg : F.args()) {
2625 VMap[&Arg] = nextID;
2626
2627 // ParamOps[0] : Result Type ID
2628 SPIRVOperandList ParamOps;
2629
2630 // Find SPIRV instruction for parameter type.
2631 uint32_t ParamTyID = lookupType(Arg.getType());
2632 if (PointerType *PTy = dyn_cast<PointerType>(Arg.getType())) {
2633 if (GlobalConstFuncTyMap.count(FTy)) {
2634 if (ArgIdx == GlobalConstFuncTyMap[FTy].second) {
2635 Type *EleTy = PTy->getPointerElementType();
2636 Type *ArgTy =
2637 PointerType::get(EleTy, AddressSpace::ModuleScopePrivate);
2638 ParamTyID = lookupType(ArgTy);
2639 GlobalConstArgSet.insert(&Arg);
2640 }
2641 }
2642 }
2643 SPIRVOperand *ParamTyOp =
2644 new SPIRVOperand(SPIRVOperandType::NUMBERID, ParamTyID);
2645 ParamOps.push_back(ParamTyOp);
2646
2647 // Generate SPIRV instruction for parameter.
2648 SPIRVInstruction *ParamInst =
2649 new SPIRVInstruction(3, spv::OpFunctionParameter, nextID++, ParamOps);
2650 SPIRVInstList.push_back(ParamInst);
2651
2652 ArgIdx++;
2653 }
2654 }
2655}
2656
2657void SPIRVProducerPass::GenerateModuleInfo() {
2658 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
2659 EntryPointVecType &EntryPoints = getEntryPointVec();
2660 ValueMapType &VMap = getValueMap();
2661 ValueList &EntryPointInterfaces = getEntryPointInterfacesVec();
2662 uint32_t &ExtInstImportID = getOpExtInstImportID();
2663 std::vector<uint32_t> &BuiltinDimVec = getBuiltinDimVec();
2664
2665 // Set up insert point.
2666 auto InsertPoint = SPIRVInstList.begin();
2667
2668 //
2669 // Generate OpCapability
2670 //
2671 // TODO: Which llvm information is mapped to SPIRV Capapbility?
2672
2673 // Ops[0] = Capability
2674 SPIRVOperandList Ops;
2675
2676 SPIRVInstruction *CapInst = new SPIRVInstruction(
2677 2, spv::OpCapability, 0 /* No id */,
2678 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::CapabilityShader));
2679 SPIRVInstList.insert(InsertPoint, CapInst);
2680
2681 for (Type *Ty : getTypeList()) {
2682 // Find the i16 type.
2683 if (Ty->isIntegerTy(16)) {
2684 // Generate OpCapability for i16 type.
2685 SPIRVInstList.insert(
2686 InsertPoint,
2687 new SPIRVInstruction(2, spv::OpCapability, 0 /* No id */,
2688 new SPIRVOperand(SPIRVOperandType::NUMBERID,
2689 spv::CapabilityInt16)));
2690 } else if (Ty->isIntegerTy(64)) {
2691 // Generate OpCapability for i64 type.
2692 SPIRVInstList.insert(
2693 InsertPoint,
2694 new SPIRVInstruction(2, spv::OpCapability, 0 /* No id */,
2695 new SPIRVOperand(SPIRVOperandType::NUMBERID,
2696 spv::CapabilityInt64)));
2697 } else if (Ty->isHalfTy()) {
2698 // Generate OpCapability for half type.
2699 SPIRVInstList.insert(
2700 InsertPoint,
2701 new SPIRVInstruction(2, spv::OpCapability, 0 /* No id */,
2702 new SPIRVOperand(SPIRVOperandType::NUMBERID,
2703 spv::CapabilityFloat16)));
2704 } else if (Ty->isDoubleTy()) {
2705 // Generate OpCapability for double type.
2706 SPIRVInstList.insert(
2707 InsertPoint,
2708 new SPIRVInstruction(2, spv::OpCapability, 0 /* No id */,
2709 new SPIRVOperand(SPIRVOperandType::NUMBERID,
2710 spv::CapabilityFloat64)));
2711 } else if (auto *STy = dyn_cast<StructType>(Ty)) {
2712 if (STy->isOpaque()) {
2713 if (STy->getName().equals("opencl.image2d_ro_t") ||
2714 STy->getName().equals("opencl.image3d_ro_t")) {
2715 // Generate OpCapability for read only image type.
2716 SPIRVInstList.insert(
2717 InsertPoint,
2718 new SPIRVInstruction(
2719 2, spv::OpCapability, 0 /* No id */,
2720 new SPIRVOperand(
2721 SPIRVOperandType::NUMBERID,
2722 spv::CapabilityStorageImageReadWithoutFormat)));
2723 } else if (STy->getName().equals("opencl.image2d_wo_t") ||
2724 STy->getName().equals("opencl.image3d_wo_t")) {
2725 // Generate OpCapability for write only image type.
2726 SPIRVInstList.insert(
2727 InsertPoint,
2728 new SPIRVInstruction(
2729 2, spv::OpCapability, 0 /* No id */,
2730 new SPIRVOperand(
2731 SPIRVOperandType::NUMBERID,
2732 spv::CapabilityStorageImageWriteWithoutFormat)));
2733 }
2734 }
2735 }
2736 }
2737
2738 if (hasVariablePointers()) {
2739 //
2740 // Generate OpCapability and OpExtension
2741 //
2742
2743 //
2744 // Generate OpCapability.
2745 //
2746 // Ops[0] = Capability
2747 //
2748 Ops.clear();
2749
2750 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
2751 spv::CapabilityVariablePointers));
2752
2753 SPIRVInstList.insert(InsertPoint, new SPIRVInstruction(2, spv::OpCapability,
2754 0 /* No id */, Ops));
2755
2756 //
2757 // Generate OpExtension.
2758 //
2759 // Ops[0] = Name (Literal String)
2760 //
2761 Ops.clear();
2762
2763 SPIRVOperand *Name = new SPIRVOperand(SPIRVOperandType::LITERAL_STRING,
2764 "SPV_KHR_variable_pointers");
2765 Ops.push_back(Name);
2766
2767 size_t NameWordSize = (Name->getLiteralStr().size() + 1) / 4;
2768 if ((Name->getLiteralStr().size() + 1) % 4) {
2769 NameWordSize += 1;
2770 }
2771
2772 assert((NameWordSize + 1) < UINT16_MAX);
2773 uint16_t WordCount = static_cast<uint16_t>(1 + NameWordSize);
2774
2775 SPIRVInstruction *ExtensionInst =
2776 new SPIRVInstruction(WordCount, spv::OpExtension, 0 /* No id */, Ops);
2777 SPIRVInstList.insert(InsertPoint, ExtensionInst);
2778 }
2779
2780 if (ExtInstImportID) {
2781 ++InsertPoint;
2782 }
2783
2784 //
2785 // Generate OpMemoryModel
2786 //
2787 // Memory model for Vulkan will always be GLSL450.
2788
2789 // Ops[0] = Addressing Model
2790 // Ops[1] = Memory Model
2791 Ops.clear();
2792 SPIRVOperand *AddrModel =
2793 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::AddressingModelLogical);
2794 Ops.push_back(AddrModel);
2795
2796 SPIRVOperand *MemModel =
2797 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::MemoryModelGLSL450);
2798 Ops.push_back(MemModel);
2799
2800 SPIRVInstruction *MemModelInst =
2801 new SPIRVInstruction(3, spv::OpMemoryModel, 0 /* No id */, Ops);
2802 SPIRVInstList.insert(InsertPoint, MemModelInst);
2803
2804 //
2805 // Generate OpEntryPoint
2806 //
2807 for (auto EntryPoint : EntryPoints) {
2808 // Ops[0] = Execution Model
2809 // Ops[1] = EntryPoint ID
2810 // Ops[2] = Name (Literal String)
2811 // ...
2812 //
2813 // TODO: Do we need to consider Interface ID for forward references???
2814 Ops.clear();
2815 SPIRVOperand *ExecModel = new SPIRVOperand(SPIRVOperandType::NUMBERID,
2816 spv::ExecutionModelGLCompute);
2817 Ops.push_back(ExecModel);
2818
2819 SPIRVOperand *EntryPointID =
2820 new SPIRVOperand(SPIRVOperandType::NUMBERID, EntryPoint.second);
2821 Ops.push_back(EntryPointID);
2822
2823 SPIRVOperand *Name = new SPIRVOperand(SPIRVOperandType::LITERAL_STRING,
2824 EntryPoint.first->getName());
2825 Ops.push_back(Name);
2826
2827 size_t NameWordSize = (Name->getLiteralStr().size() + 1) / 4;
2828 if ((Name->getLiteralStr().size() + 1) % 4) {
2829 NameWordSize += 1;
2830 }
2831
2832 assert((3 + NameWordSize) < UINT16_MAX);
2833 uint16_t WordCount = static_cast<uint16_t>(3 + NameWordSize);
2834
2835 for (Value *Interface : EntryPointInterfaces) {
2836 SPIRVOperand *GIDOp =
2837 new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[Interface]);
2838 Ops.push_back(GIDOp);
2839 WordCount++;
2840 }
2841
2842 SPIRVInstruction *EntryPointInst =
2843 new SPIRVInstruction(WordCount, spv::OpEntryPoint, 0 /* No id */, Ops);
2844 SPIRVInstList.insert(InsertPoint, EntryPointInst);
2845 }
2846
2847 for (auto EntryPoint : EntryPoints) {
2848 if (const MDNode *MD = dyn_cast<Function>(EntryPoint.first)
2849 ->getMetadata("reqd_work_group_size")) {
2850
2851 if (!BuiltinDimVec.empty()) {
2852 llvm_unreachable(
2853 "Kernels should have consistent work group size definition");
2854 }
2855
2856 //
2857 // Generate OpExecutionMode
2858 //
2859
2860 // Ops[0] = Entry Point ID
2861 // Ops[1] = Execution Mode
2862 // Ops[2] ... Ops[n] = Optional literals according to Execution Mode
2863 Ops.clear();
2864 SPIRVOperand *EntryPointID =
2865 new SPIRVOperand(SPIRVOperandType::NUMBERID, EntryPoint.second);
2866 Ops.push_back(EntryPointID);
2867
2868 SPIRVOperand *ExecMode = new SPIRVOperand(SPIRVOperandType::NUMBERID,
2869 spv::ExecutionModeLocalSize);
2870 Ops.push_back(ExecMode);
2871
2872 uint32_t XDim = static_cast<uint32_t>(
2873 mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue());
2874 uint32_t YDim = static_cast<uint32_t>(
2875 mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue());
2876 uint32_t ZDim = static_cast<uint32_t>(
2877 mdconst::extract<ConstantInt>(MD->getOperand(2))->getZExtValue());
2878
2879 std::vector<uint32_t> LiteralNum;
2880 LiteralNum.push_back(XDim);
2881 SPIRVOperand *XDimOp =
2882 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2883 Ops.push_back(XDimOp);
2884
2885 LiteralNum.clear();
2886 LiteralNum.push_back(YDim);
2887 SPIRVOperand *YDimOp =
2888 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2889 Ops.push_back(YDimOp);
2890
2891 LiteralNum.clear();
2892 LiteralNum.push_back(ZDim);
2893 SPIRVOperand *ZDimOp =
2894 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2895 Ops.push_back(ZDimOp);
2896
2897 SPIRVInstruction *ExecModeInst =
2898 new SPIRVInstruction(static_cast<uint16_t>(1 + Ops.size()),
2899 spv::OpExecutionMode, 0 /* No id */, Ops);
2900 SPIRVInstList.insert(InsertPoint, ExecModeInst);
2901 }
2902 }
2903
2904 //
2905 // Generate OpSource.
2906 //
2907 // Ops[0] = SourceLanguage ID
2908 // Ops[1] = Version (LiteralNum)
2909 //
2910 Ops.clear();
2911 SPIRVOperand *SourceLanguage =
2912 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::SourceLanguageOpenCL_C);
2913 Ops.push_back(SourceLanguage);
2914
2915 std::vector<uint32_t> LiteralNum;
2916 LiteralNum.push_back(120);
2917 SPIRVOperand *Version =
2918 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2919 Ops.push_back(Version);
2920
2921 SPIRVInstruction *OpenSourceInst =
2922 new SPIRVInstruction(3, spv::OpSource, 0 /* No id */, Ops);
2923 SPIRVInstList.insert(InsertPoint, OpenSourceInst);
2924
2925 if (!BuiltinDimVec.empty()) {
2926 //
2927 // Generate OpDecorates for x/y/z dimension.
2928 //
2929 // Ops[0] = Target ID
2930 // Ops[1] = Decoration (SpecId)
2931 // Ops[2] = Specialization Cosntant ID (Literal Number)
2932
2933 // X Dimension
2934 Ops.clear();
2935
2936 SPIRVOperand *TargetID =
2937 new SPIRVOperand(SPIRVOperandType::NUMBERID, BuiltinDimVec[0]);
2938 Ops.push_back(TargetID);
2939
2940 SPIRVOperand *DecoOp =
2941 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::DecorationSpecId);
2942 Ops.push_back(DecoOp);
2943
2944 LiteralNum.clear();
2945 LiteralNum.push_back(0);
2946 SPIRVOperand *XDim =
2947 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2948 Ops.push_back(XDim);
2949
2950 SPIRVInstruction *XDimDecoInst =
2951 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2952 SPIRVInstList.insert(InsertPoint, XDimDecoInst);
2953
2954 // Y Dimension
2955 Ops.clear();
2956
2957 TargetID = new SPIRVOperand(SPIRVOperandType::NUMBERID, BuiltinDimVec[1]);
2958 Ops.push_back(TargetID);
2959
2960 DecoOp =
2961 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::DecorationSpecId);
2962 Ops.push_back(DecoOp);
2963
2964 LiteralNum.clear();
2965 LiteralNum.push_back(1);
2966 SPIRVOperand *YDim =
2967 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2968 Ops.push_back(YDim);
2969
2970 SPIRVInstruction *YDimDecoInst =
2971 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2972 SPIRVInstList.insert(InsertPoint, YDimDecoInst);
2973
2974 // Z Dimension
2975 Ops.clear();
2976
2977 TargetID = new SPIRVOperand(SPIRVOperandType::NUMBERID, BuiltinDimVec[2]);
2978 Ops.push_back(TargetID);
2979
2980 DecoOp =
2981 new SPIRVOperand(SPIRVOperandType::NUMBERID, spv::DecorationSpecId);
2982 Ops.push_back(DecoOp);
2983
2984 LiteralNum.clear();
2985 LiteralNum.push_back(2);
2986 SPIRVOperand *ZDim =
2987 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
2988 Ops.push_back(ZDim);
2989
2990 SPIRVInstruction *ZDimDecoInst =
2991 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
2992 SPIRVInstList.insert(InsertPoint, ZDimDecoInst);
2993 }
2994}
2995
2996void SPIRVProducerPass::GenerateInstForArg(Function &F) {
2997 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
2998 ValueMapType &VMap = getValueMap();
2999 Module *Module = F.getParent();
3000 LLVMContext &Context = Module->getContext();
3001 ValueToValueMapTy &ArgGVMap = getArgumentGVMap();
3002
3003 for (Argument &Arg : F.args()) {
3004 if (Arg.use_empty()) {
3005 continue;
3006 }
3007
3008 // Check the type of users of arguments.
3009 bool HasOnlyGEPUse = true;
3010 for (auto *U : Arg.users()) {
3011 if (!isa<GetElementPtrInst>(U) && isa<Instruction>(U)) {
3012 HasOnlyGEPUse = false;
3013 break;
3014 }
3015 }
3016
3017 Type *ArgTy = Arg.getType();
3018
3019 if (PointerType *PTy = dyn_cast<PointerType>(ArgTy)) {
3020 if (StructType *STy = dyn_cast<StructType>(PTy->getElementType())) {
3021 if (STy->isOpaque()) {
3022 // Generate OpLoad for sampler and image types.
3023 if (STy->getName().equals("opencl.sampler_t") ||
3024 STy->getName().equals("opencl.image2d_ro_t") ||
3025 STy->getName().equals("opencl.image2d_wo_t") ||
3026 STy->getName().equals("opencl.image3d_ro_t") ||
3027 STy->getName().equals("opencl.image3d_wo_t")) {
3028 //
3029 // Generate OpLoad.
3030 //
3031 // Ops[0] = Result Type ID
3032 // Ops[1] = Pointer ID
3033 // Ops[2] ... Ops[n] = Optional Memory Access
3034 //
3035 // TODO: Do we need to implement Optional Memory Access???
3036 SPIRVOperandList Ops;
3037
3038 // Use type with address space modified.
3039 ArgTy = ArgGVMap[&Arg]->getType()->getPointerElementType();
3040
3041 uint32_t ResTyID = lookupType(ArgTy);
3042 SPIRVOperand *ResTyIDOp =
3043 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3044 Ops.push_back(ResTyIDOp);
3045
3046 uint32_t PointerID = VMap[&Arg];
3047 SPIRVOperand *PointerIDOp =
3048 new SPIRVOperand(SPIRVOperandType::NUMBERID, PointerID);
3049 Ops.push_back(PointerIDOp);
3050
3051 VMap[&Arg] = nextID;
3052 SPIRVInstruction *Inst =
3053 new SPIRVInstruction(4, spv::OpLoad, nextID++, Ops);
3054 SPIRVInstList.push_back(Inst);
3055 continue;
3056 }
3057 }
3058 }
3059
3060 if (!HasOnlyGEPUse) {
3061 //
3062 // Generate OpAccessChain.
3063 //
3064 // Ops[0] = Result Type ID
3065 // Ops[1] = Base ID
3066 // Ops[2] ... Ops[n] = Indexes ID
3067 SPIRVOperandList Ops;
3068
3069 uint32_t ResTyID = lookupType(ArgTy);
3070 if (!isa<PointerType>(ArgTy)) {
3071 ResTyID = lookupType(PointerType::get(ArgTy, AddressSpace::Global));
3072 }
3073 SPIRVOperand *ResTyOp =
3074 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3075 Ops.push_back(ResTyOp);
3076
3077 uint32_t BaseID = VMap[&Arg];
3078 SPIRVOperand *BaseOp =
3079 new SPIRVOperand(SPIRVOperandType::NUMBERID, BaseID);
3080 Ops.push_back(BaseOp);
3081
3082 Type *IdxTy = Type::getInt32Ty(Context);
3083 uint32_t IndexID = VMap[ConstantInt::get(IdxTy, 0)];
3084 SPIRVOperand *IndexIDOp =
3085 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3086 Ops.push_back(IndexIDOp);
3087 Ops.push_back(IndexIDOp);
3088
3089 // Generate SPIRV instruction for argument.
3090 VMap[&Arg] = nextID;
3091 SPIRVInstruction *ArgInst =
3092 new SPIRVInstruction(6, spv::OpAccessChain, nextID++, Ops);
3093 SPIRVInstList.push_back(ArgInst);
3094 } else {
3095 // For GEP uses, generate OpAccessChain with folding GEP ahead of GEP.
3096 // Nothing to do here.
3097 }
3098 } else {
3099 //
3100 // Generate OpAccessChain and OpLoad for non-pointer type argument.
3101 //
3102
3103 //
3104 // Generate OpAccessChain.
3105 //
3106 // Ops[0] = Result Type ID
3107 // Ops[1] = Base ID
3108 // Ops[2] ... Ops[n] = Indexes ID
3109 SPIRVOperandList Ops;
3110
3111 uint32_t ResTyID = lookupType(ArgTy);
3112 if (!isa<PointerType>(ArgTy)) {
3113 ResTyID = lookupType(PointerType::get(ArgTy, AddressSpace::Global));
3114 }
3115 SPIRVOperand *ResTyIDOp =
3116 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3117 Ops.push_back(ResTyIDOp);
3118
3119 uint32_t BaseID = VMap[&Arg];
3120 SPIRVOperand *BaseOp =
3121 new SPIRVOperand(SPIRVOperandType::NUMBERID, BaseID);
3122 Ops.push_back(BaseOp);
3123
3124 Type *IdxTy = Type::getInt32Ty(Context);
3125 uint32_t IndexID = VMap[ConstantInt::get(IdxTy, 0)];
3126 SPIRVOperand *IndexIDOp =
3127 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3128 Ops.push_back(IndexIDOp);
3129
3130 // Generate SPIRV instruction for argument.
3131 uint32_t PointerID = nextID;
3132 VMap[&Arg] = nextID;
3133 SPIRVInstruction *ArgInst =
3134 new SPIRVInstruction(5, spv::OpAccessChain, nextID++, Ops);
3135 SPIRVInstList.push_back(ArgInst);
3136
3137 //
3138 // Generate OpLoad.
3139 //
3140
3141 // Ops[0] = Result Type ID
3142 // Ops[1] = Pointer ID
3143 // Ops[2] ... Ops[n] = Optional Memory Access
3144 //
3145 // TODO: Do we need to implement Optional Memory Access???
3146 Ops.clear();
3147
3148 ResTyID = lookupType(ArgTy);
3149 ResTyIDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3150 Ops.push_back(ResTyIDOp);
3151
3152 SPIRVOperand *PointerIDOp =
3153 new SPIRVOperand(SPIRVOperandType::NUMBERID, PointerID);
3154 Ops.push_back(PointerIDOp);
3155
3156 VMap[&Arg] = nextID;
3157 SPIRVInstruction *Inst =
3158 new SPIRVInstruction(4, spv::OpLoad, nextID++, Ops);
3159 SPIRVInstList.push_back(Inst);
3160 }
3161 }
3162}
3163
3164void SPIRVProducerPass::GenerateFuncBody(Function &F) {
3165 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
3166 ValueMapType &VMap = getValueMap();
3167
3168 bool IsKernel = false;
3169 if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
3170 IsKernel = true;
3171 }
3172
3173 for (BasicBlock &BB : F) {
3174 // Register BasicBlock to ValueMap.
3175 VMap[&BB] = nextID;
3176
3177 //
3178 // Generate OpLabel for Basic Block.
3179 //
3180 SPIRVOperandList Ops;
3181 SPIRVInstruction *Inst =
3182 new SPIRVInstruction(2, spv::OpLabel, nextID++, Ops);
3183 SPIRVInstList.push_back(Inst);
3184
David Neto6dcd4712017-06-23 11:06:47 -04003185 // OpVariable instructions must come first.
3186 for (Instruction &I : BB) {
3187 if (isa<AllocaInst>(I)) {
3188 GenerateInstruction(I);
3189 }
3190 }
3191
David Neto22f144c2017-06-12 14:26:21 -04003192 if (&BB == &F.getEntryBlock() && IsKernel) {
3193 GenerateInstForArg(F);
3194 }
3195
3196 for (Instruction &I : BB) {
David Neto6dcd4712017-06-23 11:06:47 -04003197 if (!isa<AllocaInst>(I)) {
3198 GenerateInstruction(I);
3199 }
David Neto22f144c2017-06-12 14:26:21 -04003200 }
3201 }
3202}
3203
3204spv::Op SPIRVProducerPass::GetSPIRVCmpOpcode(CmpInst *I) {
3205 const std::map<CmpInst::Predicate, spv::Op> Map = {
3206 {CmpInst::ICMP_EQ, spv::OpIEqual},
3207 {CmpInst::ICMP_NE, spv::OpINotEqual},
3208 {CmpInst::ICMP_UGT, spv::OpUGreaterThan},
3209 {CmpInst::ICMP_UGE, spv::OpUGreaterThanEqual},
3210 {CmpInst::ICMP_ULT, spv::OpULessThan},
3211 {CmpInst::ICMP_ULE, spv::OpULessThanEqual},
3212 {CmpInst::ICMP_SGT, spv::OpSGreaterThan},
3213 {CmpInst::ICMP_SGE, spv::OpSGreaterThanEqual},
3214 {CmpInst::ICMP_SLT, spv::OpSLessThan},
3215 {CmpInst::ICMP_SLE, spv::OpSLessThanEqual},
3216 {CmpInst::FCMP_OEQ, spv::OpFOrdEqual},
3217 {CmpInst::FCMP_OGT, spv::OpFOrdGreaterThan},
3218 {CmpInst::FCMP_OGE, spv::OpFOrdGreaterThanEqual},
3219 {CmpInst::FCMP_OLT, spv::OpFOrdLessThan},
3220 {CmpInst::FCMP_OLE, spv::OpFOrdLessThanEqual},
3221 {CmpInst::FCMP_ONE, spv::OpFOrdNotEqual},
3222 {CmpInst::FCMP_UEQ, spv::OpFUnordEqual},
3223 {CmpInst::FCMP_UGT, spv::OpFUnordGreaterThan},
3224 {CmpInst::FCMP_UGE, spv::OpFUnordGreaterThanEqual},
3225 {CmpInst::FCMP_ULT, spv::OpFUnordLessThan},
3226 {CmpInst::FCMP_ULE, spv::OpFUnordLessThanEqual},
3227 {CmpInst::FCMP_UNE, spv::OpFUnordNotEqual}};
3228
3229 assert(0 != Map.count(I->getPredicate()));
3230
3231 return Map.at(I->getPredicate());
3232}
3233
3234spv::Op SPIRVProducerPass::GetSPIRVCastOpcode(Instruction &I) {
3235 const std::map<unsigned, spv::Op> Map{
3236 {Instruction::Trunc, spv::OpUConvert},
3237 {Instruction::ZExt, spv::OpUConvert},
3238 {Instruction::SExt, spv::OpSConvert},
3239 {Instruction::FPToUI, spv::OpConvertFToU},
3240 {Instruction::FPToSI, spv::OpConvertFToS},
3241 {Instruction::UIToFP, spv::OpConvertUToF},
3242 {Instruction::SIToFP, spv::OpConvertSToF},
3243 {Instruction::FPTrunc, spv::OpFConvert},
3244 {Instruction::FPExt, spv::OpFConvert},
3245 {Instruction::BitCast, spv::OpBitcast}};
3246
3247 assert(0 != Map.count(I.getOpcode()));
3248
3249 return Map.at(I.getOpcode());
3250}
3251
3252spv::Op SPIRVProducerPass::GetSPIRVBinaryOpcode(Instruction &I) {
3253 if (I.getType()->isIntegerTy(1)) {
3254 switch (I.getOpcode()) {
3255 default:
3256 break;
3257 case Instruction::Or:
3258 return spv::OpLogicalOr;
3259 case Instruction::And:
3260 return spv::OpLogicalAnd;
3261 case Instruction::Xor:
3262 return spv::OpLogicalNotEqual;
3263 }
3264 }
3265
3266 const std::map<unsigned, spv::Op> Map {
3267 {Instruction::Add, spv::OpIAdd},
3268 {Instruction::FAdd, spv::OpFAdd},
3269 {Instruction::Sub, spv::OpISub},
3270 {Instruction::FSub, spv::OpFSub},
3271 {Instruction::Mul, spv::OpIMul},
3272 {Instruction::FMul, spv::OpFMul},
3273 {Instruction::UDiv, spv::OpUDiv},
3274 {Instruction::SDiv, spv::OpSDiv},
3275 {Instruction::FDiv, spv::OpFDiv},
3276 {Instruction::URem, spv::OpUMod},
3277 {Instruction::SRem, spv::OpSRem},
3278 {Instruction::FRem, spv::OpFRem},
3279 {Instruction::Or, spv::OpBitwiseOr},
3280 {Instruction::Xor, spv::OpBitwiseXor},
3281 {Instruction::And, spv::OpBitwiseAnd},
3282 {Instruction::Shl, spv::OpShiftLeftLogical},
3283 {Instruction::LShr, spv::OpShiftRightLogical},
3284 {Instruction::AShr, spv::OpShiftRightArithmetic}};
3285
3286 assert(0 != Map.count(I.getOpcode()));
3287
3288 return Map.at(I.getOpcode());
3289}
3290
3291void SPIRVProducerPass::GenerateInstruction(Instruction &I) {
3292 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
3293 ValueMapType &VMap = getValueMap();
3294 ValueToValueMapTy &ArgGVMap = getArgumentGVMap();
3295 ValueMapType &ArgGVIDMap = getArgumentGVIDMap();
3296 DeferredInstVecType &DeferredInsts = getDeferredInstVec();
3297 LLVMContext &Context = I.getParent()->getParent()->getParent()->getContext();
3298
3299 // Register Instruction to ValueMap.
3300 if (0 == VMap[&I]) {
3301 VMap[&I] = nextID;
3302 }
3303
3304 switch (I.getOpcode()) {
3305 default: {
3306 if (Instruction::isCast(I.getOpcode())) {
3307 //
3308 // Generate SPIRV instructions for cast operators.
3309 //
3310
3311 auto OpTy = I.getOperand(0)->getType();
3312 // Handle zext, sext and uitofp with i1 type specially.
3313 if ((I.getOpcode() == Instruction::ZExt ||
3314 I.getOpcode() == Instruction::SExt ||
3315 I.getOpcode() == Instruction::UIToFP) &&
3316 (OpTy->isIntegerTy(1) ||
3317 (OpTy->isVectorTy() &&
3318 OpTy->getVectorElementType()->isIntegerTy(1)))) {
3319 //
3320 // Generate OpSelect.
3321 //
3322
3323 // Ops[0] = Result Type ID
3324 // Ops[1] = Condition ID
3325 // Ops[2] = True Constant ID
3326 // Ops[3] = False Constant ID
3327 SPIRVOperandList Ops;
3328
3329 uint32_t ResTyID = lookupType(I.getType());
3330 SPIRVOperand *ResTyIDOp =
3331 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3332 Ops.push_back(ResTyIDOp);
3333
3334 // TODO: zext's first operand should be compare instructions???
3335 uint32_t CondID = VMap[I.getOperand(0)];
3336 SPIRVOperand *CondIDOp =
3337 new SPIRVOperand(SPIRVOperandType::NUMBERID, CondID);
3338 Ops.push_back(CondIDOp);
3339
3340 uint32_t TrueID = 0;
3341 if (I.getOpcode() == Instruction::ZExt) {
3342 APInt One(32, 1);
3343 TrueID = VMap[Constant::getIntegerValue(I.getType(), One)];
3344 } else if (I.getOpcode() == Instruction::SExt) {
3345 APInt MinusOne(32, UINT64_MAX, true);
3346 TrueID = VMap[Constant::getIntegerValue(I.getType(), MinusOne)];
3347 } else {
3348 TrueID = VMap[ConstantFP::get(Context, APFloat(1.0f))];
3349 }
3350 SPIRVOperand *TrueIDOp =
3351 new SPIRVOperand(SPIRVOperandType::NUMBERID, TrueID);
3352 Ops.push_back(TrueIDOp);
3353
3354 uint32_t FalseID = 0;
3355 if (I.getOpcode() == Instruction::ZExt) {
3356 FalseID = VMap[Constant::getNullValue(I.getType())];
3357 } else if (I.getOpcode() == Instruction::SExt) {
3358 FalseID = VMap[Constant::getNullValue(I.getType())];
3359 } else {
3360 FalseID = VMap[ConstantFP::get(Context, APFloat(0.0f))];
3361 }
3362 SPIRVOperand *FalseIDOp =
3363 new SPIRVOperand(SPIRVOperandType::NUMBERID, FalseID);
3364 Ops.push_back(FalseIDOp);
3365
3366 SPIRVInstruction *Inst =
3367 new SPIRVInstruction(6, spv::OpSelect, nextID++, Ops);
3368 SPIRVInstList.push_back(Inst);
3369 } else {
3370 // Ops[0] = Result Type ID
3371 // Ops[1] = Source Value ID
3372 SPIRVOperandList Ops;
3373
3374 uint32_t ResTyID = lookupType(I.getType());
3375 SPIRVOperand *ResTyIDOp =
3376 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3377 Ops.push_back(ResTyIDOp);
3378
3379 uint32_t SrcID = VMap[I.getOperand(0)];
3380 SPIRVOperand *SrcIDOp =
3381 new SPIRVOperand(SPIRVOperandType::NUMBERID, SrcID);
3382 Ops.push_back(SrcIDOp);
3383
3384 SPIRVInstruction *Inst =
3385 new SPIRVInstruction(4, GetSPIRVCastOpcode(I), nextID++, Ops);
3386 SPIRVInstList.push_back(Inst);
3387 }
3388 } else if (isa<BinaryOperator>(I)) {
3389 //
3390 // Generate SPIRV instructions for binary operators.
3391 //
3392
3393 // Handle xor with i1 type specially.
3394 if (I.getOpcode() == Instruction::Xor &&
3395 I.getType() == Type::getInt1Ty(Context) &&
3396 (isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
3397 //
3398 // Generate OpLogicalNot.
3399 //
3400 // Ops[0] = Result Type ID
3401 // Ops[1] = Operand
3402 SPIRVOperandList Ops;
3403
3404 uint32_t ResTyID = lookupType(I.getType());
3405 SPIRVOperand *ResTyIDOp =
3406 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3407 Ops.push_back(ResTyIDOp);
3408
3409 Value *CondV = I.getOperand(0);
3410 if (isa<Constant>(I.getOperand(0))) {
3411 CondV = I.getOperand(1);
3412 }
3413 uint32_t CondID = VMap[CondV];
3414 SPIRVOperand *CondIDOp =
3415 new SPIRVOperand(SPIRVOperandType::NUMBERID, CondID);
3416 Ops.push_back(CondIDOp);
3417
3418 SPIRVInstruction *Inst =
3419 new SPIRVInstruction(4, spv::OpLogicalNot, nextID++, Ops);
3420 SPIRVInstList.push_back(Inst);
3421 } else {
3422 // Ops[0] = Result Type ID
3423 // Ops[1] = Operand 0
3424 // Ops[2] = Operand 1
3425 SPIRVOperandList Ops;
3426
3427 uint32_t ResTyID = lookupType(I.getType());
3428 SPIRVOperand *ResTyIDOp =
3429 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3430 Ops.push_back(ResTyIDOp);
3431
3432 uint32_t Op0ID = VMap[I.getOperand(0)];
3433 SPIRVOperand *Op0IDOp =
3434 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3435 Ops.push_back(Op0IDOp);
3436
3437 uint32_t Op1ID = VMap[I.getOperand(1)];
3438 SPIRVOperand *Op1IDOp =
3439 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3440 Ops.push_back(Op1IDOp);
3441
3442 SPIRVInstruction *Inst =
3443 new SPIRVInstruction(5, GetSPIRVBinaryOpcode(I), nextID++, Ops);
3444 SPIRVInstList.push_back(Inst);
3445 }
3446 } else {
3447 I.print(errs());
3448 llvm_unreachable("Unsupported instruction???");
3449 }
3450 break;
3451 }
3452 case Instruction::GetElementPtr: {
3453 auto &GlobalConstArgSet = getGlobalConstArgSet();
3454
3455 //
3456 // Generate OpAccessChain.
3457 //
3458 GetElementPtrInst *GEP = cast<GetElementPtrInst>(&I);
3459
3460 //
3461 // Generate OpAccessChain.
3462 //
3463
3464 // Ops[0] = Result Type ID
3465 // Ops[1] = Base ID
3466 // Ops[2] ... Ops[n] = Indexes ID
3467 SPIRVOperandList Ops;
3468
David Neto1a1a0582017-07-07 12:01:44 -04003469 PointerType* ResultType = cast<PointerType>(GEP->getType());
David Neto22f144c2017-06-12 14:26:21 -04003470 if (GEP->getPointerAddressSpace() == AddressSpace::ModuleScopePrivate ||
3471 GlobalConstArgSet.count(GEP->getPointerOperand())) {
3472 // Use pointer type with private address space for global constant.
3473 Type *EleTy = I.getType()->getPointerElementType();
David Neto1a1a0582017-07-07 12:01:44 -04003474 ResultType = PointerType::get(EleTy, AddressSpace::ModuleScopePrivate);
David Neto22f144c2017-06-12 14:26:21 -04003475 }
David Neto1a1a0582017-07-07 12:01:44 -04003476 const uint32_t ResTyID = lookupType(ResultType);
David Neto22f144c2017-06-12 14:26:21 -04003477 SPIRVOperand *ResTyIDOp =
3478 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3479 Ops.push_back(ResTyIDOp);
3480
3481 // Check whether GEP's pointer operand is pointer argument.
3482 bool HasArgBasePointer = false;
3483 for (auto ArgGV : ArgGVMap) {
3484 if (ArgGV.first == GEP->getPointerOperand()) {
3485 if (isa<PointerType>(ArgGV.first->getType())) {
3486 HasArgBasePointer = true;
3487 } else {
3488 llvm_unreachable(
3489 "GEP's pointer operand is argument of non-poninter type???");
3490 }
3491 }
3492 }
3493
3494 uint32_t BaseID;
3495 if (HasArgBasePointer) {
3496 // Point to global variable for argument directly.
3497 BaseID = ArgGVIDMap[GEP->getPointerOperand()];
3498 } else {
3499 BaseID = VMap[GEP->getPointerOperand()];
3500 }
3501
3502 SPIRVOperand *BaseIDOp =
3503 new SPIRVOperand(SPIRVOperandType::NUMBERID, BaseID);
3504 Ops.push_back(BaseIDOp);
3505
3506 uint16_t WordCount = 4;
3507
3508 if (HasArgBasePointer) {
3509 // If GEP's pointer operand is argument, add one more index for struct
3510 // type to wrap up argument type.
3511 Type *IdxTy = Type::getInt32Ty(Context);
3512 uint32_t IndexID = VMap[ConstantInt::get(IdxTy, 0)];
3513 SPIRVOperand *IndexIDOp =
3514 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3515 Ops.push_back(IndexIDOp);
3516
3517 WordCount++;
3518 }
3519
3520 //
3521 // Follows below rules for gep.
3522 //
3523 // 1. If gep's first index is 0 and gep's base is not kernel function's
3524 // argument, generate OpAccessChain and ignore gep's first index.
3525 // 2. If gep's first index is not 0, generate OpPtrAccessChain and use gep's
3526 // first index.
3527 // 3. If gep's first index is not constant, generate OpPtrAccessChain and
3528 // use gep's first index.
3529 // 4. If it is not above case 1, 2 and 3, generate OpAccessChain and use
3530 // gep's first index.
3531 //
3532 spv::Op Opcode = spv::OpAccessChain;
3533 unsigned offset = 0;
3534 if (ConstantInt *CstInt = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
3535 if (CstInt->getZExtValue() == 0 && !HasArgBasePointer) {
3536 offset = 1;
3537 } else if (CstInt->getZExtValue() != 0 && !HasArgBasePointer) {
3538 Opcode = spv::OpPtrAccessChain;
David Neto22f144c2017-06-12 14:26:21 -04003539 }
3540 } else if (!HasArgBasePointer) {
3541 Opcode = spv::OpPtrAccessChain;
David Neto1a1a0582017-07-07 12:01:44 -04003542 }
3543
3544 if (Opcode == spv::OpPtrAccessChain) {
David Neto22f144c2017-06-12 14:26:21 -04003545 setVariablePointers(true);
David Neto1a1a0582017-07-07 12:01:44 -04003546 // Do we need to generate ArrayStride? Check against the GEP result type
3547 // rather than the pointer type of the base because when indexing into
3548 // an OpenCL program-scope constant, we'll swap out the LLVM base pointer
3549 // for something else in the SPIR-V.
3550 // E.g. see test/PointerAccessChain/pointer_index_is_constant_1.cl
3551 if (GetStorageClass(ResultType->getAddressSpace()) ==
3552 spv::StorageClassStorageBuffer) {
3553 // Save the need to generate an ArrayStride decoration. But defer
3554 // generation until later, so we only make one decoration.
3555 getPointerTypesNeedingArrayStride().insert(ResultType);
3556 }
David Neto22f144c2017-06-12 14:26:21 -04003557 }
3558
3559 for (auto II = GEP->idx_begin() + offset; II != GEP->idx_end(); II++) {
3560 uint32_t IndexID = VMap[*II];
3561 SPIRVOperand *IndexIDOp =
3562 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3563 Ops.push_back(IndexIDOp);
3564
3565 WordCount++;
3566 }
3567
3568 SPIRVInstruction *Inst =
3569 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
3570 SPIRVInstList.push_back(Inst);
3571 break;
3572 }
3573 case Instruction::ExtractValue: {
3574 ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
3575 // Ops[0] = Result Type ID
3576 // Ops[1] = Composite ID
3577 // Ops[2] ... Ops[n] = Indexes (Literal Number)
3578 SPIRVOperandList Ops;
3579
3580 uint32_t ResTyID = lookupType(I.getType());
3581 SPIRVOperand *ResTyIDOp =
3582 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3583 Ops.push_back(ResTyIDOp);
3584
3585 uint32_t CompositeID = VMap[EVI->getAggregateOperand()];
3586 SPIRVOperand *CompositeIDOp =
3587 new SPIRVOperand(SPIRVOperandType::NUMBERID, CompositeID);
3588 Ops.push_back(CompositeIDOp);
3589
3590 for (auto &Index : EVI->indices()) {
3591 Ops.push_back(new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, Index));
3592 }
3593
3594 uint16_t WordCount = static_cast<uint16_t>(2 + Ops.size());
3595 SPIRVInstruction *Inst =
3596 new SPIRVInstruction(WordCount, spv::OpCompositeExtract, nextID++, Ops);
3597 SPIRVInstList.push_back(Inst);
3598 break;
3599 }
3600 case Instruction::InsertValue: {
3601 InsertValueInst *IVI = cast<InsertValueInst>(&I);
3602 // Ops[0] = Result Type ID
3603 // Ops[1] = Object ID
3604 // Ops[2] = Composite ID
3605 // Ops[3] ... Ops[n] = Indexes (Literal Number)
3606 SPIRVOperandList Ops;
3607
3608 uint32_t ResTyID = lookupType(I.getType());
3609 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID));
3610
3611 uint32_t ObjectID = VMap[IVI->getInsertedValueOperand()];
3612 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, ObjectID));
3613
3614 uint32_t CompositeID = VMap[IVI->getAggregateOperand()];
3615 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, CompositeID));
3616
3617 for (auto &Index : IVI->indices()) {
3618 Ops.push_back(new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, Index));
3619 }
3620
3621 uint16_t WordCount = static_cast<uint16_t>(2 + Ops.size());
3622 SPIRVInstruction *Inst =
3623 new SPIRVInstruction(WordCount, spv::OpCompositeInsert, nextID++, Ops);
3624 SPIRVInstList.push_back(Inst);
3625 break;
3626 }
3627 case Instruction::Select: {
3628 //
3629 // Generate OpSelect.
3630 //
3631
3632 // Ops[0] = Result Type ID
3633 // Ops[1] = Condition ID
3634 // Ops[2] = True Constant ID
3635 // Ops[3] = False Constant ID
3636 SPIRVOperandList Ops;
3637
3638 // Find SPIRV instruction for parameter type.
3639 auto Ty = I.getType();
3640 if (Ty->isPointerTy()) {
3641 auto PointeeTy = Ty->getPointerElementType();
3642 if (PointeeTy->isStructTy() &&
3643 dyn_cast<StructType>(PointeeTy)->isOpaque()) {
3644 Ty = PointeeTy;
3645 }
3646 }
3647
3648 uint32_t ResTyID = lookupType(Ty);
3649 SPIRVOperand *ResTyIDOp =
3650 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3651 Ops.push_back(ResTyIDOp);
3652
3653 uint32_t CondID = VMap[I.getOperand(0)];
3654 SPIRVOperand *CondIDOp =
3655 new SPIRVOperand(SPIRVOperandType::NUMBERID, CondID);
3656 Ops.push_back(CondIDOp);
3657
3658 uint32_t TrueID = VMap[I.getOperand(1)];
3659 SPIRVOperand *TrueIDOp =
3660 new SPIRVOperand(SPIRVOperandType::NUMBERID, TrueID);
3661 Ops.push_back(TrueIDOp);
3662
3663 uint32_t FalseID = VMap[I.getOperand(2)];
3664 SPIRVOperand *FalseIDOp =
3665 new SPIRVOperand(SPIRVOperandType::NUMBERID, FalseID);
3666 Ops.push_back(FalseIDOp);
3667
3668 SPIRVInstruction *Inst =
3669 new SPIRVInstruction(6, spv::OpSelect, nextID++, Ops);
3670 SPIRVInstList.push_back(Inst);
3671 break;
3672 }
3673 case Instruction::ExtractElement: {
3674 // Handle <4 x i8> type manually.
3675 Type *CompositeTy = I.getOperand(0)->getType();
3676 if (is4xi8vec(CompositeTy)) {
3677 //
3678 // Generate OpShiftRightLogical and OpBitwiseAnd for extractelement with
3679 // <4 x i8>.
3680 //
3681
3682 //
3683 // Generate OpShiftRightLogical
3684 //
3685 // Ops[0] = Result Type ID
3686 // Ops[1] = Operand 0
3687 // Ops[2] = Operand 1
3688 //
3689 SPIRVOperandList Ops;
3690
3691 uint32_t ResTyID = lookupType(CompositeTy);
3692 SPIRVOperand *ResTyIDOp =
3693 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3694 Ops.push_back(ResTyIDOp);
3695
3696 uint32_t Op0ID = VMap[I.getOperand(0)];
3697 SPIRVOperand *Op0IDOp =
3698 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3699 Ops.push_back(Op0IDOp);
3700
3701 uint32_t Op1ID = 0;
3702 if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) {
3703 // Handle constant index.
3704 uint64_t Idx = CI->getZExtValue();
3705 Value *ShiftAmount =
3706 ConstantInt::get(Type::getInt32Ty(Context), Idx * 8);
3707 Op1ID = VMap[ShiftAmount];
3708 } else {
3709 // Handle variable index.
3710 SPIRVOperandList TmpOps;
3711
3712 uint32_t TmpResTyID = lookupType(Type::getInt32Ty(Context));
3713 SPIRVOperand *TmpResTyIDOp =
3714 new SPIRVOperand(SPIRVOperandType::NUMBERID, TmpResTyID);
3715 TmpOps.push_back(TmpResTyIDOp);
3716
3717 uint32_t IdxID = VMap[I.getOperand(1)];
3718 SPIRVOperand *TmpOp0IDOp =
3719 new SPIRVOperand(SPIRVOperandType::NUMBERID, IdxID);
3720 TmpOps.push_back(TmpOp0IDOp);
3721
3722 ConstantInt *Cst8 = ConstantInt::get(Type::getInt32Ty(Context), 8);
3723 uint32_t Cst8ID = VMap[Cst8];
3724 SPIRVOperand *TmpOp1IDOp =
3725 new SPIRVOperand(SPIRVOperandType::NUMBERID, Cst8ID);
3726 TmpOps.push_back(TmpOp1IDOp);
3727
3728 Op1ID = nextID;
3729
3730 SPIRVInstruction *TmpInst =
3731 new SPIRVInstruction(5, spv::OpIMul, nextID++, TmpOps);
3732 SPIRVInstList.push_back(TmpInst);
3733 }
3734 SPIRVOperand *Op1IDOp =
3735 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3736 Ops.push_back(Op1IDOp);
3737
3738 uint32_t ShiftID = nextID;
3739
3740 SPIRVInstruction *Inst =
3741 new SPIRVInstruction(5, spv::OpShiftRightLogical, nextID++, Ops);
3742 SPIRVInstList.push_back(Inst);
3743
3744 //
3745 // Generate OpBitwiseAnd
3746 //
3747 // Ops[0] = Result Type ID
3748 // Ops[1] = Operand 0
3749 // Ops[2] = Operand 1
3750 //
3751 Ops.clear();
3752
3753 ResTyID = lookupType(CompositeTy);
3754 ResTyIDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3755 Ops.push_back(ResTyIDOp);
3756
3757 Op0ID = ShiftID;
3758 Op0IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3759 Ops.push_back(Op0IDOp);
3760
3761 Constant *CstFF = ConstantInt::get(Type::getInt32Ty(Context), 0xFF);
3762 Op1ID = VMap[CstFF];
3763 Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3764 Ops.push_back(Op1IDOp);
3765
3766 Inst = new SPIRVInstruction(5, spv::OpBitwiseAnd, nextID++, Ops);
3767 SPIRVInstList.push_back(Inst);
3768 break;
3769 }
3770
3771 // Ops[0] = Result Type ID
3772 // Ops[1] = Composite ID
3773 // Ops[2] ... Ops[n] = Indexes (Literal Number)
3774 SPIRVOperandList Ops;
3775
3776 uint32_t ResTyID = lookupType(I.getType());
3777 SPIRVOperand *ResTyIDOp =
3778 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3779 Ops.push_back(ResTyIDOp);
3780
3781 uint32_t CompositeID = VMap[I.getOperand(0)];
3782 SPIRVOperand *CompositeIDOp =
3783 new SPIRVOperand(SPIRVOperandType::NUMBERID, CompositeID);
3784 Ops.push_back(CompositeIDOp);
3785
3786 spv::Op Opcode = spv::OpCompositeExtract;
3787 if (const ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) {
3788 std::vector<uint32_t> LiteralNum;
3789 assert(CI->getZExtValue() < UINT32_MAX);
3790 LiteralNum.push_back(static_cast<uint32_t>(CI->getZExtValue()));
3791 SPIRVOperand *Indexes =
3792 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
3793 Ops.push_back(Indexes);
3794 } else {
3795 uint32_t IndexID = VMap[I.getOperand(1)];
3796 SPIRVOperand *IndexIDOp =
3797 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3798 Ops.push_back(IndexIDOp);
3799 Opcode = spv::OpVectorExtractDynamic;
3800 }
3801
3802 uint16_t WordCount = 5;
3803 SPIRVInstruction *Inst =
3804 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
3805 SPIRVInstList.push_back(Inst);
3806 break;
3807 }
3808 case Instruction::InsertElement: {
3809 // Handle <4 x i8> type manually.
3810 Type *CompositeTy = I.getOperand(0)->getType();
3811 if (is4xi8vec(CompositeTy)) {
3812 Constant *CstFF = ConstantInt::get(Type::getInt32Ty(Context), 0xFF);
3813 uint32_t CstFFID = VMap[CstFF];
3814
3815 uint32_t ShiftAmountID = 0;
3816 if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2))) {
3817 // Handle constant index.
3818 uint64_t Idx = CI->getZExtValue();
3819 Value *ShiftAmount =
3820 ConstantInt::get(Type::getInt32Ty(Context), Idx * 8);
3821 ShiftAmountID = VMap[ShiftAmount];
3822 } else {
3823 // Handle variable index.
3824 SPIRVOperandList TmpOps;
3825
3826 uint32_t TmpResTyID = lookupType(Type::getInt32Ty(Context));
3827 SPIRVOperand *TmpResTyIDOp =
3828 new SPIRVOperand(SPIRVOperandType::NUMBERID, TmpResTyID);
3829 TmpOps.push_back(TmpResTyIDOp);
3830
3831 uint32_t IdxID = VMap[I.getOperand(2)];
3832 SPIRVOperand *TmpOp0IDOp =
3833 new SPIRVOperand(SPIRVOperandType::NUMBERID, IdxID);
3834 TmpOps.push_back(TmpOp0IDOp);
3835
3836 ConstantInt *Cst8 = ConstantInt::get(Type::getInt32Ty(Context), 8);
3837 uint32_t Cst8ID = VMap[Cst8];
3838 SPIRVOperand *TmpOp1IDOp =
3839 new SPIRVOperand(SPIRVOperandType::NUMBERID, Cst8ID);
3840 TmpOps.push_back(TmpOp1IDOp);
3841
3842 ShiftAmountID = nextID;
3843
3844 SPIRVInstruction *TmpInst =
3845 new SPIRVInstruction(5, spv::OpIMul, nextID++, TmpOps);
3846 SPIRVInstList.push_back(TmpInst);
3847 }
3848
3849 //
3850 // Generate mask operations.
3851 //
3852
3853 // ShiftLeft mask according to index of insertelement.
3854 SPIRVOperandList Ops;
3855
3856 uint32_t ResTyID = lookupType(CompositeTy);
3857 SPIRVOperand *ResTyIDOp =
3858 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3859 Ops.push_back(ResTyIDOp);
3860
3861 uint32_t Op0ID = CstFFID;
3862 SPIRVOperand *Op0IDOp =
3863 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3864 Ops.push_back(Op0IDOp);
3865
3866 uint32_t Op1ID = ShiftAmountID;
3867 SPIRVOperand *Op1IDOp =
3868 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3869 Ops.push_back(Op1IDOp);
3870
3871 uint32_t MaskID = nextID;
3872
3873 SPIRVInstruction *Inst =
3874 new SPIRVInstruction(5, spv::OpShiftLeftLogical, nextID++, Ops);
3875 SPIRVInstList.push_back(Inst);
3876
3877 // Inverse mask.
3878 Ops.clear();
3879
3880 Ops.push_back(ResTyIDOp);
3881
3882 Op0ID = MaskID;
3883 Op0IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3884 Ops.push_back(Op0IDOp);
3885
3886 uint32_t InvMaskID = nextID;
3887
3888 Inst = new SPIRVInstruction(4, spv::OpLogicalNot, nextID++, Ops);
3889 SPIRVInstList.push_back(Inst);
3890
3891 // Apply mask.
3892 Ops.clear();
3893
3894 Ops.push_back(ResTyIDOp);
3895
3896 Op0ID = VMap[I.getOperand(0)];
3897 Op0IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3898 Ops.push_back(Op0IDOp);
3899
3900 Op1ID = InvMaskID;
3901 Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3902 Ops.push_back(Op1IDOp);
3903
3904 uint32_t OrgValID = nextID;
3905
3906 Inst = new SPIRVInstruction(5, spv::OpBitwiseAnd, nextID++, Ops);
3907 SPIRVInstList.push_back(Inst);
3908
3909 // Create correct value according to index of insertelement.
3910 Ops.clear();
3911
3912 Ops.push_back(ResTyIDOp);
3913
3914 Op0ID = VMap[I.getOperand(1)];
3915 Op0IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3916 Ops.push_back(Op0IDOp);
3917
3918 Op1ID = ShiftAmountID;
3919 Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3920 Ops.push_back(Op1IDOp);
3921
3922 uint32_t InsertValID = nextID;
3923
3924 Inst = new SPIRVInstruction(5, spv::OpShiftLeftLogical, nextID++, Ops);
3925 SPIRVInstList.push_back(Inst);
3926
3927 // Insert value to original value.
3928 Ops.clear();
3929
3930 Ops.push_back(ResTyIDOp);
3931
3932 Op0ID = OrgValID;
3933 Op0IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
3934 Ops.push_back(Op0IDOp);
3935
3936 Op1ID = InsertValID;
3937 Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
3938 Ops.push_back(Op1IDOp);
3939
3940 Inst = new SPIRVInstruction(5, spv::OpBitwiseOr, nextID++, Ops);
3941 SPIRVInstList.push_back(Inst);
3942
3943 break;
3944 }
3945
3946 // Ops[0] = Result Type ID
3947 // Ops[1] = Object ID
3948 // Ops[2] = Composite ID
3949 // Ops[3] ... Ops[n] = Indexes (Literal Number)
3950 SPIRVOperandList Ops;
3951
3952 uint32_t ResTyID = lookupType(I.getType());
3953 SPIRVOperand *ResTyIDOp =
3954 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3955 Ops.push_back(ResTyIDOp);
3956
3957 uint32_t ObjectID = VMap[I.getOperand(1)];
3958 SPIRVOperand *ObjectIDOp =
3959 new SPIRVOperand(SPIRVOperandType::NUMBERID, ObjectID);
3960 Ops.push_back(ObjectIDOp);
3961
3962 uint32_t CompositeID = VMap[I.getOperand(0)];
3963 SPIRVOperand *CompositeIDOp =
3964 new SPIRVOperand(SPIRVOperandType::NUMBERID, CompositeID);
3965 Ops.push_back(CompositeIDOp);
3966
3967 spv::Op Opcode = spv::OpCompositeInsert;
3968 if (const ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2))) {
3969 std::vector<uint32_t> LiteralNum;
3970 assert(CI->getZExtValue() < UINT32_MAX);
3971 LiteralNum.push_back(static_cast<uint32_t>(CI->getZExtValue()));
3972 SPIRVOperand *Indexes =
3973 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
3974 Ops.push_back(Indexes);
3975 } else {
3976 uint32_t IndexID = VMap[I.getOperand(1)];
3977 SPIRVOperand *IndexIDOp =
3978 new SPIRVOperand(SPIRVOperandType::NUMBERID, IndexID);
3979 Ops.push_back(IndexIDOp);
3980 Opcode = spv::OpVectorInsertDynamic;
3981 }
3982
3983 uint16_t WordCount = 6;
3984 SPIRVInstruction *Inst =
3985 new SPIRVInstruction(WordCount, Opcode, nextID++, Ops);
3986 SPIRVInstList.push_back(Inst);
3987 break;
3988 }
3989 case Instruction::ShuffleVector: {
3990 // Ops[0] = Result Type ID
3991 // Ops[1] = Vector 1 ID
3992 // Ops[2] = Vector 2 ID
3993 // Ops[3] ... Ops[n] = Components (Literal Number)
3994 SPIRVOperandList Ops;
3995
3996 uint32_t ResTyID = lookupType(I.getType());
3997 SPIRVOperand *ResTyIDOp =
3998 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
3999 Ops.push_back(ResTyIDOp);
4000
4001 uint32_t Vec1ID = VMap[I.getOperand(0)];
4002 SPIRVOperand *Vec1IDOp =
4003 new SPIRVOperand(SPIRVOperandType::NUMBERID, Vec1ID);
4004 Ops.push_back(Vec1IDOp);
4005
4006 uint32_t Vec2ID = VMap[I.getOperand(1)];
4007 SPIRVOperand *Vec2IDOp =
4008 new SPIRVOperand(SPIRVOperandType::NUMBERID, Vec2ID);
4009 Ops.push_back(Vec2IDOp);
4010
4011 uint64_t NumElements = 0;
4012 if (Constant *Cst = dyn_cast<Constant>(I.getOperand(2))) {
4013 NumElements = cast<VectorType>(Cst->getType())->getNumElements();
4014
4015 if (Cst->isNullValue()) {
4016 for (unsigned i = 0; i < NumElements; i++) {
4017 std::vector<uint32_t> LiteralNum;
4018 LiteralNum.push_back(0);
4019 SPIRVOperand *Component =
4020 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
4021 Ops.push_back(Component);
4022 }
4023 } else if (const ConstantDataSequential *CDS =
4024 dyn_cast<ConstantDataSequential>(Cst)) {
4025 for (unsigned i = 0; i < CDS->getNumElements(); i++) {
4026 std::vector<uint32_t> LiteralNum;
4027 assert(CDS->getElementAsInteger(i) < UINT32_MAX);
4028 LiteralNum.push_back(
4029 static_cast<uint32_t>(CDS->getElementAsInteger(i)));
4030 SPIRVOperand *Component =
4031 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
4032 Ops.push_back(Component);
4033 }
4034 } else if (const ConstantVector *CV = dyn_cast<ConstantVector>(Cst)) {
4035 for (unsigned i = 0; i < CV->getNumOperands(); i++) {
4036 auto Op = CV->getOperand(i);
4037
4038 uint32_t literal = 0;
4039
4040 if (auto CI = dyn_cast<ConstantInt>(Op)) {
4041 literal = static_cast<uint32_t>(CI->getZExtValue());
4042 } else if (auto UI = dyn_cast<UndefValue>(Op)) {
4043 literal = 0xFFFFFFFFu;
4044 } else {
4045 Op->print(errs());
4046 llvm_unreachable("Unsupported element in ConstantVector!");
4047 }
4048
4049 std::vector<uint32_t> LiteralNum;
4050 LiteralNum.push_back(literal);
4051 SPIRVOperand *Component =
4052 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
4053 Ops.push_back(Component);
4054 }
4055 } else {
4056 Cst->print(errs());
4057 llvm_unreachable("Unsupported constant mask in ShuffleVector!");
4058 }
4059 }
4060
4061 uint16_t WordCount = static_cast<uint16_t>(5 + NumElements);
4062 SPIRVInstruction *Inst =
4063 new SPIRVInstruction(WordCount, spv::OpVectorShuffle, nextID++, Ops);
4064 SPIRVInstList.push_back(Inst);
4065 break;
4066 }
4067 case Instruction::ICmp:
4068 case Instruction::FCmp: {
4069 CmpInst *CmpI = cast<CmpInst>(&I);
4070
4071 // Ops[0] = Result Type ID
4072 // Ops[1] = Operand 1 ID
4073 // Ops[2] = Operand 2 ID
4074 SPIRVOperandList Ops;
4075
4076 uint32_t ResTyID = lookupType(CmpI->getType());
4077 SPIRVOperand *ResTyIDOp =
4078 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4079 Ops.push_back(ResTyIDOp);
4080
David Netod4ca2e62017-07-06 18:47:35 -04004081 // Pointer equality is invalid.
4082 Type* ArgTy = CmpI->getOperand(0)->getType();
4083 if (isa<PointerType>(ArgTy)) {
4084 CmpI->print(errs());
4085 std::string name = I.getParent()->getParent()->getName();
4086 errs()
4087 << "\nPointer equality test is not supported by SPIR-V for Vulkan, "
4088 << "in function " << name << "\n";
4089 llvm_unreachable("Pointer equality check is invalid");
4090 break;
4091 }
4092
David Neto22f144c2017-06-12 14:26:21 -04004093 uint32_t Op1ID = VMap[CmpI->getOperand(0)];
4094 SPIRVOperand *Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op1ID);
4095 Ops.push_back(Op1IDOp);
4096
4097 uint32_t Op2ID = VMap[CmpI->getOperand(1)];
4098 SPIRVOperand *Op2IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, Op2ID);
4099 Ops.push_back(Op2IDOp);
4100
4101 spv::Op Opcode = GetSPIRVCmpOpcode(CmpI);
4102 SPIRVInstruction *Inst = new SPIRVInstruction(5, Opcode, nextID++, Ops);
4103 SPIRVInstList.push_back(Inst);
4104 break;
4105 }
4106 case Instruction::Br: {
4107 // Branch instrucion is deferred because it needs label's ID. Record slot's
4108 // location on SPIRVInstructionList.
4109 DeferredInsts.push_back(
4110 std::make_tuple(&I, --SPIRVInstList.end(), 0 /* No id */));
4111 break;
4112 }
4113 case Instruction::Switch: {
4114 I.print(errs());
4115 llvm_unreachable("Unsupported instruction???");
4116 break;
4117 }
4118 case Instruction::IndirectBr: {
4119 I.print(errs());
4120 llvm_unreachable("Unsupported instruction???");
4121 break;
4122 }
4123 case Instruction::PHI: {
4124 // Branch instrucion is deferred because it needs label's ID. Record slot's
4125 // location on SPIRVInstructionList.
4126 DeferredInsts.push_back(
4127 std::make_tuple(&I, --SPIRVInstList.end(), nextID++));
4128 break;
4129 }
4130 case Instruction::Alloca: {
4131 //
4132 // Generate OpVariable.
4133 //
4134 // Ops[0] : Result Type ID
4135 // Ops[1] : Storage Class
4136 SPIRVOperandList Ops;
4137
4138 Type *ResTy = I.getType();
4139 uint32_t ResTyID = lookupType(ResTy);
4140 SPIRVOperand *ResTyOp =
4141 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4142 Ops.push_back(ResTyOp);
4143
4144 spv::StorageClass StorageClass = spv::StorageClassFunction;
4145 SPIRVOperand *StorageClassOp =
4146 new SPIRVOperand(SPIRVOperandType::NUMBERID, StorageClass);
4147 Ops.push_back(StorageClassOp);
4148
4149 SPIRVInstruction *Inst =
4150 new SPIRVInstruction(4, spv::OpVariable, nextID++, Ops);
4151 SPIRVInstList.push_back(Inst);
4152 break;
4153 }
4154 case Instruction::Load: {
4155 LoadInst *LD = cast<LoadInst>(&I);
4156 //
4157 // Generate OpLoad.
4158 //
4159
4160 // Ops[0] = Result Type ID
4161 // Ops[1] = Pointer ID
4162 // Ops[2] ... Ops[n] = Optional Memory Access
4163 //
4164 // TODO: Do we need to implement Optional Memory Access???
4165 SPIRVOperandList Ops;
4166
4167 uint32_t ResTyID = lookupType(LD->getType());
4168 SPIRVOperand *ResTyIDOp =
4169 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4170 Ops.push_back(ResTyIDOp);
4171
4172 uint32_t PointerID = VMap[LD->getPointerOperand()];
4173 SPIRVOperand *PointerIDOp =
4174 new SPIRVOperand(SPIRVOperandType::NUMBERID, PointerID);
4175 Ops.push_back(PointerIDOp);
4176
4177 SPIRVInstruction *Inst =
4178 new SPIRVInstruction(4, spv::OpLoad, nextID++, Ops);
4179 SPIRVInstList.push_back(Inst);
4180 break;
4181 }
4182 case Instruction::Store: {
4183 StoreInst *ST = cast<StoreInst>(&I);
4184 //
4185 // Generate OpStore.
4186 //
4187
4188 // Ops[0] = Pointer ID
4189 // Ops[1] = Object ID
4190 // Ops[2] ... Ops[n] = Optional Memory Access (later???)
4191 //
4192 // TODO: Do we need to implement Optional Memory Access???
4193 SPIRVOperand *Ops[2] = {new SPIRVOperand(SPIRVOperandType::NUMBERID,
4194 VMap[ST->getPointerOperand()]),
4195 new SPIRVOperand(SPIRVOperandType::NUMBERID,
4196 VMap[ST->getValueOperand()])};
4197
4198 SPIRVInstruction *Inst =
4199 new SPIRVInstruction(3, spv::OpStore, 0 /* No id */, Ops);
4200 SPIRVInstList.push_back(Inst);
4201 break;
4202 }
4203 case Instruction::AtomicCmpXchg: {
4204 I.print(errs());
4205 llvm_unreachable("Unsupported instruction???");
4206 break;
4207 }
4208 case Instruction::AtomicRMW: {
4209 I.print(errs());
4210 llvm_unreachable("Unsupported instruction???");
4211 break;
4212 }
4213 case Instruction::Fence: {
4214 I.print(errs());
4215 llvm_unreachable("Unsupported instruction???");
4216 break;
4217 }
4218 case Instruction::Call: {
4219 CallInst *Call = dyn_cast<CallInst>(&I);
4220 Function *Callee = Call->getCalledFunction();
4221
4222 // Sampler initializers become a load of the corresponding sampler.
4223 if (Callee->getName().equals("__translate_sampler_initializer")) {
4224 // Check that the sampler map was definitely used though.
4225 if (0 == getSamplerMap().size()) {
4226 llvm_unreachable("Sampler literal in source without sampler map!");
4227 }
4228
4229 SPIRVOperandList Ops;
4230
4231 uint32_t ResTyID = lookupType(SamplerTy->getPointerElementType());
4232 SPIRVOperand *ResTyIDOp =
4233 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4234 Ops.push_back(ResTyIDOp);
4235
4236 uint32_t PointerID = VMap[Call];
4237 SPIRVOperand *PointerIDOp =
4238 new SPIRVOperand(SPIRVOperandType::NUMBERID, PointerID);
4239 Ops.push_back(PointerIDOp);
4240
4241 VMap[Call] = nextID;
4242 SPIRVInstruction *Inst =
4243 new SPIRVInstruction(4, spv::OpLoad, nextID++, Ops);
4244 SPIRVInstList.push_back(Inst);
4245
4246 break;
4247 }
4248
4249 if (Callee->getName().startswith("spirv.atomic")) {
4250 spv::Op opcode = StringSwitch<spv::Op>(Callee->getName())
4251 .Case("spirv.atomic_add", spv::OpAtomicIAdd)
4252 .Case("spirv.atomic_sub", spv::OpAtomicISub)
4253 .Case("spirv.atomic_exchange", spv::OpAtomicExchange)
4254 .Case("spirv.atomic_inc", spv::OpAtomicIIncrement)
4255 .Case("spirv.atomic_dec", spv::OpAtomicIDecrement)
4256 .Case("spirv.atomic_compare_exchange",
4257 spv::OpAtomicCompareExchange)
4258 .Case("spirv.atomic_umin", spv::OpAtomicUMin)
4259 .Case("spirv.atomic_smin", spv::OpAtomicSMin)
4260 .Case("spirv.atomic_umax", spv::OpAtomicUMax)
4261 .Case("spirv.atomic_smax", spv::OpAtomicSMax)
4262 .Case("spirv.atomic_and", spv::OpAtomicAnd)
4263 .Case("spirv.atomic_or", spv::OpAtomicOr)
4264 .Case("spirv.atomic_xor", spv::OpAtomicXor)
4265 .Default(spv::OpNop);
4266
4267 //
4268 // Generate OpAtomic*.
4269 //
4270 SPIRVOperandList Ops;
4271
4272 uint32_t TyID = lookupType(I.getType());
4273 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID));
4274
4275 for (unsigned i = 0; i < Call->getNumArgOperands(); i++) {
4276 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
4277 VMap[Call->getArgOperand(i)]));
4278 }
4279
4280 VMap[&I] = nextID;
4281
4282 SPIRVInstruction *Inst = new SPIRVInstruction(
4283 static_cast<uint16_t>(2 + Ops.size()), opcode, nextID++, Ops);
4284 SPIRVInstList.push_back(Inst);
4285 break;
4286 }
4287
4288 if (Callee->getName().startswith("_Z3dot")) {
4289 // If the argument is a vector type, generate OpDot
4290 if (Call->getArgOperand(0)->getType()->isVectorTy()) {
4291 //
4292 // Generate OpDot.
4293 //
4294 SPIRVOperandList Ops;
4295
4296 uint32_t TyID = lookupType(I.getType());
4297 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID));
4298
4299 for (unsigned i = 0; i < Call->getNumArgOperands(); i++) {
4300 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
4301 VMap[Call->getArgOperand(i)]));
4302 }
4303
4304 VMap[&I] = nextID;
4305
4306 SPIRVInstruction *Inst = new SPIRVInstruction(
4307 static_cast<uint16_t>(2 + Ops.size()), spv::OpDot, nextID++, Ops);
4308 SPIRVInstList.push_back(Inst);
4309 } else {
4310 //
4311 // Generate OpFMul.
4312 //
4313 SPIRVOperandList Ops;
4314
4315 uint32_t TyID = lookupType(I.getType());
4316 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID));
4317
4318 for (unsigned i = 0; i < Call->getNumArgOperands(); i++) {
4319 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
4320 VMap[Call->getArgOperand(i)]));
4321 }
4322
4323 VMap[&I] = nextID;
4324
4325 SPIRVInstruction *Inst = new SPIRVInstruction(
4326 static_cast<uint16_t>(2 + Ops.size()), spv::OpFMul, nextID++, Ops);
4327 SPIRVInstList.push_back(Inst);
4328 }
4329 break;
4330 }
4331
4332 // spirv.store_null.* intrinsics become OpStore's.
4333 if (Callee->getName().startswith("spirv.store_null")) {
4334 //
4335 // Generate OpStore.
4336 //
4337
4338 // Ops[0] = Pointer ID
4339 // Ops[1] = Object ID
4340 // Ops[2] ... Ops[n]
4341 SPIRVOperandList Ops;
4342
4343 uint32_t PointerID = VMap[Call->getArgOperand(0)];
4344 SPIRVOperand *PointerIDOp =
4345 new SPIRVOperand(SPIRVOperandType::NUMBERID, PointerID);
4346 Ops.push_back(PointerIDOp);
4347
4348 uint32_t ObjectID = VMap[Call->getArgOperand(1)];
4349 SPIRVOperand *ObjectIDOp =
4350 new SPIRVOperand(SPIRVOperandType::NUMBERID, ObjectID);
4351 Ops.push_back(ObjectIDOp);
4352
4353 SPIRVInstruction *Inst =
4354 new SPIRVInstruction(3, spv::OpStore, 0 /* No id */, Ops);
4355 SPIRVInstList.push_back(Inst);
4356
4357 break;
4358 }
4359
4360 // spirv.copy_memory.* intrinsics become OpMemoryMemory's.
4361 if (Callee->getName().startswith("spirv.copy_memory")) {
4362 //
4363 // Generate OpCopyMemory.
4364 //
4365
4366 // Ops[0] = Dst ID
4367 // Ops[1] = Src ID
4368 // Ops[2] = Memory Access
4369 // Ops[3] = Alignment
4370
4371 auto IsVolatile =
4372 dyn_cast<ConstantInt>(Call->getArgOperand(3))->getZExtValue() != 0;
4373
4374 auto VolatileMemoryAccess = (IsVolatile) ? spv::MemoryAccessVolatileMask
4375 : spv::MemoryAccessMaskNone;
4376
4377 auto MemoryAccess = VolatileMemoryAccess | spv::MemoryAccessAlignedMask;
4378
4379 auto Alignment =
4380 dyn_cast<ConstantInt>(Call->getArgOperand(2))->getZExtValue();
4381
4382 SPIRVOperand *Ops[4] = {
4383 new SPIRVOperand(SPIRVOperandType::NUMBERID,
4384 VMap[Call->getArgOperand(0)]),
4385 new SPIRVOperand(SPIRVOperandType::NUMBERID,
4386 VMap[Call->getArgOperand(1)]),
4387 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, MemoryAccess),
4388 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER,
4389 static_cast<uint32_t>(Alignment))};
4390
4391 SPIRVInstruction *Inst =
4392 new SPIRVInstruction(5, spv::OpCopyMemory, 0 /* No id */, Ops);
4393
4394 SPIRVInstList.push_back(Inst);
4395
4396 break;
4397 }
4398
4399 // Nothing to do for abs with uint. Map abs's operand ID to VMap for abs
4400 // with unit.
4401 if (Callee->getName().equals("_Z3absj") ||
4402 Callee->getName().equals("_Z3absDv2_j") ||
4403 Callee->getName().equals("_Z3absDv3_j") ||
4404 Callee->getName().equals("_Z3absDv4_j")) {
4405 VMap[&I] = VMap[Call->getOperand(0)];
4406 break;
4407 }
4408
4409 // barrier is converted to OpControlBarrier
4410 if (Callee->getName().equals("__spirv_control_barrier")) {
4411 //
4412 // Generate OpControlBarrier.
4413 //
4414 // Ops[0] = Execution Scope ID
4415 // Ops[1] = Memory Scope ID
4416 // Ops[2] = Memory Semantics ID
4417 //
4418 Value *ExecutionScope = Call->getArgOperand(0);
4419 Value *MemoryScope = Call->getArgOperand(1);
4420 Value *MemorySemantics = Call->getArgOperand(2);
4421
4422 SPIRVOperand *Ops[3] = {
4423 new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[ExecutionScope]),
4424 new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[MemoryScope]),
4425 new SPIRVOperand(SPIRVOperandType::NUMBERID, VMap[MemorySemantics])};
4426
4427 SPIRVInstList.push_back(
4428 new SPIRVInstruction(4, spv::OpControlBarrier, 0 /* No id */, Ops));
4429 break;
4430 }
4431
4432 // memory barrier is converted to OpMemoryBarrier
4433 if (Callee->getName().equals("__spirv_memory_barrier")) {
4434 //
4435 // Generate OpMemoryBarrier.
4436 //
4437 // Ops[0] = Memory Scope ID
4438 // Ops[1] = Memory Semantics ID
4439 //
4440 SPIRVOperandList Ops;
4441
4442 Value *MemoryScope = Call->getArgOperand(0);
4443 Value *MemorySemantics = Call->getArgOperand(1);
4444
4445 uint32_t MemoryScopeID = VMap[MemoryScope];
4446 Ops.push_back(
4447 new SPIRVOperand(SPIRVOperandType::NUMBERID, MemoryScopeID));
4448
4449 uint32_t MemorySemanticsID = VMap[MemorySemantics];
4450 Ops.push_back(
4451 new SPIRVOperand(SPIRVOperandType::NUMBERID, MemorySemanticsID));
4452
4453 SPIRVInstruction *Inst =
4454 new SPIRVInstruction(3, spv::OpMemoryBarrier, 0 /* No id */, Ops);
4455 SPIRVInstList.push_back(Inst);
4456 break;
4457 }
4458
4459 // isinf is converted to OpIsInf
4460 if (Callee->getName().equals("__spirv_isinff") ||
4461 Callee->getName().equals("__spirv_isinfDv2_f") ||
4462 Callee->getName().equals("__spirv_isinfDv3_f") ||
4463 Callee->getName().equals("__spirv_isinfDv4_f")) {
4464 //
4465 // Generate OpIsInf.
4466 //
4467 // Ops[0] = Result Type ID
4468 // Ops[1] = X ID
4469 //
4470 SPIRVOperandList Ops;
4471
4472 uint32_t TyID = lookupType(I.getType());
4473 SPIRVOperand *ResTyIDOp =
4474 new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID);
4475 Ops.push_back(ResTyIDOp);
4476
4477 uint32_t XID = VMap[Call->getArgOperand(0)];
4478 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, XID));
4479
4480 VMap[&I] = nextID;
4481
4482 SPIRVInstruction *Inst =
4483 new SPIRVInstruction(4, spv::OpIsInf, nextID++, Ops);
4484 SPIRVInstList.push_back(Inst);
4485 break;
4486 }
4487
4488 // isnan is converted to OpIsNan
4489 if (Callee->getName().equals("__spirv_isnanf") ||
4490 Callee->getName().equals("__spirv_isnanDv2_f") ||
4491 Callee->getName().equals("__spirv_isnanDv3_f") ||
4492 Callee->getName().equals("__spirv_isnanDv4_f")) {
4493 //
4494 // Generate OpIsInf.
4495 //
4496 // Ops[0] = Result Type ID
4497 // Ops[1] = X ID
4498 //
4499 SPIRVOperandList Ops;
4500
4501 uint32_t TyID = lookupType(I.getType());
4502 SPIRVOperand *ResTyIDOp =
4503 new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID);
4504 Ops.push_back(ResTyIDOp);
4505
4506 uint32_t XID = VMap[Call->getArgOperand(0)];
4507 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, XID));
4508
4509 VMap[&I] = nextID;
4510
4511 SPIRVInstruction *Inst =
4512 new SPIRVInstruction(4, spv::OpIsNan, nextID++, Ops);
4513 SPIRVInstList.push_back(Inst);
4514 break;
4515 }
4516
4517 // all is converted to OpAll
4518 if (Callee->getName().equals("__spirv_allDv2_i") ||
4519 Callee->getName().equals("__spirv_allDv3_i") ||
4520 Callee->getName().equals("__spirv_allDv4_i")) {
4521 //
4522 // Generate OpAll.
4523 //
4524 // Ops[0] = Result Type ID
4525 // Ops[1] = Vector ID
4526 //
4527 SPIRVOperandList Ops;
4528
4529 uint32_t TyID = lookupType(I.getType());
4530 SPIRVOperand *ResTyIDOp =
4531 new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID);
4532 Ops.push_back(ResTyIDOp);
4533
4534 uint32_t VectorID = VMap[Call->getArgOperand(0)];
4535 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, VectorID));
4536
4537 VMap[&I] = nextID;
4538
4539 SPIRVInstruction *Inst =
4540 new SPIRVInstruction(4, spv::OpAll, nextID++, Ops);
4541 SPIRVInstList.push_back(Inst);
4542 break;
4543 }
4544
4545 // any is converted to OpAny
4546 if (Callee->getName().equals("__spirv_anyDv2_i") ||
4547 Callee->getName().equals("__spirv_anyDv3_i") ||
4548 Callee->getName().equals("__spirv_anyDv4_i")) {
4549 //
4550 // Generate OpAny.
4551 //
4552 // Ops[0] = Result Type ID
4553 // Ops[1] = Vector ID
4554 //
4555 SPIRVOperandList Ops;
4556
4557 uint32_t TyID = lookupType(I.getType());
4558 SPIRVOperand *ResTyIDOp =
4559 new SPIRVOperand(SPIRVOperandType::NUMBERID, TyID);
4560 Ops.push_back(ResTyIDOp);
4561
4562 uint32_t VectorID = VMap[Call->getArgOperand(0)];
4563 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID, VectorID));
4564
4565 VMap[&I] = nextID;
4566
4567 SPIRVInstruction *Inst =
4568 new SPIRVInstruction(4, spv::OpAny, nextID++, Ops);
4569 SPIRVInstList.push_back(Inst);
4570 break;
4571 }
4572
4573 // read_image is converted to OpSampledImage and OpImageSampleExplicitLod.
4574 // Additionally, OpTypeSampledImage is generated.
4575 if (Callee->getName().equals(
4576 "_Z11read_imagef14ocl_image2d_ro11ocl_samplerDv2_f") ||
4577 Callee->getName().equals(
4578 "_Z11read_imagef14ocl_image3d_ro11ocl_samplerDv4_f")) {
4579 //
4580 // Generate OpSampledImage.
4581 //
4582 // Ops[0] = Result Type ID
4583 // Ops[1] = Image ID
4584 // Ops[2] = Sampler ID
4585 //
4586 SPIRVOperandList Ops;
4587
4588 Value *Image = Call->getArgOperand(0);
4589 Value *Sampler = Call->getArgOperand(1);
4590 Value *Coordinate = Call->getArgOperand(2);
4591
4592 TypeMapType &OpImageTypeMap = getImageTypeMap();
4593 Type *ImageTy = Image->getType()->getPointerElementType();
4594 uint32_t ImageTyID = OpImageTypeMap[ImageTy];
4595 SPIRVOperand *ResTyIDOp =
4596 new SPIRVOperand(SPIRVOperandType::NUMBERID, ImageTyID);
4597 Ops.push_back(ResTyIDOp);
4598
4599 uint32_t ImageID = VMap[Image];
4600 SPIRVOperand *ImageIDOp =
4601 new SPIRVOperand(SPIRVOperandType::NUMBERID, ImageID);
4602 Ops.push_back(ImageIDOp);
4603
4604 uint32_t SamplerID = VMap[Sampler];
4605 SPIRVOperand *SamplerIDOp =
4606 new SPIRVOperand(SPIRVOperandType::NUMBERID, SamplerID);
4607 Ops.push_back(SamplerIDOp);
4608
4609 uint32_t SampledImageID = nextID;
4610
4611 SPIRVInstruction *Inst =
4612 new SPIRVInstruction(5, spv::OpSampledImage, nextID++, Ops);
4613 SPIRVInstList.push_back(Inst);
4614
4615 //
4616 // Generate OpImageSampleExplicitLod.
4617 //
4618 // Ops[0] = Result Type ID
4619 // Ops[1] = Sampled Image ID
4620 // Ops[2] = Coordinate ID
4621 // Ops[3] = Image Operands Type ID
4622 // Ops[4] ... Ops[n] = Operands ID
4623 //
4624 Ops.clear();
4625
4626 uint32_t RetTyID = lookupType(Call->getType());
4627 ResTyIDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID, RetTyID);
4628 Ops.push_back(ResTyIDOp);
4629
4630 SPIRVOperand *SampledImageIDOp =
4631 new SPIRVOperand(SPIRVOperandType::NUMBERID, SampledImageID);
4632 Ops.push_back(SampledImageIDOp);
4633
4634 uint32_t CoordinateID = VMap[Coordinate];
4635 SPIRVOperand *CoordinateIDOp =
4636 new SPIRVOperand(SPIRVOperandType::NUMBERID, CoordinateID);
4637 Ops.push_back(CoordinateIDOp);
4638
4639 std::vector<uint32_t> LiteralNum;
4640 LiteralNum.push_back(spv::ImageOperandsLodMask);
4641 SPIRVOperand *ImageOperandTyIDOp =
4642 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
4643 Ops.push_back(ImageOperandTyIDOp);
4644
4645 Constant *CstFP0 = ConstantFP::get(Context, APFloat(0.0f));
4646 uint32_t OperandID = VMap[CstFP0];
4647 SPIRVOperand *OperandIDOp =
4648 new SPIRVOperand(SPIRVOperandType::NUMBERID, OperandID);
4649 Ops.push_back(OperandIDOp);
4650
4651 VMap[&I] = nextID;
4652
4653 Inst =
4654 new SPIRVInstruction(7, spv::OpImageSampleExplicitLod, nextID++, Ops);
4655 SPIRVInstList.push_back(Inst);
4656 break;
4657 }
4658
4659 // write_imagef is mapped to OpImageWrite.
4660 if (Callee->getName().equals(
4661 "_Z12write_imagef14ocl_image2d_woDv2_iDv4_f") ||
4662 Callee->getName().equals(
4663 "_Z12write_imagef14ocl_image3d_woDv4_iDv4_f")) {
4664 //
4665 // Generate OpImageWrite.
4666 //
4667 // Ops[0] = Image ID
4668 // Ops[1] = Coordinate ID
4669 // Ops[2] = Texel ID
4670 // Ops[3] = (Optional) Image Operands Type (Literal Number)
4671 // Ops[4] ... Ops[n] = (Optional) Operands ID
4672 //
4673 SPIRVOperandList Ops;
4674
4675 Value *Image = Call->getArgOperand(0);
4676 Value *Coordinate = Call->getArgOperand(1);
4677 Value *Texel = Call->getArgOperand(2);
4678
4679 uint32_t ImageID = VMap[Image];
4680 SPIRVOperand *ImageIDOp =
4681 new SPIRVOperand(SPIRVOperandType::NUMBERID, ImageID);
4682 Ops.push_back(ImageIDOp);
4683
4684 uint32_t CoordinateID = VMap[Coordinate];
4685 SPIRVOperand *CoordinateIDOp =
4686 new SPIRVOperand(SPIRVOperandType::NUMBERID, CoordinateID);
4687 Ops.push_back(CoordinateIDOp);
4688
4689 uint32_t TexelID = VMap[Texel];
4690 SPIRVOperand *TexelIDOp =
4691 new SPIRVOperand(SPIRVOperandType::NUMBERID, TexelID);
4692 Ops.push_back(TexelIDOp);
4693
4694 SPIRVInstruction *Inst =
4695 new SPIRVInstruction(4, spv::OpImageWrite, 0 /* No id */, Ops);
4696 SPIRVInstList.push_back(Inst);
4697 break;
4698 }
4699
4700 // Call instrucion is deferred because it needs function's ID. Record
4701 // slot's location on SPIRVInstructionList.
4702 DeferredInsts.push_back(
4703 std::make_tuple(&I, --SPIRVInstList.end(), nextID++));
4704
4705 // Check whether this call is for extend instructions.
4706 glsl::ExtInst EInst = getExtInstEnum(Callee->getName());
4707 if (EInst == glsl::ExtInstFindUMsb) {
4708 // clz needs OpExtInst and OpISub with constant 31. Increase nextID.
4709 VMap[&I] = nextID;
4710 nextID++;
4711 }
4712 break;
4713 }
4714 case Instruction::Ret: {
4715 unsigned NumOps = I.getNumOperands();
4716 if (NumOps == 0) {
4717 //
4718 // Generate OpReturn.
4719 //
4720
4721 // Empty Ops
4722 SPIRVOperandList Ops;
4723 SPIRVInstruction *Inst =
4724 new SPIRVInstruction(1, spv::OpReturn, 0 /* No id */, Ops);
4725 SPIRVInstList.push_back(Inst);
4726 } else {
4727 //
4728 // Generate OpReturnValue.
4729 //
4730
4731 // Ops[0] = Return Value ID
4732 SPIRVOperandList Ops;
4733 uint32_t RetValID = VMap[I.getOperand(0)];
4734 SPIRVOperand *RetValIDOp =
4735 new SPIRVOperand(SPIRVOperandType::NUMBERID, RetValID);
4736 Ops.push_back(RetValIDOp);
4737
4738 SPIRVInstruction *Inst =
4739 new SPIRVInstruction(2, spv::OpReturnValue, 0 /* No id */, Ops);
4740 SPIRVInstList.push_back(Inst);
4741 break;
4742 }
4743 break;
4744 }
4745 }
4746}
4747
4748void SPIRVProducerPass::GenerateFuncEpilogue() {
4749 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
4750
4751 //
4752 // Generate OpFunctionEnd
4753 //
4754
4755 // Empty Ops
4756 SPIRVOperandList Ops;
4757 SPIRVInstruction *Inst =
4758 new SPIRVInstruction(1, spv::OpFunctionEnd, 0 /* No id */, Ops);
4759 SPIRVInstList.push_back(Inst);
4760}
4761
4762bool SPIRVProducerPass::is4xi8vec(Type *Ty) const {
4763 LLVMContext &Context = Ty->getContext();
4764 if (Ty->isVectorTy()) {
4765 if (Ty->getVectorElementType() == Type::getInt8Ty(Context) &&
4766 Ty->getVectorNumElements() == 4) {
4767 return true;
4768 }
4769 }
4770
4771 return false;
4772}
4773
4774void SPIRVProducerPass::HandleDeferredInstruction() {
4775 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
4776 ValueMapType &VMap = getValueMap();
4777 DeferredInstVecType &DeferredInsts = getDeferredInstVec();
4778
4779 for (auto DeferredInst = DeferredInsts.rbegin();
4780 DeferredInst != DeferredInsts.rend(); ++DeferredInst) {
4781 Value *Inst = std::get<0>(*DeferredInst);
4782 SPIRVInstructionList::iterator InsertPoint = ++std::get<1>(*DeferredInst);
4783 if (InsertPoint != SPIRVInstList.end()) {
4784 while ((*InsertPoint)->getOpcode() == spv::OpPhi) {
4785 ++InsertPoint;
4786 }
4787 }
4788
4789 if (BranchInst *Br = dyn_cast<BranchInst>(Inst)) {
4790 // Check whether basic block, which has this branch instruction, is loop
4791 // header or not. If it is loop header, generate OpLoopMerge and
4792 // OpBranchConditional.
4793 Function *Func = Br->getParent()->getParent();
4794 DominatorTree &DT =
4795 getAnalysis<DominatorTreeWrapperPass>(*Func).getDomTree();
4796 const LoopInfo &LI =
4797 getAnalysis<LoopInfoWrapperPass>(*Func).getLoopInfo();
4798
4799 BasicBlock *BrBB = Br->getParent();
4800 if (LI.isLoopHeader(BrBB)) {
4801 Value *ContinueBB = nullptr;
4802 Value *MergeBB = nullptr;
4803
4804 Loop *L = LI.getLoopFor(BrBB);
4805 MergeBB = L->getExitBlock();
4806 if (!MergeBB) {
4807 // StructurizeCFG pass converts CFG into triangle shape and the cfg
4808 // has regions with single entry/exit. As a result, loop should not
4809 // have multiple exits.
4810 llvm_unreachable("Loop has multiple exits???");
4811 }
4812
4813 if (L->isLoopLatch(BrBB)) {
4814 ContinueBB = BrBB;
4815 } else {
4816 // From SPIR-V spec 2.11, Continue Target must dominate that back-edge
4817 // block.
4818 BasicBlock *Header = L->getHeader();
4819 BasicBlock *Latch = L->getLoopLatch();
4820 for (BasicBlock *BB : L->blocks()) {
4821 if (BB == Header) {
4822 continue;
4823 }
4824
4825 // Check whether block dominates block with back-edge.
4826 if (DT.dominates(BB, Latch)) {
4827 ContinueBB = BB;
4828 }
4829 }
4830
4831 if (!ContinueBB) {
4832 llvm_unreachable("Wrong continue block from loop");
4833 }
4834 }
4835
4836 //
4837 // Generate OpLoopMerge.
4838 //
4839 // Ops[0] = Merge Block ID
4840 // Ops[1] = Continue Target ID
4841 // Ops[2] = Selection Control
4842 SPIRVOperandList Ops;
4843
4844 // StructurizeCFG pass already manipulated CFG. Just use false block of
4845 // branch instruction as merge block.
4846 uint32_t MergeBBID = VMap[MergeBB];
4847 SPIRVOperand *MergeBBIDOp =
4848 new SPIRVOperand(SPIRVOperandType::NUMBERID, MergeBBID);
4849 Ops.push_back(MergeBBIDOp);
4850
4851 uint32_t ContinueBBID = VMap[ContinueBB];
4852 SPIRVOperand *ContinueBBIDOp =
4853 new SPIRVOperand(SPIRVOperandType::NUMBERID, ContinueBBID);
4854 Ops.push_back(ContinueBBIDOp);
4855
4856 SPIRVOperand *SelectionControlOp = new SPIRVOperand(
4857 SPIRVOperandType::NUMBERID, spv::SelectionControlMaskNone);
4858 Ops.push_back(SelectionControlOp);
4859
4860 SPIRVInstruction *MergeInst =
4861 new SPIRVInstruction(4, spv::OpLoopMerge, 0 /* No id */, Ops);
4862 SPIRVInstList.insert(InsertPoint, MergeInst);
4863
4864 } else if (Br->isConditional()) {
4865 bool HasBackEdge = false;
4866
4867 for (unsigned i = 0; i < Br->getNumSuccessors(); i++) {
4868 if (LI.isLoopHeader(Br->getSuccessor(i))) {
4869 HasBackEdge = true;
4870 }
4871 }
4872 if (!HasBackEdge) {
4873 //
4874 // Generate OpSelectionMerge.
4875 //
4876 // Ops[0] = Merge Block ID
4877 // Ops[1] = Selection Control
4878 SPIRVOperandList Ops;
4879
4880 // StructurizeCFG pass already manipulated CFG. Just use false block
4881 // of branch instruction as merge block.
4882 uint32_t MergeBBID = VMap[Br->getSuccessor(1)];
4883 SPIRVOperand *MergeBBIDOp =
4884 new SPIRVOperand(SPIRVOperandType::NUMBERID, MergeBBID);
4885 Ops.push_back(MergeBBIDOp);
4886
4887 SPIRVOperand *SelectionControlOp = new SPIRVOperand(
4888 SPIRVOperandType::NUMBERID, spv::SelectionControlMaskNone);
4889 Ops.push_back(SelectionControlOp);
4890
4891 SPIRVInstruction *MergeInst = new SPIRVInstruction(
4892 3, spv::OpSelectionMerge, 0 /* No id */, Ops);
4893 SPIRVInstList.insert(InsertPoint, MergeInst);
4894 }
4895 }
4896
4897 if (Br->isConditional()) {
4898 //
4899 // Generate OpBranchConditional.
4900 //
4901 // Ops[0] = Condition ID
4902 // Ops[1] = True Label ID
4903 // Ops[2] = False Label ID
4904 // Ops[3] ... Ops[n] = Branch weights (Literal Number)
4905 SPIRVOperandList Ops;
4906
4907 uint32_t CondID = VMap[Br->getCondition()];
4908 SPIRVOperand *CondIDOp =
4909 new SPIRVOperand(SPIRVOperandType::NUMBERID, CondID);
4910 Ops.push_back(CondIDOp);
4911
4912 uint32_t TrueBBID = VMap[Br->getSuccessor(0)];
4913 SPIRVOperand *TrueBBIDOp =
4914 new SPIRVOperand(SPIRVOperandType::NUMBERID, TrueBBID);
4915 Ops.push_back(TrueBBIDOp);
4916
4917 uint32_t FalseBBID = VMap[Br->getSuccessor(1)];
4918 SPIRVOperand *FalseBBIDOp =
4919 new SPIRVOperand(SPIRVOperandType::NUMBERID, FalseBBID);
4920 Ops.push_back(FalseBBIDOp);
4921
4922 SPIRVInstruction *BrInst = new SPIRVInstruction(
4923 4, spv::OpBranchConditional, 0 /* No id */, Ops);
4924 SPIRVInstList.insert(InsertPoint, BrInst);
4925 } else {
4926 //
4927 // Generate OpBranch.
4928 //
4929 // Ops[0] = Target Label ID
4930 SPIRVOperandList Ops;
4931
4932 uint32_t TargetID = VMap[Br->getSuccessor(0)];
4933 SPIRVOperand *TargetIDOp =
4934 new SPIRVOperand(SPIRVOperandType::NUMBERID, TargetID);
4935 Ops.push_back(TargetIDOp);
4936
4937 SPIRVInstList.insert(
4938 InsertPoint,
4939 new SPIRVInstruction(2, spv::OpBranch, 0 /* No id */, Ops));
4940 }
4941 } else if (PHINode *PHI = dyn_cast<PHINode>(Inst)) {
4942 //
4943 // Generate OpPhi.
4944 //
4945 // Ops[0] = Result Type ID
4946 // Ops[1] ... Ops[n] = (Variable ID, Parent ID) pairs
4947 SPIRVOperandList Ops;
4948
4949 uint32_t ResTyID = lookupType(PHI->getType());
4950 SPIRVOperand *ResTyIDOp =
4951 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4952 Ops.push_back(ResTyIDOp);
4953
4954 uint16_t WordCount = 3;
4955 for (unsigned i = 0; i < PHI->getNumIncomingValues(); i++) {
4956 uint32_t VarID = VMap[PHI->getIncomingValue(i)];
4957 SPIRVOperand *VarIDOp =
4958 new SPIRVOperand(SPIRVOperandType::NUMBERID, VarID);
4959 Ops.push_back(VarIDOp);
4960
4961 uint32_t ParentID = VMap[PHI->getIncomingBlock(i)];
4962 SPIRVOperand *ParentIDOp =
4963 new SPIRVOperand(SPIRVOperandType::NUMBERID, ParentID);
4964 Ops.push_back(ParentIDOp);
4965
4966 WordCount += 2;
4967 }
4968
4969 SPIRVInstList.insert(
4970 InsertPoint, new SPIRVInstruction(WordCount, spv::OpPhi,
4971 std::get<2>(*DeferredInst), Ops));
4972 } else if (CallInst *Call = dyn_cast<CallInst>(Inst)) {
4973 Function *Callee = Call->getCalledFunction();
4974 glsl::ExtInst EInst = getExtInstEnum(Callee->getName());
4975
4976 if (EInst) {
4977 uint32_t &ExtInstImportID = getOpExtInstImportID();
4978
4979 //
4980 // Generate OpExtInst.
4981 //
4982
4983 // Ops[0] = Result Type ID
4984 // Ops[1] = Set ID (OpExtInstImport ID)
4985 // Ops[2] = Instruction Number (Literal Number)
4986 // Ops[3] ... Ops[n] = Operand 1, ... , Operand n
4987 SPIRVOperandList Ops;
4988
4989 uint32_t ResTyID = lookupType(Call->getType());
4990 SPIRVOperand *ResTyIDOp =
4991 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
4992 Ops.push_back(ResTyIDOp);
4993
4994 SPIRVOperand *SetIDOp =
4995 new SPIRVOperand(SPIRVOperandType::NUMBERID, ExtInstImportID);
4996 Ops.push_back(SetIDOp);
4997
4998 std::vector<uint32_t> LiteralNum;
4999 LiteralNum.push_back(EInst);
5000 SPIRVOperand *InstructionOp =
5001 new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, LiteralNum);
5002 Ops.push_back(InstructionOp);
5003
5004 uint16_t WordCount = 5;
5005
5006 FunctionType *CalleeFTy = cast<FunctionType>(Call->getFunctionType());
5007 for (unsigned i = 0; i < CalleeFTy->getNumParams(); i++) {
5008 uint32_t ArgID = VMap[Call->getOperand(i)];
5009 SPIRVOperand *ArgIDOp =
5010 new SPIRVOperand(SPIRVOperandType::NUMBERID, ArgID);
5011 Ops.push_back(ArgIDOp);
5012 WordCount++;
5013 }
5014
5015 SPIRVInstruction *ExtInst = new SPIRVInstruction(
5016 WordCount, spv::OpExtInst, std::get<2>(*DeferredInst), Ops);
5017 SPIRVInstList.insert(InsertPoint, ExtInst);
5018
5019 // clz needs OpExtInst and OpISub with constant 31.
5020 if (EInst == glsl::ExtInstFindUMsb) {
5021 LLVMContext &Context =
5022 Call->getParent()->getParent()->getParent()->getContext();
5023 //
5024 // Generate OpISub with constant 31.
5025 //
5026 // Ops[0] = Result Type ID
5027 // Ops[1] = Operand 0
5028 // Ops[2] = Operand 1
5029 Ops.clear();
5030
5031 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
5032 lookupType(Call->getType())));
5033
5034 Type *IdxTy = Type::getInt32Ty(Context);
5035 Constant *Cst31 = ConstantInt::get(IdxTy, 31);
5036 uint32_t Op0ID = VMap[Cst31];
5037 SPIRVOperand *Op0IDOp =
5038 new SPIRVOperand(SPIRVOperandType::NUMBERID, Op0ID);
5039 Ops.push_back(Op0IDOp);
5040
5041 SPIRVOperand *Op1IDOp = new SPIRVOperand(SPIRVOperandType::NUMBERID,
5042 std::get<2>(*DeferredInst));
5043 Ops.push_back(Op1IDOp);
5044
5045 SPIRVInstList.insert(
5046 InsertPoint,
5047 new SPIRVInstruction(5, spv::OpISub,
5048 std::get<2>(*DeferredInst) + 1, Ops));
5049 }
5050 } else if (Callee->getName().equals("_Z8popcounti") ||
5051 Callee->getName().equals("_Z8popcountj") ||
5052 Callee->getName().equals("_Z8popcountDv2_i") ||
5053 Callee->getName().equals("_Z8popcountDv3_i") ||
5054 Callee->getName().equals("_Z8popcountDv4_i") ||
5055 Callee->getName().equals("_Z8popcountDv2_j") ||
5056 Callee->getName().equals("_Z8popcountDv3_j") ||
5057 Callee->getName().equals("_Z8popcountDv4_j")) {
5058 //
5059 // Generate OpBitCount
5060 //
5061 // Ops[0] = Result Type ID
5062 // Ops[1] = Base ID
5063 SPIRVOperand *Ops[2]{new SPIRVOperand(SPIRVOperandType::NUMBERID,
5064 lookupType(Call->getType())),
5065 new SPIRVOperand(SPIRVOperandType::NUMBERID,
5066 VMap[Call->getOperand(0)])};
5067
5068 SPIRVInstList.insert(
5069 InsertPoint, new SPIRVInstruction(4, spv::OpBitCount,
5070 std::get<2>(*DeferredInst), Ops));
5071 } else {
5072 //
5073 // Generate OpFunctionCall.
5074 //
5075
5076 // Ops[0] = Result Type ID
5077 // Ops[1] = Callee Function ID
5078 // Ops[2] ... Ops[n] = Argument 0, ... , Argument n
5079 SPIRVOperandList Ops;
5080
5081 uint32_t ResTyID = lookupType(Call->getType());
5082 SPIRVOperand *ResTyIDOp =
5083 new SPIRVOperand(SPIRVOperandType::NUMBERID, ResTyID);
5084 Ops.push_back(ResTyIDOp);
5085
5086 uint32_t CalleeID = VMap[Callee];
5087
5088 SPIRVOperand *CalleeIDOp =
5089 new SPIRVOperand(SPIRVOperandType::NUMBERID, CalleeID);
5090 Ops.push_back(CalleeIDOp);
5091
5092 uint16_t WordCount = 4;
5093
5094 FunctionType *CalleeFTy = cast<FunctionType>(Call->getFunctionType());
5095 for (unsigned i = 0; i < CalleeFTy->getNumParams(); i++) {
5096 uint32_t ArgID = VMap[Call->getOperand(i)];
5097 SPIRVOperand *ArgIDOp =
5098 new SPIRVOperand(SPIRVOperandType::NUMBERID, ArgID);
5099 Ops.push_back(ArgIDOp);
5100 WordCount++;
5101 }
5102
5103 SPIRVInstruction *CallInst = new SPIRVInstruction(
5104 WordCount, spv::OpFunctionCall, std::get<2>(*DeferredInst), Ops);
5105 SPIRVInstList.insert(InsertPoint, CallInst);
5106 }
5107 }
5108 }
5109}
5110
David Neto1a1a0582017-07-07 12:01:44 -04005111void SPIRVProducerPass::HandleDeferredDecorations(const DataLayout &DL) {
5112 // Insert ArrayStride decorations on pointer types, due to OpPtrAccessChain
5113 // instructions we generated earlier.
5114 if (getPointerTypesNeedingArrayStride().empty())
5115 return;
5116
5117 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
5118 ValueMapType &VMap = getValueMap();
5119
5120 // Find an iterator pointing just past the last decoration.
5121 bool seen_decorations = false;
5122 auto DecoInsertPoint =
5123 std::find_if(SPIRVInstList.begin(), SPIRVInstList.end(),
5124 [&seen_decorations](SPIRVInstruction *Inst) -> bool {
5125 const bool is_decoration =
5126 Inst->getOpcode() == spv::OpDecorate ||
5127 Inst->getOpcode() == spv::OpMemberDecorate;
5128 if (is_decoration) {
5129 seen_decorations = true;
5130 return false;
5131 } else {
5132 return seen_decorations;
5133 }
5134 });
5135
5136 for (auto *type : getPointerTypesNeedingArrayStride()) {
5137 auto *ptrType = cast<PointerType>(type);
5138
5139 // Ops[0] = Target ID
5140 // Ops[1] = Decoration (ArrayStride)
5141 // Ops[2] = Stride number (Literal Number)
5142 SPIRVOperandList Ops;
5143
5144 Ops.push_back(
5145 new SPIRVOperand(SPIRVOperandType::NUMBERID, lookupType(ptrType)));
5146 Ops.push_back(new SPIRVOperand(SPIRVOperandType::NUMBERID,
5147 spv::DecorationArrayStride));
5148 Type *elemTy = ptrType->getElementType();
5149 // Same as DL.getIndexedOfffsetInType( elemTy, { 1 } );
5150 const unsigned stride = DL.getTypeAllocSize(elemTy);
5151 Ops.push_back(new SPIRVOperand(SPIRVOperandType::LITERAL_INTEGER, stride));
5152
5153 SPIRVInstruction *DecoInst =
5154 new SPIRVInstruction(4, spv::OpDecorate, 0 /* No id */, Ops);
5155 SPIRVInstList.insert(DecoInsertPoint, DecoInst);
5156 }
5157}
5158
David Neto22f144c2017-06-12 14:26:21 -04005159glsl::ExtInst SPIRVProducerPass::getExtInstEnum(StringRef Name) {
5160 return StringSwitch<glsl::ExtInst>(Name)
5161 .Case("_Z3absi", glsl::ExtInst::ExtInstSAbs)
5162 .Case("_Z3absDv2_i", glsl::ExtInst::ExtInstSAbs)
5163 .Case("_Z3absDv3_i", glsl::ExtInst::ExtInstSAbs)
5164 .Case("_Z3absDv4_i", glsl::ExtInst::ExtInstSAbs)
5165 .Case("_Z5clampiii", glsl::ExtInst::ExtInstSClamp)
5166 .Case("_Z5clampDv2_iS_S_", glsl::ExtInst::ExtInstSClamp)
5167 .Case("_Z5clampDv3_iS_S_", glsl::ExtInst::ExtInstSClamp)
5168 .Case("_Z5clampDv4_iS_S_", glsl::ExtInst::ExtInstSClamp)
5169 .Case("_Z5clampjjj", glsl::ExtInst::ExtInstUClamp)
5170 .Case("_Z5clampDv2_jS_S_", glsl::ExtInst::ExtInstUClamp)
5171 .Case("_Z5clampDv3_jS_S_", glsl::ExtInst::ExtInstUClamp)
5172 .Case("_Z5clampDv4_jS_S_", glsl::ExtInst::ExtInstUClamp)
5173 .Case("_Z5clampfff", glsl::ExtInst::ExtInstFClamp)
5174 .Case("_Z5clampDv2_fS_S_", glsl::ExtInst::ExtInstFClamp)
5175 .Case("_Z5clampDv3_fS_S_", glsl::ExtInst::ExtInstFClamp)
5176 .Case("_Z5clampDv4_fS_S_", glsl::ExtInst::ExtInstFClamp)
5177 .StartsWith("_Z3clz", glsl::ExtInst::ExtInstFindUMsb)
5178 .Case("_Z3maxii", glsl::ExtInst::ExtInstSMax)
5179 .Case("_Z3maxDv2_iS_", glsl::ExtInst::ExtInstSMax)
5180 .Case("_Z3maxDv3_iS_", glsl::ExtInst::ExtInstSMax)
5181 .Case("_Z3maxDv4_iS_", glsl::ExtInst::ExtInstSMax)
5182 .Case("_Z3maxjj", glsl::ExtInst::ExtInstUMax)
5183 .Case("_Z3maxDv2_jS_", glsl::ExtInst::ExtInstUMax)
5184 .Case("_Z3maxDv3_jS_", glsl::ExtInst::ExtInstUMax)
5185 .Case("_Z3maxDv4_jS_", glsl::ExtInst::ExtInstUMax)
5186 .Case("_Z3maxff", glsl::ExtInst::ExtInstFMax)
5187 .Case("_Z3maxDv2_fS_", glsl::ExtInst::ExtInstFMax)
5188 .Case("_Z3maxDv3_fS_", glsl::ExtInst::ExtInstFMax)
5189 .Case("_Z3maxDv4_fS_", glsl::ExtInst::ExtInstFMax)
5190 .StartsWith("_Z4fmax", glsl::ExtInst::ExtInstFMax)
5191 .Case("_Z3minii", glsl::ExtInst::ExtInstSMin)
5192 .Case("_Z3minDv2_iS_", glsl::ExtInst::ExtInstSMin)
5193 .Case("_Z3minDv3_iS_", glsl::ExtInst::ExtInstSMin)
5194 .Case("_Z3minDv4_iS_", glsl::ExtInst::ExtInstSMin)
5195 .Case("_Z3minjj", glsl::ExtInst::ExtInstUMin)
5196 .Case("_Z3minDv2_jS_", glsl::ExtInst::ExtInstUMin)
5197 .Case("_Z3minDv3_jS_", glsl::ExtInst::ExtInstUMin)
5198 .Case("_Z3minDv4_jS_", glsl::ExtInst::ExtInstUMin)
5199 .Case("_Z3minff", glsl::ExtInst::ExtInstFMin)
5200 .Case("_Z3minDv2_fS_", glsl::ExtInst::ExtInstFMin)
5201 .Case("_Z3minDv3_fS_", glsl::ExtInst::ExtInstFMin)
5202 .Case("_Z3minDv4_fS_", glsl::ExtInst::ExtInstFMin)
5203 .StartsWith("_Z4fmin", glsl::ExtInst::ExtInstFMin)
5204 .StartsWith("_Z7degrees", glsl::ExtInst::ExtInstDegrees)
5205 .StartsWith("_Z7radians", glsl::ExtInst::ExtInstRadians)
5206 .StartsWith("_Z3mix", glsl::ExtInst::ExtInstFMix)
5207 .StartsWith("_Z4acos", glsl::ExtInst::ExtInstAcos)
5208 .StartsWith("_Z5acosh", glsl::ExtInst::ExtInstAcosh)
5209 .StartsWith("_Z4asin", glsl::ExtInst::ExtInstAsin)
5210 .StartsWith("_Z5asinh", glsl::ExtInst::ExtInstAsinh)
5211 .StartsWith("_Z4atan", glsl::ExtInst::ExtInstAtan)
5212 .StartsWith("_Z5atan2", glsl::ExtInst::ExtInstAtan2)
5213 .StartsWith("_Z5atanh", glsl::ExtInst::ExtInstAtanh)
5214 .StartsWith("_Z4ceil", glsl::ExtInst::ExtInstCeil)
5215 .StartsWith("_Z3sin", glsl::ExtInst::ExtInstSin)
5216 .StartsWith("_Z4sinh", glsl::ExtInst::ExtInstSinh)
5217 .StartsWith("_Z8half_sin", glsl::ExtInst::ExtInstSin)
5218 .StartsWith("_Z10native_sin", glsl::ExtInst::ExtInstSin)
5219 .StartsWith("_Z3cos", glsl::ExtInst::ExtInstCos)
5220 .StartsWith("_Z4cosh", glsl::ExtInst::ExtInstCosh)
5221 .StartsWith("_Z8half_cos", glsl::ExtInst::ExtInstCos)
5222 .StartsWith("_Z10native_cos", glsl::ExtInst::ExtInstCos)
5223 .StartsWith("_Z3tan", glsl::ExtInst::ExtInstTan)
5224 .StartsWith("_Z4tanh", glsl::ExtInst::ExtInstTanh)
5225 .StartsWith("_Z8half_tan", glsl::ExtInst::ExtInstTan)
5226 .StartsWith("_Z10native_tan", glsl::ExtInst::ExtInstTan)
5227 .StartsWith("_Z3exp", glsl::ExtInst::ExtInstExp)
5228 .StartsWith("_Z8half_exp", glsl::ExtInst::ExtInstExp)
5229 .StartsWith("_Z10native_exp", glsl::ExtInst::ExtInstExp)
5230 .StartsWith("_Z4exp2", glsl::ExtInst::ExtInstExp2)
5231 .StartsWith("_Z9half_exp2", glsl::ExtInst::ExtInstExp2)
5232 .StartsWith("_Z11native_exp2", glsl::ExtInst::ExtInstExp2)
5233 .StartsWith("_Z3log", glsl::ExtInst::ExtInstLog)
5234 .StartsWith("_Z8half_log", glsl::ExtInst::ExtInstLog)
5235 .StartsWith("_Z10native_log", glsl::ExtInst::ExtInstLog)
5236 .StartsWith("_Z4log2", glsl::ExtInst::ExtInstLog2)
5237 .StartsWith("_Z9half_log2", glsl::ExtInst::ExtInstLog2)
5238 .StartsWith("_Z11native_log2", glsl::ExtInst::ExtInstLog2)
5239 .StartsWith("_Z4fabs", glsl::ExtInst::ExtInstFAbs)
5240 .StartsWith("_Z5floor", glsl::ExtInst::ExtInstFloor)
5241 .StartsWith("_Z5ldexp", glsl::ExtInst::ExtInstLdexp)
5242 .StartsWith("_Z3pow", glsl::ExtInst::ExtInstPow)
5243 .StartsWith("_Z4powr", glsl::ExtInst::ExtInstPow)
5244 .StartsWith("_Z9half_powr", glsl::ExtInst::ExtInstPow)
5245 .StartsWith("_Z11native_powr", glsl::ExtInst::ExtInstPow)
5246 .StartsWith("_Z5round", glsl::ExtInst::ExtInstRound)
5247 .StartsWith("_Z4sqrt", glsl::ExtInst::ExtInstSqrt)
5248 .StartsWith("_Z9half_sqrt", glsl::ExtInst::ExtInstSqrt)
5249 .StartsWith("_Z11native_sqrt", glsl::ExtInst::ExtInstSqrt)
5250 .StartsWith("_Z5rsqrt", glsl::ExtInst::ExtInstInverseSqrt)
5251 .StartsWith("_Z10half_rsqrt", glsl::ExtInst::ExtInstInverseSqrt)
5252 .StartsWith("_Z12native_rsqrt", glsl::ExtInst::ExtInstInverseSqrt)
5253 .StartsWith("_Z5trunc", glsl::ExtInst::ExtInstTrunc)
5254 .StartsWith("_Z5frexp", glsl::ExtInst::ExtInstFrexp)
5255 .StartsWith("_Z4sign", glsl::ExtInst::ExtInstFSign)
5256 .StartsWith("_Z6length", glsl::ExtInst::ExtInstLength)
5257 .StartsWith("_Z8distance", glsl::ExtInst::ExtInstDistance)
5258 .Case("_Z5crossDv3_fS_", glsl::ExtInst::ExtInstCross)
5259 .StartsWith("_Z9normalize", glsl::ExtInst::ExtInstNormalize)
5260 .StartsWith("llvm.fmuladd.", glsl::ExtInst::ExtInstFma)
5261 .Case("spirv.unpack.v2f16", glsl::ExtInst::ExtInstUnpackHalf2x16)
5262 .Case("spirv.pack.v2f16", glsl::ExtInst::ExtInstPackHalf2x16)
5263 .Default(static_cast<glsl::ExtInst>(0));
5264}
5265
5266void SPIRVProducerPass::PrintResID(SPIRVInstruction *Inst) {
5267 out << "%" << Inst->getResultID();
5268}
5269
5270void SPIRVProducerPass::PrintOpcode(SPIRVInstruction *Inst) {
5271 spv::Op Opcode = static_cast<spv::Op>(Inst->getOpcode());
5272 out << "\t" << spv::getOpName(Opcode);
5273}
5274
5275void SPIRVProducerPass::PrintOperand(SPIRVOperand *Op) {
5276 SPIRVOperandType OpTy = Op->getType();
5277 switch (OpTy) {
5278 default: {
5279 llvm_unreachable("Unsupported SPIRV Operand Type???");
5280 break;
5281 }
5282 case SPIRVOperandType::NUMBERID: {
5283 out << "%" << Op->getNumID();
5284 break;
5285 }
5286 case SPIRVOperandType::LITERAL_STRING: {
5287 out << "\"" << Op->getLiteralStr() << "\"";
5288 break;
5289 }
5290 case SPIRVOperandType::LITERAL_INTEGER: {
5291 // TODO: Handle LiteralNum carefully.
5292 for (auto Word : Op->getLiteralNum()) {
5293 out << Word;
5294 }
5295 break;
5296 }
5297 case SPIRVOperandType::LITERAL_FLOAT: {
5298 // TODO: Handle LiteralNum carefully.
5299 for (auto Word : Op->getLiteralNum()) {
5300 APFloat APF = APFloat(APFloat::IEEEsingle(), APInt(32, Word));
5301 SmallString<8> Str;
5302 APF.toString(Str, 6, 2);
5303 out << Str;
5304 }
5305 break;
5306 }
5307 }
5308}
5309
5310void SPIRVProducerPass::PrintCapability(SPIRVOperand *Op) {
5311 spv::Capability Cap = static_cast<spv::Capability>(Op->getNumID());
5312 out << spv::getCapabilityName(Cap);
5313}
5314
5315void SPIRVProducerPass::PrintExtInst(SPIRVOperand *Op) {
5316 auto LiteralNum = Op->getLiteralNum();
5317 glsl::ExtInst Ext = static_cast<glsl::ExtInst>(LiteralNum[0]);
5318 out << glsl::getExtInstName(Ext);
5319}
5320
5321void SPIRVProducerPass::PrintAddrModel(SPIRVOperand *Op) {
5322 spv::AddressingModel AddrModel =
5323 static_cast<spv::AddressingModel>(Op->getNumID());
5324 out << spv::getAddressingModelName(AddrModel);
5325}
5326
5327void SPIRVProducerPass::PrintMemModel(SPIRVOperand *Op) {
5328 spv::MemoryModel MemModel = static_cast<spv::MemoryModel>(Op->getNumID());
5329 out << spv::getMemoryModelName(MemModel);
5330}
5331
5332void SPIRVProducerPass::PrintExecModel(SPIRVOperand *Op) {
5333 spv::ExecutionModel ExecModel =
5334 static_cast<spv::ExecutionModel>(Op->getNumID());
5335 out << spv::getExecutionModelName(ExecModel);
5336}
5337
5338void SPIRVProducerPass::PrintExecMode(SPIRVOperand *Op) {
5339 spv::ExecutionMode ExecMode = static_cast<spv::ExecutionMode>(Op->getNumID());
5340 out << spv::getExecutionModeName(ExecMode);
5341}
5342
5343void SPIRVProducerPass::PrintSourceLanguage(SPIRVOperand *Op) {
5344 spv::SourceLanguage SourceLang = static_cast<spv::SourceLanguage>(Op->getNumID());
5345 out << spv::getSourceLanguageName(SourceLang);
5346}
5347
5348void SPIRVProducerPass::PrintFuncCtrl(SPIRVOperand *Op) {
5349 spv::FunctionControlMask FuncCtrl =
5350 static_cast<spv::FunctionControlMask>(Op->getNumID());
5351 out << spv::getFunctionControlName(FuncCtrl);
5352}
5353
5354void SPIRVProducerPass::PrintStorageClass(SPIRVOperand *Op) {
5355 spv::StorageClass StClass = static_cast<spv::StorageClass>(Op->getNumID());
5356 out << getStorageClassName(StClass);
5357}
5358
5359void SPIRVProducerPass::PrintDecoration(SPIRVOperand *Op) {
5360 spv::Decoration Deco = static_cast<spv::Decoration>(Op->getNumID());
5361 out << getDecorationName(Deco);
5362}
5363
5364void SPIRVProducerPass::PrintBuiltIn(SPIRVOperand *Op) {
5365 spv::BuiltIn BIn = static_cast<spv::BuiltIn>(Op->getNumID());
5366 out << getBuiltInName(BIn);
5367}
5368
5369void SPIRVProducerPass::PrintSelectionControl(SPIRVOperand *Op) {
5370 spv::SelectionControlMask BIn =
5371 static_cast<spv::SelectionControlMask>(Op->getNumID());
5372 out << getSelectionControlName(BIn);
5373}
5374
5375void SPIRVProducerPass::PrintLoopControl(SPIRVOperand *Op) {
5376 spv::LoopControlMask BIn = static_cast<spv::LoopControlMask>(Op->getNumID());
5377 out << getLoopControlName(BIn);
5378}
5379
5380void SPIRVProducerPass::PrintDimensionality(SPIRVOperand *Op) {
5381 spv::Dim DIM = static_cast<spv::Dim>(Op->getNumID());
5382 out << getDimName(DIM);
5383}
5384
5385void SPIRVProducerPass::PrintImageFormat(SPIRVOperand *Op) {
5386 spv::ImageFormat Format = static_cast<spv::ImageFormat>(Op->getNumID());
5387 out << getImageFormatName(Format);
5388}
5389
5390void SPIRVProducerPass::PrintMemoryAccess(SPIRVOperand *Op) {
5391 out << spv::getMemoryAccessName(
5392 static_cast<spv::MemoryAccessMask>(Op->getNumID()));
5393}
5394
5395void SPIRVProducerPass::PrintImageOperandsType(SPIRVOperand *Op) {
5396 auto LiteralNum = Op->getLiteralNum();
5397 spv::ImageOperandsMask Type =
5398 static_cast<spv::ImageOperandsMask>(LiteralNum[0]);
5399 out << getImageOperandsName(Type);
5400}
5401
5402void SPIRVProducerPass::WriteSPIRVAssembly() {
5403 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
5404
5405 for (auto Inst : SPIRVInstList) {
5406 SPIRVOperandList Ops = Inst->getOperands();
5407 spv::Op Opcode = static_cast<spv::Op>(Inst->getOpcode());
5408
5409 switch (Opcode) {
5410 default: {
5411 llvm_unreachable("Unsupported SPIRV instruction");
5412 break;
5413 }
5414 case spv::OpCapability: {
5415 // Ops[0] = Capability
5416 PrintOpcode(Inst);
5417 out << " ";
5418 PrintCapability(Ops[0]);
5419 out << "\n";
5420 break;
5421 }
5422 case spv::OpMemoryModel: {
5423 // Ops[0] = Addressing Model
5424 // Ops[1] = Memory Model
5425 PrintOpcode(Inst);
5426 out << " ";
5427 PrintAddrModel(Ops[0]);
5428 out << " ";
5429 PrintMemModel(Ops[1]);
5430 out << "\n";
5431 break;
5432 }
5433 case spv::OpEntryPoint: {
5434 // Ops[0] = Execution Model
5435 // Ops[1] = EntryPoint ID
5436 // Ops[2] = Name (Literal String)
5437 // Ops[3] ... Ops[n] = Interface ID
5438 PrintOpcode(Inst);
5439 out << " ";
5440 PrintExecModel(Ops[0]);
5441 for (uint32_t i = 1; i < Ops.size(); i++) {
5442 out << " ";
5443 PrintOperand(Ops[i]);
5444 }
5445 out << "\n";
5446 break;
5447 }
5448 case spv::OpExecutionMode: {
5449 // Ops[0] = Entry Point ID
5450 // Ops[1] = Execution Mode
5451 // Ops[2] ... Ops[n] = Optional literals according to Execution Mode
5452 PrintOpcode(Inst);
5453 out << " ";
5454 PrintOperand(Ops[0]);
5455 out << " ";
5456 PrintExecMode(Ops[1]);
5457 for (uint32_t i = 2; i < Ops.size(); i++) {
5458 out << " ";
5459 PrintOperand(Ops[i]);
5460 }
5461 out << "\n";
5462 break;
5463 }
5464 case spv::OpSource: {
5465 // Ops[0] = SourceLanguage ID
5466 // Ops[1] = Version (LiteralNum)
5467 PrintOpcode(Inst);
5468 out << " ";
5469 PrintSourceLanguage(Ops[0]);
5470 out << " ";
5471 PrintOperand(Ops[1]);
5472 out << "\n";
5473 break;
5474 }
5475 case spv::OpDecorate: {
5476 // Ops[0] = Target ID
5477 // Ops[1] = Decoration (Block or BufferBlock)
5478 // Ops[2] ... Ops[n] = Optional literals according to Decoration
5479 PrintOpcode(Inst);
5480 out << " ";
5481 PrintOperand(Ops[0]);
5482 out << " ";
5483 PrintDecoration(Ops[1]);
5484 // Handle BuiltIn OpDecorate specially.
5485 if (Ops[1]->getNumID() == spv::DecorationBuiltIn) {
5486 out << " ";
5487 PrintBuiltIn(Ops[2]);
5488 } else {
5489 for (uint32_t i = 2; i < Ops.size(); i++) {
5490 out << " ";
5491 PrintOperand(Ops[i]);
5492 }
5493 }
5494 out << "\n";
5495 break;
5496 }
5497 case spv::OpMemberDecorate: {
5498 // Ops[0] = Structure Type ID
5499 // Ops[1] = Member Index(Literal Number)
5500 // Ops[2] = Decoration
5501 // Ops[3] ... Ops[n] = Optional literals according to Decoration
5502 PrintOpcode(Inst);
5503 out << " ";
5504 PrintOperand(Ops[0]);
5505 out << " ";
5506 PrintOperand(Ops[1]);
5507 out << " ";
5508 PrintDecoration(Ops[2]);
5509 for (uint32_t i = 3; i < Ops.size(); i++) {
5510 out << " ";
5511 PrintOperand(Ops[i]);
5512 }
5513 out << "\n";
5514 break;
5515 }
5516 case spv::OpTypePointer: {
5517 // Ops[0] = Storage Class
5518 // Ops[1] = Element Type ID
5519 PrintResID(Inst);
5520 out << " = ";
5521 PrintOpcode(Inst);
5522 out << " ";
5523 PrintStorageClass(Ops[0]);
5524 out << " ";
5525 PrintOperand(Ops[1]);
5526 out << "\n";
5527 break;
5528 }
5529 case spv::OpTypeImage: {
5530 // Ops[0] = Sampled Type ID
5531 // Ops[1] = Dim ID
5532 // Ops[2] = Depth (Literal Number)
5533 // Ops[3] = Arrayed (Literal Number)
5534 // Ops[4] = MS (Literal Number)
5535 // Ops[5] = Sampled (Literal Number)
5536 // Ops[6] = Image Format ID
5537 PrintResID(Inst);
5538 out << " = ";
5539 PrintOpcode(Inst);
5540 out << " ";
5541 PrintOperand(Ops[0]);
5542 out << " ";
5543 PrintDimensionality(Ops[1]);
5544 out << " ";
5545 PrintOperand(Ops[2]);
5546 out << " ";
5547 PrintOperand(Ops[3]);
5548 out << " ";
5549 PrintOperand(Ops[4]);
5550 out << " ";
5551 PrintOperand(Ops[5]);
5552 out << " ";
5553 PrintImageFormat(Ops[6]);
5554 out << "\n";
5555 break;
5556 }
5557 case spv::OpFunction: {
5558 // Ops[0] : Result Type ID
5559 // Ops[1] : Function Control
5560 // Ops[2] : Function Type ID
5561 PrintResID(Inst);
5562 out << " = ";
5563 PrintOpcode(Inst);
5564 out << " ";
5565 PrintOperand(Ops[0]);
5566 out << " ";
5567 PrintFuncCtrl(Ops[1]);
5568 out << " ";
5569 PrintOperand(Ops[2]);
5570 out << "\n";
5571 break;
5572 }
5573 case spv::OpSelectionMerge: {
5574 // Ops[0] = Merge Block ID
5575 // Ops[1] = Selection Control
5576 PrintOpcode(Inst);
5577 out << " ";
5578 PrintOperand(Ops[0]);
5579 out << " ";
5580 PrintSelectionControl(Ops[1]);
5581 out << "\n";
5582 break;
5583 }
5584 case spv::OpLoopMerge: {
5585 // Ops[0] = Merge Block ID
5586 // Ops[1] = Continue Target ID
5587 // Ops[2] = Selection Control
5588 PrintOpcode(Inst);
5589 out << " ";
5590 PrintOperand(Ops[0]);
5591 out << " ";
5592 PrintOperand(Ops[1]);
5593 out << " ";
5594 PrintLoopControl(Ops[2]);
5595 out << "\n";
5596 break;
5597 }
5598 case spv::OpImageSampleExplicitLod: {
5599 // Ops[0] = Result Type ID
5600 // Ops[1] = Sampled Image ID
5601 // Ops[2] = Coordinate ID
5602 // Ops[3] = Image Operands Type ID
5603 // Ops[4] ... Ops[n] = Operands ID
5604 PrintResID(Inst);
5605 out << " = ";
5606 PrintOpcode(Inst);
5607 for (uint32_t i = 0; i < 3; i++) {
5608 out << " ";
5609 PrintOperand(Ops[i]);
5610 }
5611 out << " ";
5612 PrintImageOperandsType(Ops[3]);
5613 for (uint32_t i = 4; i < Ops.size(); i++) {
5614 out << " ";
5615 PrintOperand(Ops[i]);
5616 }
5617 out << "\n";
5618 break;
5619 }
5620 case spv::OpVariable: {
5621 // Ops[0] : Result Type ID
5622 // Ops[1] : Storage Class
5623 // Ops[2] ... Ops[n] = Initializer IDs
5624 PrintResID(Inst);
5625 out << " = ";
5626 PrintOpcode(Inst);
5627 out << " ";
5628 PrintOperand(Ops[0]);
5629 out << " ";
5630 PrintStorageClass(Ops[1]);
5631 for (uint32_t i = 2; i < Ops.size(); i++) {
5632 out << " ";
5633 PrintOperand(Ops[i]);
5634 }
5635 out << "\n";
5636 break;
5637 }
5638 case spv::OpExtInst: {
5639 // Ops[0] = Result Type ID
5640 // Ops[1] = Set ID (OpExtInstImport ID)
5641 // Ops[2] = Instruction Number (Literal Number)
5642 // Ops[3] ... Ops[n] = Operand 1, ... , Operand n
5643 PrintResID(Inst);
5644 out << " = ";
5645 PrintOpcode(Inst);
5646 out << " ";
5647 PrintOperand(Ops[0]);
5648 out << " ";
5649 PrintOperand(Ops[1]);
5650 out << " ";
5651 PrintExtInst(Ops[2]);
5652 for (uint32_t i = 3; i < Ops.size(); i++) {
5653 out << " ";
5654 PrintOperand(Ops[i]);
5655 }
5656 out << "\n";
5657 break;
5658 }
5659 case spv::OpCopyMemory: {
5660 // Ops[0] = Addressing Model
5661 // Ops[1] = Memory Model
5662 PrintOpcode(Inst);
5663 out << " ";
5664 PrintOperand(Ops[0]);
5665 out << " ";
5666 PrintOperand(Ops[1]);
5667 out << " ";
5668 PrintMemoryAccess(Ops[2]);
5669 out << " ";
5670 PrintOperand(Ops[3]);
5671 out << "\n";
5672 break;
5673 }
5674 case spv::OpExtension:
5675 case spv::OpControlBarrier:
5676 case spv::OpMemoryBarrier:
5677 case spv::OpBranch:
5678 case spv::OpBranchConditional:
5679 case spv::OpStore:
5680 case spv::OpImageWrite:
5681 case spv::OpReturnValue:
5682 case spv::OpReturn:
5683 case spv::OpFunctionEnd: {
5684 PrintOpcode(Inst);
5685 for (uint32_t i = 0; i < Ops.size(); i++) {
5686 out << " ";
5687 PrintOperand(Ops[i]);
5688 }
5689 out << "\n";
5690 break;
5691 }
5692 case spv::OpExtInstImport:
5693 case spv::OpTypeRuntimeArray:
5694 case spv::OpTypeStruct:
5695 case spv::OpTypeSampler:
5696 case spv::OpTypeSampledImage:
5697 case spv::OpTypeInt:
5698 case spv::OpTypeFloat:
5699 case spv::OpTypeArray:
5700 case spv::OpTypeVector:
5701 case spv::OpTypeBool:
5702 case spv::OpTypeVoid:
5703 case spv::OpTypeFunction:
5704 case spv::OpFunctionParameter:
5705 case spv::OpLabel:
5706 case spv::OpPhi:
5707 case spv::OpLoad:
5708 case spv::OpSelect:
5709 case spv::OpAccessChain:
5710 case spv::OpPtrAccessChain:
5711 case spv::OpInBoundsAccessChain:
5712 case spv::OpUConvert:
5713 case spv::OpSConvert:
5714 case spv::OpConvertFToU:
5715 case spv::OpConvertFToS:
5716 case spv::OpConvertUToF:
5717 case spv::OpConvertSToF:
5718 case spv::OpFConvert:
5719 case spv::OpConvertPtrToU:
5720 case spv::OpConvertUToPtr:
5721 case spv::OpBitcast:
5722 case spv::OpIAdd:
5723 case spv::OpFAdd:
5724 case spv::OpISub:
5725 case spv::OpFSub:
5726 case spv::OpIMul:
5727 case spv::OpFMul:
5728 case spv::OpUDiv:
5729 case spv::OpSDiv:
5730 case spv::OpFDiv:
5731 case spv::OpUMod:
5732 case spv::OpSRem:
5733 case spv::OpFRem:
5734 case spv::OpBitwiseOr:
5735 case spv::OpBitwiseXor:
5736 case spv::OpBitwiseAnd:
5737 case spv::OpShiftLeftLogical:
5738 case spv::OpShiftRightLogical:
5739 case spv::OpShiftRightArithmetic:
5740 case spv::OpBitCount:
5741 case spv::OpCompositeExtract:
5742 case spv::OpVectorExtractDynamic:
5743 case spv::OpCompositeInsert:
5744 case spv::OpVectorInsertDynamic:
5745 case spv::OpVectorShuffle:
5746 case spv::OpIEqual:
5747 case spv::OpINotEqual:
5748 case spv::OpUGreaterThan:
5749 case spv::OpUGreaterThanEqual:
5750 case spv::OpULessThan:
5751 case spv::OpULessThanEqual:
5752 case spv::OpSGreaterThan:
5753 case spv::OpSGreaterThanEqual:
5754 case spv::OpSLessThan:
5755 case spv::OpSLessThanEqual:
5756 case spv::OpFOrdEqual:
5757 case spv::OpFOrdGreaterThan:
5758 case spv::OpFOrdGreaterThanEqual:
5759 case spv::OpFOrdLessThan:
5760 case spv::OpFOrdLessThanEqual:
5761 case spv::OpFOrdNotEqual:
5762 case spv::OpFUnordEqual:
5763 case spv::OpFUnordGreaterThan:
5764 case spv::OpFUnordGreaterThanEqual:
5765 case spv::OpFUnordLessThan:
5766 case spv::OpFUnordLessThanEqual:
5767 case spv::OpFUnordNotEqual:
5768 case spv::OpSampledImage:
5769 case spv::OpFunctionCall:
5770 case spv::OpConstantTrue:
5771 case spv::OpConstantFalse:
5772 case spv::OpConstant:
5773 case spv::OpSpecConstant:
5774 case spv::OpConstantComposite:
5775 case spv::OpSpecConstantComposite:
5776 case spv::OpConstantNull:
5777 case spv::OpLogicalOr:
5778 case spv::OpLogicalAnd:
5779 case spv::OpLogicalNot:
5780 case spv::OpLogicalNotEqual:
5781 case spv::OpUndef:
5782 case spv::OpIsInf:
5783 case spv::OpIsNan:
5784 case spv::OpAny:
5785 case spv::OpAll:
5786 case spv::OpAtomicIAdd:
5787 case spv::OpAtomicISub:
5788 case spv::OpAtomicExchange:
5789 case spv::OpAtomicIIncrement:
5790 case spv::OpAtomicIDecrement:
5791 case spv::OpAtomicCompareExchange:
5792 case spv::OpAtomicUMin:
5793 case spv::OpAtomicSMin:
5794 case spv::OpAtomicUMax:
5795 case spv::OpAtomicSMax:
5796 case spv::OpAtomicAnd:
5797 case spv::OpAtomicOr:
5798 case spv::OpAtomicXor:
5799 case spv::OpDot: {
5800 PrintResID(Inst);
5801 out << " = ";
5802 PrintOpcode(Inst);
5803 for (uint32_t i = 0; i < Ops.size(); i++) {
5804 out << " ";
5805 PrintOperand(Ops[i]);
5806 }
5807 out << "\n";
5808 break;
5809 }
5810 }
5811 }
5812}
5813
5814void SPIRVProducerPass::WriteOneWord(uint32_t Word) {
David Neto0676e6f2017-07-11 18:47:44 -04005815 binaryOut->write(reinterpret_cast<const char *>(&Word), sizeof(uint32_t));
David Neto22f144c2017-06-12 14:26:21 -04005816}
5817
5818void SPIRVProducerPass::WriteResultID(SPIRVInstruction *Inst) {
5819 WriteOneWord(Inst->getResultID());
5820}
5821
5822void SPIRVProducerPass::WriteWordCountAndOpcode(SPIRVInstruction *Inst) {
5823 // High 16 bit : Word Count
5824 // Low 16 bit : Opcode
5825 uint32_t Word = Inst->getOpcode();
5826 Word |= Inst->getWordCount() << 16;
5827 WriteOneWord(Word);
5828}
5829
5830void SPIRVProducerPass::WriteOperand(SPIRVOperand *Op) {
5831 SPIRVOperandType OpTy = Op->getType();
5832 switch (OpTy) {
5833 default: {
5834 llvm_unreachable("Unsupported SPIRV Operand Type???");
5835 break;
5836 }
5837 case SPIRVOperandType::NUMBERID: {
5838 WriteOneWord(Op->getNumID());
5839 break;
5840 }
5841 case SPIRVOperandType::LITERAL_STRING: {
5842 std::string Str = Op->getLiteralStr();
5843 const char *Data = Str.c_str();
5844 size_t WordSize = Str.size() / 4;
5845 for (unsigned Idx = 0; Idx < WordSize; Idx++) {
5846 WriteOneWord(*reinterpret_cast<const uint32_t *>(&Data[4 * Idx]));
5847 }
5848
5849 uint32_t Remainder = Str.size() % 4;
5850 uint32_t LastWord = 0;
5851 if (Remainder) {
5852 for (unsigned Idx = 0; Idx < Remainder; Idx++) {
5853 LastWord |= Data[4 * WordSize + Idx] << 8 * Idx;
5854 }
5855 }
5856
5857 WriteOneWord(LastWord);
5858 break;
5859 }
5860 case SPIRVOperandType::LITERAL_INTEGER:
5861 case SPIRVOperandType::LITERAL_FLOAT: {
5862 auto LiteralNum = Op->getLiteralNum();
5863 // TODO: Handle LiteranNum carefully.
5864 for (auto Word : LiteralNum) {
5865 WriteOneWord(Word);
5866 }
5867 break;
5868 }
5869 }
5870}
5871
5872void SPIRVProducerPass::WriteSPIRVBinary() {
5873 SPIRVInstructionList &SPIRVInstList = getSPIRVInstList();
5874
5875 for (auto Inst : SPIRVInstList) {
5876 SPIRVOperandList Ops = Inst->getOperands();
5877 spv::Op Opcode = static_cast<spv::Op>(Inst->getOpcode());
5878
5879 switch (Opcode) {
5880 default: {
5881 llvm_unreachable("Unsupported SPIRV instruction");
5882 break;
5883 }
5884 case spv::OpCapability:
5885 case spv::OpExtension:
5886 case spv::OpMemoryModel:
5887 case spv::OpEntryPoint:
5888 case spv::OpExecutionMode:
5889 case spv::OpSource:
5890 case spv::OpDecorate:
5891 case spv::OpMemberDecorate:
5892 case spv::OpBranch:
5893 case spv::OpBranchConditional:
5894 case spv::OpSelectionMerge:
5895 case spv::OpLoopMerge:
5896 case spv::OpStore:
5897 case spv::OpImageWrite:
5898 case spv::OpReturnValue:
5899 case spv::OpControlBarrier:
5900 case spv::OpMemoryBarrier:
5901 case spv::OpReturn:
5902 case spv::OpFunctionEnd:
5903 case spv::OpCopyMemory: {
5904 WriteWordCountAndOpcode(Inst);
5905 for (uint32_t i = 0; i < Ops.size(); i++) {
5906 WriteOperand(Ops[i]);
5907 }
5908 break;
5909 }
5910 case spv::OpTypeBool:
5911 case spv::OpTypeVoid:
5912 case spv::OpTypeSampler:
5913 case spv::OpLabel:
5914 case spv::OpExtInstImport:
5915 case spv::OpTypePointer:
5916 case spv::OpTypeRuntimeArray:
5917 case spv::OpTypeStruct:
5918 case spv::OpTypeImage:
5919 case spv::OpTypeSampledImage:
5920 case spv::OpTypeInt:
5921 case spv::OpTypeFloat:
5922 case spv::OpTypeArray:
5923 case spv::OpTypeVector:
5924 case spv::OpTypeFunction: {
5925 WriteWordCountAndOpcode(Inst);
5926 WriteResultID(Inst);
5927 for (uint32_t i = 0; i < Ops.size(); i++) {
5928 WriteOperand(Ops[i]);
5929 }
5930 break;
5931 }
5932 case spv::OpFunction:
5933 case spv::OpFunctionParameter:
5934 case spv::OpAccessChain:
5935 case spv::OpPtrAccessChain:
5936 case spv::OpInBoundsAccessChain:
5937 case spv::OpUConvert:
5938 case spv::OpSConvert:
5939 case spv::OpConvertFToU:
5940 case spv::OpConvertFToS:
5941 case spv::OpConvertUToF:
5942 case spv::OpConvertSToF:
5943 case spv::OpFConvert:
5944 case spv::OpConvertPtrToU:
5945 case spv::OpConvertUToPtr:
5946 case spv::OpBitcast:
5947 case spv::OpIAdd:
5948 case spv::OpFAdd:
5949 case spv::OpISub:
5950 case spv::OpFSub:
5951 case spv::OpIMul:
5952 case spv::OpFMul:
5953 case spv::OpUDiv:
5954 case spv::OpSDiv:
5955 case spv::OpFDiv:
5956 case spv::OpUMod:
5957 case spv::OpSRem:
5958 case spv::OpFRem:
5959 case spv::OpBitwiseOr:
5960 case spv::OpBitwiseXor:
5961 case spv::OpBitwiseAnd:
5962 case spv::OpShiftLeftLogical:
5963 case spv::OpShiftRightLogical:
5964 case spv::OpShiftRightArithmetic:
5965 case spv::OpBitCount:
5966 case spv::OpCompositeExtract:
5967 case spv::OpVectorExtractDynamic:
5968 case spv::OpCompositeInsert:
5969 case spv::OpVectorInsertDynamic:
5970 case spv::OpVectorShuffle:
5971 case spv::OpIEqual:
5972 case spv::OpINotEqual:
5973 case spv::OpUGreaterThan:
5974 case spv::OpUGreaterThanEqual:
5975 case spv::OpULessThan:
5976 case spv::OpULessThanEqual:
5977 case spv::OpSGreaterThan:
5978 case spv::OpSGreaterThanEqual:
5979 case spv::OpSLessThan:
5980 case spv::OpSLessThanEqual:
5981 case spv::OpFOrdEqual:
5982 case spv::OpFOrdGreaterThan:
5983 case spv::OpFOrdGreaterThanEqual:
5984 case spv::OpFOrdLessThan:
5985 case spv::OpFOrdLessThanEqual:
5986 case spv::OpFOrdNotEqual:
5987 case spv::OpFUnordEqual:
5988 case spv::OpFUnordGreaterThan:
5989 case spv::OpFUnordGreaterThanEqual:
5990 case spv::OpFUnordLessThan:
5991 case spv::OpFUnordLessThanEqual:
5992 case spv::OpFUnordNotEqual:
5993 case spv::OpExtInst:
5994 case spv::OpIsInf:
5995 case spv::OpIsNan:
5996 case spv::OpAny:
5997 case spv::OpAll:
5998 case spv::OpUndef:
5999 case spv::OpConstantNull:
6000 case spv::OpLogicalOr:
6001 case spv::OpLogicalAnd:
6002 case spv::OpLogicalNot:
6003 case spv::OpLogicalNotEqual:
6004 case spv::OpConstantComposite:
6005 case spv::OpSpecConstantComposite:
6006 case spv::OpConstantTrue:
6007 case spv::OpConstantFalse:
6008 case spv::OpConstant:
6009 case spv::OpSpecConstant:
6010 case spv::OpVariable:
6011 case spv::OpFunctionCall:
6012 case spv::OpSampledImage:
6013 case spv::OpImageSampleExplicitLod:
6014 case spv::OpSelect:
6015 case spv::OpPhi:
6016 case spv::OpLoad:
6017 case spv::OpAtomicIAdd:
6018 case spv::OpAtomicISub:
6019 case spv::OpAtomicExchange:
6020 case spv::OpAtomicIIncrement:
6021 case spv::OpAtomicIDecrement:
6022 case spv::OpAtomicCompareExchange:
6023 case spv::OpAtomicUMin:
6024 case spv::OpAtomicSMin:
6025 case spv::OpAtomicUMax:
6026 case spv::OpAtomicSMax:
6027 case spv::OpAtomicAnd:
6028 case spv::OpAtomicOr:
6029 case spv::OpAtomicXor:
6030 case spv::OpDot: {
6031 WriteWordCountAndOpcode(Inst);
6032 WriteOperand(Ops[0]);
6033 WriteResultID(Inst);
6034 for (uint32_t i = 1; i < Ops.size(); i++) {
6035 WriteOperand(Ops[i]);
6036 }
6037 break;
6038 }
6039 }
6040 }
6041}