10e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===- SPIRVModule.cpp - Class to represent SPIR-V module --------*- C++ -*-===//
20e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
30e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//                     The LLVM/SPIRV Translator
40e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
50e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// This file is distributed under the University of Illinois Open Source
60e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// License. See LICENSE.TXT for details.
70e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
80e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
90e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Permission is hereby granted, free of charge, to any person obtaining a
110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// copy of this software and associated documentation files (the "Software"),
120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// to deal with the Software without restriction, including without limitation
130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// the rights to use, copy, modify, merge, publish, distribute, sublicense,
140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// and/or sell copies of the Software, and to permit persons to whom the
150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Software is furnished to do so, subject to the following conditions:
160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Redistributions of source code must retain the above copyright notice,
180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// this list of conditions and the following disclaimers.
190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Redistributions in binary form must reproduce the above copyright notice,
200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// this list of conditions and the following disclaimers in the documentation
210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// and/or other materials provided with the distribution.
220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Neither the names of Advanced Micro Devices, Inc., nor the names of its
230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// contributors may be used to endorse or promote products derived from this
240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Software without specific prior written permission.
250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// THE SOFTWARE.
320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//
330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===----------------------------------------------------------------------===//
340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \file
350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///
360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// This file implements Module class for SPIR-V.
370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///
380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===----------------------------------------------------------------------===//
390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVModule.h"
410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVDebug.h"
420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVEntry.h"
430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVType.h"
440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVValue.h"
450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVExtInst.h"
460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVFunction.h"
470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVInstruction.h"
480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVStream.h"
490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <set>
510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <unordered_map>
520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <unordered_set>
530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace SPIRV{
550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModule::SPIRVModule():AutoAddCapability(true), ValidateCapability(false)
570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung{}
580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModule::~SPIRVModule()
600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung{}
610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVModuleImpl : public SPIRVModule {
630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungpublic:
64a4eb334c79d78bbd63feff3780572f4213f82abaDavid Gross  SPIRVModuleImpl():SPIRVModule(), NextId(1),
650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVVersion(SPIRV_1_0),
660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    GeneratorId(SPIRVGEN_KhronosLLVMSPIRVTranslator),
670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    GeneratorVer(0),
680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    InstSchema(SPIRVISCH_Default),
690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SrcLang(SourceLanguageOpenCL_C),
700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SrcLangVer(102000),
710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    MemoryModel(MemoryModelOpenCL){
720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    AddrModel = sizeof(size_t) == 32 ? AddressingModelPhysical32
730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        : AddressingModelPhysical64;
740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  };
750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual ~SPIRVModuleImpl();
760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Object query functions
780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool exist(SPIRVId) const;
790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool exist(SPIRVId, SPIRVEntry **) const;
800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId getId(SPIRVId Id = SPIRVID_INVALID, unsigned Increment = 1);
810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVEntry *getEntry(SPIRVId Id) const;
820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool hasDebugInfo() const { return !LineVec.empty();}
830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Error handling functions
850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVErrorLog &getErrorLog() { return ErrLog;}
860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVErrorCode getError(std::string &ErrMsg) { return ErrLog.getError(ErrMsg);}
870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Module query functions
890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVAddressingModelKind getAddressingModel() { return AddrModel;}
900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVExtInstSetKind getBuiltinSet(SPIRVId SetId) const;
910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const SPIRVCapMap &getCapability() const { return CapMap; }
920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool hasCapability(SPIRVCapabilityKind Cap) const {
930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return CapMap.find(Cap) != CapMap.end();
940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<std::string> &getExtension() { return SPIRVExt;}
960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVFunction *getFunction(unsigned I) const { return FuncVec[I];}
970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVVariable *getVariable(unsigned I) const { return VariableVec[I];}
980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *getValue(SPIRVId TheId) const;
990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual std::vector<SPIRVValue *> getValues(const std::vector<SPIRVId>&)const;
1000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual std::vector<SPIRVId> getIds(const std::vector<SPIRVEntry *>&)const;
1010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual std::vector<SPIRVId> getIds(const std::vector<SPIRVValue *>&)const;
1020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVType *getValueType(SPIRVId TheId)const;
1030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual std::vector<SPIRVType *> getValueTypes(const std::vector<SPIRVId>&)
1040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const;
1050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVMemoryModelKind getMemoryModel() const { return MemoryModel;}
1060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVConstant* getLiteralAsConstant(unsigned Literal);
1070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned getNumEntryPoints(SPIRVExecutionModelKind EM) const {
1080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto Loc = EntryPointVec.find(EM);
1090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == EntryPointVec.end())
1100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return 0;
1110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Loc->second.size();
1120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
1130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVFunction *getEntryPoint(SPIRVExecutionModelKind EM, unsigned I) const {
1140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto Loc = EntryPointVec.find(EM);
1150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == EntryPointVec.end())
1160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return nullptr;
1170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(I < Loc->second.size());
1180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return get<SPIRVFunction>(Loc->second[I]);
1190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
1200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned getNumFunctions() const { return FuncVec.size();}
1210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned getNumVariables() const { return VariableVec.size();}
1220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SourceLanguage getSourceLanguage(SPIRVWord * Ver = nullptr) const {
1230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Ver)
1240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      *Ver = SrcLangVer;
1250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return SrcLang;
1260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
1270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<std::string> &getSourceExtension() { return SrcExtension;}
1280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isEntryPoint(SPIRVExecutionModelKind, SPIRVId EP) const;
1290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned short getGeneratorId() const { return GeneratorId; }
1300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned short getGeneratorVer() const { return GeneratorVer; }
1310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVWord getSPIRVVersion() const { return SPIRVVersion; }
1320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Module changing functions
1340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool importBuiltinSet(const std::string &, SPIRVId *);
1350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool importBuiltinSetWithId(const std::string &, SPIRVId);
1360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void optimizeDecorates();
1370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setAddressingModel(SPIRVAddressingModelKind AM) { AddrModel = AM;}
1380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setAlignment(SPIRVValue *, SPIRVWord);
1390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setMemoryModel(SPIRVMemoryModelKind MM) {
1400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    MemoryModel = MM;
1410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (MemoryModel == spv::MemoryModelOpenCL)
1420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      addCapability(CapabilityKernel);
1430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
1440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setName(SPIRVEntry *E, const std::string &Name);
1450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setSourceLanguage(SourceLanguage Lang, SPIRVWord Ver) {
1460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SrcLang = Lang;
1470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SrcLangVer = Ver;
1480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
1490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setGeneratorId(unsigned short Id) { GeneratorId = Id; }
1500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setGeneratorVer(unsigned short Ver) { GeneratorVer = Ver; }
1510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void resolveUnknownStructFields();
1520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setSPIRVVersion(SPIRVWord Ver) override { SPIRVVersion = Ver; }
1540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Object creation functions
1560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  template<class T> void addTo(std::vector<T *> &V, SPIRVEntry *E);
1570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVEntry *addEntry(SPIRVEntry *E);
1580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVBasicBlock *addBasicBlock(SPIRVFunction *, SPIRVId);
1590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVString *getString(const std::string &Str);
1600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVMemberName *addMemberName(SPIRVTypeStruct *ST,
1610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVWord MemberNumber, const std::string &Name);
1620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void addUnknownStructField(SPIRVTypeStruct *Struct, unsigned I,
1630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                                     SPIRVId ID);
1640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVLine *addLine(SPIRVEntry *E, SPIRVString *FileName, SPIRVWord Line,
1650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVWord Column);
1660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void addCapability(SPIRVCapabilityKind);
1670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void addCapabilityInternal(SPIRVCapabilityKind);
1680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual const SPIRVDecorateGeneric *addDecorate(const SPIRVDecorateGeneric *);
1690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVDecorationGroup *addDecorationGroup();
1700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVDecorationGroup *addDecorationGroup(SPIRVDecorationGroup *Group);
1710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVGroupDecorate *addGroupDecorate(SPIRVDecorationGroup *Group,
1720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVEntry *> &Targets);
1730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVGroupDecorateGeneric *addGroupDecorateGeneric(
1740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVGroupDecorateGeneric *GDec);
1750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVGroupMemberDecorate *addGroupMemberDecorate(
1760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVDecorationGroup *Group, const std::vector<SPIRVEntry *> &Targets);
1770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void addEntryPoint(SPIRVExecutionModelKind ExecModel,
1780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVId EntryPoint);
1790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVForward *addForward(SPIRVType *Ty);
1800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVForward *addForward(SPIRVId, SPIRVType *Ty);
1810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVFunction *addFunction(SPIRVFunction *);
1820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVFunction *addFunction(SPIRVTypeFunction *, SPIRVId);
1830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVEntry *replaceForward(SPIRVForward *, SPIRVEntry *);
1840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Type creation functions
1860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  template<class T> T * addType(T *Ty);
1870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeArray *addArrayType(SPIRVType *, SPIRVConstant *);
1880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeBool *addBoolType();
1890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeFloat *addFloatType(unsigned BitWidth);
1900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeFunction *addFunctionType(SPIRVType *,
1910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVType *> &);
1920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeInt *addIntegerType(unsigned BitWidth);
1930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeOpaque *addOpaqueType(const std::string &);
1940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypePointer *addPointerType(SPIRVStorageClassKind, SPIRVType *);
1950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeImage *addImageType(SPIRVType *,
1960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const SPIRVTypeImageDescriptor &);
1970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeImage *addImageType(SPIRVType *,
1980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const SPIRVTypeImageDescriptor &, SPIRVAccessQualifierKind);
1990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeSampler *addSamplerType();
2000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypePipeStorage *addPipeStorageType();
2010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeSampledImage *addSampledImageType(SPIRVTypeImage *T);
2020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeStruct *openStructType(unsigned, const std::string &);
2030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void closeStructType(SPIRVTypeStruct *T, bool);
2040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeVector *addVectorType(SPIRVType *, SPIRVWord);
2050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVType *addOpaqueGenericType(Op);
2060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeDeviceEvent *addDeviceEventType();
2070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeQueue *addQueueType();
2080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypePipe *addPipeType();
2090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVTypeVoid *addVoidType();
2100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void createForwardPointers();
2110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Constant creation functions
2130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addBranchInst(SPIRVLabel *, SPIRVBasicBlock *);
2140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addBranchConditionalInst(SPIRVValue *, SPIRVLabel *,
2150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVLabel *, SPIRVBasicBlock *);
2160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addCompositeConstant(SPIRVType *,
2170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVValue*>&);
2180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addConstant(SPIRVValue *);
2190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addConstant(SPIRVType *, uint64_t);
2200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addDoubleConstant(SPIRVTypeFloat *, double);
2210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addFloatConstant(SPIRVTypeFloat *, float);
2220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addIntegerConstant(SPIRVTypeInt *, uint64_t);
2230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addNullConstant(SPIRVType *);
2240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addUndef(SPIRVType *TheType);
2250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addSamplerConstant(SPIRVType *TheType, SPIRVWord AddrMode,
2260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVWord ParametricMode, SPIRVWord FilterMode);
2270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue* addPipeStorageConstant(SPIRVType* TheType,
2280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord PacketSize, SPIRVWord PacketAlign, SPIRVWord Capacity);
2290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Instruction creation functions
2310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, SPIRVValue *,
2320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      std::vector<SPIRVValue *>, SPIRVBasicBlock *, bool);
2330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addAsyncGroupCopy(SPIRVValue *Scope,
2340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *Dest, SPIRVValue *Src, SPIRVValue *NumElems, SPIRVValue *Stride,
2350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *Event, SPIRVBasicBlock *BB);
2360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addExtInst(SPIRVType *,
2370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVWord, SPIRVWord, const std::vector<SPIRVWord> &,
2380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addExtInst(SPIRVType *,
2400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVWord, SPIRVWord, const std::vector<SPIRVValue *> &,
2410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addBinaryInst(Op, SPIRVType *, SPIRVValue *,
2430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *, SPIRVBasicBlock *);
2440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCallInst(SPIRVFunction*,
2450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVWord> &, SPIRVBasicBlock *);
2460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCmpInst(Op, SPIRVType *, SPIRVValue *,
2470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *, SPIRVBasicBlock *);
2480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addLoadInst(SPIRVValue *,
2490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVWord>&, SPIRVBasicBlock *);
2500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addPhiInst(SPIRVType *, std::vector<SPIRVValue *>,
2510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCompositeExtractInst(SPIRVType *, SPIRVValue *,
2530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVWord>&, SPIRVBasicBlock *);
2540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCompositeInsertInst(SPIRVValue *Object,
2550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *Composite, const std::vector<SPIRVWord>& Indices,
2560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *BB);
2570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCopyObjectInst(SPIRVType *TheType,
2580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *Operand, SPIRVBasicBlock *BB);
2590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCopyMemoryInst(SPIRVValue *, SPIRVValue *,
2600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord>&, SPIRVBasicBlock *);
2610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addCopyMemorySizedInst(SPIRVValue *, SPIRVValue *,
2620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *, const std::vector<SPIRVWord>&, SPIRVBasicBlock *);
2630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addControlBarrierInst(
2640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *ExecKind, SPIRVValue *MemKind,
2650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *MemSema, SPIRVBasicBlock *BB);
2660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addGroupInst(Op OpCode, SPIRVType *Type,
2670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Scope Scope, const std::vector<SPIRVValue *> &Ops,
2680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *BB);
2690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addInstruction(SPIRVInstruction *Inst,
2700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *BB);
2710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstTemplateBase *addInstTemplate(Op OC,
2720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock* BB, SPIRVType *Ty);
2730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstTemplateBase *addInstTemplate(Op OC,
2740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVWord>& Ops, SPIRVBasicBlock* BB, SPIRVType *Ty);
2750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addMemoryBarrierInst(
2760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Scope ScopeKind, SPIRVWord MemFlag, SPIRVBasicBlock *BB);
2770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addReturnInst(SPIRVBasicBlock *);
2780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addReturnValueInst(SPIRVValue *, SPIRVBasicBlock *);
2790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addSelectInst(SPIRVValue *, SPIRVValue *, SPIRVValue *,
2800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addStoreInst(SPIRVValue *, SPIRVValue *,
2820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<SPIRVWord>&, SPIRVBasicBlock *);
2830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addSwitchInst(SPIRVValue *, SPIRVBasicBlock *,
2840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      const std::vector<std::pair<SPIRVWord, SPIRVBasicBlock *>>&,
2850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addUnaryInst(Op, SPIRVType *, SPIRVValue *,
2870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *);
2880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addVariable(SPIRVType *, bool, SPIRVLinkageTypeKind,
2890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *, const std::string &, SPIRVStorageClassKind, SPIRVBasicBlock *);
2900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVValue *addVectorShuffleInst(SPIRVType *Type, SPIRVValue *Vec1,
2910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *Vec2, const std::vector<SPIRVWord> &Components,
2920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVBasicBlock *BB);
2930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addVectorExtractDynamicInst(SPIRVValue *,
2940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVValue *, SPIRVBasicBlock *);
2950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual SPIRVInstruction *addVectorInsertDynamicInst(SPIRVValue *,
2960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *, SPIRVValue*, SPIRVBasicBlock *);
2970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // I/O functions
2990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  friend spv_ostream & operator<<(spv_ostream &O, SPIRVModule& M);
3000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  friend std::istream & operator>>(std::istream &I, SPIRVModule& M);
3010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungprivate:
3030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVErrorLog ErrLog;
3040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId NextId;
3050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVWord SPIRVVersion;
3060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned short GeneratorId;
3070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned short GeneratorVer;
3080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVInstructionSchemaKind InstSchema;
3090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SourceLanguage SrcLang;
3100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVWord SrcLangVer;
3110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<std::string> SrcExtension;
3120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<std::string> SPIRVExt;
3130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVAddressingModelKind AddrModel;
3140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVMemoryModelKind MemoryModel;
3150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVId, SPIRVEntry *> SPIRVIdToEntryMap;
3170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVEntry *> SPIRVEntryVector;
3180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::set<SPIRVId> SPIRVIdSet;
3190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVId> SPIRVIdVec;
3200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVFunction *> SPIRVFunctionVector;
3210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVTypeForwardPointer *> SPIRVForwardPointerVec;
3220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVType *> SPIRVTypeVec;
3230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVValue *> SPIRVConstantVector;
3240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVVariable *> SPIRVVariableVec;
3250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVString *> SPIRVStringVec;
3260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVMemberName *> SPIRVMemberNameVec;
3270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVLine *> SPIRVLineVec;
3280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVDecorationGroup *> SPIRVDecGroupVec;
3290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVGroupDecorateGeneric *> SPIRVGroupDecVec;
3300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVId, SPIRVExtInstSetKind> SPIRVIdToBuiltinSetMap;
3310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVExecutionModelKind, SPIRVIdSet> SPIRVExecModelIdSetMap;
3320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVExecutionModelKind, SPIRVIdVec> SPIRVExecModelIdVecMap;
3330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::unordered_map<std::string, SPIRVString*> SPIRVStringMap;
3340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVTypeStruct *, std::vector<std::pair<unsigned, SPIRVId>>>
3350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVUnknownStructFieldMap;
3360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVForwardPointerVec ForwardPointerVec;
3380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVTypeVec TypeVec;
3390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVIdToEntryMap IdEntryMap;
3400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVFunctionVector FuncVec;
3410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVConstantVector ConstVec;
3420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVVariableVec VariableVec;
3430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVEntryVector EntryNoId;         // Entries without id
3440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVIdToBuiltinSetMap IdBuiltinMap;
3450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVIdSet NamedId;
3460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVStringVec StringVec;
3470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVMemberNameVec MemberNameVec;
3480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVLineVec LineVec;
3490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDecorateSet DecorateSet;
3500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDecGroupVec DecGroupVec;
3510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVGroupDecVec GroupDecVec;
3520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVExecModelIdSetMap EntryPointSet;
3530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVExecModelIdVecMap EntryPointVec;
3540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVStringMap StrMap;
3550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVCapMap CapMap;
3560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVUnknownStructFieldMap UnknownStructFieldMap;
3570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::map<unsigned, SPIRVTypeInt*> IntTypeMap;
3580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::map<unsigned, SPIRVConstant*> LiteralMap;
3590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void layoutEntry(SPIRVEntry* Entry);
3610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
3620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::~SPIRVModuleImpl() {
3640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //ToDo: Fix bug causing crash
3650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //for (auto I:IdEntryMap)
3660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //  delete I.second;
3670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // ToDo: Fix bug causing crash
3690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //for (auto I:EntryNoId) {
3700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //  bildbgs() << "[delete] " << *I;
3710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //  delete I;
3720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  //}
3730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto C : CapMap)
3750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    delete C.second;
3760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVLine*
3790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addLine(SPIRVEntry* E, SPIRVString* FileName,
3800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord Line, SPIRVWord Column) {
3810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto L = add(new SPIRVLine(E, FileName->getId(), Line, Column));
3820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  E->setLine(L);
3830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return L;
3840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Creates decoration group and group decorates from decorates shared by
3870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// multiple targets.
3880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
3890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::optimizeDecorates() {
3900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDBG(spvdbgs() << "[optimizeDecorates] begin\n");
3910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto I = DecorateSet.begin(), E = DecorateSet.end(); I != E;) {
3920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto D = *I;
3930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVDBG(spvdbgs() << "  check " << *D << '\n');
3940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (D->getOpCode() == OpMemberDecorate) {
3950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      ++I;
3960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      continue;
3970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
3980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto ER = DecorateSet.equal_range(D);
3990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVDBG(spvdbgs() << "  equal range " << **ER.first
4000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                      << " to ";
4010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung            if (ER.second != DecorateSet.end())
4020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung              spvdbgs() << **ER.second;
4030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung            else
4040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung              spvdbgs() << "end";
4050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung            spvdbgs() << '\n');
4060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (std::distance(ER.first, ER.second) < 2) {
4070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      I = ER.second;
4080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVDBG(spvdbgs() << "  skip equal range \n");
4090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      continue;
4100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
4110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVDBG(spvdbgs() << "  add deco group. erase equal range\n");
4120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto G = new SPIRVDecorationGroup(this, getId());
4130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::vector<SPIRVId> Targets;
4140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Targets.push_back(D->getTargetId());
4150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const_cast<SPIRVDecorateGeneric*>(D)->setTargetId(G->getId());
4160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    G->getDecorations().insert(D);
4170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (I = ER.first; I != ER.second; ++I) {
4180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto E = *I;
4190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (*E == *D)
4200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        continue;
4210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Targets.push_back(E->getTargetId());
4220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
4230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // WordCount is only 16 bits.  We can only have 65535 - FixedWC targtets per
4250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // group.
4260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // For now, just skip using a group if the number of targets to too big
4270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Targets.size() < 65530) {
4280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      DecorateSet.erase(ER.first, ER.second);
4290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto GD = new SPIRVGroupDecorate(G, Targets);
4300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      DecGroupVec.push_back(G);
4310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      GroupDecVec.push_back(GD);
4320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
4330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue*
4370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addSamplerConstant(SPIRVType* TheType,
4380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord AddrMode, SPIRVWord ParametricMode, SPIRVWord FilterMode) {
4390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstantSampler(this, TheType, getId(), AddrMode,
4400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      ParametricMode, FilterMode));
4410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue*
4440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPipeStorageConstant(SPIRVType* TheType,
4450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord PacketSize, SPIRVWord PacketAlign, SPIRVWord Capacity) {
4460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstantPipeStorage(this, TheType, getId(),
4470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    PacketSize, PacketAlign, Capacity));
4480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
4510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCapability(SPIRVCapabilityKind Cap) {
4520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addCapabilities(SPIRV::getCapability(Cap));
4530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDBG(spvdbgs() << "addCapability: " << Cap << '\n');
4540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (hasCapability(Cap))
4550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return;
4560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CapMap.insert(std::make_pair(Cap, new SPIRVCapability(this, Cap)));
4580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
4610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCapabilityInternal(SPIRVCapabilityKind Cap) {
4620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (AutoAddCapability) {
4630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (hasCapability(Cap))
4640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return;
4650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    CapMap.insert(std::make_pair(Cap, new SPIRVCapability(this, Cap)));
4670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVConstant*
4710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getLiteralAsConstant(unsigned Literal) {
4720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Loc = LiteralMap.find(Literal);
4730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Loc != LiteralMap.end())
4740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Loc->second;
4750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Ty = addIntegerType(32);
4760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto V = new SPIRVConstant(this, Ty, getId(), static_cast<uint64_t>(Literal));
4770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  LiteralMap[Literal] = V;
4780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addConstant(V);
4790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return V;
4800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
4830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::layoutEntry(SPIRVEntry* E) {
4840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto OC = E->getOpCode();
4850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  switch (OC) {
4860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  case OpString:
4870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    addTo(StringVec, E);
4880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    break;
4890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  case OpMemberName:
4900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    addTo(MemberNameVec, E);
4910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    break;
4920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  case OpLine:
4930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    addTo(LineVec, E);
4940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    break;
4950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  case OpVariable: {
4960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto BV = static_cast<SPIRVVariable*>(E);
4970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (!BV->getParent())
4980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      addTo(VariableVec, E);
4990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
5000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    break;
5010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  default:
5020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (isTypeOpCode(OC))
5030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TypeVec.push_back(static_cast<SPIRVType*>(E));
5040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    else if (isConstantOpCode(OC))
5050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      ConstVec.push_back(static_cast<SPIRVConstant*>(E));
5060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    break;
5070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
5080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Add an entry to the id to entry map.
5110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Assert if the id is mapped to a different entry.
5120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Certain entries need to be add to specific collectors to maintain
5130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// logic layout of SPIRV.
5140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVEntry *
5150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addEntry(SPIRVEntry *Entry) {
5160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(Entry && "Invalid entry");
5170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Entry->hasId()) {
5180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVId Id = Entry->getId();
5190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(Entry->getId() != SPIRVID_INVALID && "Invalid id");
5200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVEntry *Mapped = nullptr;
5210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (exist(Id, &Mapped)) {
5220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (Mapped->getOpCode() == OpForward) {
5230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        replaceForward(static_cast<SPIRVForward *>(Mapped), Entry);
5240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      } else {
5250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        assert(Mapped == Entry && "Id used twice");
5260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      }
5270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    } else
5280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      IdEntryMap[Id] = Entry;
5290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  } else {
5300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    EntryNoId.push_back(Entry);
5310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
5320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Entry->setModule(this);
5340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  layoutEntry(Entry);
5360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (AutoAddCapability) {
5370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &I:Entry->getRequiredCapability()) {
5380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      addCapability(I);
5390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
5400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
5410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (ValidateCapability) {
5420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &I:Entry->getRequiredCapability()) {
5430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      (void) I;
5440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      assert(CapMap.count(I));
5450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
5460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
5470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Entry;
5480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
5510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::exist(SPIRVId Id) const {
5520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return exist(Id, nullptr);
5530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
5560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::exist(SPIRVId Id, SPIRVEntry **Entry) const {
5570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (Id != SPIRVID_INVALID && "Invalid Id");
5580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVIdToEntryMap::const_iterator Loc = IdEntryMap.find(Id);
5590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Loc == IdEntryMap.end())
5600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
5610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Entry)
5620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    *Entry = Loc->second;
5630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return true;
5640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// If Id is invalid, returns the next available id.
5670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Otherwise returns the given id and adjust the next available id by increment.
5680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVId
5690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getId(SPIRVId Id, unsigned increment) {
5700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!isValidId(Id))
5710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Id = NextId;
5720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  else
5730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    NextId = std::max(Id, NextId);
5740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  NextId += increment;
5750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Id;
5760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVEntry *
5790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getEntry(SPIRVId Id) const {
5800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (Id != SPIRVID_INVALID && "Invalid Id");
5810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVIdToEntryMap::const_iterator Loc = IdEntryMap.find(Id);
5820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (Loc != IdEntryMap.end() && "Id is not in map");
5830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Loc->second;
5840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVExtInstSetKind
5870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getBuiltinSet(SPIRVId SetId) const {
5880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Loc = IdBuiltinMap.find(SetId);
5890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(Loc != IdBuiltinMap.end() && "Invalid builtin set id");
5900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Loc->second;
5910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
5940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::isEntryPoint(SPIRVExecutionModelKind ExecModel, SPIRVId EP)
5950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const {
5960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(isValid(ExecModel) && "Invalid execution model");
5970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(EP != SPIRVID_INVALID && "Invalid function id");
5980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Loc = EntryPointSet.find(ExecModel);
5990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Loc == EntryPointSet.end())
6000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
6010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Loc->second.count(EP);
6020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Module change functions
6050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
6060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::importBuiltinSet(const std::string& BuiltinSetName,
6070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVId *BuiltinSetId) {
6080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId TmpBuiltinSetId = getId();
6090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!importBuiltinSetWithId(BuiltinSetName, TmpBuiltinSetId))
6100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
6110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (BuiltinSetId)
6120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    *BuiltinSetId = TmpBuiltinSetId;
6130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return true;
6140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
6170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::importBuiltinSetWithId(const std::string& BuiltinSetName,
6180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVId BuiltinSetId) {
6190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVExtInstSetKind BuiltinSet = SPIRVEIS_Count;
6200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVCKRT(SPIRVBuiltinSetNameMap::rfind(BuiltinSetName, &BuiltinSet),
6210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      InvalidBuiltinSetName, "Actual is " + BuiltinSetName);
6220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  IdBuiltinMap[BuiltinSetId] = BuiltinSet;
6230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return true;
6240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
6270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::setAlignment(SPIRVValue *V, SPIRVWord A) {
6280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  V->setAlignment(A);
6290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
6320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::setName(SPIRVEntry *E, const std::string &Name) {
6330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  E->setName(Name);
6340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!E->hasId())
6350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return;
6360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!Name.empty())
6370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    NamedId.insert(E->getId());
6380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  else
6390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    NamedId.erase(E->getId());
6400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid SPIRVModuleImpl::resolveUnknownStructFields() {
6430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &KV : UnknownStructFieldMap) {
6440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto *Struct = KV.first;
6450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &Indices : KV.second) {
6460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      unsigned I = Indices.first;
6470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVId ID = Indices.second;
6480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto Ty = static_cast<SPIRVType *>(getEntry(ID));
6500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Struct->setMemberType(I, Ty);
6510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
6520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
6530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Type creation functions
6560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<class T>
6570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungT *
6580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addType(T *Ty) {
6590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Ty);
6600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!Ty->getName().empty())
6610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    setName(Ty, Ty->getName());
6620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Ty;
6630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeVoid *
6660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVoidType() {
6670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeVoid(this, getId()));
6680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeArray *
6710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addArrayType(SPIRVType *ElementType, SPIRVConstant *Length) {
6720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeArray(this, getId(), ElementType, Length));
6730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeBool *
6760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addBoolType() {
6770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeBool(this, getId()));
6780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeInt *
6810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addIntegerType(unsigned BitWidth) {
6820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Loc = IntTypeMap.find(BitWidth);
6830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Loc != IntTypeMap.end())
6840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Loc->second;
6850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Ty = new SPIRVTypeInt(this, getId(), BitWidth, false);
6860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  IntTypeMap[BitWidth] = Ty;
6870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(Ty);
6880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeFloat *
6910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addFloatType(unsigned BitWidth) {
6920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVTypeFloat *T = addType(new SPIRVTypeFloat(this, getId(), BitWidth));
6930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return T;
6940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
6950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypePointer *
6970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPointerType(SPIRVStorageClassKind StorageClass,
6980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVType *ElementType) {
6990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypePointer(this, getId(), StorageClass,
7000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      ElementType));
7010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeFunction *
7040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addFunctionType(SPIRVType *ReturnType,
7050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVType *>& ParameterTypes) {
7060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeFunction(this, getId(), ReturnType,
7070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      ParameterTypes));
7080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeOpaque*
7110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addOpaqueType(const std::string& Name) {
7120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeOpaque(this, getId(), Name));
7130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeStruct *SPIRVModuleImpl::openStructType(unsigned NumMembers,
7160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                                                 const std::string &Name) {
7170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto T = new SPIRVTypeStruct(this, getId(), NumMembers, Name);
7180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return T;
7190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid SPIRVModuleImpl::closeStructType(SPIRVTypeStruct *T, bool Packed) {
7220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addType(T);
7230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  T->setPacked(Packed);
7240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeVector*
7270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVectorType(SPIRVType* CompType, SPIRVWord CompCount) {
7280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeVector(this, getId(), CompType, CompCount));
7290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVType *
7310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addOpaqueGenericType(Op TheOpCode) {
7320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeOpaqueGeneric(TheOpCode, this, getId()));
7330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeDeviceEvent *
7360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addDeviceEventType() {
7370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeDeviceEvent(this, getId()));
7380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeQueue *
7410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addQueueType() {
7420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeQueue(this, getId()));
7430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypePipe*
7460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPipeType() {
7470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypePipe(this, getId()));
7480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeImage *
7510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addImageType(SPIRVType *SampledType,
7520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const SPIRVTypeImageDescriptor &Desc) {
7530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeImage(this, getId(),
7540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SampledType ? SampledType->getId() : 0, Desc));
7550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeImage *
7580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addImageType(SPIRVType *SampledType,
7590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const SPIRVTypeImageDescriptor &Desc, SPIRVAccessQualifierKind Acc) {
7600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeImage(this, getId(),
7610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SampledType ? SampledType->getId() : 0, Desc, Acc));
7620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeSampler *
7650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addSamplerType() {
7660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeSampler(this, getId()));
7670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypePipeStorage*
7700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPipeStorageType() {
7710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypePipeStorage(this, getId()));
7720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVTypeSampledImage *
7750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addSampledImageType(SPIRVTypeImage *T) {
7760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addType(new SPIRVTypeSampledImage(this, getId(), T));
7770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
7780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid SPIRVModuleImpl::createForwardPointers() {
7800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::unordered_set<SPIRVId> Seen;
7810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto *T : TypeVec) {
7830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (T->hasId())
7840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Seen.insert(T->getId());
7850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (!T->isTypeStruct())
7870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      continue;
7880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto ST = static_cast<SPIRVTypeStruct *>(T);
7900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (unsigned i = 0; i < ST->getStructMemberCount(); ++i) {
7920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto MemberTy = ST->getStructMemberType(i);
7930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (!MemberTy->isTypePointer()) continue;
7940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto Ptr = static_cast<SPIRVTypePointer *>(MemberTy);
7950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (Seen.find(Ptr->getId()) == Seen.end()) {
7970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        ForwardPointerVec.push_back(new SPIRVTypeForwardPointer(
7980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung            this, Ptr, Ptr->getPointerStorageClass()));
7990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      }
8000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
8010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
8020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVFunction *
8050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addFunction(SPIRVFunction *Func) {
8060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  FuncVec.push_back(add(Func));
8070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Func;
8080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVFunction *
8110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addFunction(SPIRVTypeFunction *FuncType, SPIRVId Id) {
8120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addFunction(new SPIRVFunction(this, FuncType,
8130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      getId(Id, FuncType->getNumParameters() + 1)));
8140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVBasicBlock *
8170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addBasicBlock(SPIRVFunction *Func, SPIRVId Id) {
8180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Func->addBasicBlock(new SPIRVBasicBlock(getId(Id), Func));
8190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungconst SPIRVDecorateGeneric *
8220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addDecorate(const SPIRVDecorateGeneric *Dec) {
8230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId Id = Dec->getTargetId();
8240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVEntry *Target = nullptr;
8250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool Found = exist(Id, &Target);
8260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  (void) Found;
8270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (Found && "Decorate target does not exist");
8280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!Dec->getOwner())
8290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    DecorateSet.insert(Dec);
8300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addCapabilities(Dec->getRequiredCapability());
8310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Dec;
8320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
8350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addEntryPoint(SPIRVExecutionModelKind ExecModel,
8360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVId EntryPoint){
8370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(isValid(ExecModel) && "Invalid execution model");
8380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(EntryPoint != SPIRVID_INVALID && "Invalid entry point");
8390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  EntryPointSet[ExecModel].insert(EntryPoint);
8400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  EntryPointVec[ExecModel].push_back(EntryPoint);
8410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addCapabilities(SPIRV::getCapability(ExecModel));
8420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVForward *
8450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addForward(SPIRVType *Ty) {
8460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return add(new SPIRVForward(this, Ty, getId()));
8470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVForward *
8500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addForward(SPIRVId Id, SPIRVType *Ty) {
8510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return add(new SPIRVForward(this, Ty, Id));
8520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVEntry *
8550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::replaceForward(SPIRVForward *Forward, SPIRVEntry *Entry) {
8560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId Id = Entry->getId();
8570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId ForwardId = Forward->getId();
8580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (ForwardId == Id)
8590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IdEntryMap[Id] = Entry;
8600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  else {
8610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto Loc = IdEntryMap.find(Id);
8620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(Loc != IdEntryMap.end());
8630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IdEntryMap.erase(Loc);
8640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Entry->setId(ForwardId);
8650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IdEntryMap[ForwardId] = Entry;
8660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
8670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Annotations include name, decorations, execution modes
8680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Entry->takeAnnotations(Forward);
8690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  delete Forward;
8700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Entry;
8710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
8740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addConstant(SPIRVValue *C) {
8750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return add(C);
8760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
8790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addConstant(SPIRVType *Ty, uint64_t V) {
8800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Ty->isTypeBool()) {
8810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (V)
8820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return addConstant(new SPIRVConstantTrue(this, Ty, getId()));
8830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    else
8840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return addConstant(new SPIRVConstantFalse(this, Ty, getId()));
8850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
8860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Ty->isTypeInt())
8870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return addIntegerConstant(static_cast<SPIRVTypeInt*>(Ty), V);
8880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstant(this, Ty, getId(), V));
8890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
8900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
8920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addIntegerConstant(SPIRVTypeInt *Ty, uint64_t V) {
8930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Ty->getBitWidth() == 32) {
8940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    unsigned I32 = V;
8950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(I32 == V && "Integer value truncated");
8960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return getLiteralAsConstant(I32);
8970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
8980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstant(this, Ty, getId(), V));
8990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
9020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addFloatConstant(SPIRVTypeFloat *Ty, float V) {
9030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstant(this, Ty, getId(), V));
9040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
9070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addDoubleConstant(SPIRVTypeFloat *Ty, double V) {
9080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstant(this, Ty, getId(), V));
9090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
9120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addNullConstant(SPIRVType *Ty) {
9130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstantNull(this, Ty, getId()));
9140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
9170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCompositeConstant(SPIRVType *Ty,
9180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVValue*>& Elements) {
9190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVConstantComposite(this, Ty, getId(), Elements));
9200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
9230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addUndef(SPIRVType *TheType) {
9240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addConstant(new SPIRVUndef(this, TheType, getId()));
9250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Instruction creation functions
9280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addStoreInst(SPIRVValue *Target, SPIRVValue *Source,
9310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord> &TheMemoryAccess, SPIRVBasicBlock *BB) {
9320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return BB->addInstruction(new SPIRVStore(Target->getId(),
9330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Source->getId(), TheMemoryAccess, BB));
9340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addSwitchInst(SPIRVValue *Select, SPIRVBasicBlock *Default,
9380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<std::pair<SPIRVWord, SPIRVBasicBlock *>>& Pairs,
9390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
9400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return BB->addInstruction(new SPIRVSwitch(Select, Default, Pairs, BB));
9410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addGroupInst(Op OpCode, SPIRVType *Type,
9450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Scope Scope, const std::vector<SPIRVValue *> &Ops,
9460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
9470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(!Type || !Type->isTypeVoid());
9480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto WordOps = getIds(Ops);
9490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  WordOps.insert(WordOps.begin(), Scope);
9500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstTemplate(OpCode, WordOps, BB, Type);
9510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addInstruction(SPIRVInstruction *Inst, SPIRVBasicBlock *BB) {
9550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (BB)
9560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return BB->addInstruction(Inst);
9570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Inst->getOpCode() != OpSpecConstantOp)
9580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Inst = createSpecConstantOpInst(Inst);
9590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return static_cast<SPIRVInstruction *>(addConstant(Inst));
9600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addLoadInst(SPIRVValue *Source,
9640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord> &TheMemoryAccess, SPIRVBasicBlock *BB) {
9650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVLoad(getId(), Source->getId(),
9660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheMemoryAccess, BB), BB);
9670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPhiInst(SPIRVType *Type,
9710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::vector<SPIRVValue *> IncomingPairs, SPIRVBasicBlock *BB) {
9720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVPhi(Type, getId(), IncomingPairs, BB), BB);
9730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addExtInst(SPIRVType *TheType, SPIRVWord BuiltinSet,
9770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord EntryPoint, const std::vector<SPIRVWord> &Args,
9780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
9790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVExtInst(TheType, getId(),
9800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      BuiltinSet, EntryPoint, Args, BB), BB);
9810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addExtInst(SPIRVType *TheType, SPIRVWord BuiltinSet,
9850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord EntryPoint, const std::vector<SPIRVValue *> &Args,
9860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
9870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVExtInst(TheType, getId(),
9880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      BuiltinSet, EntryPoint, Args, BB), BB);
9890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction*
9920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCallInst(SPIRVFunction* TheFunction,
9930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord> &TheArguments, SPIRVBasicBlock *BB) {
9940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVFunctionCall(getId(), TheFunction,
9950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheArguments, BB), BB);
9960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
9990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addBinaryInst(Op TheOpCode, SPIRVType *Type,
10000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Op1, SPIRVValue *Op2, SPIRVBasicBlock *BB){
10010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(SPIRVInstTemplateBase::create(TheOpCode, Type, getId(),
10020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      getVec(Op1->getId(), Op2->getId()), BB, this), BB);
10030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addReturnInst(SPIRVBasicBlock *BB) {
10070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVReturn(BB), BB);
10080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addReturnValueInst(SPIRVValue *ReturnValue, SPIRVBasicBlock *BB) {
10120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVReturnValue(ReturnValue, BB), BB);
10130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addUnaryInst(Op TheOpCode, SPIRVType *TheType,
10170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Op, SPIRVBasicBlock *BB) {
10180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(SPIRVInstTemplateBase::create(TheOpCode,
10190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheType, getId(), getVec(Op->getId()), BB, this), BB);
10200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVectorExtractDynamicInst(SPIRVValue *TheVector,
10240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Index, SPIRVBasicBlock *BB) {
10250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVVectorExtractDynamic(getId(), TheVector,
10260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Index, BB), BB);
10270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVectorInsertDynamicInst(SPIRVValue *TheVector,
10310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *TheComponent, SPIRVValue*Index, SPIRVBasicBlock *BB) {
10320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVVectorInsertDynamic(getId(), TheVector,
10330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheComponent, Index, BB), BB);
10340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
10370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVectorShuffleInst(SPIRVType * Type, SPIRVValue *Vec1,
10380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Vec2, const std::vector<SPIRVWord> &Components,
10390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
10400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVVectorShuffle(getId(), Type, Vec1, Vec2,
10410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Components, BB), BB);
10420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addBranchInst(SPIRVLabel *TargetLabel, SPIRVBasicBlock *BB) {
10460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVBranch(TargetLabel, BB), BB);
10470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addBranchConditionalInst(SPIRVValue *Condition,
10510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVLabel *TrueLabel, SPIRVLabel *FalseLabel, SPIRVBasicBlock *BB) {
10520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVBranchConditional(Condition, TrueLabel,
10530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      FalseLabel, BB), BB);
10540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCmpInst(Op TheOpCode, SPIRVType *TheType,
10580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Op1, SPIRVValue *Op2, SPIRVBasicBlock *BB) {
10590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(SPIRVInstTemplateBase::create(TheOpCode,
10600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheType, getId(), getVec(Op1->getId(), Op2->getId()), BB, this), BB);
10610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addControlBarrierInst(SPIRVValue *ExecKind,
10650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *MemKind, SPIRVValue *MemSema, SPIRVBasicBlock *BB) {
10660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(
10670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      new SPIRVControlBarrier(ExecKind, MemKind, MemSema, BB), BB);
10680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addMemoryBarrierInst(Scope ScopeKind,
10720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord MemFlag, SPIRVBasicBlock *BB) {
10730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(SPIRVInstTemplateBase::create(OpMemoryBarrier,
10740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      nullptr, SPIRVID_INVALID,
10750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      getVec(static_cast<SPIRVWord>(ScopeKind), MemFlag), BB, this), BB);
10760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addSelectInst(SPIRVValue *Condition, SPIRVValue *Op1,
10800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Op2, SPIRVBasicBlock *BB) {
10810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVSelect(getId(), Condition->getId(),
10820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Op1->getId(), Op2->getId(), BB), BB);
10830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addPtrAccessChainInst(SPIRVType *Type, SPIRVValue *Base,
10870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::vector<SPIRVValue *> Indices, SPIRVBasicBlock *BB, bool IsInBounds){
10880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(SPIRVInstTemplateBase::create(
10890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IsInBounds?OpInBoundsPtrAccessChain:OpPtrAccessChain,
10900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Type, getId(), getVec(Base->getId(), Base->getIds(Indices)),
10910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BB, this), BB);
10920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
10930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
10940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
10950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addAsyncGroupCopy(SPIRVValue *Scope,
10960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Dest, SPIRVValue *Src, SPIRVValue *NumElems, SPIRVValue *Stride,
10970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Event, SPIRVBasicBlock *BB) {
10980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVGroupAsyncCopy(Scope, getId(), Dest, Src,
10990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    NumElems, Stride, Event, BB), BB);
11000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
11030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCompositeExtractInst(SPIRVType *Type, SPIRVValue *TheVector,
11040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord>& Indices, SPIRVBasicBlock *BB) {
11050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVCompositeExtract(Type, getId(), TheVector,
11060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Indices, BB), BB);
11070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
11100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCompositeInsertInst(SPIRVValue *Object,
11110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *Composite, const std::vector<SPIRVWord>& Indices,
11120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
11130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVCompositeInsert(getId(), Object, Composite,
11140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Indices, BB), BB);
11150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
11180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCopyObjectInst(SPIRVType *TheType, SPIRVValue *Operand,
11190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
11200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVCopyObject(TheType, getId(), Operand, BB), BB);
11210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
11250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCopyMemoryInst(SPIRVValue *TheTarget, SPIRVValue *TheSource,
11260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord> &TheMemoryAccess, SPIRVBasicBlock *BB) {
11270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVCopyMemory(TheTarget, TheSource,
11280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TheMemoryAccess, BB), BB);
11290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction *
11320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addCopyMemorySizedInst(SPIRVValue *TheTarget,
11330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVValue *TheSource, SPIRVValue *TheSize,
11340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord> &TheMemoryAccess, SPIRVBasicBlock *BB) {
11350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addInstruction(new SPIRVCopyMemorySized(TheTarget, TheSource, TheSize,
11360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    TheMemoryAccess, BB), BB);
11370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstruction*
11400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addVariable(SPIRVType *Type, bool IsConstant,
11410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVLinkageTypeKind LinkageType, SPIRVValue *Initializer,
11420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::string &Name, SPIRVStorageClassKind StorageClass,
11430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock *BB) {
11440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVVariable *Variable = new SPIRVVariable(Type, getId(), Initializer,
11450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Name, StorageClass, BB, this);
11460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (BB)
11470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return addInstruction(Variable, BB);
11480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Variable);
11500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (LinkageType != LinkageTypeInternal)
11510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Variable->setLinkageType(LinkageType);
11520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Variable->setIsConstant(IsConstant);
11530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Variable;
11540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<class T>
11570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungspv_ostream &
11580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungoperator<< (spv_ostream &O, const std::vector<T *>& V) {
11590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I: V)
11600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O << *I;
11610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return O;
11620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<class T, class B>
11650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungspv_ostream &
11660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungoperator<< (spv_ostream &O, const std::multiset<T *, B>& V) {
11670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I: V)
11680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O << *I;
11690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return O;
11700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
11710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// To satisfy SPIR-V spec requirement:
11730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// "All operands must be declared before being used",
11740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// we do DFS based topological sort
11750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
11760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass TopologicalSort {
11770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  enum DFSState : char {
11780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Unvisited,
11790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Discovered,
11800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Visited
11810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  };
11820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVType *> SPIRVTypeVec;
11830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVValue *> SPIRVConstantVector;
11840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVVariable *> SPIRVVariableVec;
11850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::vector<SPIRVTypeForwardPointer *> SPIRVForwardPointerVec;
11860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::function<bool(SPIRVEntry*, SPIRVEntry*)> IdComp;
11870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  typedef std::map<SPIRVEntry*, DFSState, IdComp> EntryStateMapTy;
11880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVTypeVec TypeIntVec;
11900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVConstantVector ConstIntVec;
11910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVTypeVec TypeVec;
11920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVConstantVector ConstVec;
11930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVVariableVec VariableVec;
11940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const SPIRVForwardPointerVec& ForwardPointerVec;
11950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  EntryStateMapTy EntryStateMap;
11960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  friend spv_ostream & operator<<(spv_ostream &O, const TopologicalSort &S);
11980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
11990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// This method implements recursive depth-first search among all Entries in
12000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// EntryStateMap. Traversing entries and adding them to corresponding container
12010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// after visiting all dependent entries(post-order traversal) guarantees that
12020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// the entry's operands will appear in the container before the entry itslef.
12030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void visit(SPIRVEntry* E) {
12040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    DFSState& State = EntryStateMap[E];
12050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(State != Discovered && "Cyclic dependency detected");
12060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (State == Visited)
12070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return;
12080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    State = Discovered;
12090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (SPIRVEntry *Op : E->getNonLiteralOperands()) {
12100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      auto Comp = [&Op](SPIRVTypeForwardPointer *FwdPtr) {
12110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        return FwdPtr->getPointer() == Op;
12120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      };
12130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      // Skip forward referenced pointers
12140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (Op->getOpCode() == OpTypePointer &&
12150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          find_if(ForwardPointerVec.begin(), ForwardPointerVec.end(), Comp) !=
12160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          ForwardPointerVec.end())
12170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        continue;
12180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      visit(Op);
12190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    }
12200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    State = Visited;
12210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Op OC = E->getOpCode();
12220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (OC == OpTypeInt)
12230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TypeIntVec.push_back(static_cast<SPIRVType*>(E));
12240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    else if (isConstantOpCode(OC)) {
12250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      SPIRVConstant *C = static_cast<SPIRVConstant*>(E);
12260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (C->getType()->isTypeInt())
12270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        ConstIntVec.push_back(C);
12280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      else
12290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        ConstVec.push_back(C);
12300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    } else if (isTypeOpCode(OC))
12310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      TypeVec.push_back(static_cast<SPIRVType*>(E));
12320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    else if (E->isVariable())
12330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      VariableVec.push_back(static_cast<SPIRVVariable*>(E));
12340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
12350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungpublic:
12360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  TopologicalSort(const SPIRVTypeVec &_TypeVec,
12370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                  const SPIRVConstantVector &_ConstVec,
12380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                  const SPIRVVariableVec &_VariableVec,
12390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                  const SPIRVForwardPointerVec &_ForwardPointerVec) :
12400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  ForwardPointerVec(_ForwardPointerVec),
12410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  EntryStateMap([](SPIRVEntry* a, SPIRVEntry* b) -> bool {
12420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                  return a->getId() < b->getId();
12430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                })
12440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  {
12450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // Collect entries for sorting
12460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto *T : _TypeVec)
12470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      EntryStateMap[T] = DFSState::Unvisited;
12480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto *C : _ConstVec)
12490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      EntryStateMap[C] = DFSState::Unvisited;
12500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto *V : _VariableVec)
12510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      EntryStateMap[V] = DFSState::Unvisited;
12520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // Run topoligical sort
12530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto ES : EntryStateMap)
12540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      visit(ES.first);
12550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
12560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
12570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungspv_ostream &
12590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungoperator<< (spv_ostream &O, const TopologicalSort &S) {
12600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << S.TypeIntVec
12610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << S.ConstIntVec
12620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << S.TypeVec
12630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << S.ConstVec
12640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << S.VariableVec;
12650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return O;
12660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
12670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungspv_ostream &
12690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungoperator<< (spv_ostream &O, SPIRVModule &M) {
12700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVModuleImpl &MI = *static_cast<SPIRVModuleImpl*>(&M);
12710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVEncoder Encoder(O);
12730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Encoder << MagicNumber
12740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          << MI.SPIRVVersion
12750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          << (((SPIRVWord)MI.GeneratorId << 16) | MI.GeneratorVer)
12760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          << MI.NextId /* Bound for Id */
12770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          << MI.InstSchema;
12780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << SPIRVNL();
12790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:MI.CapMap)
12810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O << *I.second;
12820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:M.getExtension()) {
12840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(!I.empty() && "Invalid extension");
12850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O << SPIRVExtension(&M, I);
12860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
12870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:MI.IdBuiltinMap)
12890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O <<  SPIRVExtInstImport(&M, I.first, SPIRVBuiltinSetNameMap::map(I.second));
12900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << SPIRVMemoryModel(&M);
12920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:MI.EntryPointVec)
12940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &II:I.second)
12950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      O << SPIRVEntryPoint(&M, I.first, II,
12960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          M.get<SPIRVFunction>(II)->getName());
12970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
12980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:MI.EntryPointVec)
12990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &II:I.second)
13000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      MI.get<SPIRVFunction>(II)->encodeExecutionModes(O);
13010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << MI.StringVec;
13030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:M.getSourceExtension()) {
13050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(!I.empty() && "Invalid source extension");
13060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    O << SPIRVSourceExtension(&M, I);
13070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
13080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << SPIRVSource(&M);
13100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:MI.NamedId) {
13120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    // Don't output name for entry point since it is redundant
13130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool IsEntryPoint = false;
13140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    for (auto &EPS:MI.EntryPointSet)
13150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      if (EPS.second.count(I)) {
13160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        IsEntryPoint = true;
13170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        break;
13180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      }
13190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (!IsEntryPoint)
13200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      M.getEntry(I)->encodeName(O);
13210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
13220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  O << MI.MemberNameVec
13240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.LineVec
13250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.DecGroupVec
13260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.DecorateSet
13270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.GroupDecVec
13280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.ForwardPointerVec
13290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << TopologicalSort(MI.TypeVec, MI.ConstVec, MI.VariableVec,
13300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                       MI.ForwardPointerVec)
13310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << SPIRVNL()
13320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    << MI.FuncVec;
13330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return O;
13340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<class T>
13370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid SPIRVModuleImpl::addTo(std::vector<T*>& V, SPIRVEntry* E) {
13380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  V.push_back(static_cast<T *>(E));
13390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// The first decoration group includes all the previously defined decorates.
13420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// The second decoration group includes all the decorates defined between the
13430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// first and second decoration group. So long so forth.
13440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDecorationGroup*
13450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addDecorationGroup() {
13460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return addDecorationGroup(new SPIRVDecorationGroup(this, getId()));
13470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDecorationGroup*
13500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addDecorationGroup(SPIRVDecorationGroup* Group) {
13510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Group);
13520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Group->takeDecorates(DecorateSet);
13530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  DecGroupVec.push_back(Group);
13540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDBG(spvdbgs() << "[addDecorationGroup] {" << *Group << "}\n";
13550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung          spvdbgs() << "  Remaining DecorateSet: {" << DecorateSet << "}\n");
13560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(DecorateSet.empty());
13570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Group;
13580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVGroupDecorateGeneric*
13610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addGroupDecorateGeneric(SPIRVGroupDecorateGeneric *GDec) {
13620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(GDec);
13630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  GDec->decorateTargets();
13640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  GroupDecVec.push_back(GDec);
13650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return GDec;
13660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVGroupDecorate*
13680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addGroupDecorate(
13690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVDecorationGroup* Group, const std::vector<SPIRVEntry*>& Targets) {
13700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto GD = new SPIRVGroupDecorate(Group, getIds(Targets));
13710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addGroupDecorateGeneric(GD);
13720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return GD;
13730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVGroupMemberDecorate*
13760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addGroupMemberDecorate(
13770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVDecorationGroup* Group, const std::vector<SPIRVEntry*>& Targets) {
13780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto GMD = new SPIRVGroupMemberDecorate(Group, getIds(Targets));
13790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  addGroupDecorateGeneric(GMD);
13800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return GMD;
13810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVString*
13840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getString(const std::string& Str) {
13850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Loc = StrMap.find(Str);
13860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Loc != StrMap.end())
13870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Loc->second;
13880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto S = add(new SPIRVString(this, getId(), Str));
13890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  StrMap[Str] = S;
13900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return S;
13910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMemberName*
13940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addMemberName(SPIRVTypeStruct* ST,
13950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVWord MemberNumber, const std::string& Name) {
13960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return add(new SPIRVMemberName(ST, MemberNumber, Name));
13970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
13980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
13990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid SPIRVModuleImpl::addUnknownStructField(SPIRVTypeStruct *Struct, unsigned I,
14000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                                            SPIRVId ID) {
14010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  UnknownStructFieldMap[Struct].push_back(std::make_pair(I, ID));
14020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::istream &
14050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungoperator>> (std::istream &I, SPIRVModule &M) {
14060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVDecoder Decoder(I, M);
14070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVModuleImpl &MI = *static_cast<SPIRVModuleImpl*>(&M);
14080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Disable automatic capability filling.
14090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.setAutoAddCapability(false);
14100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVWord Magic;
14120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Decoder >> Magic;
14130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(Magic == MagicNumber && "Invalid magic number");
14140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Decoder >> MI.SPIRVVersion;
14160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(MI.SPIRVVersion <= SPV_VERSION && "Unsupported SPIRV version number");
14170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVWord Generator = 0;
14190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Decoder >> Generator;
14200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.GeneratorId = Generator >> 16;
14210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.GeneratorVer = Generator & 0xFFFF;
14220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // Bound for Id
14240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Decoder >> MI.NextId;
14250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Decoder >> MI.InstSchema;
14270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(MI.InstSchema == SPIRVISCH_Default && "Unsupported instruction schema");
14280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  while(Decoder.getWordCountAndOpCode())
14300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Decoder.getEntry();
14310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.optimizeDecorates();
14330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.resolveUnknownStructFields();
14340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  MI.createForwardPointers();
14350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return I;
14360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModule *
14390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModule::createSPIRVModule() {
14400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return new SPIRVModuleImpl;
14410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *
14440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getValue(SPIRVId TheId)const {
14450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return get<SPIRVValue>(TheId);
14460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVType *
14490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getValueType(SPIRVId TheId)const {
14500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return get<SPIRVValue>(TheId)->getType();
14510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<SPIRVValue *>
14540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getValues(const std::vector<SPIRVId>& IdVec)const {
14550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<SPIRVValue *> ValueVec;
14560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto i:IdVec)
14570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ValueVec.push_back(getValue(i));
14580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return ValueVec;
14590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<SPIRVType *>
14620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getValueTypes(const std::vector<SPIRVId>& IdVec)const {
14630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<SPIRVType *> TypeVec;
14640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto i:IdVec)
14650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    TypeVec.push_back(getValue(i)->getType());
14660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return TypeVec;
14670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<SPIRVId>
14700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getIds(const std::vector<SPIRVEntry *> &ValueVec)const {
14710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<SPIRVId> IdVec;
14720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto i:ValueVec)
14730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IdVec.push_back(i->getId());
14740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return IdVec;
14750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<SPIRVId>
14780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::getIds(const std::vector<SPIRVValue *> &ValueVec)const {
14790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<SPIRVId> IdVec;
14800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto i:ValueVec)
14810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    IdVec.push_back(i->getId());
14820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return IdVec;
14830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstTemplateBase*
14860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addInstTemplate(Op OC,
14870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVBasicBlock* BB, SPIRVType *Ty) {
14880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (!Ty || !Ty->isTypeVoid());
14890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId Id = Ty ? getId() : SPIRVID_INVALID;
14900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Ins = SPIRVInstTemplateBase::create(OC, Ty, Id, BB, this);
14910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  BB->addInstruction(Ins);
14920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Ins;
14930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
14940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
14950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVInstTemplateBase*
14960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVModuleImpl::addInstTemplate(Op OC,
14970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const std::vector<SPIRVWord>& Ops, SPIRVBasicBlock* BB, SPIRVType *Ty) {
14980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert (!Ty || !Ty->isTypeVoid());
14990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVId Id = Ty ? getId() : SPIRVID_INVALID;
15000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Ins = SPIRVInstTemplateBase::create(OC, Ty, Id, Ops, BB, this);
15010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  BB->addInstruction(Ins);
15020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Ins;
15030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDbgInfo::SPIRVDbgInfo(SPIRVModule *TM)
15060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung:M(TM){
15070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
15100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDbgInfo::getEntryPointFileStr(SPIRVExecutionModelKind EM, unsigned I) {
15110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (M->getNumEntryPoints(EM) == 0)
15120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return "";
15130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return getFunctionFileStr(M->getEntryPoint(EM, I));
15140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
15170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDbgInfo::getFunctionFileStr(SPIRVFunction *F) {
15180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (F->hasLine())
15190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return F->getLine()->getFileNameStr();
15200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return "";
15210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungunsigned
15240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDbgInfo::getFunctionLineNo(SPIRVFunction *F) {
15250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (F->hasLine())
15260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return F->getLine()->getLine();
15270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return 0;
15280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool IsSPIRVBinary(const std::string &Img) {
15310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (Img.size() < sizeof(unsigned))
15320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
15330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto Magic = reinterpret_cast<const unsigned*>(Img.data());
15340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return *Magic == MagicNumber;
15350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#ifdef _SPIRV_SUPPORT_TEXT_FMT
15380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool ConvertSPIRV(std::istream &IS, spv_ostream &OS,
15400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::string &ErrMsg, bool FromText, bool ToText) {
15410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto SaveOpt = SPIRVUseTextFormat;
15420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVUseTextFormat = FromText;
15430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVModuleImpl M;
15440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  IS >> M;
15450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (M.getError(ErrMsg) != SPIRVEC_Success) {
15460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVUseTextFormat = SaveOpt;
15470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
15480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
15490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVUseTextFormat = ToText;
15500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  OS << M;
15510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (M.getError(ErrMsg) != SPIRVEC_Success) {
15520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVUseTextFormat = SaveOpt;
15530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
15540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
15550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVUseTextFormat = SaveOpt;
15560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return true;
15570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool IsSPIRVText(const std::string &Img) {
15600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::istringstream SS(Img);
15610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned Magic = 0;
15620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SS >> Magic;
15630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (SS.bad())
15640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
15650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Magic == MagicNumber;
15660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool ConvertSPIRV(std::string &Input, std::string &Out,
15690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::string &ErrMsg, bool ToText) {
15700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto FromText = IsSPIRVText(Input);
15710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (ToText == FromText) {
15720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Out = Input;
15730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return true;
15740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
15750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::istringstream IS(Input);
15760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#ifdef _SPIRV_LLVM_API
15770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  llvm::raw_string_ostream OS(Out);
15780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#else
15790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::ostringstream OS;
15800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#endif
15810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (!ConvertSPIRV(IS, OS, ErrMsg, FromText, ToText))
15820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return false;
15830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  Out = OS.str();
15840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return true;
15850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
15860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#endif // _SPIRV_SUPPORT_TEXT_FMT
15880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
15890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
1590