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