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