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