Add support for GL_NV_shader_invocation_reorder. (#3054)
[platform/upstream/glslang.git] / SPIRV / SpvBuilder.cpp
1 //
2 // Copyright (C) 2014-2015 LunarG, Inc.
3 // Copyright (C) 2015-2018 Google, Inc.
4 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 //    Redistributions of source code must retain the above copyright
13 //    notice, this list of conditions and the following disclaimer.
14 //
15 //    Redistributions in binary form must reproduce the above
16 //    copyright notice, this list of conditions and the following
17 //    disclaimer in the documentation and/or other materials provided
18 //    with the distribution.
19 //
20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
21 //    contributors may be used to endorse or promote products derived
22 //    from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 // POSSIBILITY OF SUCH DAMAGE.
36
37 //
38 // Helper for making SPIR-V IR.  Generally, this is documented in the header
39 // SpvBuilder.h.
40 //
41
42 #include <cassert>
43 #include <cstdlib>
44
45 #include <unordered_set>
46 #include <algorithm>
47
48 #include "SpvBuilder.h"
49
50 #ifndef GLSLANG_WEB
51 #include "hex_float.h"
52 #endif
53
54 #ifndef _WIN32
55     #include <cstdio>
56 #endif
57
58 namespace spv {
59
60 Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogger* buildLogger) :
61     spvVersion(spvVersion),
62     sourceLang(SourceLanguageUnknown),
63     sourceVersion(0),
64     sourceFileStringId(NoResult),
65     currentLine(0),
66     currentFile(nullptr),
67     currentFileId(NoResult),
68     lastDebugScopeId(NoResult),
69     emitOpLines(false),
70     emitNonSemanticShaderDebugInfo(false),
71     addressModel(AddressingModelLogical),
72     memoryModel(MemoryModelGLSL450),
73     builderNumber(magicNumber),
74     buildPoint(nullptr),
75     uniqueId(0),
76     entryPointFunction(nullptr),
77     generatingOpCodeForSpecConst(false),
78     logger(buildLogger)
79 {
80     clearAccessChain();
81 }
82
83 Builder::~Builder()
84 {
85 }
86
87 Id Builder::import(const char* name)
88 {
89     Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);
90     import->addStringOperand(name);
91     module.mapInstruction(import);
92
93     imports.push_back(std::unique_ptr<Instruction>(import));
94     return import->getResultId();
95 }
96
97 // Emit instruction for non-filename-based #line directives (ie. no filename
98 // seen yet): emit an OpLine if we've been asked to emit OpLines and the line
99 // number has changed since the last time, and is a valid line number.
100 void Builder::setLine(int lineNum)
101 {
102     if (lineNum != 0 && lineNum != currentLine) {
103         currentLine = lineNum;
104         if (emitOpLines) {
105           if (emitNonSemanticShaderDebugInfo)
106               addDebugScopeAndLine(currentFileId, currentLine, 0);
107           else
108               addLine(sourceFileStringId, currentLine, 0);
109         }
110     }
111 }
112
113 // If no filename, do non-filename-based #line emit. Else do filename-based emit.
114 // Emit OpLine if we've been asked to emit OpLines and the line number or filename
115 // has changed since the last time, and line number is valid.
116 void Builder::setLine(int lineNum, const char* filename)
117 {
118     if (filename == nullptr) {
119         setLine(lineNum);
120         return;
121     }
122     if ((lineNum != 0 && lineNum != currentLine) || currentFile == nullptr ||
123             strncmp(filename, currentFile, strlen(currentFile) + 1) != 0) {
124         currentLine = lineNum;
125         currentFile = filename;
126         if (emitOpLines) {
127             spv::Id strId = getStringId(filename);
128             if (emitNonSemanticShaderDebugInfo)
129                 addDebugScopeAndLine(strId, currentLine, 0);
130             else
131                 addLine(strId, currentLine, 0);
132         }
133     }
134 }
135
136 void Builder::addLine(Id fileName, int lineNum, int column)
137 {
138     Instruction* line = new Instruction(OpLine);
139     line->addIdOperand(fileName);
140     line->addImmediateOperand(lineNum);
141     line->addImmediateOperand(column);
142     buildPoint->addInstruction(std::unique_ptr<Instruction>(line));
143 }
144
145 void Builder::addDebugScopeAndLine(Id fileName, int lineNum, int column)
146 {
147     if (currentDebugScopeId.top() != lastDebugScopeId) {
148         spv::Id resultId = getUniqueId();
149         Instruction* scopeInst = new Instruction(resultId, makeVoidType(), OpExtInst);
150         scopeInst->addIdOperand(nonSemanticShaderDebugInfo);
151         scopeInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugScope);
152         scopeInst->addIdOperand(currentDebugScopeId.top());
153         buildPoint->addInstruction(std::unique_ptr<Instruction>(scopeInst));
154         lastDebugScopeId = currentDebugScopeId.top();
155     }
156     spv::Id resultId = getUniqueId();
157     Instruction* lineInst = new Instruction(resultId, makeVoidType(), OpExtInst);
158     lineInst->addIdOperand(nonSemanticShaderDebugInfo);
159     lineInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLine);
160     lineInst->addIdOperand(makeDebugSource(fileName));
161     lineInst->addIdOperand(makeUintConstant(lineNum));
162     lineInst->addIdOperand(makeUintConstant(lineNum));
163     lineInst->addIdOperand(makeUintConstant(column));
164     lineInst->addIdOperand(makeUintConstant(column));
165     buildPoint->addInstruction(std::unique_ptr<Instruction>(lineInst));
166 }
167
168 // For creating new groupedTypes (will return old type if the requested one was already made).
169 Id Builder::makeVoidType()
170 {
171     Instruction* type;
172     if (groupedTypes[OpTypeVoid].size() == 0) {
173         Id typeId = getUniqueId();
174         type = new Instruction(typeId, NoType, OpTypeVoid);
175         groupedTypes[OpTypeVoid].push_back(type);
176         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
177         module.mapInstruction(type);
178         // Core OpTypeVoid used for debug void type
179         if (emitNonSemanticShaderDebugInfo)
180             debugId[typeId] = typeId;
181     } else
182         type = groupedTypes[OpTypeVoid].back();
183
184     return type->getResultId();
185 }
186
187 Id Builder::makeBoolType(bool const compilerGenerated)
188 {
189     Instruction* type;
190     if (groupedTypes[OpTypeBool].size() == 0) {
191         type = new Instruction(getUniqueId(), NoType, OpTypeBool);
192         groupedTypes[OpTypeBool].push_back(type);
193         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
194         module.mapInstruction(type);
195     } else
196         type = groupedTypes[OpTypeBool].back();
197
198     if (emitNonSemanticShaderDebugInfo && !compilerGenerated)
199     {
200         auto const debugResultId = makeBoolDebugType(32);
201         debugId[type->getResultId()] = debugResultId;
202     }
203
204     return type->getResultId();
205 }
206
207 Id Builder::makeSamplerType()
208 {
209     Instruction* type;
210     if (groupedTypes[OpTypeSampler].size() == 0) {
211         type = new Instruction(getUniqueId(), NoType, OpTypeSampler);
212         groupedTypes[OpTypeSampler].push_back(type);
213         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
214         module.mapInstruction(type);
215     } else
216         type = groupedTypes[OpTypeSampler].back();
217
218     if (emitNonSemanticShaderDebugInfo)
219     {
220         auto const debugResultId = makeCompositeDebugType({}, "type.sampler", NonSemanticShaderDebugInfo100Structure, true);
221         debugId[type->getResultId()] = debugResultId;
222     }
223
224     return type->getResultId();
225 }
226
227 Id Builder::makePointer(StorageClass storageClass, Id pointee)
228 {
229     // try to find it
230     Instruction* type;
231     for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
232         type = groupedTypes[OpTypePointer][t];
233         if (type->getImmediateOperand(0) == (unsigned)storageClass &&
234             type->getIdOperand(1) == pointee)
235             return type->getResultId();
236     }
237
238     // not found, make it
239     type = new Instruction(getUniqueId(), NoType, OpTypePointer);
240     type->addImmediateOperand(storageClass);
241     type->addIdOperand(pointee);
242     groupedTypes[OpTypePointer].push_back(type);
243     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
244     module.mapInstruction(type);
245
246     return type->getResultId();
247 }
248
249 Id Builder::makeForwardPointer(StorageClass storageClass)
250 {
251     // Caching/uniquifying doesn't work here, because we don't know the
252     // pointee type and there can be multiple forward pointers of the same
253     // storage type. Somebody higher up in the stack must keep track.
254     Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeForwardPointer);
255     type->addImmediateOperand(storageClass);
256     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
257     module.mapInstruction(type);
258
259     return type->getResultId();
260 }
261
262 Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardPointerType, Id pointee)
263 {
264     // try to find it
265     Instruction* type;
266     for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
267         type = groupedTypes[OpTypePointer][t];
268         if (type->getImmediateOperand(0) == (unsigned)storageClass &&
269             type->getIdOperand(1) == pointee)
270             return type->getResultId();
271     }
272
273     type = new Instruction(forwardPointerType, NoType, OpTypePointer);
274     type->addImmediateOperand(storageClass);
275     type->addIdOperand(pointee);
276     groupedTypes[OpTypePointer].push_back(type);
277     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
278     module.mapInstruction(type);
279
280     return type->getResultId();
281 }
282
283 Id Builder::makeIntegerType(int width, bool hasSign)
284 {
285 #ifdef GLSLANG_WEB
286     assert(width == 32);
287     width = 32;
288 #endif
289
290     // try to find it
291     Instruction* type;
292     for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {
293         type = groupedTypes[OpTypeInt][t];
294         if (type->getImmediateOperand(0) == (unsigned)width &&
295             type->getImmediateOperand(1) == (hasSign ? 1u : 0u))
296             return type->getResultId();
297     }
298
299     // not found, make it
300     type = new Instruction(getUniqueId(), NoType, OpTypeInt);
301     type->addImmediateOperand(width);
302     type->addImmediateOperand(hasSign ? 1 : 0);
303     groupedTypes[OpTypeInt].push_back(type);
304     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
305     module.mapInstruction(type);
306
307     // deal with capabilities
308     switch (width) {
309     case 8:
310     case 16:
311         // these are currently handled by storage-type declarations and post processing
312         break;
313     case 64:
314         addCapability(CapabilityInt64);
315         break;
316     default:
317         break;
318     }
319
320     if (emitNonSemanticShaderDebugInfo)
321     {
322         auto const debugResultId = makeIntegerDebugType(width, hasSign);
323         debugId[type->getResultId()] = debugResultId;
324     }
325
326     return type->getResultId();
327 }
328
329 Id Builder::makeFloatType(int width)
330 {
331 #ifdef GLSLANG_WEB
332     assert(width == 32);
333     width = 32;
334 #endif
335
336     // try to find it
337     Instruction* type;
338     for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {
339         type = groupedTypes[OpTypeFloat][t];
340         if (type->getImmediateOperand(0) == (unsigned)width)
341             return type->getResultId();
342     }
343
344     // not found, make it
345     type = new Instruction(getUniqueId(), NoType, OpTypeFloat);
346     type->addImmediateOperand(width);
347     groupedTypes[OpTypeFloat].push_back(type);
348     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
349     module.mapInstruction(type);
350
351     // deal with capabilities
352     switch (width) {
353     case 16:
354         // currently handled by storage-type declarations and post processing
355         break;
356     case 64:
357         addCapability(CapabilityFloat64);
358         break;
359     default:
360         break;
361     }
362
363     if (emitNonSemanticShaderDebugInfo)
364     {
365         auto const debugResultId = makeFloatDebugType(width);
366         debugId[type->getResultId()] = debugResultId;
367     }
368
369     return type->getResultId();
370 }
371
372 // Make a struct without checking for duplication.
373 // See makeStructResultType() for non-decorated structs
374 // needed as the result of some instructions, which does
375 // check for duplicates.
376 Id Builder::makeStructType(const std::vector<Id>& members, const char* name, bool const compilerGenerated)
377 {
378     // Don't look for previous one, because in the general case,
379     // structs can be duplicated except for decorations.
380
381     // not found, make it
382     Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeStruct);
383     for (int op = 0; op < (int)members.size(); ++op)
384         type->addIdOperand(members[op]);
385     groupedTypes[OpTypeStruct].push_back(type);
386     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
387     module.mapInstruction(type);
388     addName(type->getResultId(), name);
389
390     if (emitNonSemanticShaderDebugInfo && !compilerGenerated)
391     {
392         auto const debugResultId = makeCompositeDebugType(members, name, NonSemanticShaderDebugInfo100Structure);
393         debugId[type->getResultId()] = debugResultId;
394     }
395
396     return type->getResultId();
397 }
398
399 // Make a struct for the simple results of several instructions,
400 // checking for duplication.
401 Id Builder::makeStructResultType(Id type0, Id type1)
402 {
403     // try to find it
404     Instruction* type;
405     for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) {
406         type = groupedTypes[OpTypeStruct][t];
407         if (type->getNumOperands() != 2)
408             continue;
409         if (type->getIdOperand(0) != type0 ||
410             type->getIdOperand(1) != type1)
411             continue;
412         return type->getResultId();
413     }
414
415     // not found, make it
416     std::vector<spv::Id> members;
417     members.push_back(type0);
418     members.push_back(type1);
419
420     return makeStructType(members, "ResType");
421 }
422
423 Id Builder::makeVectorType(Id component, int size)
424 {
425     // try to find it
426     Instruction* type;
427     for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t) {
428         type = groupedTypes[OpTypeVector][t];
429         if (type->getIdOperand(0) == component &&
430             type->getImmediateOperand(1) == (unsigned)size)
431             return type->getResultId();
432     }
433
434     // not found, make it
435     type = new Instruction(getUniqueId(), NoType, OpTypeVector);
436     type->addIdOperand(component);
437     type->addImmediateOperand(size);
438     groupedTypes[OpTypeVector].push_back(type);
439     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
440     module.mapInstruction(type);
441
442     if (emitNonSemanticShaderDebugInfo)
443     {
444         auto const debugResultId = makeVectorDebugType(component, size);
445         debugId[type->getResultId()] = debugResultId;
446     }
447
448     return type->getResultId();
449 }
450
451 Id Builder::makeMatrixType(Id component, int cols, int rows)
452 {
453     assert(cols <= maxMatrixSize && rows <= maxMatrixSize);
454
455     Id column = makeVectorType(component, rows);
456
457     // try to find it
458     Instruction* type;
459     for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t) {
460         type = groupedTypes[OpTypeMatrix][t];
461         if (type->getIdOperand(0) == column &&
462             type->getImmediateOperand(1) == (unsigned)cols)
463             return type->getResultId();
464     }
465
466     // not found, make it
467     type = new Instruction(getUniqueId(), NoType, OpTypeMatrix);
468     type->addIdOperand(column);
469     type->addImmediateOperand(cols);
470     groupedTypes[OpTypeMatrix].push_back(type);
471     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
472     module.mapInstruction(type);
473
474     if (emitNonSemanticShaderDebugInfo)
475     {
476         auto const debugResultId = makeMatrixDebugType(column, cols);
477         debugId[type->getResultId()] = debugResultId;
478     }
479
480     return type->getResultId();
481 }
482
483 Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols)
484 {
485     // try to find it
486     Instruction* type;
487     for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) {
488         type = groupedTypes[OpTypeCooperativeMatrixNV][t];
489         if (type->getIdOperand(0) == component &&
490             type->getIdOperand(1) == scope &&
491             type->getIdOperand(2) == rows &&
492             type->getIdOperand(3) == cols)
493             return type->getResultId();
494     }
495
496     // not found, make it
497     type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixNV);
498     type->addIdOperand(component);
499     type->addIdOperand(scope);
500     type->addIdOperand(rows);
501     type->addIdOperand(cols);
502     groupedTypes[OpTypeCooperativeMatrixNV].push_back(type);
503     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
504     module.mapInstruction(type);
505
506     return type->getResultId();
507 }
508
509 Id Builder::makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands)
510 {
511     // try to find it
512     Instruction* type;
513     for (int t = 0; t < (int)groupedTypes[opcode].size(); ++t) {
514         type = groupedTypes[opcode][t];
515         if (static_cast<size_t>(type->getNumOperands()) != operands.size())
516             continue; // Number mismatch, find next
517
518         bool match = true;
519         for (int op = 0; match && op < (int)operands.size(); ++op) {
520             match = (operands[op].isId ? type->getIdOperand(op) : type->getImmediateOperand(op)) == operands[op].word;
521         }
522         if (match)
523             return type->getResultId();
524     }
525
526     // not found, make it
527     type = new Instruction(getUniqueId(), NoType, opcode);
528     for (size_t op = 0; op < operands.size(); ++op) {
529         if (operands[op].isId)
530             type->addIdOperand(operands[op].word);
531         else
532             type->addImmediateOperand(operands[op].word);
533     }
534     groupedTypes[opcode].push_back(type);
535     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
536     module.mapInstruction(type);
537
538     return type->getResultId();
539 }
540
541 // TODO: performance: track arrays per stride
542 // If a stride is supplied (non-zero) make an array.
543 // If no stride (0), reuse previous array types.
544 // 'size' is an Id of a constant or specialization constant of the array size
545 Id Builder::makeArrayType(Id element, Id sizeId, int stride)
546 {
547     Instruction* type;
548     if (stride == 0) {
549         // try to find existing type
550         for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t) {
551             type = groupedTypes[OpTypeArray][t];
552             if (type->getIdOperand(0) == element &&
553                 type->getIdOperand(1) == sizeId)
554                 return type->getResultId();
555         }
556     }
557
558     // not found, make it
559     type = new Instruction(getUniqueId(), NoType, OpTypeArray);
560     type->addIdOperand(element);
561     type->addIdOperand(sizeId);
562     groupedTypes[OpTypeArray].push_back(type);
563     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
564     module.mapInstruction(type);
565
566     if (emitNonSemanticShaderDebugInfo)
567     {
568         auto const debugResultId = makeArrayDebugType(element, sizeId);
569         debugId[type->getResultId()] = debugResultId;
570     }
571
572     return type->getResultId();
573 }
574
575 Id Builder::makeRuntimeArray(Id element)
576 {
577     Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeRuntimeArray);
578     type->addIdOperand(element);
579     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
580     module.mapInstruction(type);
581
582     if (emitNonSemanticShaderDebugInfo)
583     {
584         auto const debugResultId = makeArrayDebugType(element, makeUintConstant(0));
585         debugId[type->getResultId()] = debugResultId;
586     }
587
588     return type->getResultId();
589 }
590
591 Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
592 {
593     // try to find it
594     Instruction* type;
595     for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t) {
596         type = groupedTypes[OpTypeFunction][t];
597         if (type->getIdOperand(0) != returnType || (int)paramTypes.size() != type->getNumOperands() - 1)
598             continue;
599         bool mismatch = false;
600         for (int p = 0; p < (int)paramTypes.size(); ++p) {
601             if (paramTypes[p] != type->getIdOperand(p + 1)) {
602                 mismatch = true;
603                 break;
604             }
605         }
606         if (! mismatch)
607         {
608             // If compiling HLSL, glslang will create a wrapper function around the entrypoint. Accordingly, a void(void)
609             // function type is created for the wrapper function. However, nonsemantic shader debug information is disabled
610             // while creating the HLSL wrapper. Consequently, if we encounter another void(void) function, we need to create
611             // the associated debug function type if it hasn't been created yet.
612             if(emitNonSemanticShaderDebugInfo && debugId[type->getResultId()] == 0) {
613                 assert(sourceLang == spv::SourceLanguageHLSL);
614                 assert(getTypeClass(returnType) == OpTypeVoid && paramTypes.size() == 0);
615
616                 Id debugTypeId = makeDebugFunctionType(returnType, {});
617                 debugId[type->getResultId()] = debugTypeId;
618             }
619             return type->getResultId();
620         }
621     }
622
623     // not found, make it
624     Id typeId = getUniqueId();
625     type = new Instruction(typeId, NoType, OpTypeFunction);
626     type->addIdOperand(returnType);
627     for (int p = 0; p < (int)paramTypes.size(); ++p)
628         type->addIdOperand(paramTypes[p]);
629     groupedTypes[OpTypeFunction].push_back(type);
630     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
631     module.mapInstruction(type);
632
633     // make debug type and map it
634     if (emitNonSemanticShaderDebugInfo) {
635         Id debugTypeId = makeDebugFunctionType(returnType, paramTypes);
636         debugId[typeId] = debugTypeId;
637     }
638
639     return type->getResultId();
640 }
641
642 Id Builder::makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes)
643 {
644     assert(debugId[returnType] != 0);
645
646     Id typeId = getUniqueId();
647     auto type = new Instruction(typeId, makeVoidType(), OpExtInst);
648     type->addIdOperand(nonSemanticShaderDebugInfo);
649     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeFunction);
650     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic));
651     type->addIdOperand(debugId[returnType]);
652     for (auto const paramType : paramTypes) {
653         assert(isPointerType(paramType) || isArrayType(paramType));
654         type->addIdOperand(debugId[getContainedTypeId(paramType)]);
655     }
656     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
657     module.mapInstruction(type);
658     return typeId;
659 }
660
661 Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled,
662     ImageFormat format)
663 {
664     assert(sampled == 1 || sampled == 2);
665
666     // try to find it
667     Instruction* type;
668     for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t) {
669         type = groupedTypes[OpTypeImage][t];
670         if (type->getIdOperand(0) == sampledType &&
671             type->getImmediateOperand(1) == (unsigned int)dim &&
672             type->getImmediateOperand(2) == (  depth ? 1u : 0u) &&
673             type->getImmediateOperand(3) == (arrayed ? 1u : 0u) &&
674             type->getImmediateOperand(4) == (     ms ? 1u : 0u) &&
675             type->getImmediateOperand(5) == sampled &&
676             type->getImmediateOperand(6) == (unsigned int)format)
677             return type->getResultId();
678     }
679
680     // not found, make it
681     type = new Instruction(getUniqueId(), NoType, OpTypeImage);
682     type->addIdOperand(sampledType);
683     type->addImmediateOperand(   dim);
684     type->addImmediateOperand(  depth ? 1 : 0);
685     type->addImmediateOperand(arrayed ? 1 : 0);
686     type->addImmediateOperand(     ms ? 1 : 0);
687     type->addImmediateOperand(sampled);
688     type->addImmediateOperand((unsigned int)format);
689
690     groupedTypes[OpTypeImage].push_back(type);
691     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
692     module.mapInstruction(type);
693
694 #ifndef GLSLANG_WEB
695     // deal with capabilities
696     switch (dim) {
697     case DimBuffer:
698         if (sampled == 1)
699             addCapability(CapabilitySampledBuffer);
700         else
701             addCapability(CapabilityImageBuffer);
702         break;
703     case Dim1D:
704         if (sampled == 1)
705             addCapability(CapabilitySampled1D);
706         else
707             addCapability(CapabilityImage1D);
708         break;
709     case DimCube:
710         if (arrayed) {
711             if (sampled == 1)
712                 addCapability(CapabilitySampledCubeArray);
713             else
714                 addCapability(CapabilityImageCubeArray);
715         }
716         break;
717     case DimRect:
718         if (sampled == 1)
719             addCapability(CapabilitySampledRect);
720         else
721             addCapability(CapabilityImageRect);
722         break;
723     case DimSubpassData:
724         addCapability(CapabilityInputAttachment);
725         break;
726     default:
727         break;
728     }
729
730     if (ms) {
731         if (sampled == 2) {
732             // Images used with subpass data are not storage
733             // images, so don't require the capability for them.
734             if (dim != Dim::DimSubpassData)
735                 addCapability(CapabilityStorageImageMultisample);
736             if (arrayed)
737                 addCapability(CapabilityImageMSArray);
738         }
739     }
740 #endif
741
742     if (emitNonSemanticShaderDebugInfo)
743     {
744         auto TypeName = [&dim]() -> char const* {
745             switch (dim) {
746                 case Dim1D: return "type.1d.image";
747                 case Dim2D: return "type.2d.image";
748                 case Dim3D: return "type.3d.image";
749                 case DimCube: return "type.cube.image";
750                 default: return "type.image";
751             }
752         };
753
754         auto const debugResultId = makeCompositeDebugType({}, TypeName(), NonSemanticShaderDebugInfo100Class, true);
755         debugId[type->getResultId()] = debugResultId;
756     }
757
758     return type->getResultId();
759 }
760
761 Id Builder::makeSampledImageType(Id imageType)
762 {
763     // try to find it
764     Instruction* type;
765     for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t) {
766         type = groupedTypes[OpTypeSampledImage][t];
767         if (type->getIdOperand(0) == imageType)
768             return type->getResultId();
769     }
770
771     // not found, make it
772     type = new Instruction(getUniqueId(), NoType, OpTypeSampledImage);
773     type->addIdOperand(imageType);
774
775     groupedTypes[OpTypeSampledImage].push_back(type);
776     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
777     module.mapInstruction(type);
778
779     if (emitNonSemanticShaderDebugInfo)
780     {
781         auto const debugResultId = makeCompositeDebugType({}, "type.sampled.image", NonSemanticShaderDebugInfo100Class, true);
782         debugId[type->getResultId()] = debugResultId;
783     }
784
785     return type->getResultId();
786 }
787
788 Id Builder::makeDebugInfoNone()
789 {
790     if (debugInfoNone != 0)
791         return debugInfoNone;
792
793     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
794     inst->addIdOperand(nonSemanticShaderDebugInfo);
795     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugInfoNone);
796
797     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
798     module.mapInstruction(inst);
799
800     debugInfoNone = inst->getResultId();
801
802     return debugInfoNone;
803 }
804
805 Id Builder::makeBoolDebugType(int const size)
806 {
807     // try to find it
808     Instruction* type;
809     for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) {
810         type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t];
811         if (type->getIdOperand(0) == getStringId("bool") &&
812             type->getIdOperand(1) == static_cast<unsigned int>(size) &&
813             type->getIdOperand(2) == NonSemanticShaderDebugInfo100Boolean)
814             return type->getResultId();
815     }
816
817     type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
818     type->addIdOperand(nonSemanticShaderDebugInfo);
819     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic);
820
821     type->addIdOperand(getStringId("bool")); // name id
822     type->addIdOperand(makeUintConstant(size)); // size id
823     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Boolean)); // encoding id
824     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id
825
826     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type);
827     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
828     module.mapInstruction(type);
829
830     return type->getResultId();
831 }
832
833 Id Builder::makeIntegerDebugType(int const width, bool const hasSign)
834 {
835     // try to find it
836     Instruction* type;
837     for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) {
838         type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t];
839         if (type->getIdOperand(0) == (hasSign ? getStringId("int") : getStringId("uint")) &&
840             type->getIdOperand(1) == static_cast<unsigned int>(width) &&
841             type->getIdOperand(2) == (hasSign ? NonSemanticShaderDebugInfo100Signed : NonSemanticShaderDebugInfo100Unsigned))
842             return type->getResultId();
843     }
844
845     // not found, make it
846     type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
847     type->addIdOperand(nonSemanticShaderDebugInfo);
848     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic);
849     if(hasSign == true) {
850         type->addIdOperand(getStringId("int")); // name id
851     } else {
852         type->addIdOperand(getStringId("uint")); // name id
853     }
854     type->addIdOperand(makeUintConstant(width)); // size id
855     if(hasSign == true) {
856         type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Signed)); // encoding id
857     } else {
858         type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Unsigned)); // encoding id
859     }
860     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id
861
862     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type);
863     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
864     module.mapInstruction(type);
865
866     return type->getResultId();
867 }
868
869 Id Builder::makeFloatDebugType(int const width)
870 {
871     // try to find it
872     Instruction* type;
873     for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) {
874         type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t];
875         if (type->getIdOperand(0) == getStringId("float") &&
876             type->getIdOperand(1) == static_cast<unsigned int>(width) &&
877             type->getIdOperand(2) == NonSemanticShaderDebugInfo100Float)
878             return type->getResultId();
879     }
880
881     // not found, make it
882     type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
883     type->addIdOperand(nonSemanticShaderDebugInfo);
884     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic);
885     type->addIdOperand(getStringId("float")); // name id
886     type->addIdOperand(makeUintConstant(width)); // size id
887     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Float)); // encoding id
888     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id
889
890     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type);
891     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
892     module.mapInstruction(type);
893
894     return type->getResultId();
895 }
896
897 Id Builder::makeSequentialDebugType(Id const baseType, Id const componentCount, NonSemanticShaderDebugInfo100Instructions const sequenceType)
898 {
899     assert(sequenceType == NonSemanticShaderDebugInfo100DebugTypeArray ||
900         sequenceType == NonSemanticShaderDebugInfo100DebugTypeVector);
901
902     // try to find it
903     Instruction* type;
904     for (int t = 0; t < (int)groupedDebugTypes[sequenceType].size(); ++t) {
905         type = groupedDebugTypes[sequenceType][t];
906         if (type->getIdOperand(0) == baseType &&
907             type->getIdOperand(1) == makeUintConstant(componentCount))
908             return type->getResultId();
909     }
910
911     // not found, make it
912     type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
913     type->addIdOperand(nonSemanticShaderDebugInfo);
914     type->addImmediateOperand(sequenceType);
915     type->addIdOperand(debugId[baseType]); // base type
916     type->addIdOperand(componentCount); // component count
917
918     groupedDebugTypes[sequenceType].push_back(type);
919     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
920     module.mapInstruction(type);
921
922     return type->getResultId();
923 }
924
925 Id Builder::makeArrayDebugType(Id const baseType, Id const componentCount)
926 {
927     return makeSequentialDebugType(baseType, componentCount, NonSemanticShaderDebugInfo100DebugTypeArray);
928 }
929
930 Id Builder::makeVectorDebugType(Id const baseType, int const componentCount)
931 {
932     return makeSequentialDebugType(baseType, makeUintConstant(componentCount), NonSemanticShaderDebugInfo100DebugTypeVector);;
933 }
934
935 Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor)
936 {
937     // try to find it
938     Instruction* type;
939     for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix].size(); ++t) {
940         type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix][t];
941         if (type->getIdOperand(0) == vectorType &&
942             type->getIdOperand(1) == makeUintConstant(vectorCount))
943             return type->getResultId();
944     }
945
946     // not found, make it
947     type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
948     type->addIdOperand(nonSemanticShaderDebugInfo);
949     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMatrix);
950     type->addIdOperand(debugId[vectorType]); // vector type id
951     type->addIdOperand(makeUintConstant(vectorCount)); // component count id
952     type->addIdOperand(makeBoolConstant(columnMajor)); // column-major id
953
954     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix].push_back(type);
955     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
956     module.mapInstruction(type);
957
958     return type->getResultId();
959 }
960
961 Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc)
962 {
963     assert(debugId[memberType] != 0);
964
965     Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
966     type->addIdOperand(nonSemanticShaderDebugInfo);
967     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember);
968     type->addIdOperand(getStringId(debugTypeLoc.name)); // name id
969     type->addIdOperand(debugId[memberType]); // type id
970     type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives
971     type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero
972     type->addIdOperand(makeUintConstant(debugTypeLoc.column)); // TODO: column id
973     type->addIdOperand(makeUintConstant(0)); // TODO: offset id
974     type->addIdOperand(makeUintConstant(0)); // TODO: size id
975     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); // flags id
976
977     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMember].push_back(type);
978     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
979     module.mapInstruction(type);
980
981     return type->getResultId();
982 }
983
984 // Note: To represent a source language opaque type, this instruction must have no Members operands, Size operand must be
985 // DebugInfoNone, and Name must start with @ to avoid clashes with user defined names.
986 Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, char const*const name,
987     NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType)
988 {
989     // Create the debug member types.
990     std::vector<Id> memberDebugTypes;
991     for(auto const memberType : memberTypes) {
992         assert(debugTypeLocs.find(memberType) != debugTypeLocs.end());
993
994         memberDebugTypes.emplace_back(makeMemberDebugType(memberType, debugTypeLocs[memberType]));
995
996         // TODO: Need to rethink this method of passing location information.
997         // debugTypeLocs.erase(memberType);
998     }
999
1000     // Create The structure debug type.
1001     Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
1002     type->addIdOperand(nonSemanticShaderDebugInfo);
1003     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeComposite);
1004     type->addIdOperand(getStringId(name)); // name id
1005     type->addIdOperand(makeUintConstant(tag)); // tag id
1006     type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives
1007     type->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero?
1008     type->addIdOperand(makeUintConstant(0)); // TODO: column id
1009     type->addIdOperand(makeDebugCompilationUnit()); // scope id
1010     if(isOpaqueType == true) {
1011         // Prepend '@' to opaque types.
1012         type->addIdOperand(getStringId('@' + std::string(name))); // linkage name id
1013         type->addIdOperand(makeDebugInfoNone()); // size id
1014     } else {
1015         type->addIdOperand(getStringId(name)); // linkage name id
1016         type->addIdOperand(makeUintConstant(0)); // TODO: size id
1017     }
1018     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); // flags id
1019     assert(isOpaqueType == false || (isOpaqueType == true && memberDebugTypes.empty()));
1020     for(auto const memberDebugType : memberDebugTypes) {
1021         type->addIdOperand(memberDebugType);
1022     }
1023
1024     groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeComposite].push_back(type);
1025     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
1026     module.mapInstruction(type);
1027
1028     return type->getResultId();
1029 }
1030
1031 Id Builder::makeDebugSource(const Id fileName) {
1032     if (debugSourceId.find(fileName) != debugSourceId.end())
1033         return debugSourceId[fileName];
1034     spv::Id resultId = getUniqueId();
1035     Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst);
1036     sourceInst->addIdOperand(nonSemanticShaderDebugInfo);
1037     sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugSource);
1038     sourceInst->addIdOperand(fileName);
1039     if (emitNonSemanticShaderDebugSource) {
1040         spv::Id sourceId = 0;
1041         if (fileName == sourceFileStringId) {
1042             sourceId = getStringId(sourceText);
1043         } else {
1044             auto incItr = includeFiles.find(fileName);
1045             assert(incItr != includeFiles.end());
1046             sourceId = getStringId(*incItr->second);
1047         }
1048         sourceInst->addIdOperand(sourceId);
1049     }
1050     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
1051     module.mapInstruction(sourceInst);
1052     debugSourceId[fileName] = resultId;
1053     return resultId;
1054 }
1055
1056 Id Builder::makeDebugCompilationUnit() {
1057     if (nonSemanticShaderCompilationUnitId != 0)
1058         return nonSemanticShaderCompilationUnitId;
1059     spv::Id resultId = getUniqueId();
1060     Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst);
1061     sourceInst->addIdOperand(nonSemanticShaderDebugInfo);
1062     sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugCompilationUnit);
1063     sourceInst->addIdOperand(makeUintConstant(1)); // TODO(greg-lunarg): Get rid of magic number
1064     sourceInst->addIdOperand(makeUintConstant(4)); // TODO(greg-lunarg): Get rid of magic number
1065     sourceInst->addIdOperand(makeDebugSource(sourceFileStringId));
1066     sourceInst->addIdOperand(makeUintConstant(sourceLang));
1067     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
1068     module.mapInstruction(sourceInst);
1069     nonSemanticShaderCompilationUnitId = resultId;
1070     return resultId;
1071 }
1072
1073 Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id const variable)
1074 {
1075     assert(type != 0);
1076
1077     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
1078     inst->addIdOperand(nonSemanticShaderDebugInfo);
1079     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugGlobalVariable);
1080     inst->addIdOperand(getStringId(name)); // name id
1081     inst->addIdOperand(type); // type id
1082     inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id
1083     inst->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero?
1084     inst->addIdOperand(makeUintConstant(0)); // TODO: column id
1085     inst->addIdOperand(makeDebugCompilationUnit()); // scope id
1086     inst->addIdOperand(getStringId(name)); // linkage name id
1087     inst->addIdOperand(variable); // variable id
1088     inst->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsDefinition)); // flags id
1089
1090     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
1091     module.mapInstruction(inst);
1092
1093     return inst->getResultId();
1094 }
1095
1096 Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t const argNumber)
1097 {
1098     assert(name != nullptr);
1099     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
1100     inst->addIdOperand(nonSemanticShaderDebugInfo);
1101     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable);
1102     inst->addIdOperand(getStringId(name)); // name id
1103     inst->addIdOperand(type); // type id
1104     inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id
1105     inst->addIdOperand(makeUintConstant(currentLine)); // line id
1106     inst->addIdOperand(makeUintConstant(0)); // TODO: column id
1107     inst->addIdOperand(currentDebugScopeId.top()); // scope id
1108     inst->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsLocal)); // flags id
1109     if(argNumber != 0) {
1110         inst->addIdOperand(makeUintConstant(argNumber));
1111     }
1112
1113     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
1114     module.mapInstruction(inst);
1115
1116     return inst->getResultId();
1117 }
1118
1119 Id Builder::makeDebugExpression()
1120 {
1121     if (debugExpression != 0)
1122         return debugExpression;
1123
1124     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
1125     inst->addIdOperand(nonSemanticShaderDebugInfo);
1126     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugExpression);
1127
1128     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
1129     module.mapInstruction(inst);
1130
1131     debugExpression = inst->getResultId();
1132
1133     return debugExpression;
1134 }
1135
1136 Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const localVariable)
1137 {
1138     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
1139     inst->addIdOperand(nonSemanticShaderDebugInfo);
1140     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare);
1141     inst->addIdOperand(debugLocalVariable); // debug local variable id
1142     inst->addIdOperand(localVariable); // local variable id
1143     inst->addIdOperand(makeDebugExpression()); // expression id
1144     buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
1145
1146     return inst->getResultId();
1147 }
1148
1149 #ifndef GLSLANG_WEB
1150 Id Builder::makeAccelerationStructureType()
1151 {
1152     Instruction *type;
1153     if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) {
1154         type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);
1155         groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
1156         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
1157         module.mapInstruction(type);
1158     } else {
1159         type = groupedTypes[OpTypeAccelerationStructureKHR].back();
1160     }
1161
1162     return type->getResultId();
1163 }
1164
1165 Id Builder::makeRayQueryType()
1166 {
1167     Instruction *type;
1168     if (groupedTypes[OpTypeRayQueryKHR].size() == 0) {
1169         type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryKHR);
1170         groupedTypes[OpTypeRayQueryKHR].push_back(type);
1171         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
1172         module.mapInstruction(type);
1173     } else {
1174         type = groupedTypes[OpTypeRayQueryKHR].back();
1175     }
1176
1177     return type->getResultId();
1178 }
1179
1180 Id Builder::makeHitObjectNVType()
1181 {
1182     Instruction *type;
1183     if (groupedTypes[OpTypeHitObjectNV].size() == 0) {
1184         type = new Instruction(getUniqueId(), NoType, OpTypeHitObjectNV);
1185         groupedTypes[OpTypeHitObjectNV].push_back(type);
1186         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
1187         module.mapInstruction(type);
1188     } else {
1189         type = groupedTypes[OpTypeHitObjectNV].back();
1190     }
1191
1192     return type->getResultId();
1193 }
1194 #endif
1195
1196 Id Builder::getDerefTypeId(Id resultId) const
1197 {
1198     Id typeId = getTypeId(resultId);
1199     assert(isPointerType(typeId));
1200
1201     return module.getInstruction(typeId)->getIdOperand(1);
1202 }
1203
1204 Op Builder::getMostBasicTypeClass(Id typeId) const
1205 {
1206     Instruction* instr = module.getInstruction(typeId);
1207
1208     Op typeClass = instr->getOpCode();
1209     switch (typeClass)
1210     {
1211     case OpTypeVector:
1212     case OpTypeMatrix:
1213     case OpTypeArray:
1214     case OpTypeRuntimeArray:
1215         return getMostBasicTypeClass(instr->getIdOperand(0));
1216     case OpTypePointer:
1217         return getMostBasicTypeClass(instr->getIdOperand(1));
1218     default:
1219         return typeClass;
1220     }
1221 }
1222
1223 int Builder::getNumTypeConstituents(Id typeId) const
1224 {
1225     Instruction* instr = module.getInstruction(typeId);
1226
1227     switch (instr->getOpCode())
1228     {
1229     case OpTypeBool:
1230     case OpTypeInt:
1231     case OpTypeFloat:
1232     case OpTypePointer:
1233         return 1;
1234     case OpTypeVector:
1235     case OpTypeMatrix:
1236         return instr->getImmediateOperand(1);
1237     case OpTypeArray:
1238     {
1239         Id lengthId = instr->getIdOperand(1);
1240         return module.getInstruction(lengthId)->getImmediateOperand(0);
1241     }
1242     case OpTypeStruct:
1243         return instr->getNumOperands();
1244     case OpTypeCooperativeMatrixNV:
1245         // has only one constituent when used with OpCompositeConstruct.
1246         return 1;
1247     default:
1248         assert(0);
1249         return 1;
1250     }
1251 }
1252
1253 // Return the lowest-level type of scalar that an homogeneous composite is made out of.
1254 // Typically, this is just to find out if something is made out of ints or floats.
1255 // However, it includes returning a structure, if say, it is an array of structure.
1256 Id Builder::getScalarTypeId(Id typeId) const
1257 {
1258     Instruction* instr = module.getInstruction(typeId);
1259
1260     Op typeClass = instr->getOpCode();
1261     switch (typeClass)
1262     {
1263     case OpTypeVoid:
1264     case OpTypeBool:
1265     case OpTypeInt:
1266     case OpTypeFloat:
1267     case OpTypeStruct:
1268         return instr->getResultId();
1269     case OpTypeVector:
1270     case OpTypeMatrix:
1271     case OpTypeArray:
1272     case OpTypeRuntimeArray:
1273     case OpTypePointer:
1274         return getScalarTypeId(getContainedTypeId(typeId));
1275     default:
1276         assert(0);
1277         return NoResult;
1278     }
1279 }
1280
1281 // Return the type of 'member' of a composite.
1282 Id Builder::getContainedTypeId(Id typeId, int member) const
1283 {
1284     Instruction* instr = module.getInstruction(typeId);
1285
1286     Op typeClass = instr->getOpCode();
1287     switch (typeClass)
1288     {
1289     case OpTypeVector:
1290     case OpTypeMatrix:
1291     case OpTypeArray:
1292     case OpTypeRuntimeArray:
1293     case OpTypeCooperativeMatrixNV:
1294         return instr->getIdOperand(0);
1295     case OpTypePointer:
1296         return instr->getIdOperand(1);
1297     case OpTypeStruct:
1298         return instr->getIdOperand(member);
1299     default:
1300         assert(0);
1301         return NoResult;
1302     }
1303 }
1304
1305 // Figure out the final resulting type of the access chain.
1306 Id Builder::getResultingAccessChainType() const
1307 {
1308     assert(accessChain.base != NoResult);
1309     Id typeId = getTypeId(accessChain.base);
1310
1311     assert(isPointerType(typeId));
1312     typeId = getContainedTypeId(typeId);
1313
1314     for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
1315         if (isStructType(typeId)) {
1316             assert(isConstantScalar(accessChain.indexChain[i]));
1317             typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i]));
1318         } else
1319             typeId = getContainedTypeId(typeId, accessChain.indexChain[i]);
1320     }
1321
1322     return typeId;
1323 }
1324
1325 // Return the immediately contained type of a given composite type.
1326 Id Builder::getContainedTypeId(Id typeId) const
1327 {
1328     return getContainedTypeId(typeId, 0);
1329 }
1330
1331 // Returns true if 'typeId' is or contains a scalar type declared with 'typeOp'
1332 // of width 'width'. The 'width' is only consumed for int and float types.
1333 // Returns false otherwise.
1334 bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const
1335 {
1336     const Instruction& instr = *module.getInstruction(typeId);
1337
1338     Op typeClass = instr.getOpCode();
1339     switch (typeClass)
1340     {
1341     case OpTypeInt:
1342     case OpTypeFloat:
1343         return typeClass == typeOp && instr.getImmediateOperand(0) == width;
1344     case OpTypeStruct:
1345         for (int m = 0; m < instr.getNumOperands(); ++m) {
1346             if (containsType(instr.getIdOperand(m), typeOp, width))
1347                 return true;
1348         }
1349         return false;
1350     case OpTypePointer:
1351         return false;
1352     case OpTypeVector:
1353     case OpTypeMatrix:
1354     case OpTypeArray:
1355     case OpTypeRuntimeArray:
1356         return containsType(getContainedTypeId(typeId), typeOp, width);
1357     default:
1358         return typeClass == typeOp;
1359     }
1360 }
1361
1362 // return true if the type is a pointer to PhysicalStorageBufferEXT or an
1363 // array of such pointers. These require restrict/aliased decorations.
1364 bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const
1365 {
1366     const Instruction& instr = *module.getInstruction(typeId);
1367
1368     Op typeClass = instr.getOpCode();
1369     switch (typeClass)
1370     {
1371     case OpTypePointer:
1372         return getTypeStorageClass(typeId) == StorageClassPhysicalStorageBufferEXT;
1373     case OpTypeArray:
1374         return containsPhysicalStorageBufferOrArray(getContainedTypeId(typeId));
1375     default:
1376         return false;
1377     }
1378 }
1379
1380 // See if a scalar constant of this type has already been created, so it
1381 // can be reused rather than duplicated.  (Required by the specification).
1382 Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
1383 {
1384     Instruction* constant;
1385     for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
1386         constant = groupedConstants[typeClass][i];
1387         if (constant->getOpCode() == opcode &&
1388             constant->getTypeId() == typeId &&
1389             constant->getImmediateOperand(0) == value)
1390             return constant->getResultId();
1391     }
1392
1393     return 0;
1394 }
1395
1396 // Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double' or 'int64').
1397 Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2)
1398 {
1399     Instruction* constant;
1400     for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
1401         constant = groupedConstants[typeClass][i];
1402         if (constant->getOpCode() == opcode &&
1403             constant->getTypeId() == typeId &&
1404             constant->getImmediateOperand(0) == v1 &&
1405             constant->getImmediateOperand(1) == v2)
1406             return constant->getResultId();
1407     }
1408
1409     return 0;
1410 }
1411
1412 // Return true if consuming 'opcode' means consuming a constant.
1413 // "constant" here means after final transform to executable code,
1414 // the value consumed will be a constant, so includes specialization.
1415 bool Builder::isConstantOpCode(Op opcode) const
1416 {
1417     switch (opcode) {
1418     case OpUndef:
1419     case OpConstantTrue:
1420     case OpConstantFalse:
1421     case OpConstant:
1422     case OpConstantComposite:
1423     case OpConstantSampler:
1424     case OpConstantNull:
1425     case OpSpecConstantTrue:
1426     case OpSpecConstantFalse:
1427     case OpSpecConstant:
1428     case OpSpecConstantComposite:
1429     case OpSpecConstantOp:
1430         return true;
1431     default:
1432         return false;
1433     }
1434 }
1435
1436 // Return true if consuming 'opcode' means consuming a specialization constant.
1437 bool Builder::isSpecConstantOpCode(Op opcode) const
1438 {
1439     switch (opcode) {
1440     case OpSpecConstantTrue:
1441     case OpSpecConstantFalse:
1442     case OpSpecConstant:
1443     case OpSpecConstantComposite:
1444     case OpSpecConstantOp:
1445         return true;
1446     default:
1447         return false;
1448     }
1449 }
1450
1451 bool Builder::isRayTracingOpCode(Op opcode) const
1452 {
1453     switch (opcode) {
1454     case OpTypeAccelerationStructureKHR:
1455     case OpTypeRayQueryKHR:
1456         return true;
1457     default:
1458         return false;
1459     }
1460 }
1461
1462 Id Builder::makeNullConstant(Id typeId)
1463 {
1464     Instruction* constant;
1465
1466     // See if we already made it.
1467     Id existing = NoResult;
1468     for (int i = 0; i < (int)nullConstants.size(); ++i) {
1469         constant = nullConstants[i];
1470         if (constant->getTypeId() == typeId)
1471             existing = constant->getResultId();
1472     }
1473
1474     if (existing != NoResult)
1475         return existing;
1476
1477     // Make it
1478     Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull);
1479     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1480     nullConstants.push_back(c);
1481     module.mapInstruction(c);
1482
1483     return c->getResultId();
1484 }
1485
1486 Id Builder::makeBoolConstant(bool b, bool specConstant)
1487 {
1488     Id typeId = makeBoolType();
1489     Instruction* constant;
1490     Op opcode = specConstant ? (b ? OpSpecConstantTrue : OpSpecConstantFalse) : (b ? OpConstantTrue : OpConstantFalse);
1491
1492     // See if we already made it. Applies only to regular constants, because specialization constants
1493     // must remain distinct for the purpose of applying a SpecId decoration.
1494     if (! specConstant) {
1495         Id existing = 0;
1496         for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) {
1497             constant = groupedConstants[OpTypeBool][i];
1498             if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
1499                 existing = constant->getResultId();
1500         }
1501
1502         if (existing)
1503             return existing;
1504     }
1505
1506     // Make it
1507     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1508     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1509     groupedConstants[OpTypeBool].push_back(c);
1510     module.mapInstruction(c);
1511
1512     return c->getResultId();
1513 }
1514
1515 Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
1516 {
1517     Op opcode = specConstant ? OpSpecConstant : OpConstant;
1518
1519     // See if we already made it. Applies only to regular constants, because specialization constants
1520     // must remain distinct for the purpose of applying a SpecId decoration.
1521     if (! specConstant) {
1522         Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);
1523         if (existing)
1524             return existing;
1525     }
1526
1527     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1528     c->addImmediateOperand(value);
1529     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1530     groupedConstants[OpTypeInt].push_back(c);
1531     module.mapInstruction(c);
1532
1533     return c->getResultId();
1534 }
1535
1536 Id Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specConstant)
1537 {
1538     Op opcode = specConstant ? OpSpecConstant : OpConstant;
1539
1540     unsigned op1 = value & 0xFFFFFFFF;
1541     unsigned op2 = value >> 32;
1542
1543     // See if we already made it. Applies only to regular constants, because specialization constants
1544     // must remain distinct for the purpose of applying a SpecId decoration.
1545     if (! specConstant) {
1546         Id existing = findScalarConstant(OpTypeInt, opcode, typeId, op1, op2);
1547         if (existing)
1548             return existing;
1549     }
1550
1551     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1552     c->addImmediateOperand(op1);
1553     c->addImmediateOperand(op2);
1554     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1555     groupedConstants[OpTypeInt].push_back(c);
1556     module.mapInstruction(c);
1557
1558     return c->getResultId();
1559 }
1560
1561 Id Builder::makeFloatConstant(float f, bool specConstant)
1562 {
1563     Op opcode = specConstant ? OpSpecConstant : OpConstant;
1564     Id typeId = makeFloatType(32);
1565     union { float fl; unsigned int ui; } u;
1566     u.fl = f;
1567     unsigned value = u.ui;
1568
1569     // See if we already made it. Applies only to regular constants, because specialization constants
1570     // must remain distinct for the purpose of applying a SpecId decoration.
1571     if (! specConstant) {
1572         Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
1573         if (existing)
1574             return existing;
1575     }
1576
1577     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1578     c->addImmediateOperand(value);
1579     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1580     groupedConstants[OpTypeFloat].push_back(c);
1581     module.mapInstruction(c);
1582
1583     return c->getResultId();
1584 }
1585
1586 Id Builder::makeDoubleConstant(double d, bool specConstant)
1587 {
1588 #ifdef GLSLANG_WEB
1589     assert(0);
1590     return NoResult;
1591 #else
1592     Op opcode = specConstant ? OpSpecConstant : OpConstant;
1593     Id typeId = makeFloatType(64);
1594     union { double db; unsigned long long ull; } u;
1595     u.db = d;
1596     unsigned long long value = u.ull;
1597     unsigned op1 = value & 0xFFFFFFFF;
1598     unsigned op2 = value >> 32;
1599
1600     // See if we already made it. Applies only to regular constants, because specialization constants
1601     // must remain distinct for the purpose of applying a SpecId decoration.
1602     if (! specConstant) {
1603         Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);
1604         if (existing)
1605             return existing;
1606     }
1607
1608     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1609     c->addImmediateOperand(op1);
1610     c->addImmediateOperand(op2);
1611     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1612     groupedConstants[OpTypeFloat].push_back(c);
1613     module.mapInstruction(c);
1614
1615     return c->getResultId();
1616 #endif
1617 }
1618
1619 Id Builder::makeFloat16Constant(float f16, bool specConstant)
1620 {
1621 #ifdef GLSLANG_WEB
1622     assert(0);
1623     return NoResult;
1624 #else
1625     Op opcode = specConstant ? OpSpecConstant : OpConstant;
1626     Id typeId = makeFloatType(16);
1627
1628     spvutils::HexFloat<spvutils::FloatProxy<float>> fVal(f16);
1629     spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>> f16Val(0);
1630     fVal.castTo(f16Val, spvutils::kRoundToZero);
1631
1632     unsigned value = f16Val.value().getAsFloat().get_value();
1633
1634     // See if we already made it. Applies only to regular constants, because specialization constants
1635     // must remain distinct for the purpose of applying a SpecId decoration.
1636     if (!specConstant) {
1637         Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
1638         if (existing)
1639             return existing;
1640     }
1641
1642     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1643     c->addImmediateOperand(value);
1644     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1645     groupedConstants[OpTypeFloat].push_back(c);
1646     module.mapInstruction(c);
1647
1648     return c->getResultId();
1649 #endif
1650 }
1651
1652 Id Builder::makeFpConstant(Id type, double d, bool specConstant)
1653 {
1654 #ifdef GLSLANG_WEB
1655     const int width = 32;
1656     assert(width == getScalarTypeWidth(type));
1657 #else
1658     const int width = getScalarTypeWidth(type);
1659 #endif
1660
1661     assert(isFloatType(type));
1662
1663     switch (width) {
1664     case 16:
1665             return makeFloat16Constant((float)d, specConstant);
1666     case 32:
1667             return makeFloatConstant((float)d, specConstant);
1668     case 64:
1669             return makeDoubleConstant(d, specConstant);
1670     default:
1671             break;
1672     }
1673
1674     assert(false);
1675     return NoResult;
1676 }
1677
1678 Id Builder::importNonSemanticShaderDebugInfoInstructions()
1679 {
1680     assert(emitNonSemanticShaderDebugInfo == true);
1681
1682     if(nonSemanticShaderDebugInfo == 0)
1683     {
1684         this->addExtension(spv::E_SPV_KHR_non_semantic_info);
1685         nonSemanticShaderDebugInfo = this->import("NonSemantic.Shader.DebugInfo.100");
1686     }
1687
1688     return nonSemanticShaderDebugInfo;
1689 }
1690
1691 Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps)
1692 {
1693     Instruction* constant = nullptr;
1694     bool found = false;
1695     for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
1696         constant = groupedConstants[typeClass][i];
1697
1698         if (constant->getTypeId() != typeId)
1699             continue;
1700
1701         // same contents?
1702         bool mismatch = false;
1703         for (int op = 0; op < constant->getNumOperands(); ++op) {
1704             if (constant->getIdOperand(op) != comps[op]) {
1705                 mismatch = true;
1706                 break;
1707             }
1708         }
1709         if (! mismatch) {
1710             found = true;
1711             break;
1712         }
1713     }
1714
1715     return found ? constant->getResultId() : NoResult;
1716 }
1717
1718 Id Builder::findStructConstant(Id typeId, const std::vector<Id>& comps)
1719 {
1720     Instruction* constant = nullptr;
1721     bool found = false;
1722     for (int i = 0; i < (int)groupedStructConstants[typeId].size(); ++i) {
1723         constant = groupedStructConstants[typeId][i];
1724
1725         // same contents?
1726         bool mismatch = false;
1727         for (int op = 0; op < constant->getNumOperands(); ++op) {
1728             if (constant->getIdOperand(op) != comps[op]) {
1729                 mismatch = true;
1730                 break;
1731             }
1732         }
1733         if (! mismatch) {
1734             found = true;
1735             break;
1736         }
1737     }
1738
1739     return found ? constant->getResultId() : NoResult;
1740 }
1741
1742 // Comments in header
1743 Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, bool specConstant)
1744 {
1745     Op opcode = specConstant ? OpSpecConstantComposite : OpConstantComposite;
1746     assert(typeId);
1747     Op typeClass = getTypeClass(typeId);
1748
1749     switch (typeClass) {
1750     case OpTypeVector:
1751     case OpTypeArray:
1752     case OpTypeMatrix:
1753     case OpTypeCooperativeMatrixNV:
1754         if (! specConstant) {
1755             Id existing = findCompositeConstant(typeClass, typeId, members);
1756             if (existing)
1757                 return existing;
1758         }
1759         break;
1760     case OpTypeStruct:
1761         if (! specConstant) {
1762             Id existing = findStructConstant(typeId, members);
1763             if (existing)
1764                 return existing;
1765         }
1766         break;
1767     default:
1768         assert(0);
1769         return makeFloatConstant(0.0);
1770     }
1771
1772     Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
1773     for (int op = 0; op < (int)members.size(); ++op)
1774         c->addIdOperand(members[op]);
1775     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
1776     if (typeClass == OpTypeStruct)
1777         groupedStructConstants[typeId].push_back(c);
1778     else
1779         groupedConstants[typeClass].push_back(c);
1780     module.mapInstruction(c);
1781
1782     return c->getResultId();
1783 }
1784
1785 Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, const char* name)
1786 {
1787     Instruction* entryPoint = new Instruction(OpEntryPoint);
1788     entryPoint->addImmediateOperand(model);
1789     entryPoint->addIdOperand(function->getId());
1790     entryPoint->addStringOperand(name);
1791
1792     entryPoints.push_back(std::unique_ptr<Instruction>(entryPoint));
1793
1794     return entryPoint;
1795 }
1796
1797 // Currently relying on the fact that all 'value' of interest are small non-negative values.
1798 void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, int value3)
1799 {
1800     Instruction* instr = new Instruction(OpExecutionMode);
1801     instr->addIdOperand(entryPoint->getId());
1802     instr->addImmediateOperand(mode);
1803     if (value1 >= 0)
1804         instr->addImmediateOperand(value1);
1805     if (value2 >= 0)
1806         instr->addImmediateOperand(value2);
1807     if (value3 >= 0)
1808         instr->addImmediateOperand(value3);
1809
1810     executionModes.push_back(std::unique_ptr<Instruction>(instr));
1811 }
1812
1813 void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector<unsigned>& literals)
1814 {
1815     Instruction* instr = new Instruction(OpExecutionMode);
1816     instr->addIdOperand(entryPoint->getId());
1817     instr->addImmediateOperand(mode);
1818     for (auto literal : literals)
1819         instr->addImmediateOperand(literal);
1820
1821     executionModes.push_back(std::unique_ptr<Instruction>(instr));
1822 }
1823
1824 void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector<Id>& operandIds)
1825 {
1826     Instruction* instr = new Instruction(OpExecutionModeId);
1827     instr->addIdOperand(entryPoint->getId());
1828     instr->addImmediateOperand(mode);
1829     for (auto operandId : operandIds)
1830         instr->addIdOperand(operandId);
1831
1832     executionModes.push_back(std::unique_ptr<Instruction>(instr));
1833 }
1834
1835 void Builder::addName(Id id, const char* string)
1836 {
1837     Instruction* name = new Instruction(OpName);
1838     name->addIdOperand(id);
1839     name->addStringOperand(string);
1840
1841     names.push_back(std::unique_ptr<Instruction>(name));
1842 }
1843
1844 void Builder::addMemberName(Id id, int memberNumber, const char* string)
1845 {
1846     Instruction* name = new Instruction(OpMemberName);
1847     name->addIdOperand(id);
1848     name->addImmediateOperand(memberNumber);
1849     name->addStringOperand(string);
1850
1851     names.push_back(std::unique_ptr<Instruction>(name));
1852 }
1853
1854 void Builder::addDecoration(Id id, Decoration decoration, int num)
1855 {
1856     if (decoration == spv::DecorationMax)
1857         return;
1858
1859     Instruction* dec = new Instruction(OpDecorate);
1860     dec->addIdOperand(id);
1861     dec->addImmediateOperand(decoration);
1862     if (num >= 0)
1863         dec->addImmediateOperand(num);
1864
1865     decorations.push_back(std::unique_ptr<Instruction>(dec));
1866 }
1867
1868 void Builder::addDecoration(Id id, Decoration decoration, const char* s)
1869 {
1870     if (decoration == spv::DecorationMax)
1871         return;
1872
1873     Instruction* dec = new Instruction(OpDecorateString);
1874     dec->addIdOperand(id);
1875     dec->addImmediateOperand(decoration);
1876     dec->addStringOperand(s);
1877
1878     decorations.push_back(std::unique_ptr<Instruction>(dec));
1879 }
1880
1881 void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& literals)
1882 {
1883     if (decoration == spv::DecorationMax)
1884         return;
1885
1886     Instruction* dec = new Instruction(OpDecorate);
1887     dec->addIdOperand(id);
1888     dec->addImmediateOperand(decoration);
1889     for (auto literal : literals)
1890         dec->addImmediateOperand(literal);
1891
1892     decorations.push_back(std::unique_ptr<Instruction>(dec));
1893 }
1894
1895 void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& strings)
1896 {
1897     if (decoration == spv::DecorationMax)
1898         return;
1899
1900     Instruction* dec = new Instruction(OpDecorateString);
1901     dec->addIdOperand(id);
1902     dec->addImmediateOperand(decoration);
1903     for (auto string : strings)
1904         dec->addStringOperand(string);
1905
1906     decorations.push_back(std::unique_ptr<Instruction>(dec));
1907 }
1908
1909 void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
1910 {
1911     if (decoration == spv::DecorationMax)
1912         return;
1913
1914     Instruction* dec = new Instruction(OpDecorateId);
1915     dec->addIdOperand(id);
1916     dec->addImmediateOperand(decoration);
1917     dec->addIdOperand(idDecoration);
1918
1919     decorations.push_back(std::unique_ptr<Instruction>(dec));
1920 }
1921
1922 void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& operandIds)
1923 {
1924     if(decoration == spv::DecorationMax)
1925         return;
1926
1927     Instruction* dec = new Instruction(OpDecorateId);
1928     dec->addIdOperand(id);
1929     dec->addImmediateOperand(decoration);
1930
1931     for (auto operandId : operandIds)
1932         dec->addIdOperand(operandId);
1933
1934     decorations.push_back(std::unique_ptr<Instruction>(dec));
1935 }
1936
1937 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
1938 {
1939     if (decoration == spv::DecorationMax)
1940         return;
1941
1942     Instruction* dec = new Instruction(OpMemberDecorate);
1943     dec->addIdOperand(id);
1944     dec->addImmediateOperand(member);
1945     dec->addImmediateOperand(decoration);
1946     if (num >= 0)
1947         dec->addImmediateOperand(num);
1948
1949     decorations.push_back(std::unique_ptr<Instruction>(dec));
1950 }
1951
1952 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s)
1953 {
1954     if (decoration == spv::DecorationMax)
1955         return;
1956
1957     Instruction* dec = new Instruction(OpMemberDecorateStringGOOGLE);
1958     dec->addIdOperand(id);
1959     dec->addImmediateOperand(member);
1960     dec->addImmediateOperand(decoration);
1961     dec->addStringOperand(s);
1962
1963     decorations.push_back(std::unique_ptr<Instruction>(dec));
1964 }
1965
1966 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& literals)
1967 {
1968     if (decoration == spv::DecorationMax)
1969         return;
1970
1971     Instruction* dec = new Instruction(OpMemberDecorate);
1972     dec->addIdOperand(id);
1973     dec->addImmediateOperand(member);
1974     dec->addImmediateOperand(decoration);
1975     for (auto literal : literals)
1976         dec->addImmediateOperand(literal);
1977
1978     decorations.push_back(std::unique_ptr<Instruction>(dec));
1979 }
1980
1981 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& strings)
1982 {
1983     if (decoration == spv::DecorationMax)
1984         return;
1985
1986     Instruction* dec = new Instruction(OpMemberDecorateString);
1987     dec->addIdOperand(id);
1988     dec->addImmediateOperand(member);
1989     dec->addImmediateOperand(decoration);
1990     for (auto string : strings)
1991         dec->addStringOperand(string);
1992
1993     decorations.push_back(std::unique_ptr<Instruction>(dec));
1994 }
1995
1996 // Comments in header
1997 Function* Builder::makeEntryPoint(const char* entryPoint)
1998 {
1999     assert(! entryPointFunction);
2000
2001     Block* entry;
2002     std::vector<Id> paramsTypes;
2003     std::vector<char const*> paramNames;
2004     std::vector<std::vector<Decoration>> decorations;
2005
2006     auto const returnType = makeVoidType();
2007
2008     restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
2009     if(sourceLang == spv::SourceLanguageHLSL) {
2010         emitNonSemanticShaderDebugInfo = false;
2011     }
2012
2013     entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, paramsTypes, paramNames, decorations, &entry);
2014
2015     emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
2016
2017     return entryPointFunction;
2018 }
2019
2020 // Comments in header
2021 Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
2022                                      const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
2023                                      const std::vector<std::vector<Decoration>>& decorations, Block **entry)
2024 {
2025     // Make the function and initial instructions in it
2026     Id typeId = makeFunctionType(returnType, paramTypes);
2027     Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size());
2028     Id funcId = getUniqueId();
2029     Function* function = new Function(funcId, returnType, typeId, firstParamId, module);
2030
2031     // Set up the precisions
2032     setPrecision(function->getId(), precision);
2033     function->setReturnPrecision(precision);
2034     for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
2035         for (int d = 0; d < (int)decorations[p].size(); ++d) {
2036             addDecoration(firstParamId + p, decorations[p][d]);
2037             function->addParamPrecision(p, decorations[p][d]);
2038         }
2039     }
2040
2041     // Make the debug function instruction
2042     if (emitNonSemanticShaderDebugInfo) {
2043         Id nameId = getStringId(unmangleFunctionName(name));
2044         Id debugFuncId = makeDebugFunction(function, nameId, typeId);
2045         debugId[funcId] = debugFuncId;
2046         currentDebugScopeId.push(debugFuncId);
2047         lastDebugScopeId = NoResult;
2048     }
2049
2050     // CFG
2051     assert(entry != nullptr);
2052     *entry = new Block(getUniqueId(), *function);
2053     function->addBlock(*entry);
2054     setBuildPoint(*entry);
2055
2056     // DebugScope and DebugLine for parameter DebugDeclares
2057     if (emitNonSemanticShaderDebugInfo && (int)paramTypes.size() > 0) {
2058         addDebugScopeAndLine(currentFileId, currentLine, 0);
2059     }
2060
2061     if (emitNonSemanticShaderDebugInfo) {
2062         assert(paramTypes.size() == paramNames.size());
2063         for(size_t p = 0; p < paramTypes.size(); ++p)
2064         {
2065             auto const& paramType = paramTypes[p];
2066             assert(isPointerType(paramType) || isArrayType(paramType));
2067             assert(debugId[getContainedTypeId(paramType)] != 0);
2068             auto const& paramName = paramNames[p];
2069             auto const debugLocalVariableId = createDebugLocalVariable(debugId[getContainedTypeId(paramType)], paramName, p+1);
2070             debugId[firstParamId + p] = debugLocalVariableId;
2071
2072             makeDebugDeclare(debugLocalVariableId, firstParamId + p);
2073         }
2074     }
2075
2076     if (name)
2077         addName(function->getId(), name);
2078
2079     functions.push_back(std::unique_ptr<Function>(function));
2080
2081     // Clear debug scope stack
2082     if (emitNonSemanticShaderDebugInfo)
2083         currentDebugScopeId.pop();
2084
2085     return function;
2086 }
2087
2088 Id Builder::makeDebugFunction(Function* function, Id nameId, Id funcTypeId) {
2089     assert(function != nullptr);
2090     assert(nameId != 0);
2091     assert(funcTypeId != 0);
2092     assert(debugId[funcTypeId] != 0);
2093
2094     Id funcId = getUniqueId();
2095     auto type = new Instruction(funcId, makeVoidType(), OpExtInst);
2096     type->addIdOperand(nonSemanticShaderDebugInfo);
2097     type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunction);
2098     type->addIdOperand(nameId);
2099     type->addIdOperand(debugId[funcTypeId]);
2100     type->addIdOperand(makeDebugSource(currentFileId)); // Will be fixed later when true filename available
2101     type->addIdOperand(makeUintConstant(currentLine)); // Will be fixed later when true line available
2102     type->addIdOperand(makeUintConstant(0)); // column
2103     type->addIdOperand(makeDebugCompilationUnit()); // scope
2104     type->addIdOperand(nameId); // linkage name
2105     type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic));
2106     type->addIdOperand(makeUintConstant(currentLine)); // TODO(greg-lunarg): correct scope line
2107     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
2108     module.mapInstruction(type);
2109     return funcId;
2110 }
2111
2112 Id Builder::makeDebugLexicalBlock(uint32_t line) {
2113     Id lexId = getUniqueId();
2114     auto lex = new Instruction(lexId, makeVoidType(), OpExtInst);
2115     lex->addIdOperand(nonSemanticShaderDebugInfo);
2116     lex->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLexicalBlock);
2117     lex->addIdOperand(makeDebugSource(currentFileId));
2118     lex->addIdOperand(makeUintConstant(line));
2119     lex->addIdOperand(makeUintConstant(0)); // column
2120     lex->addIdOperand(currentDebugScopeId.top()); // scope
2121     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(lex));
2122     module.mapInstruction(lex);
2123     return lexId;
2124 }
2125
2126 std::string Builder::unmangleFunctionName(std::string const& name) const
2127 {
2128     assert(name.length() > 0);
2129
2130     if(name.rfind('(') != std::string::npos) {
2131         return name.substr(0, name.rfind('('));
2132     } else {
2133         return name;
2134     }
2135 }
2136
2137 // Comments in header
2138 void Builder::makeReturn(bool implicit, Id retVal)
2139 {
2140     if (retVal) {
2141         Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
2142         inst->addIdOperand(retVal);
2143         buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
2144     } else
2145         buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));
2146
2147     if (! implicit)
2148         createAndSetNoPredecessorBlock("post-return");
2149 }
2150
2151 // Comments in header
2152 void Builder::enterScope(uint32_t line)
2153 {
2154     // Generate new lexical scope debug instruction
2155     Id lexId = makeDebugLexicalBlock(line);
2156     currentDebugScopeId.push(lexId);
2157     lastDebugScopeId = NoResult;
2158 }
2159
2160 // Comments in header
2161 void Builder::leaveScope()
2162 {
2163     // Pop current scope from stack and clear current scope
2164     currentDebugScopeId.pop();
2165     lastDebugScopeId = NoResult;
2166 }
2167
2168 // Comments in header
2169 void Builder::enterFunction(Function const* function)
2170 {
2171     // Save and disable debugInfo for HLSL entry point function. It is a wrapper
2172     // function with no user code in it.
2173     restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
2174     if (sourceLang == spv::SourceLanguageHLSL && function == entryPointFunction) {
2175         emitNonSemanticShaderDebugInfo = false;
2176     }
2177
2178     if (emitNonSemanticShaderDebugInfo) {
2179         // Initialize scope state
2180         Id funcId = function->getFuncId();
2181         currentDebugScopeId.push(debugId[funcId]);
2182         // Create DebugFunctionDefinition
2183         spv::Id resultId = getUniqueId();
2184         Instruction* defInst = new Instruction(resultId, makeVoidType(), OpExtInst);
2185         defInst->addIdOperand(nonSemanticShaderDebugInfo);
2186         defInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunctionDefinition);
2187         defInst->addIdOperand(debugId[funcId]);
2188         defInst->addIdOperand(funcId);
2189         buildPoint->addInstruction(std::unique_ptr<Instruction>(defInst));
2190     }
2191 }
2192
2193 // Comments in header
2194 void Builder::leaveFunction()
2195 {
2196     Block* block = buildPoint;
2197     Function& function = buildPoint->getParent();
2198     assert(block);
2199
2200     // If our function did not contain a return, add a return void now.
2201     if (! block->isTerminated()) {
2202         if (function.getReturnType() == makeVoidType())
2203             makeReturn(true);
2204         else {
2205             makeReturn(true, createUndefined(function.getReturnType()));
2206         }
2207     }
2208
2209     // Clear function scope from debug scope stack
2210     if (emitNonSemanticShaderDebugInfo)
2211         currentDebugScopeId.pop();
2212
2213     emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
2214 }
2215
2216 // Comments in header
2217 void Builder::makeStatementTerminator(spv::Op opcode, const char *name)
2218 {
2219     buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
2220     createAndSetNoPredecessorBlock(name);
2221 }
2222
2223 // Comments in header
2224 void Builder::makeStatementTerminator(spv::Op opcode, const std::vector<Id>& operands, const char* name)
2225 {
2226     // It's assumed that the terminator instruction is always of void return type
2227     // However in future if there is a need for non void return type, new helper
2228     // methods can be created.
2229     createNoResultOp(opcode, operands);
2230     createAndSetNoPredecessorBlock(name);
2231 }
2232
2233 // Comments in header
2234 Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer,
2235     bool const compilerGenerated)
2236 {
2237     Id pointerType = makePointer(storageClass, type);
2238     Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
2239     inst->addImmediateOperand(storageClass);
2240     if (initializer != NoResult)
2241         inst->addIdOperand(initializer);
2242
2243     switch (storageClass) {
2244     case StorageClassFunction:
2245         // Validation rules require the declaration in the entry block
2246         buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));
2247
2248         if (emitNonSemanticShaderDebugInfo && !compilerGenerated)
2249         {
2250             auto const debugLocalVariableId = createDebugLocalVariable(debugId[type], name);
2251             debugId[inst->getResultId()] = debugLocalVariableId;
2252
2253             makeDebugDeclare(debugLocalVariableId, inst->getResultId());
2254         }
2255
2256         break;
2257
2258     default:
2259         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
2260         module.mapInstruction(inst);
2261
2262         if (emitNonSemanticShaderDebugInfo && !isRayTracingOpCode(getOpCode(type)))
2263         {
2264             auto const debugResultId = createDebugGlobalVariable(debugId[type], name, inst->getResultId());
2265             debugId[inst->getResultId()] = debugResultId;
2266         }
2267         break;
2268     }
2269
2270     if (name)
2271         addName(inst->getResultId(), name);
2272     setPrecision(inst->getResultId(), precision);
2273
2274     return inst->getResultId();
2275 }
2276
2277 // Comments in header
2278 Id Builder::createUndefined(Id type)
2279 {
2280   Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);
2281   buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
2282   return inst->getResultId();
2283 }
2284
2285 // av/vis/nonprivate are unnecessary and illegal for some storage classes.
2286 spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
2287     const
2288 {
2289     switch (sc) {
2290     case spv::StorageClassUniform:
2291     case spv::StorageClassWorkgroup:
2292     case spv::StorageClassStorageBuffer:
2293     case spv::StorageClassPhysicalStorageBufferEXT:
2294         break;
2295     default:
2296         memoryAccess = spv::MemoryAccessMask(memoryAccess &
2297                         ~(spv::MemoryAccessMakePointerAvailableKHRMask |
2298                           spv::MemoryAccessMakePointerVisibleKHRMask |
2299                           spv::MemoryAccessNonPrivatePointerKHRMask));
2300         break;
2301     }
2302     return memoryAccess;
2303 }
2304
2305 // Comments in header
2306 void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope,
2307     unsigned int alignment)
2308 {
2309     Instruction* store = new Instruction(OpStore);
2310     store->addIdOperand(lValue);
2311     store->addIdOperand(rValue);
2312
2313     memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
2314
2315     if (memoryAccess != MemoryAccessMaskNone) {
2316         store->addImmediateOperand(memoryAccess);
2317         if (memoryAccess & spv::MemoryAccessAlignedMask) {
2318             store->addImmediateOperand(alignment);
2319         }
2320         if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
2321             store->addIdOperand(makeUintConstant(scope));
2322         }
2323     }
2324
2325     buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
2326 }
2327
2328 // Comments in header
2329 Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess,
2330     spv::Scope scope, unsigned int alignment)
2331 {
2332     Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
2333     load->addIdOperand(lValue);
2334
2335     memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
2336
2337     if (memoryAccess != MemoryAccessMaskNone) {
2338         load->addImmediateOperand(memoryAccess);
2339         if (memoryAccess & spv::MemoryAccessAlignedMask) {
2340             load->addImmediateOperand(alignment);
2341         }
2342         if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
2343             load->addIdOperand(makeUintConstant(scope));
2344         }
2345     }
2346
2347     buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
2348     setPrecision(load->getResultId(), precision);
2349
2350     return load->getResultId();
2351 }
2352
2353 // Comments in header
2354 Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
2355 {
2356     // Figure out the final resulting type.
2357     Id typeId = getResultingAccessChainType();
2358     typeId = makePointer(storageClass, typeId);
2359
2360     // Make the instruction
2361     Instruction* chain = new Instruction(getUniqueId(), typeId, OpAccessChain);
2362     chain->addIdOperand(base);
2363     for (int i = 0; i < (int)offsets.size(); ++i)
2364         chain->addIdOperand(offsets[i]);
2365     buildPoint->addInstruction(std::unique_ptr<Instruction>(chain));
2366
2367     return chain->getResultId();
2368 }
2369
2370 Id Builder::createArrayLength(Id base, unsigned int member)
2371 {
2372     spv::Id intType = makeUintType(32);
2373     Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength);
2374     length->addIdOperand(base);
2375     length->addImmediateOperand(member);
2376     buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
2377
2378     return length->getResultId();
2379 }
2380
2381 Id Builder::createCooperativeMatrixLength(Id type)
2382 {
2383     spv::Id intType = makeUintType(32);
2384
2385     // Generate code for spec constants if in spec constant operation
2386     // generation mode.
2387     if (generatingOpCodeForSpecConst) {
2388         return createSpecConstantOp(OpCooperativeMatrixLengthNV, intType, std::vector<Id>(1, type), std::vector<Id>());
2389     }
2390
2391     Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV);
2392     length->addIdOperand(type);
2393     buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
2394
2395     return length->getResultId();
2396 }
2397
2398 Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
2399 {
2400     // Generate code for spec constants if in spec constant operation
2401     // generation mode.
2402     if (generatingOpCodeForSpecConst) {
2403         return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite),
2404             std::vector<Id>(1, index));
2405     }
2406     Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
2407     extract->addIdOperand(composite);
2408     extract->addImmediateOperand(index);
2409     buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
2410
2411     return extract->getResultId();
2412 }
2413
2414 Id Builder::createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes)
2415 {
2416     // Generate code for spec constants if in spec constant operation
2417     // generation mode.
2418     if (generatingOpCodeForSpecConst) {
2419         return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite), indexes);
2420     }
2421     Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
2422     extract->addIdOperand(composite);
2423     for (int i = 0; i < (int)indexes.size(); ++i)
2424         extract->addImmediateOperand(indexes[i]);
2425     buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
2426
2427     return extract->getResultId();
2428 }
2429
2430 Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned index)
2431 {
2432     Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert);
2433     insert->addIdOperand(object);
2434     insert->addIdOperand(composite);
2435     insert->addImmediateOperand(index);
2436     buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
2437
2438     return insert->getResultId();
2439 }
2440
2441 Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, const std::vector<unsigned>& indexes)
2442 {
2443     Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert);
2444     insert->addIdOperand(object);
2445     insert->addIdOperand(composite);
2446     for (int i = 0; i < (int)indexes.size(); ++i)
2447         insert->addImmediateOperand(indexes[i]);
2448     buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
2449
2450     return insert->getResultId();
2451 }
2452
2453 Id Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex)
2454 {
2455     Instruction* extract = new Instruction(getUniqueId(), typeId, OpVectorExtractDynamic);
2456     extract->addIdOperand(vector);
2457     extract->addIdOperand(componentIndex);
2458     buildPoint->addInstruction(std::unique_ptr<Instruction>(extract));
2459
2460     return extract->getResultId();
2461 }
2462
2463 Id Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex)
2464 {
2465     Instruction* insert = new Instruction(getUniqueId(), typeId, OpVectorInsertDynamic);
2466     insert->addIdOperand(vector);
2467     insert->addIdOperand(component);
2468     insert->addIdOperand(componentIndex);
2469     buildPoint->addInstruction(std::unique_ptr<Instruction>(insert));
2470
2471     return insert->getResultId();
2472 }
2473
2474 // An opcode that has no operands, no result id, and no type
2475 void Builder::createNoResultOp(Op opCode)
2476 {
2477     Instruction* op = new Instruction(opCode);
2478     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2479 }
2480
2481 // An opcode that has one id operand, no result id, and no type
2482 void Builder::createNoResultOp(Op opCode, Id operand)
2483 {
2484     Instruction* op = new Instruction(opCode);
2485     op->addIdOperand(operand);
2486     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2487 }
2488
2489 // An opcode that has one or more operands, no result id, and no type
2490 void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
2491 {
2492     Instruction* op = new Instruction(opCode);
2493     for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
2494         op->addIdOperand(*it);
2495     }
2496     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2497 }
2498
2499 // An opcode that has multiple operands, no result id, and no type
2500 void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
2501 {
2502     Instruction* op = new Instruction(opCode);
2503     for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
2504         if (it->isId)
2505             op->addIdOperand(it->word);
2506         else
2507             op->addImmediateOperand(it->word);
2508     }
2509     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2510 }
2511
2512 void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
2513 {
2514     Instruction* op = new Instruction(OpControlBarrier);
2515     op->addIdOperand(makeUintConstant(execution));
2516     op->addIdOperand(makeUintConstant(memory));
2517     op->addIdOperand(makeUintConstant(semantics));
2518     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2519 }
2520
2521 void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)
2522 {
2523     Instruction* op = new Instruction(OpMemoryBarrier);
2524     op->addIdOperand(makeUintConstant(executionScope));
2525     op->addIdOperand(makeUintConstant(memorySemantics));
2526     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2527 }
2528
2529 // An opcode that has one operands, a result id, and a type
2530 Id Builder::createUnaryOp(Op opCode, Id typeId, Id operand)
2531 {
2532     // Generate code for spec constants if in spec constant operation
2533     // generation mode.
2534     if (generatingOpCodeForSpecConst) {
2535         return createSpecConstantOp(opCode, typeId, std::vector<Id>(1, operand), std::vector<Id>());
2536     }
2537     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
2538     op->addIdOperand(operand);
2539     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2540
2541     return op->getResultId();
2542 }
2543
2544 Id Builder::createBinOp(Op opCode, Id typeId, Id left, Id right)
2545 {
2546     // Generate code for spec constants if in spec constant operation
2547     // generation mode.
2548     if (generatingOpCodeForSpecConst) {
2549         std::vector<Id> operands(2);
2550         operands[0] = left; operands[1] = right;
2551         return createSpecConstantOp(opCode, typeId, operands, std::vector<Id>());
2552     }
2553     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
2554     op->addIdOperand(left);
2555     op->addIdOperand(right);
2556     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2557
2558     return op->getResultId();
2559 }
2560
2561 Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)
2562 {
2563     // Generate code for spec constants if in spec constant operation
2564     // generation mode.
2565     if (generatingOpCodeForSpecConst) {
2566         std::vector<Id> operands(3);
2567         operands[0] = op1;
2568         operands[1] = op2;
2569         operands[2] = op3;
2570         return createSpecConstantOp(
2571             opCode, typeId, operands, std::vector<Id>());
2572     }
2573     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
2574     op->addIdOperand(op1);
2575     op->addIdOperand(op2);
2576     op->addIdOperand(op3);
2577     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2578
2579     return op->getResultId();
2580 }
2581
2582 Id Builder::createOp(Op opCode, Id typeId, const std::vector<Id>& operands)
2583 {
2584     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
2585     for (auto it = operands.cbegin(); it != operands.cend(); ++it)
2586         op->addIdOperand(*it);
2587     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2588
2589     return op->getResultId();
2590 }
2591
2592 Id Builder::createOp(Op opCode, Id typeId, const std::vector<IdImmediate>& operands)
2593 {
2594     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
2595     for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
2596         if (it->isId)
2597             op->addIdOperand(it->word);
2598         else
2599             op->addImmediateOperand(it->word);
2600     }
2601     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2602
2603     return op->getResultId();
2604 }
2605
2606 Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands,
2607     const std::vector<unsigned>& literals)
2608 {
2609     Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
2610     op->addImmediateOperand((unsigned) opCode);
2611     for (auto it = operands.cbegin(); it != operands.cend(); ++it)
2612         op->addIdOperand(*it);
2613     for (auto it = literals.cbegin(); it != literals.cend(); ++it)
2614         op->addImmediateOperand(*it);
2615     module.mapInstruction(op);
2616     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(op));
2617
2618     return op->getResultId();
2619 }
2620
2621 Id Builder::createFunctionCall(spv::Function* function, const std::vector<spv::Id>& args)
2622 {
2623     Instruction* op = new Instruction(getUniqueId(), function->getReturnType(), OpFunctionCall);
2624     op->addIdOperand(function->getId());
2625     for (int a = 0; a < (int)args.size(); ++a)
2626         op->addIdOperand(args[a]);
2627     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
2628
2629     return op->getResultId();
2630 }
2631
2632 // Comments in header
2633 Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, const std::vector<unsigned>& channels)
2634 {
2635     if (channels.size() == 1)
2636         return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision);
2637
2638     if (generatingOpCodeForSpecConst) {
2639         std::vector<Id> operands(2);
2640         operands[0] = operands[1] = source;
2641         return setPrecision(createSpecConstantOp(OpVectorShuffle, typeId, operands, channels), precision);
2642     }
2643     Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
2644     assert(isVector(source));
2645     swizzle->addIdOperand(source);
2646     swizzle->addIdOperand(source);
2647     for (int i = 0; i < (int)channels.size(); ++i)
2648         swizzle->addImmediateOperand(channels[i]);
2649     buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));
2650
2651     return setPrecision(swizzle->getResultId(), precision);
2652 }
2653
2654 // Comments in header
2655 Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vector<unsigned>& channels)
2656 {
2657     if (channels.size() == 1 && getNumComponents(source) == 1)
2658         return createCompositeInsert(source, target, typeId, channels.front());
2659
2660     Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
2661
2662     assert(isVector(target));
2663     swizzle->addIdOperand(target);
2664
2665     assert(getNumComponents(source) == (int)channels.size());
2666     assert(isVector(source));
2667     swizzle->addIdOperand(source);
2668
2669     // Set up an identity shuffle from the base value to the result value
2670     unsigned int components[4];
2671     int numTargetComponents = getNumComponents(target);
2672     for (int i = 0; i < numTargetComponents; ++i)
2673         components[i] = i;
2674
2675     // Punch in the l-value swizzle
2676     for (int i = 0; i < (int)channels.size(); ++i)
2677         components[channels[i]] = numTargetComponents + i;
2678
2679     // finish the instruction with these components selectors
2680     for (int i = 0; i < numTargetComponents; ++i)
2681         swizzle->addImmediateOperand(components[i]);
2682     buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));
2683
2684     return swizzle->getResultId();
2685 }
2686
2687 // Comments in header
2688 void Builder::promoteScalar(Decoration precision, Id& left, Id& right)
2689 {
2690     int direction = getNumComponents(right) - getNumComponents(left);
2691
2692     if (direction > 0)
2693         left = smearScalar(precision, left, makeVectorType(getTypeId(left), getNumComponents(right)));
2694     else if (direction < 0)
2695         right = smearScalar(precision, right, makeVectorType(getTypeId(right), getNumComponents(left)));
2696
2697     return;
2698 }
2699
2700 // Comments in header
2701 Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
2702 {
2703     assert(getNumComponents(scalar) == 1);
2704     assert(getTypeId(scalar) == getScalarTypeId(vectorType));
2705
2706     int numComponents = getNumTypeComponents(vectorType);
2707     if (numComponents == 1)
2708         return scalar;
2709
2710     Instruction* smear = nullptr;
2711     if (generatingOpCodeForSpecConst) {
2712         auto members = std::vector<spv::Id>(numComponents, scalar);
2713         // Sometime even in spec-constant-op mode, the temporary vector created by
2714         // promoting a scalar might not be a spec constant. This should depend on
2715         // the scalar.
2716         // e.g.:
2717         //  const vec2 spec_const_result = a_spec_const_vec2 + a_front_end_const_scalar;
2718         // In such cases, the temporary vector created from a_front_end_const_scalar
2719         // is not a spec constant vector, even though the binary operation node is marked
2720         // as 'specConstant' and we are in spec-constant-op mode.
2721         auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar));
2722         smear = module.getInstruction(result_id);
2723     } else {
2724         smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct);
2725         for (int c = 0; c < numComponents; ++c)
2726             smear->addIdOperand(scalar);
2727         buildPoint->addInstruction(std::unique_ptr<Instruction>(smear));
2728     }
2729
2730     return setPrecision(smear->getResultId(), precision);
2731 }
2732
2733 // Comments in header
2734 Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector<Id>& args)
2735 {
2736     Instruction* inst = new Instruction(getUniqueId(), resultType, OpExtInst);
2737     inst->addIdOperand(builtins);
2738     inst->addImmediateOperand(entryPoint);
2739     for (int arg = 0; arg < (int)args.size(); ++arg)
2740         inst->addIdOperand(args[arg]);
2741
2742     buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
2743
2744     return inst->getResultId();
2745 }
2746
2747 // Accept all parameters needed to create a texture instruction.
2748 // Create the correct instruction based on the inputs, and make the call.
2749 Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
2750     bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
2751 {
2752     static const int maxTextureArgs = 10;
2753     Id texArgs[maxTextureArgs] = {};
2754
2755     //
2756     // Set up the fixed arguments
2757     //
2758     int numArgs = 0;
2759     bool explicitLod = false;
2760     texArgs[numArgs++] = parameters.sampler;
2761     texArgs[numArgs++] = parameters.coords;
2762     if (parameters.Dref != NoResult)
2763         texArgs[numArgs++] = parameters.Dref;
2764     if (parameters.component != NoResult)
2765         texArgs[numArgs++] = parameters.component;
2766
2767 #ifndef GLSLANG_WEB
2768     if (parameters.granularity != NoResult)
2769         texArgs[numArgs++] = parameters.granularity;
2770     if (parameters.coarse != NoResult)
2771         texArgs[numArgs++] = parameters.coarse;
2772 #endif
2773
2774     //
2775     // Set up the optional arguments
2776     //
2777     int optArgNum = numArgs;    // track which operand, if it exists, is the mask of optional arguments
2778     ++numArgs;                  // speculatively make room for the mask operand
2779     ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
2780     if (parameters.bias) {
2781         mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
2782         texArgs[numArgs++] = parameters.bias;
2783     }
2784     if (parameters.lod) {
2785         mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
2786         texArgs[numArgs++] = parameters.lod;
2787         explicitLod = true;
2788     } else if (parameters.gradX) {
2789         mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
2790         texArgs[numArgs++] = parameters.gradX;
2791         texArgs[numArgs++] = parameters.gradY;
2792         explicitLod = true;
2793     } else if (noImplicitLod && ! fetch && ! gather) {
2794         // have to explicitly use lod of 0 if not allowed to have them be implicit, and
2795         // we would otherwise be about to issue an implicit instruction
2796         mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
2797         texArgs[numArgs++] = makeFloatConstant(0.0);
2798         explicitLod = true;
2799     }
2800     if (parameters.offset) {
2801         if (isConstant(parameters.offset))
2802             mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask);
2803         else {
2804             addCapability(CapabilityImageGatherExtended);
2805             mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
2806         }
2807         texArgs[numArgs++] = parameters.offset;
2808     }
2809     if (parameters.offsets) {
2810         addCapability(CapabilityImageGatherExtended);
2811         mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
2812         texArgs[numArgs++] = parameters.offsets;
2813     }
2814 #ifndef GLSLANG_WEB
2815     if (parameters.sample) {
2816         mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
2817         texArgs[numArgs++] = parameters.sample;
2818     }
2819     if (parameters.lodClamp) {
2820         // capability if this bit is used
2821         addCapability(CapabilityMinLod);
2822
2823         mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
2824         texArgs[numArgs++] = parameters.lodClamp;
2825     }
2826     if (parameters.nonprivate) {
2827         mask = mask | ImageOperandsNonPrivateTexelKHRMask;
2828     }
2829     if (parameters.volatil) {
2830         mask = mask | ImageOperandsVolatileTexelKHRMask;
2831     }
2832 #endif
2833     mask = mask | signExtensionMask;
2834     if (mask == ImageOperandsMaskNone)
2835         --numArgs;  // undo speculative reservation for the mask argument
2836     else
2837         texArgs[optArgNum] = mask;
2838
2839     //
2840     // Set up the instruction
2841     //
2842     Op opCode = OpNop;  // All paths below need to set this
2843     if (fetch) {
2844         if (sparse)
2845             opCode = OpImageSparseFetch;
2846         else
2847             opCode = OpImageFetch;
2848 #ifndef GLSLANG_WEB
2849     } else if (parameters.granularity && parameters.coarse) {
2850         opCode = OpImageSampleFootprintNV;
2851     } else if (gather) {
2852         if (parameters.Dref)
2853             if (sparse)
2854                 opCode = OpImageSparseDrefGather;
2855             else
2856                 opCode = OpImageDrefGather;
2857         else
2858             if (sparse)
2859                 opCode = OpImageSparseGather;
2860             else
2861                 opCode = OpImageGather;
2862 #endif
2863     } else if (explicitLod) {
2864         if (parameters.Dref) {
2865             if (proj)
2866                 if (sparse)
2867                     opCode = OpImageSparseSampleProjDrefExplicitLod;
2868                 else
2869                     opCode = OpImageSampleProjDrefExplicitLod;
2870             else
2871                 if (sparse)
2872                     opCode = OpImageSparseSampleDrefExplicitLod;
2873                 else
2874                     opCode = OpImageSampleDrefExplicitLod;
2875         } else {
2876             if (proj)
2877                 if (sparse)
2878                     opCode = OpImageSparseSampleProjExplicitLod;
2879                 else
2880                     opCode = OpImageSampleProjExplicitLod;
2881             else
2882                 if (sparse)
2883                     opCode = OpImageSparseSampleExplicitLod;
2884                 else
2885                     opCode = OpImageSampleExplicitLod;
2886         }
2887     } else {
2888         if (parameters.Dref) {
2889             if (proj)
2890                 if (sparse)
2891                     opCode = OpImageSparseSampleProjDrefImplicitLod;
2892                 else
2893                     opCode = OpImageSampleProjDrefImplicitLod;
2894             else
2895                 if (sparse)
2896                     opCode = OpImageSparseSampleDrefImplicitLod;
2897                 else
2898                     opCode = OpImageSampleDrefImplicitLod;
2899         } else {
2900             if (proj)
2901                 if (sparse)
2902                     opCode = OpImageSparseSampleProjImplicitLod;
2903                 else
2904                     opCode = OpImageSampleProjImplicitLod;
2905             else
2906                 if (sparse)
2907                     opCode = OpImageSparseSampleImplicitLod;
2908                 else
2909                     opCode = OpImageSampleImplicitLod;
2910         }
2911     }
2912
2913     // See if the result type is expecting a smeared result.
2914     // This happens when a legacy shadow*() call is made, which
2915     // gets a vec4 back instead of a float.
2916     Id smearedType = resultType;
2917     if (! isScalarType(resultType)) {
2918         switch (opCode) {
2919         case OpImageSampleDrefImplicitLod:
2920         case OpImageSampleDrefExplicitLod:
2921         case OpImageSampleProjDrefImplicitLod:
2922         case OpImageSampleProjDrefExplicitLod:
2923             resultType = getScalarTypeId(resultType);
2924             break;
2925         default:
2926             break;
2927         }
2928     }
2929
2930     Id typeId0 = 0;
2931     Id typeId1 = 0;
2932
2933     if (sparse) {
2934         typeId0 = resultType;
2935         typeId1 = getDerefTypeId(parameters.texelOut);
2936         resultType = makeStructResultType(typeId0, typeId1);
2937     }
2938
2939     // Build the SPIR-V instruction
2940     Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
2941     for (int op = 0; op < optArgNum; ++op)
2942         textureInst->addIdOperand(texArgs[op]);
2943     if (optArgNum < numArgs)
2944         textureInst->addImmediateOperand(texArgs[optArgNum]);
2945     for (int op = optArgNum + 1; op < numArgs; ++op)
2946         textureInst->addIdOperand(texArgs[op]);
2947     setPrecision(textureInst->getResultId(), precision);
2948     buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));
2949
2950     Id resultId = textureInst->getResultId();
2951
2952     if (sparse) {
2953         // set capability
2954         addCapability(CapabilitySparseResidency);
2955
2956         // Decode the return type that was a special structure
2957         createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
2958         resultId = createCompositeExtract(resultId, typeId0, 0);
2959         setPrecision(resultId, precision);
2960     } else {
2961         // When a smear is needed, do it, as per what was computed
2962         // above when resultType was changed to a scalar type.
2963         if (resultType != smearedType)
2964             resultId = smearScalar(precision, resultId, smearedType);
2965     }
2966
2967     return resultId;
2968 }
2969
2970 // Comments in header
2971 Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameters, bool isUnsignedResult)
2972 {
2973     // Figure out the result type
2974     Id resultType = 0;
2975     switch (opCode) {
2976     case OpImageQuerySize:
2977     case OpImageQuerySizeLod:
2978     {
2979         int numComponents = 0;
2980         switch (getTypeDimensionality(getImageType(parameters.sampler))) {
2981         case Dim1D:
2982         case DimBuffer:
2983             numComponents = 1;
2984             break;
2985         case Dim2D:
2986         case DimCube:
2987         case DimRect:
2988         case DimSubpassData:
2989             numComponents = 2;
2990             break;
2991         case Dim3D:
2992             numComponents = 3;
2993             break;
2994
2995         default:
2996             assert(0);
2997             break;
2998         }
2999         if (isArrayedImageType(getImageType(parameters.sampler)))
3000             ++numComponents;
3001
3002         Id intType = isUnsignedResult ? makeUintType(32) : makeIntType(32);
3003         if (numComponents == 1)
3004             resultType = intType;
3005         else
3006             resultType = makeVectorType(intType, numComponents);
3007
3008         break;
3009     }
3010     case OpImageQueryLod:
3011         resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2);
3012         break;
3013     case OpImageQueryLevels:
3014     case OpImageQuerySamples:
3015         resultType = isUnsignedResult ? makeUintType(32) : makeIntType(32);
3016         break;
3017     default:
3018         assert(0);
3019         break;
3020     }
3021
3022     Instruction* query = new Instruction(getUniqueId(), resultType, opCode);
3023     query->addIdOperand(parameters.sampler);
3024     if (parameters.coords)
3025         query->addIdOperand(parameters.coords);
3026     if (parameters.lod)
3027         query->addIdOperand(parameters.lod);
3028     buildPoint->addInstruction(std::unique_ptr<Instruction>(query));
3029     addCapability(CapabilityImageQuery);
3030
3031     return query->getResultId();
3032 }
3033
3034 // External comments in header.
3035 // Operates recursively to visit the composite's hierarchy.
3036 Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, bool equal)
3037 {
3038     Id boolType = makeBoolType();
3039     Id valueType = getTypeId(value1);
3040
3041     Id resultId = NoResult;
3042
3043     int numConstituents = getNumTypeConstituents(valueType);
3044
3045     // Scalars and Vectors
3046
3047     if (isScalarType(valueType) || isVectorType(valueType)) {
3048         assert(valueType == getTypeId(value2));
3049         // These just need a single comparison, just have
3050         // to figure out what it is.
3051         Op op;
3052         switch (getMostBasicTypeClass(valueType)) {
3053         case OpTypeFloat:
3054             op = equal ? OpFOrdEqual : OpFUnordNotEqual;
3055             break;
3056         case OpTypeInt:
3057         default:
3058             op = equal ? OpIEqual : OpINotEqual;
3059             break;
3060         case OpTypeBool:
3061             op = equal ? OpLogicalEqual : OpLogicalNotEqual;
3062             precision = NoPrecision;
3063             break;
3064         }
3065
3066         if (isScalarType(valueType)) {
3067             // scalar
3068             resultId = createBinOp(op, boolType, value1, value2);
3069         } else {
3070             // vector
3071             resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);
3072             setPrecision(resultId, precision);
3073             // reduce vector compares...
3074             resultId = createUnaryOp(equal ? OpAll : OpAny, boolType, resultId);
3075         }
3076
3077         return setPrecision(resultId, precision);
3078     }
3079
3080     // Only structs, arrays, and matrices should be left.
3081     // They share in common the reduction operation across their constituents.
3082     assert(isAggregateType(valueType) || isMatrixType(valueType));
3083
3084     // Compare each pair of constituents
3085     for (int constituent = 0; constituent < numConstituents; ++constituent) {
3086         std::vector<unsigned> indexes(1, constituent);
3087         Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent);
3088         Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent);
3089         Id constituent1 = createCompositeExtract(value1, constituentType1, indexes);
3090         Id constituent2 = createCompositeExtract(value2, constituentType2, indexes);
3091
3092         Id subResultId = createCompositeCompare(precision, constituent1, constituent2, equal);
3093
3094         if (constituent == 0)
3095             resultId = subResultId;
3096         else
3097             resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
3098                                     precision);
3099     }
3100
3101     return resultId;
3102 }
3103
3104 // OpCompositeConstruct
3105 Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
3106 {
3107     assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 &&
3108            getNumTypeConstituents(typeId) == (int)constituents.size()));
3109
3110     if (generatingOpCodeForSpecConst) {
3111         // Sometime, even in spec-constant-op mode, the constant composite to be
3112         // constructed may not be a specialization constant.
3113         // e.g.:
3114         //  const mat2 m2 = mat2(a_spec_const, a_front_end_const, another_front_end_const, third_front_end_const);
3115         // The first column vector should be a spec constant one, as a_spec_const is a spec constant.
3116         // The second column vector should NOT be spec constant, as it does not contain any spec constants.
3117         // To handle such cases, we check the constituents of the constant vector to determine whether this
3118         // vector should be created as a spec constant.
3119         return makeCompositeConstant(typeId, constituents,
3120                                      std::any_of(constituents.begin(), constituents.end(),
3121                                                  [&](spv::Id id) { return isSpecConstant(id); }));
3122     }
3123
3124     Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct);
3125     for (int c = 0; c < (int)constituents.size(); ++c)
3126         op->addIdOperand(constituents[c]);
3127     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
3128
3129     return op->getResultId();
3130 }
3131
3132 // Vector or scalar constructor
3133 Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId)
3134 {
3135     Id result = NoResult;
3136     unsigned int numTargetComponents = getNumTypeComponents(resultTypeId);
3137     unsigned int targetComponent = 0;
3138
3139     // Special case: when calling a vector constructor with a single scalar
3140     // argument, smear the scalar
3141     if (sources.size() == 1 && isScalar(sources[0]) && numTargetComponents > 1)
3142         return smearScalar(precision, sources[0], resultTypeId);
3143
3144     // accumulate the arguments for OpCompositeConstruct
3145     std::vector<Id> constituents;
3146     Id scalarTypeId = getScalarTypeId(resultTypeId);
3147
3148     // lambda to store the result of visiting an argument component
3149     const auto latchResult = [&](Id comp) {
3150         if (numTargetComponents > 1)
3151             constituents.push_back(comp);
3152         else
3153             result = comp;
3154         ++targetComponent;
3155     };
3156
3157     // lambda to visit a vector argument's components
3158     const auto accumulateVectorConstituents = [&](Id sourceArg) {
3159         unsigned int sourceSize = getNumComponents(sourceArg);
3160         unsigned int sourcesToUse = sourceSize;
3161         if (sourcesToUse + targetComponent > numTargetComponents)
3162             sourcesToUse = numTargetComponents - targetComponent;
3163
3164         for (unsigned int s = 0; s < sourcesToUse; ++s) {
3165             std::vector<unsigned> swiz;
3166             swiz.push_back(s);
3167             latchResult(createRvalueSwizzle(precision, scalarTypeId, sourceArg, swiz));
3168         }
3169     };
3170
3171     // lambda to visit a matrix argument's components
3172     const auto accumulateMatrixConstituents = [&](Id sourceArg) {
3173         unsigned int sourceSize = getNumColumns(sourceArg) * getNumRows(sourceArg);
3174         unsigned int sourcesToUse = sourceSize;
3175         if (sourcesToUse + targetComponent > numTargetComponents)
3176             sourcesToUse = numTargetComponents - targetComponent;
3177
3178         int col = 0;
3179         int row = 0;
3180         for (unsigned int s = 0; s < sourcesToUse; ++s) {
3181             if (row >= getNumRows(sourceArg)) {
3182                 row = 0;
3183                 col++;
3184             }
3185             std::vector<Id> indexes;
3186             indexes.push_back(col);
3187             indexes.push_back(row);
3188             latchResult(createCompositeExtract(sourceArg, scalarTypeId, indexes));
3189             row++;
3190         }
3191     };
3192
3193     // Go through the source arguments, each one could have either
3194     // a single or multiple components to contribute.
3195     for (unsigned int i = 0; i < sources.size(); ++i) {
3196
3197         if (isScalar(sources[i]) || isPointer(sources[i]))
3198             latchResult(sources[i]);
3199         else if (isVector(sources[i]))
3200             accumulateVectorConstituents(sources[i]);
3201         else if (isMatrix(sources[i]))
3202             accumulateMatrixConstituents(sources[i]);
3203         else
3204             assert(0);
3205
3206         if (targetComponent >= numTargetComponents)
3207             break;
3208     }
3209
3210     // If the result is a vector, make it from the gathered constituents.
3211     if (constituents.size() > 0)
3212         result = createCompositeConstruct(resultTypeId, constituents);
3213
3214     return setPrecision(result, precision);
3215 }
3216
3217 // Comments in header
3218 Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId)
3219 {
3220     Id componentTypeId = getScalarTypeId(resultTypeId);
3221     int numCols = getTypeNumColumns(resultTypeId);
3222     int numRows = getTypeNumRows(resultTypeId);
3223
3224     Instruction* instr = module.getInstruction(componentTypeId);
3225 #ifdef GLSLANG_WEB
3226     const unsigned bitCount = 32;
3227     assert(bitCount == instr->getImmediateOperand(0));
3228 #else
3229     const unsigned bitCount = instr->getImmediateOperand(0);
3230 #endif
3231
3232     // Optimize matrix constructed from a bigger matrix
3233     if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
3234         // To truncate the matrix to a smaller number of rows/columns, we need to:
3235         // 1. For each column, extract the column and truncate it to the required size using shuffle
3236         // 2. Assemble the resulting matrix from all columns
3237         Id matrix = sources[0];
3238         Id columnTypeId = getContainedTypeId(resultTypeId);
3239         Id sourceColumnTypeId = getContainedTypeId(getTypeId(matrix));
3240
3241         std::vector<unsigned> channels;
3242         for (int row = 0; row < numRows; ++row)
3243             channels.push_back(row);
3244
3245         std::vector<Id> matrixColumns;
3246         for (int col = 0; col < numCols; ++col) {
3247             std::vector<unsigned> indexes;
3248             indexes.push_back(col);
3249             Id colv = createCompositeExtract(matrix, sourceColumnTypeId, indexes);
3250             setPrecision(colv, precision);
3251
3252             if (numRows != getNumRows(matrix)) {
3253                 matrixColumns.push_back(createRvalueSwizzle(precision, columnTypeId, colv, channels));
3254             } else {
3255                 matrixColumns.push_back(colv);
3256             }
3257         }
3258
3259         return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
3260     }
3261
3262     // Otherwise, will use a two step process
3263     // 1. make a compile-time 2D array of values
3264     // 2. construct a matrix from that array
3265
3266     // Step 1.
3267
3268     // initialize the array to the identity matrix
3269     Id ids[maxMatrixSize][maxMatrixSize];
3270     Id  one = (bitCount == 64 ? makeDoubleConstant(1.0) : makeFloatConstant(1.0));
3271     Id zero = (bitCount == 64 ? makeDoubleConstant(0.0) : makeFloatConstant(0.0));
3272     for (int col = 0; col < 4; ++col) {
3273         for (int row = 0; row < 4; ++row) {
3274             if (col == row)
3275                 ids[col][row] = one;
3276             else
3277                 ids[col][row] = zero;
3278         }
3279     }
3280
3281     // modify components as dictated by the arguments
3282     if (sources.size() == 1 && isScalar(sources[0])) {
3283         // a single scalar; resets the diagonals
3284         for (int col = 0; col < 4; ++col)
3285             ids[col][col] = sources[0];
3286     } else if (isMatrix(sources[0])) {
3287         // constructing from another matrix; copy over the parts that exist in both the argument and constructee
3288         Id matrix = sources[0];
3289         int minCols = std::min(numCols, getNumColumns(matrix));
3290         int minRows = std::min(numRows, getNumRows(matrix));
3291         for (int col = 0; col < minCols; ++col) {
3292             std::vector<unsigned> indexes;
3293             indexes.push_back(col);
3294             for (int row = 0; row < minRows; ++row) {
3295                 indexes.push_back(row);
3296                 ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes);
3297                 indexes.pop_back();
3298                 setPrecision(ids[col][row], precision);
3299             }
3300         }
3301     } else {
3302         // fill in the matrix in column-major order with whatever argument components are available
3303         int row = 0;
3304         int col = 0;
3305
3306         for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) {
3307             Id argComp = sources[arg];
3308             for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
3309                 if (getNumComponents(sources[arg]) > 1) {
3310                     argComp = createCompositeExtract(sources[arg], componentTypeId, comp);
3311                     setPrecision(argComp, precision);
3312                 }
3313                 ids[col][row++] = argComp;
3314                 if (row == numRows) {
3315                     row = 0;
3316                     col++;
3317                 }
3318                 if (col == numCols) {
3319                     // If more components are provided than fit the matrix, discard the rest.
3320                     break;
3321                 }
3322             }
3323         }
3324     }
3325
3326     // Step 2:  Construct a matrix from that array.
3327     // First make the column vectors, then make the matrix.
3328
3329     // make the column vectors
3330     Id columnTypeId = getContainedTypeId(resultTypeId);
3331     std::vector<Id> matrixColumns;
3332     for (int col = 0; col < numCols; ++col) {
3333         std::vector<Id> vectorComponents;
3334         for (int row = 0; row < numRows; ++row)
3335             vectorComponents.push_back(ids[col][row]);
3336         Id column = createCompositeConstruct(columnTypeId, vectorComponents);
3337         setPrecision(column, precision);
3338         matrixColumns.push_back(column);
3339     }
3340
3341     // make the matrix
3342     return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
3343 }
3344
3345 // Comments in header
3346 Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) :
3347     builder(gb),
3348     condition(cond),
3349     control(ctrl),
3350     elseBlock(nullptr)
3351 {
3352     function = &builder.getBuildPoint()->getParent();
3353
3354     // make the blocks, but only put the then-block into the function,
3355     // the else-block and merge-block will be added later, in order, after
3356     // earlier code is emitted
3357     thenBlock = new Block(builder.getUniqueId(), *function);
3358     mergeBlock = new Block(builder.getUniqueId(), *function);
3359
3360     // Save the current block, so that we can add in the flow control split when
3361     // makeEndIf is called.
3362     headerBlock = builder.getBuildPoint();
3363
3364     function->addBlock(thenBlock);
3365     builder.setBuildPoint(thenBlock);
3366 }
3367
3368 // Comments in header
3369 void Builder::If::makeBeginElse()
3370 {
3371     // Close out the "then" by having it jump to the mergeBlock
3372     builder.createBranch(mergeBlock);
3373
3374     // Make the first else block and add it to the function
3375     elseBlock = new Block(builder.getUniqueId(), *function);
3376     function->addBlock(elseBlock);
3377
3378     // Start building the else block
3379     builder.setBuildPoint(elseBlock);
3380 }
3381
3382 // Comments in header
3383 void Builder::If::makeEndIf()
3384 {
3385     // jump to the merge block
3386     builder.createBranch(mergeBlock);
3387
3388     // Go back to the headerBlock and make the flow control split
3389     builder.setBuildPoint(headerBlock);
3390     builder.createSelectionMerge(mergeBlock, control);
3391     if (elseBlock)
3392         builder.createConditionalBranch(condition, thenBlock, elseBlock);
3393     else
3394         builder.createConditionalBranch(condition, thenBlock, mergeBlock);
3395
3396     // add the merge block to the function
3397     function->addBlock(mergeBlock);
3398     builder.setBuildPoint(mergeBlock);
3399 }
3400
3401 // Comments in header
3402 void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, const std::vector<int>& caseValues,
3403                          const std::vector<int>& valueIndexToSegment, int defaultSegment,
3404                          std::vector<Block*>& segmentBlocks)
3405 {
3406     Function& function = buildPoint->getParent();
3407
3408     // make all the blocks
3409     for (int s = 0; s < numSegments; ++s)
3410         segmentBlocks.push_back(new Block(getUniqueId(), function));
3411
3412     Block* mergeBlock = new Block(getUniqueId(), function);
3413
3414     // make and insert the switch's selection-merge instruction
3415     createSelectionMerge(mergeBlock, control);
3416
3417     // make the switch instruction
3418     Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);
3419     switchInst->addIdOperand(selector);
3420     auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock;
3421     switchInst->addIdOperand(defaultOrMerge->getId());
3422     defaultOrMerge->addPredecessor(buildPoint);
3423     for (int i = 0; i < (int)caseValues.size(); ++i) {
3424         switchInst->addImmediateOperand(caseValues[i]);
3425         switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());
3426         segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);
3427     }
3428     buildPoint->addInstruction(std::unique_ptr<Instruction>(switchInst));
3429
3430     // push the merge block
3431     switchMerges.push(mergeBlock);
3432 }
3433
3434 // Comments in header
3435 void Builder::addSwitchBreak()
3436 {
3437     // branch to the top of the merge block stack
3438     createBranch(switchMerges.top());
3439     createAndSetNoPredecessorBlock("post-switch-break");
3440 }
3441
3442 // Comments in header
3443 void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegment)
3444 {
3445     int lastSegment = nextSegment - 1;
3446     if (lastSegment >= 0) {
3447         // Close out previous segment by jumping, if necessary, to next segment
3448         if (! buildPoint->isTerminated())
3449             createBranch(segmentBlock[nextSegment]);
3450     }
3451     Block* block = segmentBlock[nextSegment];
3452     block->getParent().addBlock(block);
3453     setBuildPoint(block);
3454 }
3455
3456 // Comments in header
3457 void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
3458 {
3459     // Close out previous segment by jumping, if necessary, to next segment
3460     if (! buildPoint->isTerminated())
3461         addSwitchBreak();
3462
3463     switchMerges.top()->getParent().addBlock(switchMerges.top());
3464     setBuildPoint(switchMerges.top());
3465
3466     switchMerges.pop();
3467 }
3468
3469 Block& Builder::makeNewBlock()
3470 {
3471     Function& function = buildPoint->getParent();
3472     auto block = new Block(getUniqueId(), function);
3473     function.addBlock(block);
3474     return *block;
3475 }
3476
3477 Builder::LoopBlocks& Builder::makeNewLoop()
3478 {
3479     // This verbosity is needed to simultaneously get the same behavior
3480     // everywhere (id's in the same order), have a syntax that works
3481     // across lots of versions of C++, have no warnings from pedantic
3482     // compilation modes, and leave the rest of the code alone.
3483     Block& head            = makeNewBlock();
3484     Block& body            = makeNewBlock();
3485     Block& merge           = makeNewBlock();
3486     Block& continue_target = makeNewBlock();
3487     LoopBlocks blocks(head, body, merge, continue_target);
3488     loops.push(blocks);
3489     return loops.top();
3490 }
3491
3492 void Builder::createLoopContinue()
3493 {
3494     createBranch(&loops.top().continue_target);
3495     // Set up a block for dead code.
3496     createAndSetNoPredecessorBlock("post-loop-continue");
3497 }
3498
3499 void Builder::createLoopExit()
3500 {
3501     createBranch(&loops.top().merge);
3502     // Set up a block for dead code.
3503     createAndSetNoPredecessorBlock("post-loop-break");
3504 }
3505
3506 void Builder::closeLoop()
3507 {
3508     loops.pop();
3509 }
3510
3511 void Builder::clearAccessChain()
3512 {
3513     accessChain.base = NoResult;
3514     accessChain.indexChain.clear();
3515     accessChain.instr = NoResult;
3516     accessChain.swizzle.clear();
3517     accessChain.component = NoResult;
3518     accessChain.preSwizzleBaseType = NoType;
3519     accessChain.isRValue = false;
3520     accessChain.coherentFlags.clear();
3521     accessChain.alignment = 0;
3522 }
3523
3524 // Comments in header
3525 void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
3526     AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
3527 {
3528     accessChain.coherentFlags |= coherentFlags;
3529     accessChain.alignment |= alignment;
3530
3531     // swizzles can be stacked in GLSL, but simplified to a single
3532     // one here; the base type doesn't change
3533     if (accessChain.preSwizzleBaseType == NoType)
3534         accessChain.preSwizzleBaseType = preSwizzleBaseType;
3535
3536     // if needed, propagate the swizzle for the current access chain
3537     if (accessChain.swizzle.size() > 0) {
3538         std::vector<unsigned> oldSwizzle = accessChain.swizzle;
3539         accessChain.swizzle.resize(0);
3540         for (unsigned int i = 0; i < swizzle.size(); ++i) {
3541             assert(swizzle[i] < oldSwizzle.size());
3542             accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
3543         }
3544     } else
3545         accessChain.swizzle = swizzle;
3546
3547     // determine if we need to track this swizzle anymore
3548     simplifyAccessChainSwizzle();
3549 }
3550
3551 // Comments in header
3552 void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
3553 {
3554     assert(accessChain.isRValue == false);
3555
3556     transferAccessChainSwizzle(true);
3557
3558     // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores.
3559     if (accessChain.swizzle.size() > 0 &&
3560         getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() &&
3561         accessChain.component == NoResult) {
3562         for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
3563             accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
3564             accessChain.instr = NoResult;
3565
3566             Id base = collapseAccessChain();
3567             addDecoration(base, nonUniform);
3568
3569             accessChain.indexChain.pop_back();
3570             accessChain.instr = NoResult;
3571
3572             // dynamic component should be gone
3573             assert(accessChain.component == NoResult);
3574
3575             Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i);
3576
3577             // take LSB of alignment
3578             alignment = alignment & ~(alignment & (alignment-1));
3579             if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
3580                 memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
3581             }
3582
3583             createStore(source, base, memoryAccess, scope, alignment);
3584         }
3585     }
3586     else {
3587         Id base = collapseAccessChain();
3588         addDecoration(base, nonUniform);
3589
3590         Id source = rvalue;
3591
3592         // dynamic component should be gone
3593         assert(accessChain.component == NoResult);
3594
3595         // If swizzle still exists, it may be out-of-order, we must load the target vector,
3596         // extract and insert elements to perform writeMask and/or swizzle.
3597         if (accessChain.swizzle.size() > 0) {
3598             Id tempBaseId = createLoad(base, spv::NoPrecision);
3599             source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
3600         }
3601
3602         // take LSB of alignment
3603         alignment = alignment & ~(alignment & (alignment-1));
3604         if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
3605             memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
3606         }
3607
3608         createStore(source, base, memoryAccess, scope, alignment);
3609     }
3610 }
3611
3612 // Comments in header
3613 Id Builder::accessChainLoad(Decoration precision, Decoration l_nonUniform,
3614     Decoration r_nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess,
3615     spv::Scope scope, unsigned int alignment)
3616 {
3617     Id id;
3618
3619     if (accessChain.isRValue) {
3620         // transfer access chain, but try to stay in registers
3621         transferAccessChainSwizzle(false);
3622         if (accessChain.indexChain.size() > 0) {
3623             Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
3624
3625             // if all the accesses are constants, we can use OpCompositeExtract
3626             std::vector<unsigned> indexes;
3627             bool constant = true;
3628             for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
3629                 if (isConstantScalar(accessChain.indexChain[i]))
3630                     indexes.push_back(getConstantScalar(accessChain.indexChain[i]));
3631                 else {
3632                     constant = false;
3633                     break;
3634                 }
3635             }
3636
3637             if (constant) {
3638                 id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
3639                 setPrecision(id, precision);
3640             } else {
3641                 Id lValue = NoResult;
3642                 if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) {
3643                     // make a new function variable for this r-value, using an initializer,
3644                     // and mark it as NonWritable so that downstream it can be detected as a lookup
3645                     // table
3646                     lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
3647                         "indexable", accessChain.base);
3648                     addDecoration(lValue, DecorationNonWritable);
3649                 } else {
3650                     lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base),
3651                         "indexable");
3652                     // store into it
3653                     createStore(accessChain.base, lValue);
3654                 }
3655                 // move base to the new variable
3656                 accessChain.base = lValue;
3657                 accessChain.isRValue = false;
3658
3659                 // load through the access chain
3660                 id = createLoad(collapseAccessChain(), precision);
3661             }
3662         } else
3663             id = accessChain.base;  // no precision, it was set when this was defined
3664     } else {
3665         transferAccessChainSwizzle(true);
3666
3667         // take LSB of alignment
3668         alignment = alignment & ~(alignment & (alignment-1));
3669         if (getStorageClass(accessChain.base) == StorageClassPhysicalStorageBufferEXT) {
3670             memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
3671         }
3672
3673         // load through the access chain
3674         id = collapseAccessChain();
3675         // Apply nonuniform both to the access chain and the loaded value.
3676         // Buffer accesses need the access chain decorated, and this is where
3677         // loaded image types get decorated. TODO: This should maybe move to
3678         // createImageTextureFunctionCall.
3679         addDecoration(id, l_nonUniform);
3680         id = createLoad(id, precision, memoryAccess, scope, alignment);
3681         addDecoration(id, r_nonUniform);
3682     }
3683
3684     // Done, unless there are swizzles to do
3685     if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
3686         return id;
3687
3688     // Do remaining swizzling
3689
3690     // Do the basic swizzle
3691     if (accessChain.swizzle.size() > 0) {
3692         Id swizzledType = getScalarTypeId(getTypeId(id));
3693         if (accessChain.swizzle.size() > 1)
3694             swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());
3695         id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle);
3696     }
3697
3698     // Do the dynamic component
3699     if (accessChain.component != NoResult)
3700         id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
3701
3702     addDecoration(id, r_nonUniform);
3703     return id;
3704 }
3705
3706 Id Builder::accessChainGetLValue()
3707 {
3708     assert(accessChain.isRValue == false);
3709
3710     transferAccessChainSwizzle(true);
3711     Id lvalue = collapseAccessChain();
3712
3713     // If swizzle exists, it is out-of-order or not full, we must load the target vector,
3714     // extract and insert elements to perform writeMask and/or swizzle.  This does not
3715     // go with getting a direct l-value pointer.
3716     assert(accessChain.swizzle.size() == 0);
3717     assert(accessChain.component == NoResult);
3718
3719     return lvalue;
3720 }
3721
3722 // comment in header
3723 Id Builder::accessChainGetInferredType()
3724 {
3725     // anything to operate on?
3726     if (accessChain.base == NoResult)
3727         return NoType;
3728     Id type = getTypeId(accessChain.base);
3729
3730     // do initial dereference
3731     if (! accessChain.isRValue)
3732         type = getContainedTypeId(type);
3733
3734     // dereference each index
3735     for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it) {
3736         if (isStructType(type))
3737             type = getContainedTypeId(type, getConstantScalar(*it));
3738         else
3739             type = getContainedTypeId(type);
3740     }
3741
3742     // dereference swizzle
3743     if (accessChain.swizzle.size() == 1)
3744         type = getContainedTypeId(type);
3745     else if (accessChain.swizzle.size() > 1)
3746         type = makeVectorType(getContainedTypeId(type), (int)accessChain.swizzle.size());
3747
3748     // dereference component selection
3749     if (accessChain.component)
3750         type = getContainedTypeId(type);
3751
3752     return type;
3753 }
3754
3755 void Builder::dump(std::vector<unsigned int>& out) const
3756 {
3757     // Header, before first instructions:
3758     out.push_back(MagicNumber);
3759     out.push_back(spvVersion);
3760     out.push_back(builderNumber);
3761     out.push_back(uniqueId + 1);
3762     out.push_back(0);
3763
3764     // Capabilities
3765     for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it) {
3766         Instruction capInst(0, 0, OpCapability);
3767         capInst.addImmediateOperand(*it);
3768         capInst.dump(out);
3769     }
3770
3771     for (auto it = extensions.cbegin(); it != extensions.cend(); ++it) {
3772         Instruction extInst(0, 0, OpExtension);
3773         extInst.addStringOperand(it->c_str());
3774         extInst.dump(out);
3775     }
3776
3777     dumpInstructions(out, imports);
3778     Instruction memInst(0, 0, OpMemoryModel);
3779     memInst.addImmediateOperand(addressModel);
3780     memInst.addImmediateOperand(memoryModel);
3781     memInst.dump(out);
3782
3783     // Instructions saved up while building:
3784     dumpInstructions(out, entryPoints);
3785     dumpInstructions(out, executionModes);
3786
3787     // Debug instructions
3788     dumpInstructions(out, strings);
3789     dumpSourceInstructions(out);
3790     for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
3791         Instruction sourceExtInst(0, 0, OpSourceExtension);
3792         sourceExtInst.addStringOperand(sourceExtensions[e]);
3793         sourceExtInst.dump(out);
3794     }
3795     dumpInstructions(out, names);
3796     dumpModuleProcesses(out);
3797
3798     // Annotation instructions
3799     dumpInstructions(out, decorations);
3800
3801     dumpInstructions(out, constantsTypesGlobals);
3802     dumpInstructions(out, externals);
3803
3804     // The functions
3805     module.dump(out);
3806 }
3807
3808 //
3809 // Protected methods.
3810 //
3811
3812 // Turn the described access chain in 'accessChain' into an instruction(s)
3813 // computing its address.  This *cannot* include complex swizzles, which must
3814 // be handled after this is called.
3815 //
3816 // Can generate code.
3817 Id Builder::collapseAccessChain()
3818 {
3819     assert(accessChain.isRValue == false);
3820
3821     // did we already emit an access chain for this?
3822     if (accessChain.instr != NoResult)
3823         return accessChain.instr;
3824
3825     // If we have a dynamic component, we can still transfer
3826     // that into a final operand to the access chain.  We need to remap the
3827     // dynamic component through the swizzle to get a new dynamic component to
3828     // update.
3829     //
3830     // This was not done in transferAccessChainSwizzle() because it might
3831     // generate code.
3832     remapDynamicSwizzle();
3833     if (accessChain.component != NoResult) {
3834         // transfer the dynamic component to the access chain
3835         accessChain.indexChain.push_back(accessChain.component);
3836         accessChain.component = NoResult;
3837     }
3838
3839     // note that non-trivial swizzling is left pending
3840
3841     // do we have an access chain?
3842     if (accessChain.indexChain.size() == 0)
3843         return accessChain.base;
3844
3845     // emit the access chain
3846     StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
3847     accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
3848
3849     return accessChain.instr;
3850 }
3851
3852 // For a dynamic component selection of a swizzle.
3853 //
3854 // Turn the swizzle and dynamic component into just a dynamic component.
3855 //
3856 // Generates code.
3857 void Builder::remapDynamicSwizzle()
3858 {
3859     // do we have a swizzle to remap a dynamic component through?
3860     if (accessChain.component != NoResult && accessChain.swizzle.size() > 1) {
3861         // build a vector of the swizzle for the component to map into
3862         std::vector<Id> components;
3863         for (int c = 0; c < (int)accessChain.swizzle.size(); ++c)
3864             components.push_back(makeUintConstant(accessChain.swizzle[c]));
3865         Id mapType = makeVectorType(makeUintType(32), (int)accessChain.swizzle.size());
3866         Id map = makeCompositeConstant(mapType, components);
3867
3868         // use it
3869         accessChain.component = createVectorExtractDynamic(map, makeUintType(32), accessChain.component);
3870         accessChain.swizzle.clear();
3871     }
3872 }
3873
3874 // clear out swizzle if it is redundant, that is reselecting the same components
3875 // that would be present without the swizzle.
3876 void Builder::simplifyAccessChainSwizzle()
3877 {
3878     // If the swizzle has fewer components than the vector, it is subsetting, and must stay
3879     // to preserve that fact.
3880     if (getNumTypeComponents(accessChain.preSwizzleBaseType) > (int)accessChain.swizzle.size())
3881         return;
3882
3883     // if components are out of order, it is a swizzle
3884     for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
3885         if (i != accessChain.swizzle[i])
3886             return;
3887     }
3888
3889     // otherwise, there is no need to track this swizzle
3890     accessChain.swizzle.clear();
3891     if (accessChain.component == NoResult)
3892         accessChain.preSwizzleBaseType = NoType;
3893 }
3894
3895 // To the extent any swizzling can become part of the chain
3896 // of accesses instead of a post operation, make it so.
3897 // If 'dynamic' is true, include transferring the dynamic component,
3898 // otherwise, leave it pending.
3899 //
3900 // Does not generate code. just updates the access chain.
3901 void Builder::transferAccessChainSwizzle(bool dynamic)
3902 {
3903     // non existent?
3904     if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
3905         return;
3906
3907     // too complex?
3908     // (this requires either a swizzle, or generating code for a dynamic component)
3909     if (accessChain.swizzle.size() > 1)
3910         return;
3911
3912     // single component, either in the swizzle and/or dynamic component
3913     if (accessChain.swizzle.size() == 1) {
3914         assert(accessChain.component == NoResult);
3915         // handle static component selection
3916         accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
3917         accessChain.swizzle.clear();
3918         accessChain.preSwizzleBaseType = NoType;
3919     } else if (dynamic && accessChain.component != NoResult) {
3920         assert(accessChain.swizzle.size() == 0);
3921         // handle dynamic component
3922         accessChain.indexChain.push_back(accessChain.component);
3923         accessChain.preSwizzleBaseType = NoType;
3924         accessChain.component = NoResult;
3925     }
3926 }
3927
3928 // Utility method for creating a new block and setting the insert point to
3929 // be in it. This is useful for flow-control operations that need a "dummy"
3930 // block proceeding them (e.g. instructions after a discard, etc).
3931 void Builder::createAndSetNoPredecessorBlock(const char* /*name*/)
3932 {
3933     Block* block = new Block(getUniqueId(), buildPoint->getParent());
3934     block->setUnreachable();
3935     buildPoint->getParent().addBlock(block);
3936     setBuildPoint(block);
3937
3938     // if (name)
3939     //    addName(block->getId(), name);
3940 }
3941
3942 // Comments in header
3943 void Builder::createBranch(Block* block)
3944 {
3945     Instruction* branch = new Instruction(OpBranch);
3946     branch->addIdOperand(block->getId());
3947     buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));
3948     block->addPredecessor(buildPoint);
3949 }
3950
3951 void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
3952 {
3953     Instruction* merge = new Instruction(OpSelectionMerge);
3954     merge->addIdOperand(mergeBlock->getId());
3955     merge->addImmediateOperand(control);
3956     buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
3957 }
3958
3959 void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
3960                               const std::vector<unsigned int>& operands)
3961 {
3962     Instruction* merge = new Instruction(OpLoopMerge);
3963     merge->addIdOperand(mergeBlock->getId());
3964     merge->addIdOperand(continueBlock->getId());
3965     merge->addImmediateOperand(control);
3966     for (int op = 0; op < (int)operands.size(); ++op)
3967         merge->addImmediateOperand(operands[op]);
3968     buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
3969 }
3970
3971 void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock)
3972 {
3973     Instruction* branch = new Instruction(OpBranchConditional);
3974     branch->addIdOperand(condition);
3975     branch->addIdOperand(thenBlock->getId());
3976     branch->addIdOperand(elseBlock->getId());
3977     buildPoint->addInstruction(std::unique_ptr<Instruction>(branch));
3978     thenBlock->addPredecessor(buildPoint);
3979     elseBlock->addPredecessor(buildPoint);
3980 }
3981
3982 // OpSource
3983 // [OpSourceContinued]
3984 // ...
3985 void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& text,
3986                                      std::vector<unsigned int>& out) const
3987 {
3988     const int maxWordCount = 0xFFFF;
3989     const int opSourceWordCount = 4;
3990     const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1;
3991
3992     if (sourceLang != SourceLanguageUnknown) {
3993         // OpSource Language Version File Source
3994         Instruction sourceInst(NoResult, NoType, OpSource);
3995         sourceInst.addImmediateOperand(sourceLang);
3996         sourceInst.addImmediateOperand(sourceVersion);
3997         // File operand
3998         if (fileId != NoResult) {
3999             sourceInst.addIdOperand(fileId);
4000             // Source operand
4001             if (text.size() > 0) {
4002                 int nextByte = 0;
4003                 std::string subString;
4004                 while ((int)text.size() - nextByte > 0) {
4005                     subString = text.substr(nextByte, nonNullBytesPerInstruction);
4006                     if (nextByte == 0) {
4007                         // OpSource
4008                         sourceInst.addStringOperand(subString.c_str());
4009                         sourceInst.dump(out);
4010                     } else {
4011                         // OpSourcContinued
4012                         Instruction sourceContinuedInst(OpSourceContinued);
4013                         sourceContinuedInst.addStringOperand(subString.c_str());
4014                         sourceContinuedInst.dump(out);
4015                     }
4016                     nextByte += nonNullBytesPerInstruction;
4017                 }
4018             } else
4019                 sourceInst.dump(out);
4020         } else
4021             sourceInst.dump(out);
4022     }
4023 }
4024
4025 // Dump an OpSource[Continued] sequence for the source and every include file
4026 void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
4027 {
4028     if (emitNonSemanticShaderDebugInfo) return;
4029     dumpSourceInstructions(sourceFileStringId, sourceText, out);
4030     for (auto iItr = includeFiles.begin(); iItr != includeFiles.end(); ++iItr)
4031         dumpSourceInstructions(iItr->first, *iItr->second, out);
4032 }
4033
4034 void Builder::dumpInstructions(std::vector<unsigned int>& out,
4035     const std::vector<std::unique_ptr<Instruction> >& instructions) const
4036 {
4037     for (int i = 0; i < (int)instructions.size(); ++i) {
4038         instructions[i]->dump(out);
4039     }
4040 }
4041
4042 void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
4043 {
4044     for (int i = 0; i < (int)moduleProcesses.size(); ++i) {
4045         Instruction moduleProcessed(OpModuleProcessed);
4046         moduleProcessed.addStringOperand(moduleProcesses[i]);
4047         moduleProcessed.dump(out);
4048     }
4049 }
4050
4051 }; // end spv namespace