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 SPIRV_LIBSPIRV_SPIRVMODULE_H
41 #define SPIRV_LIBSPIRV_SPIRVMODULE_H
42 
43 #include "LLVMSPIRVOpts.h"
44 #include "SPIRVEntry.h"
45 
46 #include "llvm/IR/Metadata.h"
47 
48 #include <iostream>
49 #include <set>
50 #include <string>
51 #include <vector>
52 
53 namespace llvm {
54 class APInt;
55 } // namespace llvm
56 
57 namespace SPIRV {
58 
59 template <Op> class SPIRVConstantBase;
60 using SPIRVConstant = SPIRVConstantBase<OpConstant>;
61 
62 class SPIRVBasicBlock;
63 class SPIRVEntry;
64 class SPIRVFunction;
65 class SPIRVInstruction;
66 class SPIRVType;
67 class SPIRVTypeArray;
68 class SPIRVTypeBool;
69 class SPIRVTypeFloat;
70 class SPIRVTypeFunction;
71 class SPIRVTypeInt;
72 class SPIRVTypeOpaque;
73 class SPIRVTypePointer;
74 class SPIRVTypeImage;
75 class SPIRVTypeSampler;
76 class SPIRVTypeSampledImage;
77 class SPIRVTypePipeStorage;
78 class SPIRVTypeStruct;
79 class SPIRVTypeVector;
80 class SPIRVTypeVoid;
81 class SPIRVTypeDeviceEvent;
82 class SPIRVTypeQueue;
83 class SPIRVTypePipe;
84 class SPIRVTypeVmeImageINTEL;
85 class SPIRVValue;
86 class SPIRVVariable;
87 class SPIRVDecorateGeneric;
88 class SPIRVDecorationGroup;
89 class SPIRVGroupDecorate;
90 class SPIRVGroupMemberDecorate;
91 class SPIRVGroupDecorateGeneric;
92 class SPIRVInstTemplateBase;
93 class SPIRVAsmTargetINTEL;
94 class SPIRVAsmINTEL;
95 class SPIRVAsmCallINTEL;
96 class SPIRVTypeBufferSurfaceINTEL;
97 class SPIRVTypeTokenINTEL;
98 
99 typedef SPIRVBasicBlock SPIRVLabel;
100 struct SPIRVTypeImageDescriptor;
101 
102 class SPIRVModule {
103 public:
104   typedef std::map<SPIRVCapabilityKind, SPIRVCapability *> SPIRVCapMap;
105 
106   static SPIRVModule *createSPIRVModule();
107   static SPIRVModule *createSPIRVModule(const SPIRV::TranslatorOpts &);
108   SPIRVModule();
109   virtual ~SPIRVModule();
110 
111   // Object query functions
112   virtual bool exist(SPIRVId) const = 0;
113   virtual bool exist(SPIRVId, SPIRVEntry **) const = 0;
get(SPIRVId Id)114   template <class T> T *get(SPIRVId Id) const {
115     return static_cast<T *>(getEntry(Id));
116   }
117   virtual SPIRVEntry *getEntry(SPIRVId) const = 0;
118   virtual bool hasDebugInfo() const = 0;
119 
120   // Error handling functions
121   virtual SPIRVErrorLog &getErrorLog() = 0;
122   virtual SPIRVErrorCode getError(std::string &) = 0;
123   // Check if extension is allowed, and set ErrCode and DetailedMsg if not.
124   // Returns true if no error.
125   virtual bool checkExtension(ExtensionID, SPIRVErrorCode,
126                               const std::string &) = 0;
setInvalid()127   void setInvalid() { IsValid = false; }
isModuleValid()128   bool isModuleValid() { return IsValid; }
129 
130   // Module query functions
131   virtual SPIRVAddressingModelKind getAddressingModel() = 0;
132   virtual const SPIRVCapMap &getCapability() const = 0;
133   virtual bool hasCapability(SPIRVCapabilityKind) const = 0;
134   virtual SPIRVExtInstSetKind getBuiltinSet(SPIRVId) const = 0;
135   virtual SPIRVFunction *getEntryPoint(SPIRVExecutionModelKind,
136                                        unsigned) const = 0;
137   virtual std::set<std::string> &getExtension() = 0;
138   virtual SPIRVFunction *getFunction(unsigned) const = 0;
139   virtual SPIRVVariable *getVariable(unsigned) const = 0;
140   virtual SPIRVMemoryModelKind getMemoryModel() const = 0;
141   virtual unsigned getNumFunctions() const = 0;
142   virtual unsigned getNumEntryPoints(SPIRVExecutionModelKind) const = 0;
143   virtual unsigned getNumVariables() const = 0;
144   virtual SourceLanguage getSourceLanguage(SPIRVWord *) const = 0;
145   virtual std::set<std::string> &getSourceExtension() = 0;
146   virtual SPIRVValue *getValue(SPIRVId TheId) const = 0;
147   virtual std::vector<SPIRVValue *>
148   getValues(const std::vector<SPIRVId> &) const = 0;
149   virtual std::vector<SPIRVId>
150   getIds(const std::vector<SPIRVEntry *> &) const = 0;
151   virtual std::vector<SPIRVId>
152   getIds(const std::vector<SPIRVValue *> &) const = 0;
153   virtual SPIRVType *getValueType(SPIRVId TheId) const = 0;
154   virtual std::vector<SPIRVType *>
155   getValueTypes(const std::vector<SPIRVId> &) const = 0;
156   virtual SPIRVConstant *getLiteralAsConstant(unsigned Literal) = 0;
157   virtual bool isEntryPoint(SPIRVExecutionModelKind, SPIRVId) const = 0;
158   virtual unsigned short getGeneratorId() const = 0;
159   virtual unsigned short getGeneratorVer() const = 0;
160   virtual SPIRVWord getSPIRVVersion() const = 0;
161   virtual const std::vector<SPIRVExtInst *> &getDebugInstVec() const = 0;
162   virtual const std::vector<SPIRVString *> &getStringVec() const = 0;
163 
164   // Module changing functions
165   virtual bool importBuiltinSet(const std::string &, SPIRVId *) = 0;
166   virtual bool importBuiltinSetWithId(const std::string &, SPIRVId) = 0;
167   virtual void setAddressingModel(SPIRVAddressingModelKind) = 0;
168   virtual void setAlignment(SPIRVValue *, SPIRVWord) = 0;
169   virtual void setMemoryModel(SPIRVMemoryModelKind) = 0;
170   virtual void setName(SPIRVEntry *, const std::string &) = 0;
171   virtual void setSourceLanguage(SourceLanguage, SPIRVWord) = 0;
setAutoAddCapability(bool E)172   virtual void setAutoAddCapability(bool E) { AutoAddCapability = E; }
setValidateCapability(bool E)173   virtual void setValidateCapability(bool E) { ValidateCapability = E; }
setAutoAddExtensions(bool E)174   virtual void setAutoAddExtensions(bool E) { AutoAddExtensions = E; }
175   virtual void setGeneratorId(unsigned short) = 0;
176   virtual void setGeneratorVer(unsigned short) = 0;
177   virtual void resolveUnknownStructFields() = 0;
178   virtual void setSPIRVVersion(SPIRVWord) = 0;
179 
setMinSPIRVVersion(SPIRVWord Ver)180   void setMinSPIRVVersion(SPIRVWord Ver) {
181     setSPIRVVersion(std::max(Ver, getSPIRVVersion()));
182   }
183 
184   // Object creation functions
add(T * Entry)185   template <class T> T *add(T *Entry) {
186     addEntry(Entry);
187     return Entry;
188   }
189   virtual SPIRVEntry *addEntry(SPIRVEntry *) = 0;
190   virtual SPIRVBasicBlock *addBasicBlock(SPIRVFunction *,
191                                          SPIRVId Id = SPIRVID_INVALID) = 0;
192   virtual SPIRVString *getString(const std::string &Str) = 0;
193   virtual SPIRVMemberName *addMemberName(SPIRVTypeStruct *ST,
194                                          SPIRVWord MemberNumber,
195                                          const std::string &Name) = 0;
196   virtual void addUnknownStructField(SPIRVTypeStruct *, unsigned Idx,
197                                      SPIRVId Id) = 0;
198   virtual void addLine(SPIRVEntry *E, SPIRVId FileNameId, SPIRVWord Line,
199                        SPIRVWord Column) = 0;
200   virtual const std::shared_ptr<const SPIRVLine> &getCurrentLine() const = 0;
201   virtual void setCurrentLine(const std::shared_ptr<const SPIRVLine> &) = 0;
202   virtual const SPIRVDecorateGeneric *addDecorate(SPIRVDecorateGeneric *) = 0;
203   virtual SPIRVDecorationGroup *addDecorationGroup() = 0;
204   virtual SPIRVDecorationGroup *
205   addDecorationGroup(SPIRVDecorationGroup *Group) = 0;
206   virtual SPIRVGroupDecorate *
207   addGroupDecorate(SPIRVDecorationGroup *Group,
208                    const std::vector<SPIRVEntry *> &Targets) = 0;
209   virtual SPIRVGroupMemberDecorate *
210   addGroupMemberDecorate(SPIRVDecorationGroup *Group,
211                          const std::vector<SPIRVEntry *> &Targets) = 0;
212   virtual SPIRVGroupDecorateGeneric *
213   addGroupDecorateGeneric(SPIRVGroupDecorateGeneric *GDec) = 0;
214   virtual void addEntryPoint(SPIRVExecutionModelKind, SPIRVId) = 0;
215   virtual SPIRVForward *addForward(SPIRVType *Ty) = 0;
216   virtual SPIRVForward *addForward(SPIRVId, SPIRVType *Ty) = 0;
217   virtual SPIRVFunction *addFunction(SPIRVFunction *) = 0;
218   virtual SPIRVFunction *addFunction(SPIRVTypeFunction *,
219                                      SPIRVId Id = SPIRVID_INVALID) = 0;
220   virtual SPIRVEntry *replaceForward(SPIRVForward *, SPIRVEntry *) = 0;
221   virtual void eraseInstruction(SPIRVInstruction *, SPIRVBasicBlock *) = 0;
222 
223   // Type creation functions
224   virtual SPIRVTypeArray *addArrayType(SPIRVType *, SPIRVConstant *) = 0;
225   virtual SPIRVTypeBool *addBoolType() = 0;
226   virtual SPIRVTypeFloat *addFloatType(unsigned) = 0;
227   virtual SPIRVTypeFunction *
228   addFunctionType(SPIRVType *, const std::vector<SPIRVType *> &) = 0;
229   virtual SPIRVTypeImage *addImageType(SPIRVType *,
230                                        const SPIRVTypeImageDescriptor &) = 0;
231   virtual SPIRVTypeImage *addImageType(SPIRVType *,
232                                        const SPIRVTypeImageDescriptor &,
233                                        SPIRVAccessQualifierKind) = 0;
234   virtual SPIRVTypeSampler *addSamplerType() = 0;
235   virtual SPIRVTypePipeStorage *addPipeStorageType() = 0;
236   virtual SPIRVTypeSampledImage *addSampledImageType(SPIRVTypeImage *T) = 0;
237   virtual SPIRVTypeInt *addIntegerType(unsigned) = 0;
238   virtual SPIRVTypeOpaque *addOpaqueType(const std::string &) = 0;
239   virtual SPIRVTypePointer *addPointerType(SPIRVStorageClassKind,
240                                            SPIRVType *) = 0;
241   virtual SPIRVTypeStruct *openStructType(unsigned, const std::string &) = 0;
242   virtual SPIRVEntry *addTypeStructContinuedINTEL(unsigned NumMembers) = 0;
243   virtual void closeStructType(SPIRVTypeStruct *, bool) = 0;
244   virtual SPIRVTypeVector *addVectorType(SPIRVType *, SPIRVWord) = 0;
245   virtual SPIRVTypeVoid *addVoidType() = 0;
246   virtual SPIRVType *addOpaqueGenericType(Op) = 0;
247   virtual SPIRVTypeDeviceEvent *addDeviceEventType() = 0;
248   virtual SPIRVTypeQueue *addQueueType() = 0;
249   virtual SPIRVTypePipe *addPipeType() = 0;
250   virtual SPIRVType *addSubgroupAvcINTELType(Op) = 0;
251   virtual SPIRVTypeVmeImageINTEL *addVmeImageINTELType(SPIRVTypeImage *) = 0;
252   virtual SPIRVTypeBufferSurfaceINTEL *
253   addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) = 0;
254   virtual SPIRVTypeTokenINTEL *addTokenTypeINTEL() = 0;
255 
256   // Constants creation functions
257   virtual SPIRVValue *
258   addCompositeConstant(SPIRVType *, const std::vector<SPIRVValue *> &) = 0;
259   virtual SPIRVEntry *
260   addCompositeConstantContinuedINTEL(const std::vector<SPIRVValue *> &) = 0;
261   virtual SPIRVValue *
262   addSpecConstantComposite(SPIRVType *Ty,
263                            const std::vector<SPIRVValue *> &Elements) = 0;
264   virtual SPIRVEntry *
265   addSpecConstantCompositeContinuedINTEL(const std::vector<SPIRVValue *> &) = 0;
266   virtual SPIRVValue *addConstFunctionPointerINTEL(SPIRVType *Ty,
267                                                    SPIRVFunction *F) = 0;
268   virtual SPIRVValue *addConstant(SPIRVValue *) = 0;
269   virtual SPIRVValue *addConstant(SPIRVType *, uint64_t) = 0;
270   virtual SPIRVValue *addConstant(SPIRVType *, llvm::APInt) = 0;
271   virtual SPIRVValue *addSpecConstant(SPIRVType *, uint64_t) = 0;
272   virtual SPIRVValue *addDoubleConstant(SPIRVTypeFloat *, double) = 0;
273   virtual SPIRVValue *addFloatConstant(SPIRVTypeFloat *, float) = 0;
274   virtual SPIRVValue *addIntegerConstant(SPIRVTypeInt *, uint64_t) = 0;
275   virtual SPIRVValue *addNullConstant(SPIRVType *) = 0;
276   virtual SPIRVValue *addUndef(SPIRVType *TheType) = 0;
277   virtual SPIRVValue *addSamplerConstant(SPIRVType *TheType, SPIRVWord AddrMode,
278                                          SPIRVWord ParametricMode,
279                                          SPIRVWord FilterMode) = 0;
280   virtual SPIRVValue *addPipeStorageConstant(SPIRVType *TheType,
281                                              SPIRVWord PacketSize,
282                                              SPIRVWord PacketAlign,
283                                              SPIRVWord Capacity) = 0;
284 
285   // Instruction creation functions
286   virtual SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, SPIRVValue *,
287                                                   std::vector<SPIRVValue *>,
288                                                   SPIRVBasicBlock *, bool) = 0;
289   virtual SPIRVInstruction *
290   addAsyncGroupCopy(SPIRVValue *Scope, SPIRVValue *Dest, SPIRVValue *Src,
291                     SPIRVValue *NumElems, SPIRVValue *Stride, SPIRVValue *Event,
292                     SPIRVBasicBlock *BB) = 0;
293   virtual SPIRVInstruction *addBinaryInst(Op, SPIRVType *, SPIRVValue *,
294                                           SPIRVValue *, SPIRVBasicBlock *) = 0;
295   virtual SPIRVInstruction *addBranchConditionalInst(SPIRVValue *, SPIRVLabel *,
296                                                      SPIRVLabel *,
297                                                      SPIRVBasicBlock *) = 0;
298   virtual SPIRVInstruction *addBranchInst(SPIRVLabel *, SPIRVBasicBlock *) = 0;
299   virtual SPIRVInstruction *addExtInst(SPIRVType *, SPIRVWord, SPIRVWord,
300                                        const std::vector<SPIRVWord> &,
301                                        SPIRVBasicBlock *,
302                                        SPIRVInstruction * = nullptr) = 0;
303   virtual SPIRVInstruction *addExtInst(SPIRVType *, SPIRVWord, SPIRVWord,
304                                        const std::vector<SPIRVValue *> &,
305                                        SPIRVBasicBlock *,
306                                        SPIRVInstruction * = nullptr) = 0;
307   virtual SPIRVEntry *addDebugInfo(SPIRVWord, SPIRVType *,
308                                    const std::vector<SPIRVWord> &) = 0;
309   virtual SPIRVEntry *addModuleProcessed(const std::string &) = 0;
310   virtual void addCapability(SPIRVCapabilityKind) = 0;
addCapabilities(const T & Caps)311   template <typename T> void addCapabilities(const T &Caps) {
312     for (auto I : Caps)
313       addCapability(I);
314   }
315   virtual void addExtension(ExtensionID) = 0;
316   /// Used by SPIRV entries to add required capability internally.
317   /// Should not be used by users directly.
318   virtual void addCapabilityInternal(SPIRVCapabilityKind) = 0;
319   virtual SPIRVInstruction *addCallInst(SPIRVFunction *,
320                                         const std::vector<SPIRVWord> &,
321                                         SPIRVBasicBlock *) = 0;
322   virtual SPIRVInstruction *addIndirectCallInst(SPIRVValue *, SPIRVType *,
323                                                 const std::vector<SPIRVWord> &,
324                                                 SPIRVBasicBlock *) = 0;
325   virtual SPIRVEntry *getOrAddAsmTargetINTEL(const std::string &) = 0;
326   virtual SPIRVValue *addAsmINTEL(SPIRVTypeFunction *, SPIRVAsmTargetINTEL *,
327                                   const std::string &, const std::string &) = 0;
328   virtual SPIRVInstruction *addAsmCallINTELInst(SPIRVAsmINTEL *,
329                                                 const std::vector<SPIRVWord> &,
330                                                 SPIRVBasicBlock *) = 0;
331   virtual SPIRVInstruction *
332   addCompositeConstructInst(SPIRVType *, const std::vector<SPIRVId> &,
333                             SPIRVBasicBlock *) = 0;
334   virtual SPIRVInstruction *
335   addCompositeExtractInst(SPIRVType *, SPIRVValue *,
336                           const std::vector<SPIRVWord> &,
337                           SPIRVBasicBlock *) = 0;
338   virtual SPIRVInstruction *
339   addCompositeInsertInst(SPIRVValue *, SPIRVValue *,
340                          const std::vector<SPIRVWord> &, SPIRVBasicBlock *) = 0;
341   virtual SPIRVInstruction *addCopyObjectInst(SPIRVType *, SPIRVValue *,
342                                               SPIRVBasicBlock *) = 0;
343   virtual SPIRVInstruction *addCopyMemoryInst(SPIRVValue *, SPIRVValue *,
344                                               const std::vector<SPIRVWord> &,
345                                               SPIRVBasicBlock *) = 0;
346   virtual SPIRVInstruction *
347   addCopyMemorySizedInst(SPIRVValue *, SPIRVValue *, SPIRVValue *,
348                          const std::vector<SPIRVWord> &, SPIRVBasicBlock *) = 0;
349   virtual SPIRVInstruction *addCmpInst(Op, SPIRVType *, SPIRVValue *,
350                                        SPIRVValue *, SPIRVBasicBlock *) = 0;
351   virtual SPIRVInstruction *addControlBarrierInst(SPIRVValue *ExecKind,
352                                                   SPIRVValue *MemKind,
353                                                   SPIRVValue *MemSema,
354                                                   SPIRVBasicBlock *BB) = 0;
355   virtual SPIRVInstruction *addGroupInst(Op OpCode, SPIRVType *Type,
356                                          Scope Scope,
357                                          const std::vector<SPIRVValue *> &Ops,
358                                          SPIRVBasicBlock *BB) = 0;
359   virtual SPIRVInstTemplateBase *addInstTemplate(Op OC, SPIRVBasicBlock *BB,
360                                                  SPIRVType *Ty) = 0;
361   virtual SPIRVInstTemplateBase *
362   addInstTemplate(Op OC, const std::vector<SPIRVWord> &Ops, SPIRVBasicBlock *BB,
363                   SPIRVType *Ty) = 0;
364   virtual void addInstTemplate(SPIRVInstTemplateBase *Ins,
365                                const std::vector<SPIRVWord> &Ops,
366                                SPIRVBasicBlock *BB, SPIRVType *Ty) = 0;
367   virtual SPIRVInstruction *addLoadInst(SPIRVValue *,
368                                         const std::vector<SPIRVWord> &,
369                                         SPIRVBasicBlock *) = 0;
370   virtual SPIRVInstruction *addLifetimeInst(Op OC, SPIRVValue *Object,
371                                             SPIRVWord Size,
372                                             SPIRVBasicBlock *BB) = 0;
373   virtual SPIRVInstruction *addMemoryBarrierInst(Scope ScopeKind,
374                                                  SPIRVWord MemFlag,
375                                                  SPIRVBasicBlock *BB) = 0;
376   virtual SPIRVInstruction *addPhiInst(SPIRVType *, std::vector<SPIRVValue *>,
377                                        SPIRVBasicBlock *) = 0;
378   virtual SPIRVInstruction *addUnreachableInst(SPIRVBasicBlock *) = 0;
379   virtual SPIRVInstruction *addReturnInst(SPIRVBasicBlock *) = 0;
380   virtual SPIRVInstruction *addReturnValueInst(SPIRVValue *,
381                                                SPIRVBasicBlock *) = 0;
382   virtual SPIRVInstruction *addSelectInst(SPIRVValue *, SPIRVValue *,
383                                           SPIRVValue *, SPIRVBasicBlock *) = 0;
384   virtual SPIRVInstruction *addSelectionMergeInst(SPIRVId MergeBlock,
385                                                   SPIRVWord SelectionControl,
386                                                   SPIRVBasicBlock *BB) = 0;
387   virtual SPIRVInstruction *addLoopMergeInst(
388       SPIRVId MergeBlock, SPIRVId ContinueTarget, SPIRVWord LoopControl,
389       std::vector<SPIRVWord> LoopControlParameters, SPIRVBasicBlock *BB) = 0;
390   virtual SPIRVInstruction *
391   addLoopControlINTELInst(SPIRVWord LoopControl,
392                           std::vector<SPIRVWord> LoopControlParameters,
393                           SPIRVBasicBlock *BB) = 0;
394   virtual SPIRVInstruction *
395   addFixedPointIntelInst(Op OC, SPIRVType *ResTy, SPIRVValue *Input,
396                          const std::vector<SPIRVWord> &Ops,
397                          SPIRVBasicBlock *BB) = 0;
398   virtual SPIRVInstruction *
399   addArbFloatPointIntelInst(Op OC, SPIRVType *ResTy, SPIRVValue *InA,
400                             SPIRVValue *InB, const std::vector<SPIRVWord> &Ops,
401                             SPIRVBasicBlock *BB) = 0;
402   virtual SPIRVInstruction *addStoreInst(SPIRVValue *, SPIRVValue *,
403                                          const std::vector<SPIRVWord> &,
404                                          SPIRVBasicBlock *) = 0;
405   virtual SPIRVInstruction *addSwitchInst(
406       SPIRVValue *, SPIRVBasicBlock *,
407       const std::vector<std::pair<std::vector<SPIRVWord>, SPIRVBasicBlock *>> &,
408       SPIRVBasicBlock *) = 0;
409   virtual SPIRVInstruction *addVectorTimesScalarInst(SPIRVType *TheType,
410                                                      SPIRVId TheVector,
411                                                      SPIRVId TheScalar,
412                                                      SPIRVBasicBlock *BB) = 0;
413   virtual SPIRVInstruction *addVectorTimesMatrixInst(SPIRVType *TheType,
414                                                      SPIRVId TheVector,
415                                                      SPIRVId TheMatrix,
416                                                      SPIRVBasicBlock *BB) = 0;
417   virtual SPIRVInstruction *addMatrixTimesScalarInst(SPIRVType *TheType,
418                                                      SPIRVId TheMatrix,
419                                                      SPIRVId TheScalar,
420                                                      SPIRVBasicBlock *BB) = 0;
421   virtual SPIRVInstruction *addMatrixTimesVectorInst(SPIRVType *TheType,
422                                                      SPIRVId TheMatrix,
423                                                      SPIRVId TheVector,
424                                                      SPIRVBasicBlock *BB) = 0;
425   virtual SPIRVInstruction *addMatrixTimesMatrixInst(SPIRVType *TheType,
426                                                      SPIRVId M1, SPIRVId M2,
427                                                      SPIRVBasicBlock *BB) = 0;
428   virtual SPIRVInstruction *addTransposeInst(SPIRVType *TheType,
429                                              SPIRVId TheMatrix,
430                                              SPIRVBasicBlock *BB) = 0;
431   virtual SPIRVInstruction *addUnaryInst(Op, SPIRVType *, SPIRVValue *,
432                                          SPIRVBasicBlock *) = 0;
433   virtual SPIRVInstruction *addVariable(SPIRVType *, bool, SPIRVLinkageTypeKind,
434                                         SPIRVValue *, const std::string &,
435                                         SPIRVStorageClassKind,
436                                         SPIRVBasicBlock *) = 0;
437   virtual SPIRVValue *
438   addVectorShuffleInst(SPIRVType *Type, SPIRVValue *Vec1, SPIRVValue *Vec2,
439                        const std::vector<SPIRVWord> &Components,
440                        SPIRVBasicBlock *BB) = 0;
441   virtual SPIRVInstruction *addVectorExtractDynamicInst(SPIRVValue *,
442                                                         SPIRVValue *,
443                                                         SPIRVBasicBlock *) = 0;
444   virtual SPIRVInstruction *addVectorInsertDynamicInst(SPIRVValue *,
445                                                        SPIRVValue *,
446                                                        SPIRVValue *,
447                                                        SPIRVBasicBlock *) = 0;
448   virtual SPIRVInstruction *addFPGARegINTELInst(SPIRVType *, SPIRVValue *,
449                                                 SPIRVBasicBlock *) = 0;
450   virtual SPIRVInstruction *addSampledImageInst(SPIRVType *, SPIRVValue *,
451                                                 SPIRVValue *,
452                                                 SPIRVBasicBlock *) = 0;
453   virtual SPIRVEntry *getOrAddAliasDomainDeclINTELInst(
454       std::vector<SPIRVId> Args, llvm::MDNode *MD) = 0;
455   virtual SPIRVEntry *getOrAddAliasScopeDeclINTELInst(
456       std::vector<SPIRVId> Args, llvm::MDNode *MD) = 0;
457   virtual SPIRVEntry *getOrAddAliasScopeListDeclINTELInst(
458       std::vector<SPIRVId> Args, llvm::MDNode *MD) = 0;
459   virtual SPIRVInstruction *addAssumeTrueKHRInst(SPIRVValue *Condition,
460                                                  SPIRVBasicBlock *BB) = 0;
461   virtual SPIRVInstruction *addExpectKHRInst(SPIRVType *ResultTy,
462                                              SPIRVValue *Value,
463                                              SPIRVValue *ExpectedValue,
464                                              SPIRVBasicBlock *BB) = 0;
465 
466   virtual SPIRVId getExtInstSetId(SPIRVExtInstSetKind Kind) const = 0;
467 
468   virtual bool
isAllowedToUseVersion(SPIRV::VersionNumber RequestedVersion)469   isAllowedToUseVersion(SPIRV::VersionNumber RequestedVersion) const final {
470     return TranslationOpts.isAllowedToUseVersion(RequestedVersion);
471   }
472 
isAllowedToUseVersion(SPIRVWord RequestedVersion)473   virtual bool isAllowedToUseVersion(SPIRVWord RequestedVersion) const final {
474     return TranslationOpts.isAllowedToUseVersion(
475         static_cast<SPIRV::VersionNumber>(RequestedVersion));
476   }
477 
getMaximumAllowedSPIRVVersion()478   virtual SPIRV::VersionNumber getMaximumAllowedSPIRVVersion() const final {
479     return TranslationOpts.getMaxVersion();
480   }
481 
482   virtual bool
isAllowedToUseExtension(ExtensionID RequestedExtension)483   isAllowedToUseExtension(ExtensionID RequestedExtension) const final {
484     return TranslationOpts.isAllowedToUseExtension(RequestedExtension);
485   }
486 
isGenArgNameMDEnabled()487   virtual bool isGenArgNameMDEnabled() const final {
488     return TranslationOpts.isGenArgNameMDEnabled();
489   }
490 
491   virtual std::vector<SPIRVModuleProcessed *> getModuleProcessedVec() = 0;
492 
getSpecializationConstant(SPIRVWord SpecId,uint64_t & ConstValue)493   bool getSpecializationConstant(SPIRVWord SpecId, uint64_t &ConstValue) {
494     return TranslationOpts.getSpecializationConstant(SpecId, ConstValue);
495   }
496 
getFPContractMode()497   FPContractMode getFPContractMode() const {
498     return TranslationOpts.getFPContractMode();
499   }
500 
isUnknownIntrinsicAllowed(llvm::IntrinsicInst * II)501   bool isUnknownIntrinsicAllowed(llvm::IntrinsicInst *II) const noexcept {
502     return TranslationOpts.isUnknownIntrinsicAllowed(II);
503   }
504 
isSPIRVAllowUnknownIntrinsicsEnabled()505   bool isSPIRVAllowUnknownIntrinsicsEnabled() const noexcept {
506     return TranslationOpts.isSPIRVAllowUnknownIntrinsicsEnabled();
507   }
508 
allowExtraDIExpressions()509   bool allowExtraDIExpressions() const noexcept {
510     return TranslationOpts.allowExtraDIExpressions();
511   }
512 
shouldReplaceLLVMFmulAddWithOpenCLMad()513   bool shouldReplaceLLVMFmulAddWithOpenCLMad() const noexcept {
514     return TranslationOpts.shouldReplaceLLVMFmulAddWithOpenCLMad();
515   }
516 
shouldPreserveOCLKernelArgTypeMetadataThroughString()517   bool shouldPreserveOCLKernelArgTypeMetadataThroughString() const noexcept {
518     return TranslationOpts
519         .shouldPreserveOCLKernelArgTypeMetadataThroughString();
520   }
521 
getDebugInfoEIS()522   SPIRVExtInstSetKind getDebugInfoEIS() const {
523     switch (TranslationOpts.getDebugInfoEIS()) {
524     case DebugInfoEIS::SPIRV_Debug:
525       return SPIRVEIS_Debug;
526     case DebugInfoEIS::OpenCL_DebugInfo_100:
527       return SPIRVEIS_OpenCL_DebugInfo_100;
528     }
529     assert(false && "Unexpected debug info EIS!");
530     return SPIRVEIS_Debug;
531   }
532 
getDesiredBIsRepresentation()533   BIsRepresentation getDesiredBIsRepresentation() const {
534     return TranslationOpts.getDesiredBIsRepresentation();
535   }
536 
537   // I/O functions
538   friend spv_ostream &operator<<(spv_ostream &O, SPIRVModule &M);
539   friend std::istream &operator>>(std::istream &I, SPIRVModule &M);
540 
541 protected:
542   bool AutoAddCapability;
543   bool ValidateCapability;
544   bool AutoAddExtensions = true;
545   SPIRV::TranslatorOpts TranslationOpts;
546 
547 private:
548   bool IsValid;
549 };
550 
551 
552 #ifdef _SPIRV_SUPPORT_TEXT_FMT
553 
554 /// Convert SPIR-V between binary and internel text formats.
555 /// This function is not thread safe and should not be used in multi-thread
556 /// applications unless guarded by a critical section.
557 bool ConvertSPIRV(std::istream &IS, spv_ostream &OS, std::string &ErrMsg,
558                   bool FromText, bool ToText);
559 
560 /// Convert SPIR-V between binary and internel text formats.
561 /// This function is not thread safe and should not be used in multi-thread
562 /// applications unless guarded by a critical section.
563 bool ConvertSPIRV(std::string &Input, std::string &Out, std::string &ErrMsg,
564                   bool ToText);
565 #endif
566 } // namespace SPIRV
567 
568 #endif // SPIRV_LIBSPIRV_SPIRVMODULE_H
569