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