1 //===- SPIRVModule.h - Class to represent a SPIR-V module --------*- 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 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. 9 // 10 // Permission is hereby granted, free of charge, to any person obtaining a 11 // copy of this software and associated documentation files (the "Software"), 12 // to deal with the Software without restriction, including without limitation 13 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 // and/or sell copies of the Software, and to permit persons to whom the 15 // Software is furnished to do so, subject to the following conditions: 16 // 17 // Redistributions of source code must retain the above copyright notice, 18 // this list of conditions and the following disclaimers. 19 // Redistributions in binary form must reproduce the above copyright notice, 20 // this list of conditions and the following disclaimers in the documentation 21 // and/or other materials provided with the distribution. 22 // Neither the names of Advanced Micro Devices, Inc., nor the names of its 23 // contributors may be used to endorse or promote products derived from this 24 // Software without specific prior written permission. 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 31 // THE SOFTWARE. 32 // 33 //===----------------------------------------------------------------------===// 34 /// \file 35 /// 36 /// This file defines Module class for SPIR-V. 37 /// 38 //===----------------------------------------------------------------------===// 39 40 #ifndef SPIRVMODULE_HPP_ 41 #define SPIRVMODULE_HPP_ 42 43 #include "SPIRVEntry.h" 44 45 #include <iostream> 46 #include <set> 47 #include <string> 48 #include <unordered_map> 49 #include <unordered_set> 50 #include <vector> 51 52 namespace SPIRV{ 53 54 class SPIRVBasicBlock; 55 class SPIRVConstant; 56 class SPIRVEntry; 57 class SPIRVFunction; 58 class SPIRVInstruction; 59 class SPIRVType; 60 class SPIRVTypeArray; 61 class SPIRVTypeBool; 62 class SPIRVTypeFloat; 63 class SPIRVTypeFunction; 64 class SPIRVTypeInt; 65 class SPIRVTypeOpaque; 66 class SPIRVTypePointer; 67 class SPIRVTypeImage; 68 class SPIRVTypeSampler; 69 class SPIRVTypeSampledImage; 70 class SPIRVTypePipeStorage; 71 class SPIRVTypeStruct; 72 class SPIRVTypeVector; 73 class SPIRVTypeVoid; 74 class SPIRVTypeDeviceEvent; 75 class SPIRVTypeQueue; 76 class SPIRVTypePipe; 77 class SPIRVValue; 78 class SPIRVVariable; 79 class SPIRVDecorateGeneric; 80 class SPIRVDecorationGroup; 81 class SPIRVGroupDecorate; 82 class SPIRVGroupMemberDecorate; 83 class SPIRVGroupDecorateGeneric; 84 class SPIRVInstTemplateBase; 85 86 typedef SPIRVBasicBlock SPIRVLabel; 87 struct SPIRVTypeImageDescriptor; 88 89 class SPIRVModule { 90 public: 91 typedef std::map<SPIRVCapabilityKind, SPIRVCapability*> SPIRVCapMap; 92 93 static SPIRVModule* createSPIRVModule(); 94 SPIRVModule(); 95 virtual ~SPIRVModule(); 96 97 // Object query functions 98 virtual bool exist(SPIRVId) const = 0; 99 virtual bool exist(SPIRVId, SPIRVEntry **)const = 0; get(SPIRVId Id)100 template<class T> T* get(SPIRVId Id) const { 101 return static_cast<T*>(getEntry(Id));} 102 virtual SPIRVEntry *getEntry(SPIRVId) const = 0; 103 virtual bool hasDebugInfo() const = 0; 104 105 // Error handling functions 106 virtual SPIRVErrorLog &getErrorLog() = 0; 107 virtual SPIRVErrorCode getError(std::string&) = 0; 108 109 // Module query functions 110 virtual SPIRVAddressingModelKind getAddressingModel() = 0; 111 virtual const SPIRVCapMap &getCapability() const = 0; 112 virtual bool hasCapability(SPIRVCapabilityKind) const = 0; 113 virtual SPIRVExtInstSetKind getBuiltinSet(SPIRVId) const = 0; 114 virtual SPIRVFunction *getEntryPoint(SPIRVExecutionModelKind, unsigned) const 115 = 0; 116 virtual std::set<std::string> &getExtension() = 0; 117 virtual SPIRVFunction *getFunction(unsigned) const = 0; 118 virtual SPIRVVariable *getVariable(unsigned) const = 0; 119 virtual SPIRVMemoryModelKind getMemoryModel() const = 0; 120 virtual unsigned getNumFunctions() const = 0; 121 virtual unsigned getNumEntryPoints(SPIRVExecutionModelKind) const = 0; 122 virtual unsigned getNumVariables() const = 0; 123 virtual SourceLanguage getSourceLanguage(SPIRVWord *) const = 0; 124 virtual std::set<std::string> &getSourceExtension() = 0; 125 virtual SPIRVValue *getValue(SPIRVId TheId)const = 0; 126 virtual std::vector<SPIRVValue *> getValues(const std::vector<SPIRVId>&)const 127 = 0; 128 virtual std::vector<SPIRVId> getIds(const std::vector<SPIRVEntry *>&)const = 0; 129 virtual std::vector<SPIRVId> getIds(const std::vector<SPIRVValue *>&)const = 0; 130 virtual SPIRVType *getValueType(SPIRVId TheId)const = 0; 131 virtual std::vector<SPIRVType *> getValueTypes(const std::vector<SPIRVId>&) 132 const = 0; 133 virtual SPIRVConstant* getLiteralAsConstant(unsigned Literal) = 0; 134 virtual bool isEntryPoint(SPIRVExecutionModelKind, SPIRVId) const = 0; 135 virtual unsigned short getGeneratorId() const = 0; 136 virtual unsigned short getGeneratorVer() const = 0; 137 virtual SPIRVWord getSPIRVVersion() const = 0; 138 139 // Module changing functions 140 virtual bool importBuiltinSet(const std::string &, SPIRVId *) = 0; 141 virtual bool importBuiltinSetWithId(const std::string &, SPIRVId) = 0; 142 virtual void setAddressingModel(SPIRVAddressingModelKind) = 0; 143 virtual void setAlignment(SPIRVValue *, SPIRVWord) = 0; 144 virtual void setMemoryModel(SPIRVMemoryModelKind) = 0; 145 virtual void setName(SPIRVEntry *, const std::string&) = 0; 146 virtual void setSourceLanguage(SourceLanguage, SPIRVWord) = 0; 147 virtual void optimizeDecorates() = 0; setAutoAddCapability(bool E)148 virtual void setAutoAddCapability(bool E){ AutoAddCapability = E;} setValidateCapability(bool E)149 virtual void setValidateCapability(bool E){ ValidateCapability = E;} 150 virtual void setGeneratorId(unsigned short) = 0; 151 virtual void setGeneratorVer(unsigned short) = 0; 152 virtual void resolveUnknownStructFields() = 0; 153 virtual void setSPIRVVersion(SPIRVWord) = 0; 154 setMinSPIRVVersion(SPIRVWord Ver)155 void setMinSPIRVVersion(SPIRVWord Ver) { 156 setSPIRVVersion(std::max(Ver, getSPIRVVersion())); 157 } 158 159 // Object creation functions add(T * Entry)160 template<class T> T *add(T *Entry) { addEntry(Entry); return Entry;} 161 virtual SPIRVEntry *addEntry(SPIRVEntry *) = 0; 162 virtual SPIRVBasicBlock *addBasicBlock(SPIRVFunction *, 163 SPIRVId Id = SPIRVID_INVALID) = 0; 164 virtual SPIRVString *getString(const std::string &Str) = 0; 165 virtual SPIRVMemberName *addMemberName(SPIRVTypeStruct *ST, 166 SPIRVWord MemberNumber, const std::string &Name) = 0; 167 virtual void addUnknownStructField(SPIRVTypeStruct *, unsigned idx, 168 SPIRVId id) = 0; 169 virtual SPIRVLine *addLine(SPIRVEntry *E, SPIRVString *FileName, SPIRVWord Line, 170 SPIRVWord Column) = 0; 171 virtual const SPIRVDecorateGeneric *addDecorate(const SPIRVDecorateGeneric*) 172 = 0; 173 virtual SPIRVDecorationGroup *addDecorationGroup() = 0; 174 virtual SPIRVDecorationGroup *addDecorationGroup(SPIRVDecorationGroup *Group) 175 = 0; 176 virtual SPIRVGroupDecorate *addGroupDecorate(SPIRVDecorationGroup *Group, 177 const std::vector<SPIRVEntry *> &Targets) = 0; 178 virtual SPIRVGroupMemberDecorate *addGroupMemberDecorate( 179 SPIRVDecorationGroup *Group, const std::vector<SPIRVEntry *> &Targets) = 0; 180 virtual SPIRVGroupDecorateGeneric *addGroupDecorateGeneric( 181 SPIRVGroupDecorateGeneric *GDec) = 0; 182 virtual void addEntryPoint(SPIRVExecutionModelKind, SPIRVId) = 0; 183 virtual SPIRVForward *addForward(SPIRVType *Ty) = 0; 184 virtual SPIRVForward *addForward(SPIRVId, SPIRVType *Ty) = 0; 185 virtual SPIRVFunction *addFunction(SPIRVFunction *) = 0; 186 virtual SPIRVFunction *addFunction(SPIRVTypeFunction *, 187 SPIRVId Id = SPIRVID_INVALID) = 0; 188 virtual SPIRVEntry *replaceForward(SPIRVForward *, SPIRVEntry *) = 0; 189 190 // Type creation functions 191 virtual SPIRVTypeArray *addArrayType(SPIRVType *, SPIRVConstant *) = 0; 192 virtual SPIRVTypeBool *addBoolType() = 0; 193 virtual SPIRVTypeFloat *addFloatType(unsigned) = 0; 194 virtual SPIRVTypeFunction *addFunctionType(SPIRVType *, 195 const std::vector<SPIRVType *> &) = 0; 196 virtual SPIRVTypeImage *addImageType(SPIRVType *, 197 const SPIRVTypeImageDescriptor &) = 0; 198 virtual SPIRVTypeImage *addImageType(SPIRVType *, 199 const SPIRVTypeImageDescriptor &, SPIRVAccessQualifierKind) = 0; 200 virtual SPIRVTypeSampler *addSamplerType() = 0; 201 virtual SPIRVTypePipeStorage *addPipeStorageType() = 0; 202 virtual SPIRVTypeSampledImage *addSampledImageType(SPIRVTypeImage *T) = 0; 203 virtual SPIRVTypeInt *addIntegerType(unsigned) = 0; 204 virtual SPIRVTypeOpaque *addOpaqueType(const std::string &) = 0; 205 virtual SPIRVTypePointer *addPointerType(SPIRVStorageClassKind, SPIRVType *) = 0; 206 virtual SPIRVTypeStruct *openStructType(unsigned, const std::string &) = 0; 207 virtual void closeStructType(SPIRVTypeStruct *, bool) = 0; 208 virtual SPIRVTypeVector *addVectorType(SPIRVType *, SPIRVWord) = 0; 209 virtual SPIRVTypeVoid *addVoidType() = 0; 210 virtual SPIRVType *addOpaqueGenericType(Op) = 0; 211 virtual SPIRVTypeDeviceEvent *addDeviceEventType() = 0; 212 virtual SPIRVTypeQueue *addQueueType() = 0; 213 virtual SPIRVTypePipe *addPipeType() = 0; 214 virtual void createForwardPointers() = 0; 215 216 // Constants creation functions 217 virtual SPIRVValue *addCompositeConstant(SPIRVType *, 218 const std::vector<SPIRVValue*>&) = 0; 219 virtual SPIRVValue *addConstant(SPIRVValue *) = 0; 220 virtual SPIRVValue *addConstant(SPIRVType *, uint64_t) = 0; 221 virtual SPIRVValue *addDoubleConstant(SPIRVTypeFloat *, double) = 0; 222 virtual SPIRVValue *addFloatConstant(SPIRVTypeFloat *, float) = 0; 223 virtual SPIRVValue *addIntegerConstant(SPIRVTypeInt *, uint64_t) = 0; 224 virtual SPIRVValue *addNullConstant(SPIRVType *) = 0; 225 virtual SPIRVValue *addUndef(SPIRVType *TheType) = 0; 226 virtual SPIRVValue *addSamplerConstant(SPIRVType *TheType, SPIRVWord AddrMode, 227 SPIRVWord ParametricMode, SPIRVWord FilterMode) = 0; 228 virtual SPIRVValue* addPipeStorageConstant(SPIRVType* TheType, 229 SPIRVWord PacketSize, SPIRVWord PacketAlign, SPIRVWord Capacity) = 0; 230 231 // Instruction creation functions 232 virtual SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, SPIRVValue *, 233 std::vector<SPIRVValue *>, SPIRVBasicBlock *, bool) = 0; 234 virtual SPIRVInstruction *addAsyncGroupCopy(SPIRVValue *Scope, 235 SPIRVValue *Dest, SPIRVValue *Src, SPIRVValue *NumElems, SPIRVValue *Stride, 236 SPIRVValue *Event, SPIRVBasicBlock *BB) = 0; 237 virtual SPIRVInstruction *addBinaryInst(Op, SPIRVType *, SPIRVValue *, 238 SPIRVValue *, SPIRVBasicBlock *) = 0; 239 virtual SPIRVInstruction *addBranchConditionalInst(SPIRVValue *, SPIRVLabel *, 240 SPIRVLabel *, SPIRVBasicBlock *) = 0; 241 virtual SPIRVInstruction *addBranchInst(SPIRVLabel *, SPIRVBasicBlock *) = 0; 242 virtual SPIRVInstruction *addExtInst(SPIRVType *, SPIRVWord, SPIRVWord, 243 const std::vector<SPIRVWord> &, SPIRVBasicBlock *) = 0; 244 virtual SPIRVInstruction *addExtInst(SPIRVType *, SPIRVWord, SPIRVWord, 245 const std::vector<SPIRVValue *> &, SPIRVBasicBlock *) = 0; 246 virtual void addCapability(SPIRVCapabilityKind) = 0; 247 template<typename T> addCapabilities(const T & Caps)248 void addCapabilities(const T& Caps) { 249 for (auto I: Caps) 250 addCapability(I); 251 } 252 /// Used by SPIRV entries to add required capability internally. 253 /// Should not be used by users directly. 254 virtual void addCapabilityInternal(SPIRVCapabilityKind) = 0; 255 virtual SPIRVInstruction *addCallInst(SPIRVFunction*, 256 const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 257 virtual SPIRVInstruction *addCompositeExtractInst(SPIRVType *, SPIRVValue *, 258 const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 259 virtual SPIRVInstruction *addCompositeInsertInst(SPIRVValue *, 260 SPIRVValue *, const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 261 virtual SPIRVInstruction *addCopyObjectInst(SPIRVType *, SPIRVValue *, 262 SPIRVBasicBlock *) = 0; 263 virtual SPIRVInstruction *addCopyMemoryInst(SPIRVValue *, SPIRVValue *, 264 const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 265 virtual SPIRVInstruction *addCopyMemorySizedInst(SPIRVValue *, SPIRVValue *, 266 SPIRVValue *, const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 267 virtual SPIRVInstruction *addCmpInst(Op, SPIRVType *, SPIRVValue *, 268 SPIRVValue *, SPIRVBasicBlock *) = 0; 269 virtual SPIRVInstruction *addControlBarrierInst( 270 SPIRVValue *ExecKind, SPIRVValue *MemKind, 271 SPIRVValue *MemSema, SPIRVBasicBlock *BB) = 0; 272 virtual SPIRVInstruction *addGroupInst(Op OpCode, SPIRVType *Type, 273 Scope Scope, const std::vector<SPIRVValue *> &Ops, 274 SPIRVBasicBlock *BB) = 0; 275 virtual SPIRVInstTemplateBase* addInstTemplate(Op OC, 276 SPIRVBasicBlock* BB, SPIRVType *Ty) = 0; 277 virtual SPIRVInstTemplateBase* addInstTemplate(Op OC, 278 const std::vector<SPIRVWord>& Ops, SPIRVBasicBlock* BB, SPIRVType *Ty) = 0; 279 virtual SPIRVInstruction *addLoadInst(SPIRVValue *, 280 const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 281 virtual SPIRVInstruction *addMemoryBarrierInst( 282 Scope ScopeKind, SPIRVWord MemFlag, SPIRVBasicBlock *BB) 283 = 0; 284 virtual SPIRVInstruction *addPhiInst(SPIRVType *, std::vector<SPIRVValue *>, 285 SPIRVBasicBlock *) = 0; 286 virtual SPIRVInstruction *addReturnInst(SPIRVBasicBlock *) = 0; 287 virtual SPIRVInstruction *addReturnValueInst(SPIRVValue *, SPIRVBasicBlock *) 288 = 0; 289 virtual SPIRVInstruction *addSelectInst(SPIRVValue *, SPIRVValue *, SPIRVValue *, 290 SPIRVBasicBlock *) = 0; 291 virtual SPIRVInstruction *addStoreInst(SPIRVValue *, SPIRVValue *, 292 const std::vector<SPIRVWord>&, SPIRVBasicBlock *) = 0; 293 virtual SPIRVInstruction *addSwitchInst(SPIRVValue *, SPIRVBasicBlock *, 294 const std::vector<std::pair<SPIRVWord, SPIRVBasicBlock *>>&, 295 SPIRVBasicBlock *) = 0; 296 virtual SPIRVInstruction *addUnaryInst(Op, SPIRVType *, SPIRVValue *, 297 SPIRVBasicBlock *) = 0; 298 virtual SPIRVInstruction *addVariable(SPIRVType *, bool, SPIRVLinkageTypeKind, 299 SPIRVValue *, const std::string &, SPIRVStorageClassKind, SPIRVBasicBlock *) 300 = 0; 301 virtual SPIRVValue *addVectorShuffleInst(SPIRVType *Type, SPIRVValue *Vec1, 302 SPIRVValue *Vec2, const std::vector<SPIRVWord> &Components, 303 SPIRVBasicBlock *BB) = 0; 304 virtual SPIRVInstruction *addVectorExtractDynamicInst(SPIRVValue *, 305 SPIRVValue *, SPIRVBasicBlock *) = 0; 306 virtual SPIRVInstruction *addVectorInsertDynamicInst(SPIRVValue *, 307 SPIRVValue *, SPIRVValue*, SPIRVBasicBlock *) = 0; 308 // I/O functions 309 friend spv_ostream & operator<<(spv_ostream &O, SPIRVModule& M); 310 friend std::istream & operator>>(std::istream &I, SPIRVModule& M); 311 protected: 312 bool AutoAddCapability; 313 bool ValidateCapability; 314 }; 315 316 class SPIRVDbgInfo { 317 public: 318 SPIRVDbgInfo(SPIRVModule *TM); 319 std::string getEntryPointFileStr(SPIRVExecutionModelKind, unsigned); 320 std::string getFunctionFileStr(SPIRVFunction *); 321 unsigned getFunctionLineNo(SPIRVFunction *); 322 private: 323 std::unordered_map<SPIRVFunction *, SPIRVLine *> FuncMap; 324 const std::string ModuleFileStr; 325 SPIRVModule *M; 326 }; 327 328 #ifdef _SPIRV_SUPPORT_TEXT_FMT 329 330 /// Convert SPIR-V between binary and internel text formats. 331 /// This function is not thread safe and should not be used in multi-thread 332 /// applications unless guarded by a critical section. 333 bool ConvertSPIRV(std::istream &IS, spv_ostream &OS, 334 std::string &ErrMsg, bool FromText, bool ToText); 335 336 /// Convert SPIR-V between binary and internel text formats. 337 /// This function is not thread safe and should not be used in multi-thread 338 /// applications unless guarded by a critical section. 339 bool ConvertSPIRV(std::string &Input, std::string &Out, 340 std::string &ErrMsg, bool ToText); 341 #endif 342 } 343 344 345 346 #endif /* SPIRVMODULE_HPP_ */ 347