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