10e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===- SPIRVFunction.h - Class to represent a SPIR-V function ----*- 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//===----------------------------------------------------------------------===// 90e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// 100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// This file defines Function class for SPIRV. 110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// 120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. 130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// 140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Permission is hereby granted, free of charge, to any person obtaining a 150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// copy of this software and associated documentation files (the "Software"), 160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// to deal with the Software without restriction, including without limitation 170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// the rights to use, copy, modify, merge, publish, distribute, sublicense, 180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// and/or sell copies of the Software, and to permit persons to whom the 190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Software is furnished to do so, subject to the following conditions: 200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// 210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Redistributions of source code must retain the above copyright notice, 220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// this list of conditions and the following disclaimers. 230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Redistributions in binary form must reproduce the above copyright notice, 240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// this list of conditions and the following disclaimers in the documentation 250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// and/or other materials provided with the distribution. 260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Neither the names of Advanced Micro Devices, Inc., nor the names of its 270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// contributors may be used to endorse or promote products derived from this 280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// Software without specific prior written permission. 290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// THE SOFTWARE. 360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung// 370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung//===----------------------------------------------------------------------===// 380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#ifndef SPIRVFUNCTION_HPP_ 400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#define SPIRVFUNCTION_HPP_ 410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVValue.h" 420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include "SPIRVBasicBlock.h" 430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#include <functional> 440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungnamespace SPIRV{ 460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass BIFunction; 480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVDecoder; 490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVFunctionParameter: public SPIRVValue { 510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungpublic: 520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunctionParameter(SPIRVType *TheType, SPIRVId TheId, 530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunction *TheParent, unsigned TheArgNo); 540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunctionParameter():SPIRVValue(OpFunctionParameter), 550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung ParentFunc(nullptr), ArgNo(0){} 560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung unsigned getArgNo()const { return ArgNo;} 570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void foreachAttr(std::function<void(SPIRVFuncParamAttrKind)>); 580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void addAttr(SPIRVFuncParamAttrKind Kind) { 590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung addDecorate(new SPIRVDecorate(DecorationFuncParamAttr, this, Kind)); 600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void setParent(SPIRVFunction *Parent) { ParentFunc = Parent;} 620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung bool hasAttr(SPIRVFuncParamAttrKind Kind) const { 630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return getDecorate(DecorationFuncParamAttr).count(Kind) ; 640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung bool isByVal()const { return hasAttr(FunctionParameterAttributeByVal);} 660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung bool isZext()const { return hasAttr(FunctionParameterAttributeZext);} 670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVCapVec getRequiredCapability() const { 680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung if (hasLinkageType() && getLinkageType() == LinkageTypeImport) 690e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return getVec(CapabilityLinkage); 700e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return SPIRVCapVec(); 710e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 720e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungprotected: 730e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void validate()const { 740e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVValue::validate(); 750e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung assert(ParentFunc && "Invalid parent function"); 760e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 770e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung _SPIRV_DEF_ENCDEC2(Type, Id) 780e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungprivate: 790e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunction *ParentFunc; 800e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung unsigned ArgNo; 810e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}; 820e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 830e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungclass SPIRVFunction: public SPIRVValue, public SPIRVComponentExecutionModes { 840e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungpublic: 850e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung // Complete constructor. It does not construct basic blocks. 860e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunction(SPIRVModule *M, SPIRVTypeFunction *FunctionType, SPIRVId TheId) 870e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung :SPIRVValue(M, 5, OpFunction, FunctionType->getReturnType(), TheId), 880e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung FuncType(FunctionType), FCtrlMask(FunctionControlMaskNone) { 890e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung addAllArguments(TheId + 1); 900e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung validate(); 910e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 920e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 930e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung // Incomplete constructor 940e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunction():SPIRVValue(OpFunction),FuncType(NULL), 950e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung FCtrlMask(FunctionControlMaskNone){} 960e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 970e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVDecoder getDecoder(std::istream &IS); 980e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVTypeFunction *getFunctionType() const { return FuncType;} 990e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVWord getFuncCtlMask() const { return FCtrlMask;} 1000e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung size_t getNumBasicBlock() const { return BBVec.size();} 1010e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVBasicBlock *getBasicBlock(size_t i) const { return BBVec[i];} 1020e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung size_t getNumArguments() const { 1030e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return getFunctionType()->getNumParameters(); 1040e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1050e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVId getArgumentId(size_t i)const { return Parameters[i]->getId();} 1060e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunctionParameter *getArgument(size_t i) const { 1070e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return Parameters[i]; 1080e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1090e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void foreachArgument(std::function<void(SPIRVFunctionParameter *)>Func) { 1100e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung for (size_t I = 0, E = getNumArguments(); I != E; ++I) 1110e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung Func(getArgument(I)); 1120e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1130e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1140e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void foreachReturnValueAttr(std::function<void(SPIRVFuncParamAttrKind)>); 1150e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1160e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void setFunctionControlMask(SPIRVWord Mask) { 1170e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung FCtrlMask = Mask; 1180e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1190e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1200e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void takeExecutionModes(SPIRVForward *Forward) { 1210e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung ExecModes = std::move(Forward->ExecModes); 1220e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1230e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1240e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung // Assume BB contains valid Id. 1250e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVBasicBlock *addBasicBlock(SPIRVBasicBlock *BB) { 1260e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung Module->add(BB); 1270e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung BB->setParent(this); 1280e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung BBVec.push_back(BB); 1290e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return BB; 1300e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1310e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1320e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void encodeChildren(spv_ostream &)const; 1330e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void encodeExecutionModes(spv_ostream &)const; 1340e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung _SPIRV_DCL_ENCDEC 1350e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void validate()const { 1360e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVValue::validate(); 1370e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung assert(FuncType && "Invalid func type"); 1380e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1390e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1400e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungprivate: 1410e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunctionParameter *addArgument(unsigned TheArgNo, SPIRVId TheId) { 1420e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVFunctionParameter *Arg = new SPIRVFunctionParameter( 1430e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung getFunctionType()->getParameterType(TheArgNo), 1440e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung TheId, this, TheArgNo); 1450e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung Module->add(Arg); 1460e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung Parameters.push_back(Arg); 1470e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung return Arg; 1480e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1490e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1500e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void addAllArguments(SPIRVId FirstArgId) { 1510e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung for (size_t i = 0, e = getFunctionType()->getNumParameters(); i != e; ++i) 1520e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung addArgument(i, FirstArgId + i); 1530e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung } 1540e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung void decodeBB(SPIRVDecoder &); 1550e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1560e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVTypeFunction *FuncType; // Function type 1570e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVWord FCtrlMask; // Function control mask 1580e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1590e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung std::vector<SPIRVFunctionParameter *> Parameters; 1600e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung typedef std::vector<SPIRVBasicBlock *> SPIRVLBasicBlockVector; 1610e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung SPIRVLBasicBlockVector BBVec; 1620e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung}; 1630e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1640e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sungtypedef SPIRVEntryOpCodeOnly<OpFunctionEnd> SPIRVFunctionEnd; 1650e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1660e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung} 1670e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung 1680e839d7e9d7e5a096949e39a4c6e00670c8dee64I-Jui (Ray) Sung#endif /* SPIRVFUNCTION_HPP_ */ 169