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