1 //===- SPIRVFunction.h - Class to represent a SPIR-V function ----*- C++ -*-===// 2 // 3 // The LLVM/SPIRV Translator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines Function class for SPIRV. 11 // 12 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining a 15 // copy of this software and associated documentation files (the "Software"), 16 // to deal with the Software without restriction, including without limitation 17 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 18 // and/or sell copies of the Software, and to permit persons to whom the 19 // Software is furnished to do so, subject to the following conditions: 20 // 21 // Redistributions of source code must retain the above copyright notice, 22 // this list of conditions and the following disclaimers. 23 // Redistributions in binary form must reproduce the above copyright notice, 24 // this list of conditions and the following disclaimers in the documentation 25 // and/or other materials provided with the distribution. 26 // Neither the names of Advanced Micro Devices, Inc., nor the names of its 27 // contributors may be used to endorse or promote products derived from this 28 // Software without specific prior written permission. 29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 35 // THE SOFTWARE. 36 // 37 //===----------------------------------------------------------------------===// 38 39 #ifndef SPIRVFUNCTION_HPP_ 40 #define SPIRVFUNCTION_HPP_ 41 #include "SPIRVValue.h" 42 #include "SPIRVBasicBlock.h" 43 #include <functional> 44 45 namespace SPIRV{ 46 47 class BIFunction; 48 class SPIRVDecoder; 49 50 class SPIRVFunctionParameter: public SPIRVValue { 51 public: 52 SPIRVFunctionParameter(SPIRVType *TheType, SPIRVId TheId, 53 SPIRVFunction *TheParent, unsigned TheArgNo); SPIRVFunctionParameter()54 SPIRVFunctionParameter():SPIRVValue(OpFunctionParameter), 55 ParentFunc(nullptr), ArgNo(0){} getArgNo()56 unsigned getArgNo()const { return ArgNo;} 57 void foreachAttr(std::function<void(SPIRVFuncParamAttrKind)>); addAttr(SPIRVFuncParamAttrKind Kind)58 void addAttr(SPIRVFuncParamAttrKind Kind) { 59 addDecorate(new SPIRVDecorate(DecorationFuncParamAttr, this, Kind)); 60 } setParent(SPIRVFunction * Parent)61 void setParent(SPIRVFunction *Parent) { ParentFunc = Parent;} hasAttr(SPIRVFuncParamAttrKind Kind)62 bool hasAttr(SPIRVFuncParamAttrKind Kind) const { 63 return getDecorate(DecorationFuncParamAttr).count(Kind) ; 64 } isByVal()65 bool isByVal()const { return hasAttr(FunctionParameterAttributeByVal);} isZext()66 bool isZext()const { return hasAttr(FunctionParameterAttributeZext);} getRequiredCapability()67 SPIRVCapVec getRequiredCapability() const { 68 if (hasLinkageType() && getLinkageType() == LinkageTypeImport) 69 return getVec(CapabilityLinkage); 70 return SPIRVCapVec(); 71 } 72 protected: validate()73 void validate()const { 74 SPIRVValue::validate(); 75 assert(ParentFunc && "Invalid parent function"); 76 } 77 _SPIRV_DEF_ENCDEC2(Type, Id) 78 private: 79 SPIRVFunction *ParentFunc; 80 unsigned ArgNo; 81 }; 82 83 class SPIRVFunction: public SPIRVValue, public SPIRVComponentExecutionModes { 84 public: 85 // Complete constructor. It does not construct basic blocks. 86 SPIRVFunction(SPIRVModule *M, SPIRVTypeFunction *FunctionType, SPIRVId TheId) 87 :SPIRVValue(M, 5, OpFunction, FunctionType->getReturnType(), TheId), 88 FuncType(FunctionType), FCtrlMask(FunctionControlMaskNone) { 89 addAllArguments(TheId + 1); 90 validate(); 91 } 92 93 // Incomplete constructor 94 SPIRVFunction():SPIRVValue(OpFunction),FuncType(NULL), 95 FCtrlMask(FunctionControlMaskNone){} 96 97 SPIRVDecoder getDecoder(std::istream &IS); 98 SPIRVTypeFunction *getFunctionType() const { return FuncType;} 99 SPIRVWord getFuncCtlMask() const { return FCtrlMask;} 100 size_t getNumBasicBlock() const { return BBVec.size();} 101 SPIRVBasicBlock *getBasicBlock(size_t i) const { return BBVec[i];} 102 size_t getNumArguments() const { 103 return getFunctionType()->getNumParameters(); 104 } 105 SPIRVId getArgumentId(size_t i)const { return Parameters[i]->getId();} 106 SPIRVFunctionParameter *getArgument(size_t i) const { 107 return Parameters[i]; 108 } 109 void foreachArgument(std::function<void(SPIRVFunctionParameter *)>Func) { 110 for (size_t I = 0, E = getNumArguments(); I != E; ++I) 111 Func(getArgument(I)); 112 } 113 114 void foreachReturnValueAttr(std::function<void(SPIRVFuncParamAttrKind)>); 115 116 void setFunctionControlMask(SPIRVWord Mask) { 117 FCtrlMask = Mask; 118 } 119 120 void takeExecutionModes(SPIRVForward *Forward) { 121 ExecModes = std::move(Forward->ExecModes); 122 } 123 124 // Assume BB contains valid Id. 125 SPIRVBasicBlock *addBasicBlock(SPIRVBasicBlock *BB) { 126 Module->add(BB); 127 BB->setParent(this); 128 BBVec.push_back(BB); 129 return BB; 130 } 131 132 void encodeChildren(spv_ostream &)const; 133 void encodeExecutionModes(spv_ostream &)const; 134 _SPIRV_DCL_ENCDEC 135 void validate()const { 136 SPIRVValue::validate(); 137 assert(FuncType && "Invalid func type"); 138 } 139 140 private: 141 SPIRVFunctionParameter *addArgument(unsigned TheArgNo, SPIRVId TheId) { 142 SPIRVFunctionParameter *Arg = new SPIRVFunctionParameter( 143 getFunctionType()->getParameterType(TheArgNo), 144 TheId, this, TheArgNo); 145 Module->add(Arg); 146 Parameters.push_back(Arg); 147 return Arg; 148 } 149 150 void addAllArguments(SPIRVId FirstArgId) { 151 for (size_t i = 0, e = getFunctionType()->getNumParameters(); i != e; ++i) 152 addArgument(i, FirstArgId + i); 153 } 154 void decodeBB(SPIRVDecoder &); 155 156 SPIRVTypeFunction *FuncType; // Function type 157 SPIRVWord FCtrlMask; // Function control mask 158 159 std::vector<SPIRVFunctionParameter *> Parameters; 160 typedef std::vector<SPIRVBasicBlock *> SPIRVLBasicBlockVector; 161 SPIRVLBasicBlockVector BBVec; 162 }; 163 164 typedef SPIRVEntryOpCodeOnly<OpFunctionEnd> SPIRVFunctionEnd; 165 166 } 167 168 #endif /* SPIRVFUNCTION_HPP_ */ 169