Home | History | Annotate | Download | only in spirit
      1 /*
      2  * Copyright 2017, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef MODULE_H
     18 #define MODULE_H
     19 
     20 #include <iostream>
     21 #include <map>
     22 #include <vector>
     23 
     24 #include "core_defs.h"
     25 #include "entity.h"
     26 #include "instructions.h"
     27 #include "stl_util.h"
     28 #include "types_generated.h"
     29 #include "visitor.h"
     30 
     31 namespace android {
     32 namespace spirit {
     33 
     34 class Builder;
     35 class AnnotationSection;
     36 class CapabilityInst;
     37 class DebugInfoSection;
     38 class ExtensionInst;
     39 class ExtInstImportInst;
     40 class EntryPointInst;
     41 class ExecutionModeInst;
     42 class EntryPointDefinition;
     43 class FunctionDeclaration;
     44 class FunctionDefinition;
     45 class GlobalSection;
     46 class InputWordStream;
     47 class Instruction;
     48 class MemoryModelInst;
     49 
     50 union VersionNumber {
     51   struct {
     52     uint8_t mLowZero;
     53     uint8_t mMinorNumber;
     54     uint8_t mMajorNumber;
     55     uint8_t mHighZero;
     56   } mMajorMinor;
     57   uint8_t mBytes[4];
     58   uint32_t mWord;
     59 };
     60 
     61 class Module : public Entity {
     62 public:
     63   static Module *getCurrentModule();
     64   uint32_t nextId() { return mNextId++; }
     65 
     66   Module();
     67 
     68   Module(Builder *b);
     69 
     70   virtual ~Module() {}
     71 
     72   bool DeserializeInternal(InputWordStream &IS) override;
     73 
     74   void Serialize(OutputWordStream &OS) const override;
     75 
     76   void SerializeHeader(OutputWordStream &OS) const;
     77 
     78   void registerId(uint32_t id, Instruction *inst) {
     79     mIdTable.insert(std::make_pair(id, inst));
     80   }
     81 
     82   void initialize();
     83 
     84   bool resolveIds();
     85 
     86   void accept(IVisitor *v) override {
     87     for (auto cap : mCapabilities) {
     88       v->visit(cap);
     89     }
     90     for (auto ext : mExtensions) {
     91       v->visit(ext);
     92     }
     93     for (auto imp : mExtInstImports) {
     94       v->visit(imp);
     95     }
     96 
     97     v->visit(mMemoryModel.get());
     98 
     99     for (auto entry : mEntryPoints) {
    100       v->visit(entry);
    101     }
    102 
    103     for (auto mode : mExecutionModes) {
    104       v->visit(mode);
    105     }
    106 
    107     v->visit(mDebugInfo.get());
    108     if (mAnnotations) {
    109       v->visit(mAnnotations.get());
    110     }
    111     if (mGlobals) {
    112       v->visit(mGlobals.get());
    113     }
    114 
    115     for (auto def : mFunctionDefinitions) {
    116       v->visit(def);
    117     }
    118   }
    119 
    120   static std::ostream &errs() { return std::cerr; }
    121 
    122   Module *addCapability(Capability cap);
    123   Module *setMemoryModel(AddressingModel am, MemoryModel mm);
    124   Module *addExtInstImport(const char *extName);
    125   Module *addSource(SourceLanguage lang, int version);
    126   Module *addSourceExtension(const char *ext);
    127   Module *addString(const char *ext);
    128   Module *addEntryPoint(EntryPointDefinition *entry);
    129 
    130   ExtInstImportInst *getGLExt() const { return mGLExt; }
    131 
    132   GlobalSection *getGlobalSection();
    133 
    134   Instruction *lookupByName(const char *) const;
    135   FunctionDefinition *
    136   getFunctionDefinitionFromInstruction(FunctionInst *) const;
    137   FunctionDefinition *lookupFunctionDefinitionByName(const char *name) const;
    138 
    139   // Find the name of the instruction, e.g., the name of a function (OpFunction
    140   // instruction).
    141   // The returned string is owned by the OpName instruction, whose first operand
    142   // is the instruction being queried on.
    143   const char *lookupNameByInstruction(const Instruction *) const;
    144 
    145   VariableInst *getInvocationId();
    146   VariableInst *getNumWorkgroups();
    147 
    148   // Adds a struct type built somewhere else.
    149   Module *addStructType(TypeStructInst *structType);
    150   Module *addVariable(VariableInst *var);
    151 
    152   // Methods to look up types. Create them if not found.
    153   TypeVoidInst *getVoidType();
    154   TypeIntInst *getIntType(int bits, bool isSigned = true);
    155   TypeIntInst *getUnsignedIntType(int bits);
    156   TypeFloatInst *getFloatType(int bits);
    157   TypeVectorInst *getVectorType(Instruction *componentType, int width);
    158   TypePointerInst *getPointerType(StorageClass storage,
    159                                   Instruction *pointeeType);
    160   TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
    161 
    162   // This implies that struct types are strictly structural equivalent, i.e.,
    163   // two structs are equivalent i.f.f. their fields are equivalent, recursively.
    164   TypeStructInst *getStructType(Instruction *fieldType[], int numField);
    165   TypeStructInst *getStructType(const std::vector<Instruction *> &fieldType);
    166   TypeStructInst *getStructType(Instruction *field0Type);
    167   TypeStructInst *getStructType(Instruction *field0Type,
    168                                 Instruction *field1Type);
    169   TypeStructInst *getStructType(Instruction *field0Type,
    170                                 Instruction *field1Type,
    171                                 Instruction *field2Type);
    172 
    173   // TODO: Can function types of different decorations be considered the same?
    174   TypeFunctionInst *getFunctionType(Instruction *retType,
    175                                     Instruction *const argType[],
    176                                     size_t numArg);
    177   TypeFunctionInst *getFunctionType(Instruction *retType,
    178                                     const std::vector<Instruction *> &argTypes);
    179 
    180   size_t getSize(TypeVoidInst *voidTy);
    181   size_t getSize(TypeIntInst *intTy);
    182   size_t getSize(TypeFloatInst *fpTy);
    183   size_t getSize(TypeVectorInst *vTy);
    184   size_t getSize(TypePointerInst *ptrTy);
    185   size_t getSize(TypeStructInst *structTy);
    186   size_t getSize(TypeFunctionInst *funcTy);
    187   size_t getSize(Instruction *inst);
    188 
    189   ConstantInst *getConstant(TypeIntInst *type, int32_t value);
    190   ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
    191   ConstantInst *getConstant(TypeFloatInst *type, float value);
    192 
    193   ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
    194                                               ConstantInst *components[],
    195                                               size_t width);
    196   ConstantCompositeInst *
    197   getConstantComposite(Instruction *type,
    198                        const std::vector<ConstantInst *> &components);
    199   ConstantCompositeInst *getConstantComposite(Instruction *type,
    200                                               ConstantInst *comp0,
    201                                               ConstantInst *comp1);
    202   ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
    203                                               ConstantInst *comp0,
    204                                               ConstantInst *comp1,
    205                                               ConstantInst *comp2);
    206   ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
    207                                               ConstantInst *comp0,
    208                                               ConstantInst *comp1,
    209                                               ConstantInst *comp2,
    210                                               ConstantInst *comp3);
    211 
    212   Module *addFunctionDefinition(FunctionDefinition *func);
    213 
    214   void consolidateAnnotations();
    215 
    216 private:
    217   static Module *mInstance;
    218   uint32_t mNextId;
    219   std::map<uint32_t, Instruction *> mIdTable;
    220 
    221   uint32_t mMagicNumber;
    222   VersionNumber mVersion;
    223   uint32_t mGeneratorMagicNumber;
    224   uint32_t mBound;
    225   uint32_t mReserved;
    226 
    227   std::vector<CapabilityInst *> mCapabilities;
    228   std::vector<ExtensionInst *> mExtensions;
    229   std::vector<ExtInstImportInst *> mExtInstImports;
    230   std::unique_ptr<MemoryModelInst> mMemoryModel;
    231   std::vector<EntryPointInst *> mEntryPointInsts;
    232   std::vector<ExecutionModeInst *> mExecutionModes;
    233   std::vector<EntryPointDefinition *> mEntryPoints;
    234   std::unique_ptr<DebugInfoSection> mDebugInfo;
    235   std::unique_ptr<AnnotationSection> mAnnotations;
    236   std::unique_ptr<GlobalSection> mGlobals;
    237   std::vector<FunctionDefinition *> mFunctionDefinitions;
    238 
    239   ExtInstImportInst *mGLExt;
    240 
    241   ContainerDeleter<std::vector<CapabilityInst *>> mCapabilitiesDeleter;
    242   ContainerDeleter<std::vector<ExtensionInst *>> mExtensionsDeleter;
    243   ContainerDeleter<std::vector<ExtInstImportInst *>> mExtInstImportsDeleter;
    244   ContainerDeleter<std::vector<EntryPointInst *>> mEntryPointInstsDeleter;
    245   ContainerDeleter<std::vector<ExecutionModeInst *>> mExecutionModesDeleter;
    246   ContainerDeleter<std::vector<EntryPointDefinition *>> mEntryPointsDeleter;
    247   ContainerDeleter<std::vector<FunctionDefinition *>>
    248       mFunctionDefinitionsDeleter;
    249 };
    250 
    251 struct Extent3D {
    252   uint32_t mWidth;
    253   uint32_t mHeight;
    254   uint32_t mDepth;
    255 };
    256 
    257 class EntryPointDefinition : public Entity {
    258 public:
    259   EntryPointDefinition() {}
    260   EntryPointDefinition(Builder *builder, ExecutionModel execModel,
    261                        FunctionDefinition *func, const char *name);
    262 
    263   virtual ~EntryPointDefinition() {
    264     // Nothing to do here since ~Module() will delete entities referenced here
    265   }
    266 
    267   void accept(IVisitor *visitor) override {
    268     visitor->visit(mEntryPointInst);
    269     // Do not visit the ExecutionMode instructions here. They are linked here
    270     // for convinience, and for convinience only. They are all grouped, stored,
    271     // and serialized directly in the module in a section right after all
    272     // EntryPoint instructions. Visit them from there.
    273   }
    274 
    275   bool DeserializeInternal(InputWordStream &IS) override;
    276 
    277   EntryPointDefinition *addToInterface(VariableInst *var);
    278   EntryPointDefinition *addExecutionMode(ExecutionModeInst *mode) {
    279     mExecutionModeInsts.push_back(mode);
    280     return this;
    281   }
    282   const std::vector<ExecutionModeInst *> &getExecutionModes() const {
    283     return mExecutionModeInsts;
    284   }
    285 
    286   EntryPointDefinition *setLocalSize(uint32_t width, uint32_t height,
    287                                      uint32_t depth);
    288 
    289   EntryPointDefinition *applyExecutionMode(ExecutionModeInst *mode);
    290 
    291   EntryPointInst *getInstruction() const { return mEntryPointInst; }
    292 
    293 private:
    294   const char *mName;
    295   FunctionInst *mFunction;
    296   ExecutionModel mExecutionModel;
    297   std::vector<VariableInst *> mInterface;
    298   Extent3D mLocalSize;
    299 
    300   EntryPointInst *mEntryPointInst;
    301   std::vector<ExecutionModeInst *> mExecutionModeInsts;
    302 };
    303 
    304 class DebugInfoSection : public Entity {
    305 public:
    306   DebugInfoSection() : mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
    307   DebugInfoSection(Builder *b)
    308       : Entity(b), mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
    309 
    310   virtual ~DebugInfoSection() {}
    311 
    312   bool DeserializeInternal(InputWordStream &IS) override;
    313 
    314   DebugInfoSection *addSource(SourceLanguage lang, int version);
    315   DebugInfoSection *addSourceExtension(const char *ext);
    316   DebugInfoSection *addString(const char *str);
    317 
    318   Instruction *lookupByName(const char *name) const;
    319   const char *lookupNameByInstruction(const Instruction *) const;
    320 
    321   void accept(IVisitor *v) override {
    322     for (auto source : mSources) {
    323       v->visit(source);
    324     }
    325     for (auto name : mNames) {
    326       v->visit(name);
    327     }
    328   }
    329 
    330 private:
    331   // (OpString|OpSource|OpSourceExtension|OpSourceContinued)*
    332   std::vector<Instruction *> mSources;
    333   // (OpName|OpMemberName)*
    334   std::vector<Instruction *> mNames;
    335 
    336   ContainerDeleter<std::vector<Instruction *>> mSourcesDeleter;
    337   ContainerDeleter<std::vector<Instruction *>> mNamesDeleter;
    338 };
    339 
    340 class AnnotationSection : public Entity {
    341 public:
    342   AnnotationSection();
    343   AnnotationSection(Builder *b);
    344 
    345   virtual ~AnnotationSection() {}
    346 
    347   bool DeserializeInternal(InputWordStream &IS) override;
    348 
    349   void accept(IVisitor *v) override {
    350     for (auto inst : mAnnotations) {
    351       v->visit(inst);
    352     }
    353   }
    354 
    355   template <typename T> void addAnnotations(T begin, T end) {
    356     mAnnotations.insert<T>(std::end(mAnnotations), begin, end);
    357   }
    358 
    359   std::vector<Instruction *>::const_iterator begin() const {
    360     return mAnnotations.begin();
    361   }
    362 
    363   std::vector<Instruction *>::const_iterator end() const {
    364     return mAnnotations.end();
    365   }
    366 
    367   void clear() { mAnnotations.clear(); }
    368 
    369 private:
    370   std::vector<Instruction *> mAnnotations; // OpDecorate, etc.
    371 
    372   ContainerDeleter<std::vector<Instruction *>> mAnnotationsDeleter;
    373 };
    374 
    375 // Types, constants, and globals
    376 class GlobalSection : public Entity {
    377 public:
    378   GlobalSection();
    379   GlobalSection(Builder *builder);
    380 
    381   virtual ~GlobalSection() {}
    382 
    383   bool DeserializeInternal(InputWordStream &IS) override;
    384 
    385   void accept(IVisitor *v) override {
    386     for (auto inst : mGlobalDefs) {
    387       v->visit(inst);
    388     }
    389 
    390     if (mInvocationId) {
    391       v->visit(mInvocationId.get());
    392     }
    393 
    394     if (mNumWorkgroups) {
    395       v->visit(mNumWorkgroups.get());
    396     }
    397   }
    398 
    399   ConstantInst *getConstant(TypeIntInst *type, int32_t value);
    400   ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
    401   ConstantInst *getConstant(TypeFloatInst *type, float value);
    402   ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
    403                                               ConstantInst *components[],
    404                                               size_t width);
    405 
    406   // Methods to look up types. Create them if not found.
    407   TypeVoidInst *getVoidType();
    408   TypeIntInst *getIntType(int bits, bool isSigned = true);
    409   TypeFloatInst *getFloatType(int bits);
    410   TypeVectorInst *getVectorType(Instruction *componentType, int width);
    411   TypePointerInst *getPointerType(StorageClass storage,
    412                                   Instruction *pointeeType);
    413   TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
    414 
    415   // This implies that struct types are strictly structural equivalent, i.e.,
    416   // two structs are equivalent i.f.f. their fields are equivalent, recursively.
    417   TypeStructInst *getStructType(Instruction *fieldType[], int numField);
    418   // TypeStructInst *getStructType(const std::vector<Instruction *>
    419   // &fieldTypes);
    420 
    421   // TODO: Can function types of different decorations be considered the same?
    422   TypeFunctionInst *getFunctionType(Instruction *retType,
    423                                     Instruction *const argType[],
    424                                     size_t numArg);
    425   // TypeStructInst *addStructType(Instruction *fieldType[], int numField);
    426   GlobalSection *addStructType(TypeStructInst *structType);
    427   GlobalSection *addVariable(VariableInst *var);
    428 
    429   VariableInst *getInvocationId();
    430   VariableInst *getNumWorkgroups();
    431 
    432 private:
    433   // TODO: Add structure to this.
    434   // Separate types, constants, variables, etc.
    435   std::vector<Instruction *> mGlobalDefs;
    436   std::unique_ptr<VariableInst> mInvocationId;
    437   std::unique_ptr<VariableInst> mNumWorkgroups;
    438 
    439   ContainerDeleter<std::vector<Instruction *>> mGlobalDefsDeleter;
    440 };
    441 
    442 class FunctionDeclaration : public Entity {
    443 public:
    444   virtual ~FunctionDeclaration() {}
    445 
    446   bool DeserializeInternal(InputWordStream &IS) override;
    447 
    448   void accept(IVisitor *v) override {
    449     v->visit(mFunc);
    450     for (auto param : mParams) {
    451       v->visit(param);
    452     }
    453     v->visit(mFuncEnd);
    454   }
    455 
    456 private:
    457   FunctionInst *mFunc;
    458   std::vector<FunctionParameterInst *> mParams;
    459   FunctionEndInst *mFuncEnd;
    460 };
    461 
    462 class Block : public Entity {
    463 public:
    464   Block() {}
    465   Block(Builder *b) : Entity(b) {}
    466 
    467   virtual ~Block() {}
    468 
    469   bool DeserializeInternal(InputWordStream &IS) override;
    470 
    471   void accept(IVisitor *v) override {
    472     for (auto inst : mInsts) {
    473       v->visit(inst);
    474     }
    475   }
    476 
    477   Block *addInstruction(Instruction *inst) {
    478     mInsts.push_back(inst);
    479     return this;
    480   }
    481 
    482 private:
    483   std::vector<Instruction *> mInsts;
    484 };
    485 
    486 class FunctionDefinition : public Entity {
    487 public:
    488   FunctionDefinition();
    489   FunctionDefinition(Builder *builder, FunctionInst *func,
    490                      FunctionEndInst *end);
    491 
    492   virtual ~FunctionDefinition() {}
    493 
    494   bool DeserializeInternal(InputWordStream &IS) override;
    495 
    496   void accept(IVisitor *v) override {
    497     v->visit(mFunc.get());
    498     for (auto param : mParams) {
    499       v->visit(param);
    500     }
    501     for (auto block : mBlocks) {
    502       v->visit(block);
    503     }
    504     v->visit(mFuncEnd.get());
    505   }
    506 
    507   FunctionDefinition *addBlock(Block *b) {
    508     mBlocks.push_back(b);
    509     return this;
    510   }
    511 
    512   FunctionInst *getInstruction() const { return mFunc.get(); }
    513   FunctionParameterInst *getParameter(uint32_t i) const { return mParams[i]; }
    514 
    515   Instruction *getReturnType() const;
    516 
    517 private:
    518   std::unique_ptr<FunctionInst> mFunc;
    519   std::vector<FunctionParameterInst *> mParams;
    520   std::vector<Block *> mBlocks;
    521   std::unique_ptr<FunctionEndInst> mFuncEnd;
    522 
    523   ContainerDeleter<std::vector<FunctionParameterInst *>> mParamsDeleter;
    524   ContainerDeleter<std::vector<Block *>> mBlocksDeleter;
    525 };
    526 
    527 } // namespace spirit
    528 } // namespace android
    529 
    530 #endif // MODULE_H
    531