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