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