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