• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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