10e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===- LLVMSPIRVInternal.h -  SPIR-V internal header file --------*- 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 declares classes and functions shared by SPIR-V reader/writer.
370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///
380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===----------------------------------------------------------------------===//
390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#ifndef LLVMSPIRVINTERNAL_HPP_
400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define LLVMSPIRVINTERNAL_HPP_
410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "libSPIRV/SPIRVUtil.h"
430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "libSPIRV/SPIRVEnum.h"
440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "libSPIRV/SPIRVNameMapEnum.h"
450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "libSPIRV/SPIRVError.h"
460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "libSPIRV/SPIRVType.h"
470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "NameMangleAPI.h"
480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "llvm/IR/Attributes.h"
500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "llvm/IR/Constants.h"
510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "llvm/IR/Instructions.h"
520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "llvm/Support/SPIRV.h"
530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <utility>
550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <functional>
560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungusing namespace SPIRV;
580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungusing namespace llvm;
590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace SPIRV{
610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// The LLVM/SPIR-V translator version used to fill the lower 16 bits of the
630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// generator's magic number in the generated SPIR-V module.
640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// This number should be bumped up whenever the generated SPIR-V changes.
650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static unsigned short kTranslatorVer = 14;
660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPCV_TARGET_LLVM_IMAGE_TYPE_ENCODE_ACCESS_QUAL 0
680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Workaround for SPIR 2 producer bug about kernel function calling convention.
690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// This workaround checks metadata to determine if a function is kernel.
700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPCV_RELAX_KERNEL_CALLING_CONV 1
710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVOpaqueType;
730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<std::string, Op, SPIRVOpaqueType>
740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVOpaqueTypeOpCodeMap;
750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Ad hoc function used by LLVM/SPIRV converter for type casting
770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPCV_CAST "spcv.cast"
780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define LLVM_MEMCPY "llvm.memcpy"
790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kOCLTypeQualifierName {
810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char *Const      = "const";
820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char *Volatile   = "volatile";
830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char *Restrict   = "restrict";
840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char *Pipe       = "pipe";
850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<unsigned, Op>::init() {
890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define _SPIRV_OP(x,y) add(Instruction::x, Op##y);
900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /* Casts */
910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ZExt, UConvert)
920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(SExt, SConvert)
930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Trunc, UConvert)
940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FPToUI, ConvertFToU)
950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FPToSI, ConvertFToS)
960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(UIToFP, ConvertUToF)
970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(SIToFP, ConvertSToF)
980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FPTrunc, FConvert)
990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FPExt, FConvert)
1000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(PtrToInt, ConvertPtrToU)
1010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(IntToPtr, ConvertUToPtr)
1020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(BitCast, Bitcast)
1030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(AddrSpaceCast, GenericCastToPtr)
1040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(GetElementPtr, AccessChain)
1050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /*Binary*/
1060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(And, BitwiseAnd)
1070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Or, BitwiseOr)
1080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Xor, BitwiseXor)
1090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Add, IAdd)
1100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FAdd, FAdd)
1110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Sub, ISub)
1120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FSub, FSub)
1130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Mul, IMul)
1140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FMul, FMul)
1150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(UDiv, UDiv)
1160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(SDiv, SDiv)
1170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FDiv, FDiv)
1180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(SRem, SRem)
1190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FRem, FRem)
1200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(URem, UMod)
1210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(Shl, ShiftLeftLogical)
1220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(LShr, ShiftRightLogical)
1230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(AShr, ShiftRightArithmetic)
1240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#undef _SPIRV_OP
1250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
1260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<unsigned, Op> OpCodeMap;
1270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
1290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<CmpInst::Predicate, Op>::init() {
1300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define _SPIRV_OP(x,y) add(CmpInst::x, Op##y);
1310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_OEQ, FOrdEqual)
1320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_OGT, FOrdGreaterThan)
1330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_OGE, FOrdGreaterThanEqual)
1340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_OLT, FOrdLessThan)
1350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_OLE, FOrdLessThanEqual)
1360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_ONE, FOrdNotEqual)
1370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_ORD, Ordered)
1380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_UNO, Unordered)
1390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_UEQ, FUnordEqual)
1400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_UGT, FUnordGreaterThan)
1410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_UGE, FUnordGreaterThanEqual)
1420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_ULT, FUnordLessThan)
1430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_ULE, FUnordLessThanEqual)
1440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(FCMP_UNE, FUnordNotEqual)
1450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_EQ, IEqual)
1460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_NE, INotEqual)
1470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_UGT, UGreaterThan)
1480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_UGE, UGreaterThanEqual)
1490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_ULT, ULessThan)
1500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_ULE, ULessThanEqual)
1510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_SGT, SGreaterThan)
1520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_SGE, SGreaterThanEqual)
1530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_SLT, SLessThan)
1540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    _SPIRV_OP(ICMP_SLE, SLessThanEqual)
1550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#undef _SPIRV_OP
1560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
1570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<CmpInst::Predicate, Op> CmpMap;
1580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass IntBoolOpMapId;
1600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
1610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<Op, Op, IntBoolOpMapId>::init() {
1620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpNot,         OpLogicalNot);
1630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpBitwiseAnd,  OpLogicalAnd);
1640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpBitwiseOr,   OpLogicalOr);
1650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpBitwiseXor,  OpLogicalNotEqual);
1660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpIEqual,      OpLogicalEqual);
1670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(OpINotEqual,   OpLogicalNotEqual);
1680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
1690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<Op, Op, IntBoolOpMapId> IntBoolOpMap;
1700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TARGETTRIPLE32 "spir-unknown-unknown"
1720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TARGETTRIPLE64 "spir64-unknown-unknown"
1730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_DATALAYOUT32 "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32"\
1740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32"\
1750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v32:32:32-v48:64:64-v64:64:64-v96:128:128"\
1760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v128:128:128-v192:256:256-v256:256:256"\
1770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v512:512:512-v1024:1024:1024"
1780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_DATALAYOUT64 "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32"\
1790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32"\
1800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v32:32:32-v48:64:64-v64:64:64-v96:128:128"\
1810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v128:128:128-v192:256:256-v256:256:256"\
1820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                          "-v512:512:512-v1024:1024:1024"
1830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungenum SPIRAddressSpace {
1850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Private,
1860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Global,
1870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Constant,
1880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Local,
1890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Generic,
1900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAS_Count,
1910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
1920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
1930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<>inline void
1940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<SPIRAddressSpace, std::string>::init() {
1950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Private, "Private");
1960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Global, "Global");
1970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Constant, "Constant");
1980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Local, "Local");
1990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Generic, "Generic");
2000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind>
2020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRAddrSpaceCapitalizedNameMap;
2030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
2050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind>::init() {
2060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Private, StorageClassFunction);
2070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Global, StorageClassCrossWorkgroup);
2080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Constant, StorageClassUniformConstant);
2090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Local, StorageClassWorkgroup);
2100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRAS_Generic, StorageClassGeneric);
2110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind> SPIRSPIRVAddrSpaceMap;
2130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Maps OCL builtin function to SPIRV builtin variable.
2150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
2160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<std::string, SPIRVAccessQualifierKind>::init() {
2170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add("read_only", AccessQualifierReadOnly);
2180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add("write_only", AccessQualifierWriteOnly);
2190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add("read_write", AccessQualifierReadWrite);
2200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<std::string, SPIRVAccessQualifierKind> SPIRSPIRVAccessQualifierMap;
2220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
2240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<Attribute::AttrKind, SPIRVFuncParamAttrKind>::init() {
2250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::ZExt, FunctionParameterAttributeZext);
2260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::SExt, FunctionParameterAttributeSext);
2270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::ByVal, FunctionParameterAttributeByVal);
2280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::StructRet, FunctionParameterAttributeSret);
2290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::NoAlias, FunctionParameterAttributeNoAlias);
2300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::NoCapture, FunctionParameterAttributeNoCapture);
2310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<Attribute::AttrKind, SPIRVFuncParamAttrKind>
2330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRSPIRVFuncParamAttrMap;
2340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
2360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<Attribute::AttrKind, SPIRVFunctionControlMaskKind>::init() {
2370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::ReadNone, FunctionControlPureMask);
2380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::ReadOnly, FunctionControlConstMask);
2390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::AlwaysInline, FunctionControlInlineMask);
2400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(Attribute::NoInline, FunctionControlDontInlineMask);
2410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<Attribute::AttrKind, SPIRVFunctionControlMaskKind>
2430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRSPIRVFuncCtlMaskMap;
2440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVExtSetShortName;
2460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
2470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<SPIRVExtInstSetKind, std::string, SPIRVExtSetShortName>::init() {
2480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(SPIRVEIS_OpenCL, "ocl");
2490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVMap<SPIRVExtInstSetKind, std::string, SPIRVExtSetShortName>
2510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIRVExtSetShortNameMap;
2520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNELS                     "opencl.kernels"
2540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_COMPILER_OPTIONS            "opencl.compiler.options"
2550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_ADDR_SPACE       "kernel_arg_addr_space"
2560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_ACCESS_QUAL      "kernel_arg_access_qual"
2570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_TYPE             "kernel_arg_type"
2580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_BASE_TYPE        "kernel_arg_base_type"
2590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_TYPE_QUAL        "kernel_arg_type_qual"
2600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_MD_KERNEL_ARG_NAME             "kernel_arg_name"
2610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define OCL_TYPE_NAME_SAMPLER_T             "sampler_t"
2630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TYPE_NAME_EVENT_T              "opencl.event_t"
2640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TYPE_NAME_CLK_EVENT_T          "opencl.clk_event_t"
2650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TYPE_NAME_BLOCK_T              "opencl.block"
2660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_INTRINSIC_BLOCK_BIND           "spir_block_bind"
2670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_INTRINSIC_GET_BLOCK_INVOKE     "spir_get_block_invoke"
2680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_INTRINSIC_GET_BLOCK_CONTEXT    "spir_get_block_context"
2690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TEMP_NAME_PREFIX_BLOCK         "block"
2700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIR_TEMP_NAME_PREFIX_CALL          "call"
2710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kLLVMTypeName {
2730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char StructPrefix[] = "struct.";
2740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIRVImageSampledTypeName {
2770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Float[] = "float";
2780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Half[]  = "half";
2790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Int[]   = "int";
2800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char UInt[]  = "uint";
2810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Void[]  = "void";
2820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
2830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
2840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIRVTypeName {
2850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Delimiter             = '.';
2860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char DeviceEvent[]         = "DeviceEvent";
2870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Event[]               = "Event";
2880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Image[]               = "Image";
2890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Pipe[]                = "Pipe";
2900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char PostfixDelim          = '_';
2910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Prefix[]              = "spirv";
2920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char PrefixAndDelim[]      = "spirv.";
2930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Queue[]               = "Queue";
2940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ReserveId[]           = "ReserveId";
2950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char SampledImg[]          = "SampledImage";
2960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Sampler[]             = "Sampler";
2970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ConstantSampler[]     = "ConstantSampler";
2980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char PipeStorage[]         = "PipeStorage";
2990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ConstantPipeStorage[] = "ConstantPipeStorage";
3000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPR2TypeName {
3030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Delimiter   = '.';
3040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char OCLPrefix[]   = "opencl.";
3050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ImagePrefix[] = "opencl.image";
3060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Pipe[]        = "opencl.pipe_t";
3070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Sampler[]     = "opencl.sampler_t";
3080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Event[]       = "opencl.event_t";
3090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kAccessQualName {
3120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ReadOnly[]    = "read_only";
3130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char WriteOnly[]   = "write_only";
3140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ReadWrite[]   = "read_write";
3150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kMangledName {
3180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Sampler[]               = "11ocl_sampler";
3190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char AtomicPrefixIncoming[]  = "U7_Atomic";
3200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char AtomicPrefixInternal[]  = "atomic_";
3210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIRVName {
3240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char GroupPrefix[]            = "group_";
3250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Prefix[]                 = "__spirv_";
3260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Postfix[]                = "__";
3270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ImageQuerySize[]         = "ImageQuerySize";
3280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ImageQuerySizeLod[]      = "ImageQuerySizeLod";
3290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ImageSampleExplicitLod[] = "ImageSampleExplicitLod";
3300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ReservedPrefix[]         = "reserved_";
3310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char SampledImage[]           = "SampledImage";
3320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char TempSampledImage[]       = "TempSampledImage";
3330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIRVPostfix {
3360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Sat[]       = "sat";
3370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Rtz[]       = "rtz";
3380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Rte[]       = "rte";
3390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Rtp[]       = "rtp";
3400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Rtn[]       = "rtn";
3410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Rt[]        = "rt";
3420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Return[]    = "R";
3430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Divider[]   = "_";
3440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// Divider between extended instruction name and postfix
3450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ExtDivider[] = "__";
3460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIRVMD {
3490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Capability[]        = "spirv.Capability";
3500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char EntryPoint[]        = "spirv.EntryPoint";
3510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char ExecutionMode[]     = "spirv.ExecutionMode";
3520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Extension[]         = "spirv.Extension";
3530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Generator[]         = "spirv.Generator";
3540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Source[]            = "spirv.Source";
3550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char SourceExtension[]   = "spirv.SourceExtension";
3560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char MemoryModel[]       = "spirv.MemoryModel";
3570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace kSPIR2MD {
3600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char Extensions[]        = "opencl.used.extensions";
3610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char FPContract[]        = "opencl.enable.FP_CONTRACT";
3620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char OCLVer[]            = "opencl.ocl.version";
3630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char OptFeatures[]       = "opencl.used.optional.core.features";
3640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char SPIRVer[]           = "opencl.spir.version";
3650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char VecTyHint[]         = "vec_type_hint";
3660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char WGSize[]            = "reqd_work_group_size";
3670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const static char WGSizeHint[]        = "work_group_size_hint";
3680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
3690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungenum Spir2SamplerKind {
3710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_ADDRESS_NONE            = 0x0000,
3720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_ADDRESS_CLAMP           = 0x0004,
3730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_ADDRESS_CLAMP_TO_EDGE   = 0x0002,
3740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_ADDRESS_REPEAT          = 0x0006,
3750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_ADDRESS_MIRRORED_REPEAT = 0x0008,
3760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_NORMALIZED_COORDS_FALSE = 0x0000,
3770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_NORMALIZED_COORDS_TRUE  = 0x0001,
3780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_FILTER_NEAREST          = 0x0010,
3790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  CLK_FILTER_LINEAR           = 0x0020,
3800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
3810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Additional information for mangling a function argument type.
3840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstruct BuiltinArgTypeMangleInfo {
3850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsSigned;
3860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsVoidPtr;
3870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsEnum;
3880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsSampler;
3890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsAtomic;
3900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool IsLocalArgBlock;
3910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  SPIR::TypePrimitiveEnum Enum;
3920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned Attr;
3930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  BuiltinArgTypeMangleInfo():IsSigned(true), IsVoidPtr(false), IsEnum(false),
3940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                             IsSampler(false), IsAtomic(false), IsLocalArgBlock(false),
3950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                             Enum(SPIR::PRIMITIVE_NONE), Attr(0)
3960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  {}
3970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
3980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
3990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Information for mangling builtin function.
4000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass BuiltinFuncMangleInfo {
4010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungpublic:
4020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// Translate builtin function name and set
4030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  /// argument attributes and unsigned args.
4040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  BuiltinFuncMangleInfo(const std::string &UniqName = "") : LocalArgBlockIdx(-1),
4050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                                                            VarArgIdx(-1) {
4060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (!UniqName.empty())
4070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      init(UniqName);
4080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual ~BuiltinFuncMangleInfo(){}
4100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  const std::string &getUnmangledName() const { return UnmangledName;}
4110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void addUnsignedArg(int Ndx) { UnsignedArgs.insert(Ndx);}
4120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void addVoidPtrArg(int Ndx) { VoidPtrArgs.insert(Ndx);}
4130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void addSamplerArg(int Ndx) { SamplerArgs.insert(Ndx);}
4140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void addAtomicArg(int Ndx) { AtomicArgs.insert(Ndx);}
4150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setLocalArgBlock(int Ndx) {
4160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(0 <= Ndx && "it is not allowed to set less than zero index");
4170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    LocalArgBlockIdx = Ndx;
4180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setEnumArg(int Ndx, SPIR::TypePrimitiveEnum Enum) {
4200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    EnumArgs[Ndx] = Enum;}
4210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setArgAttr(int Ndx, unsigned Attr) {
4220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Attrs[Ndx] = Attr;}
4230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  void setVarArg(int Ndx) {
4240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    assert(0 <= Ndx && "it is not allowed to set less than zero index");
4250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    VarArgIdx = Ndx;
4260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isArgUnsigned(int Ndx) {
4280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return UnsignedArgs.count(-1) || UnsignedArgs.count(Ndx);}
4290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isArgVoidPtr(int Ndx) {
4300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return VoidPtrArgs.count(-1) || VoidPtrArgs.count(Ndx);}
4310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isArgSampler(int Ndx) {
4320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return SamplerArgs.count(Ndx);}
4330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isArgAtomic(int Ndx) {
4340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return AtomicArgs.count(Ndx);}
4350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isLocalArgBlock(int Ndx) {
4360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return LocalArgBlockIdx == Ndx;}
4370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  bool isArgEnum(int Ndx, SPIR::TypePrimitiveEnum *Enum = nullptr) {
4380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto Loc = EnumArgs.find(Ndx);
4390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == EnumArgs.end())
4400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Loc = EnumArgs.find(-1);
4410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == EnumArgs.end())
4420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return false;
4430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Enum)
4440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      *Enum = Loc->second;
4450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return true;
4460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  unsigned getArgAttr(int Ndx) {
4480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    auto Loc = Attrs.find(Ndx);
4490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == Attrs.end())
4500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      Loc = Attrs.find(-1);
4510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    if (Loc == Attrs.end())
4520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      return 0;
4530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Loc->second;
4540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // get ellipsis index, single ellipsis at the end of the function is possible only
4560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  // return value < 0 if none
4570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  int getVarArg() const {
4580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return VarArgIdx;
4590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  BuiltinArgTypeMangleInfo getTypeMangleInfo(int Ndx) {
4610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinArgTypeMangleInfo Info;
4620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsSigned = !isArgUnsigned(Ndx);
4630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsVoidPtr = isArgVoidPtr(Ndx);
4640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsEnum = isArgEnum(Ndx, &Info.Enum);
4650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsSampler = isArgSampler(Ndx);
4660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsAtomic = isArgAtomic(Ndx);
4670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.IsLocalArgBlock = isLocalArgBlock(Ndx);
4680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Info.Attr = getArgAttr(Ndx);
4690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return Info;
4700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  virtual void init(const std::string &UniqUnmangledName){
4720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    UnmangledName = UniqUnmangledName;
4730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  }
4740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungprotected:
4750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::string UnmangledName;
4760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<int> UnsignedArgs; // unsigned arguments, or -1 if all are unsigned
4770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<int> VoidPtrArgs;  // void pointer arguments, or -1 if all are void
4780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                              // pointer
4790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<int> SamplerArgs;  // sampler arguments
4800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::set<int> AtomicArgs;   // atomic arguments
4810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::map<int, SPIR::TypePrimitiveEnum> EnumArgs; // enum arguments
4820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::map<int, unsigned> Attrs;                   // argument attributes
4830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  int LocalArgBlockIdx; // index of a block with local arguments, idx < 0 if none
4840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  int VarArgIdx;        // index of ellipsis argument, idx < 0 if none
4850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
4860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \returns a vector of types for a collection of values.
4880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<class T>
4890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<Type *>
4900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetTypes(T V) {
4910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<Type *> Tys;
4920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  for (auto &I:V)
4930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Tys.push_back(I->getType());
4940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return Tys;
4950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
4960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
4970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Move elements of std::vector from [begin, end) to target.
4980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate <typename T>
4990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid move(std::vector<T>& V, size_t begin, size_t end, size_t target) {
5000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  assert(begin < end && end <= V.size() && target <= V.size() &&
5010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung      !(begin < target && target < end));
5020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (begin <= target && target <= end)
5030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return;
5040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto B = V.begin() + begin, E = V.begin() + end;
5050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (target > V.size())
5060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    target = V.size();
5070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  if (target > end)
5080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    target -= (end - begin);
5090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  std::vector<T> Segment(B, E);
5100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  V.erase(B, E);
5110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  V.insert(V.begin() + target, Segment.begin(), Segment.end());
5120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Find position of first pointer type value in a vector.
5150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sunginline size_t findFirstPtr(const std::vector<Value *> &Args) {
5160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  auto PtArg = std::find_if(Args.begin(), Args.end(), [](Value *V){
5170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    return V->getType()->isPointerTy();
5180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  });
5190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return PtArg - Args.begin();
5200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid removeFnAttr(LLVMContext *Context, CallInst *Call,
5230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Attribute::AttrKind Attr);
5240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid addFnAttr(LLVMContext *Context, CallInst *Call,
5250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Attribute::AttrKind Attr);
5260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid saveLLVMModule(Module *M, const std::string &OutputFile);
5270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string mapSPIRVTypeToOCLType(SPIRVType* Ty, bool Signed);
5280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string mapLLVMTypeToOCLType(const Type* Ty, bool Signed);
5290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVDecorate *mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target);
5300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Add decorations to a SPIR-V entry.
5320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Decs Each string is a postfix without _ at the beginning.
5330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVValue *addDecorations(SPIRVValue *Target,
5340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    const SmallVectorImpl<std::string>& Decs);
5350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungPointerType *getOrCreateOpaquePtrType(Module *M, const std::string &Name,
5370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    unsigned AddrSpace = SPIRAS_Global);
5380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungPointerType* getSamplerType(Module *M);
5390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungPointerType* getPipeStorageType(Module *M);
5400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid getFunctionTypeParameterTypes(llvm::FunctionType* FT,
5410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::vector<Type*>& ArgTys);
5420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungFunction *getOrCreateFunction(Module *M, Type *RetTy,
5430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ArrayRef<Type *> ArgTypes, StringRef Name,
5440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinFuncMangleInfo *Mangle = nullptr,
5450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    AttributeSet *Attrs = nullptr, bool takeName = true);
5460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get function call arguments.
5480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Start Starting index.
5490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param End Ending index.
5500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<Value *> getArguments(CallInst* CI, unsigned Start = 0,
5510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    unsigned End = 0);
5520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get constant function call argument as an integer.
5540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param I argument index.
5550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sunguint64_t getArgAsInt(CallInst *CI, unsigned I);
5560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get constant function call argument as type \param T.
5580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param I argument index.
5590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<typename T>
5600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungT getArgAs(CallInst *CI, unsigned I){
5610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  return static_cast<T>(getArgAsInt(CI, I));
5620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
5630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get constant function call argument as a Scope enum.
5650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param I argument index.
5660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungScope getArgAsScope(CallInst *CI, unsigned I);
5670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get constant function call argument as a Decoration enum.
5690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param I argument index.
5700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungDecoration getArgAsDecoration(CallInst *CI, unsigned I);
5710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isPointerToOpaqueStructType(llvm::Type* Ty);
5730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isPointerToOpaqueStructType(llvm::Type* Ty, const std::string &Name);
5740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Check if a type is OCL image type.
5760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return type name without "opencl." prefix.
5770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isOCLImageType(llvm::Type* Ty, StringRef *Name = nullptr);
5780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param BaseTyName is the type name as in spirv.BaseTyName.Postfixes
5800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Postfix contains postfixes extracted from the SPIR-V image
5810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///   type name as spirv.BaseTyName.Postfixes.
58291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nibool
5830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisSPIRVType(llvm::Type* Ty, StringRef BaseTyName, StringRef *Postfix = 0);
5840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Decorate a function name as __spirv_{Name}_
5860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string decorateSPIRVFunction(const std::string &S);
5870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Remove prefix/postfix from __spirv_{Name}_
5890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string undecorateSPIRVFunction(const std::string &S);
5900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Check if a function has decorated name as __spirv_{Name}_
5920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// and get the original name.
5930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isDecoratedSPIRVFunc(const Function *F, std::string *UndecName = nullptr);
5940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a canonical function name for a SPIR-V op code.
5960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getSPIRVFuncName(Op OC, StringRef PostFix = "");
5970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
5980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getSPIRVFuncName(Op OC, const Type *pRetTy, bool IsSigned = false);
5990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a canonical function name for a SPIR-V extended instruction
6010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getSPIRVExtFuncName(SPIRVExtInstSetKind Set, unsigned ExtOp,
6020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    StringRef PostFix = "");
6030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get SPIR-V op code given the canonical function name.
6050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Assume \param Name is either IA64 mangled or unmangled, and the unmangled
6060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// name takes the __spirv_{OpName}_{Postfixes} format.
6070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return op code if the unmangled function name is a valid op code name,
6080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///   otherwise return OpNop.
6090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Dec contains decorations decoded from function name if it is
6100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///   not nullptr.
6110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungOp getSPIRVFuncOC(const std::string& Name,
6120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SmallVectorImpl<std::string> *Dec = nullptr);
6130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get SPIR-V builtin variable enum given the canonical builtin name
6150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Assume \param Name is in format __spirv_BuiltIn{Name}
6160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return false if \param Name is not a valid builtin name.
6170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool getSPIRVBuiltin(const std::string &Name, spv::BuiltIn &Builtin);
6180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Name LLVM function name
6200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param DemangledName demanged name of the OpenCL built-in function
6210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \returns true if Name is the name of the OpenCL built-in function,
6220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// false for other functions
6230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool oclIsBuiltin(const StringRef &Name, std::string *DemangledName = nullptr,
6240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                  bool isCPP = false);
6250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Check if a function type is void(void).
6270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isVoidFuncTy(FunctionType *FT);
6280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \returns true if \p T is a function pointer type.
6300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool isFunctionPointerType(Type *T);
6310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \returns true if function \p F has function pointer type argument.
6330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param AI points to the function pointer type argument if returns true.
6340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool hasFunctionPointerArg(Function *F, Function::arg_iterator& AI);
6350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \returns true if function \p F has array type argument.
6370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool hasArrayArg(Function *F);
6380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mutates function call instruction by changing the arguments.
6400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param ArgMutate mutates the function arguments.
6410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return mutated call instruction.
6420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungCallInst *mutateCallInst(Module *M, CallInst *CI,
6430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
6440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
6450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool takeName = false);
6460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mutates function call instruction by changing the arguments and return
6480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// value.
6490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param ArgMutate mutates the function arguments.
6500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param RetMutate mutates the return value.
6510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return mutated instruction.
6520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungInstruction *mutateCallInst(Module *M, CallInst *CI,
6530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<std::string (CallInst *, std::vector<Value *> &,
6540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        Type *&RetTy)> ArgMutate,
6550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<Instruction *(CallInst *)> RetMutate,
6560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
6570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool takeName = false);
6580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mutate call instruction to call SPIR-V builtin function.
6600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungCallInst *
6610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungmutateCallInstSPIRV(Module *M, CallInst *CI,
6620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
6630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    AttributeSet *Attrs = nullptr);
6640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mutate call instruction to call SPIR-V builtin function.
6660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungInstruction *
6670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungmutateCallInstSPIRV(Module *M, CallInst *CI,
6680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<std::string (CallInst *, std::vector<Value *> &,
6690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung        Type *&RetTy)> ArgMutate,
6700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<Instruction *(CallInst *)> RetMutate,
6710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    AttributeSet *Attrs = nullptr);
6720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mutate function by change the arguments.
6740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param ArgMutate mutates the function arguments.
6750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param TakeName Take the original function's name if a new function with
6760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///   different type needs to be created.
6770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid mutateFunction(Function *F,
6780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
6790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
6800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool TakeName = true);
6810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Add a call instruction at \p Pos.
6830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungCallInst *addCallInst(Module *M, StringRef FuncName, Type *RetTy,
6840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ArrayRef<Value *> Args, AttributeSet *Attrs, Instruction *Pos,
6850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    BuiltinFuncMangleInfo *Mangle = nullptr,
6860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    StringRef InstName = SPIR_TEMP_NAME_PREFIX_CALL,
6870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool TakeFuncName = true);
6880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Add a call instruction for SPIR-V builtin function.
6900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungCallInst *
6910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungaddCallInstSPIRV(Module *M, StringRef FuncName, Type *RetTy,
6920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ArrayRef<Value *> Args,
6930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    AttributeSet *Attrs, Instruction *Pos, StringRef InstName);
6940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
6950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Add a call of spir_block_bind function.
6960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungCallInst *
6970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungaddBlockBind(Module *M, Function *InvokeFunc, Value *BlkCtx, Value *CtxLen,
6980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    Value *CtxAlign, Instruction *InsPos,
6990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    StringRef InstName = SPIR_TEMP_NAME_PREFIX_BLOCK);
7000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef std::pair<std::vector<Value *>::iterator,
7020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::vector<Value *>::iterator> ValueVecRange;
7030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Add a vector at \param InsPos.
7050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungValue *
7060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungaddVector(Instruction *InsPos, ValueVecRange Range);
7070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Replace scalar values with a vector created at \param InsPos.
7090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
7100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungmakeVector(Instruction *InsPos, std::vector<Value *> &Ops,
7110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ValueVecRange Range);
7120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Expand a vector type value in \param Ops at index \param VecPos.
7140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Generate extract element instructions at \param InsPos and replace
7150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// the vector type value with scalar type values.
7160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// If the value to be expanded is not vector type, do nothing.
7170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
7180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungexpandVector(Instruction *InsPos, std::vector<Value *> &Ops, size_t VecPos);
7190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get size_t type.
7210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungIntegerType *getSizetType(Module *M);
7220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get void(void) function type.
7240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType *getVoidFuncType(Module *M);
7250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get void(void) function pointer type.
7270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType *getVoidFuncPtrType(Module *M, unsigned AddrSpace = 0);
7280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a 64 bit integer constant.
7300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *getInt64(Module *M, int64_t value);
7310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a 32 bit integer constant.
7330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *getInt32(Module *M, int value);
7340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a 32 bit unsigned integer constant.
7360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *getUInt32(Module *M, unsigned value);
7370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a 16 bit unsigned integer constant.
7390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *getUInt16(Module *M, unsigned short value);
7400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Get a 32 bit floating point constant.
7420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstant *getFloat32(Module *M, float value);
7430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a 32 bit integer constant vector.
7450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::vector<Value *> getInt32(Module *M, const std::vector<int> &value);
7460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a size_t type constant.
7480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *getSizet(Module *M, uint64_t value);
7490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get metadata operand as int.
7510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungint getMDOperandAsInt(MDNode* N, unsigned I);
7520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get metadata operand as string.
7540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getMDOperandAsString(MDNode* N, unsigned I);
7550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get metadata operand as type.
7570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType* getMDOperandAsType(MDNode* N, unsigned I);
7580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a named metadata as a set of string.
7600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Assume the named metadata has one or more operands each of which might
7610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// contain set of strings. For instance:
7620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// !opencl.used.optional.core.features = !{!0}
7630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// !0 = !{!"cl_doubles", !"cl_images"}
7640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// or if we linked two modules we may have
7650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// !opencl.used.optional.core.features = !{!0, !1}
7660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// !0 = !{!"cl_doubles"}
7670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// !1 = !{!"cl_images"}
7680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::set<std::string> getNamedMDAsStringSet(Module *M,
7690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung                                            const std::string &MDName);
7700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get SPIR-V language by SPIR-V metadata spirv.Source
7720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::tuple<unsigned, unsigned, std::string>
7730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetSPIRVSource(Module *M);
7740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Map an unsigned integer constant by applying a function.
7760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *mapUInt(Module *M, ConstantInt *I,
7770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<unsigned(unsigned)> F);
7780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Map a signed integer constant by applying a function.
7800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstantInt *mapSInt(Module *M, ConstantInt *I,
7810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    std::function<int(int)> F);
7820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get postfix for given decoration.
7840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// The returned postfix does not include "_" at the beginning.
7850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getPostfix(Decoration Dec, unsigned Value = 0);
7860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get postfix _R{ReturnType} for return type
7880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// The returned postfix does not includ "_" at the beginning
7890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getPostfixForReturnType(CallInst *CI, bool IsSigned = false);
7900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string getPostfixForReturnType(const Type *pRetTy, bool IsSigned = false);
7910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstant *
7930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetScalarOrVectorConstantInt(Type *T, uint64_t V, bool isSigned = false);
7940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
7950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get a constant int or a constant int array.
7960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param T is the type of the constant. It should be an integer type or
7970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//  an integer pointer type.
7980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Len is the length of the array.
7990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param V is the value to fill the array.
8000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungValue *
8010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetScalarOrArrayConstantInt(Instruction *P, Type *T, unsigned Len, uint64_t V,
8020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    bool isSigned = false);
8030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get the array from GEP.
8050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param V is a GEP whose pointer operand is a pointer to an array of size
8060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \param Size.
8070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungValue *
8080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetScalarOrArray(Value *V, unsigned Size, Instruction *Pos);
8090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
8110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungdumpUsers(Value* V, StringRef Prompt = "");
8120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get SPIR-V type name as spirv.BaseTyName.Postfixes.
8140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
8150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetSPIRVTypeName(StringRef BaseTyName, StringRef Postfixes = "");
8160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Checks if given type name is either ConstantSampler or ConsantPipeStorage.
8180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisSPIRVConstantName(StringRef TyName);
8200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get SPIR-V type by changing the type name from spirv.OldName.Postfixes
8220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// to spirv.NewName.Postfixes.
8230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType *
8240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetSPIRVTypeByChangeBaseTypeName(Module *M, Type *T, StringRef OldName,
8250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    StringRef NewName);
8260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get the postfixes of SPIR-V image type name as in spirv.Image.postfixes.
8280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
8290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetSPIRVImageTypePostfixes(StringRef SampledType,
8300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVTypeImageDescriptor Desc,
8310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SPIRVAccessQualifierKind Acc);
8320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get the sampled type name used in postfix of image type in SPIR-V
8340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// friendly LLVM IR.
8350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
8360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetSPIRVImageSampledTypeName(SPIRVType *Ty);
8370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Translates OpenCL image type names to SPIR-V.
8390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// E.g. %opencl.image1d_rw_t -> %spirv.Image._void_0_0_0_0_0_0_2
8400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType *getSPIRVImageTypeFromOCL(Module *M, Type *T);
8410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get LLVM type for sampled type of SPIR-V image type by postfix.
8430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungType*
8440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SunggetLLVMTypeForSPIRVImageSampledTypePostfix(StringRef Postfix,
8450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  LLVMContext &Ctx);
8460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Map OpenCL opaque type name to SPIR-V type name.
8480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
8490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungmapOCLTypeNameToSPIRV(StringRef Name, StringRef Acc = "");
8500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Check if access qualifier is encoded in the type name.
8520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool hasAccessQualifiedName(StringRef TyName);
8530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get access qualifier from the type name.
8550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungStringRef getAccessQualifier(StringRef TyName);
8560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungeraseUselessFunctions(Module *M);
8590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Erase a function if it is declaration, has internal linkage and has no use.
8610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungeraseIfNoUse(Function *F);
8630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungvoid
8650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungeraseIfNoUse(Value *V);
8660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if a mangled type name is unsigned
8680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisMangledTypeUnsigned(char Mangled);
8700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if a mangled type name is signed
8720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisMangledTypeSigned(char Mangled);
8740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if a mangled type name is floating point (except half)
8760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisMangledTypeFP(char Mangled);
8780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if a mangled type name is half
8800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisMangledTypeHalf(std::string Mangled);
8820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if \param I is valid vector size: 2, 3, 4, 8, 16.
8840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisValidVectorSize(unsigned I);
8860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungenum class ParamType
8880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung{
8890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    FLOAT    = 0,
8900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    SIGNED   = 1,
8910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    UNSIGNED = 2,
8920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    UNKNOWN  = 3
8930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung};
8940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungParamType LastFuncParamType(const std::string& MangledName);
8960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
8970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if the last function parameter is signed
8980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
8990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungisLastFuncParamSigned(const std::string& MangledName);
9000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Check if a mangled function name contains unsigned atomic type
9020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungbool
9030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungcontainsUnsignedAtomicType(StringRef Name);
9040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Mangle builtin function name.
9060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// \return \param UniqName if \param BtnInfo is null pointer, otherwise
9070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung///    return IA64 mangled name.
9080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungstd::string
9090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungmangleBuiltin(const std::string &UniqName,
9100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung    ArrayRef<Type*> ArgTypes, BuiltinFuncMangleInfo* BtnInfo);
9110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Remove cast from a value.
9130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungValue *
9140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungremoveCast(Value *V);
9150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Cast a function to a void(void) funtion pointer.
9170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungConstant *
9180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungcastToVoidFuncPtr(Function *F);
9190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Get i8* with the same address space.
9210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungPointerType *getInt8PtrTy(PointerType *T);
9220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung/// Cast a value to a i8* by inserting a cast instruction.
9240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungValue *
9250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungcastToInt8Ptr(Value *V, Instruction *Pos);
9260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtemplate<> inline void
9280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) SungSPIRVMap<std::string, Op, SPIRVOpaqueType>::init() {
9290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::DeviceEvent, OpTypeDeviceEvent);
9300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::Event, OpTypeEvent);
9310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::Image, OpTypeImage);
9320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::Pipe, OpTypePipe);
9330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::Queue, OpTypeQueue);
9340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::ReserveId, OpTypeReserveId);
9350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::Sampler, OpTypeSampler);
9360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung  add(kSPIRVTypeName::SampledImg, OpTypeSampledImage);
9370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}
9400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung
9410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#endif
942