Home | History | Annotate | Download | only in libSPIRV
      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;
    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;
    148   virtual void setAutoAddCapability(bool E){ AutoAddCapability = 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 
    155   void setMinSPIRVVersion(SPIRVWord Ver) {
    156     setSPIRVVersion(std::max(Ver, getSPIRVVersion()));
    157   }
    158 
    159   // Object creation functions
    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>
    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