14df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni/*
24df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Copyright 2017, The Android Open Source Project
34df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
44df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
54df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * you may not use this file except in compliance with the License.
64df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * You may obtain a copy of the License at
74df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
84df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *     http://www.apache.org/licenses/LICENSE-2.0
94df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Unless required by applicable law or agreed to in writing, software
114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * See the License for the specific language governing permissions and
144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * limitations under the License.
154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni */
164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#ifndef MODULE_H
184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#define MODULE_H
194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include <iostream>
214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include <map>
224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include <vector>
234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "core_defs.h"
254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "entity.h"
263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "instructions.h"
274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "stl_util.h"
284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "types_generated.h"
294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "visitor.h"
304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace android {
324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace spirit {
334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass Builder;
354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass AnnotationSection;
364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass CapabilityInst;
374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass DebugInfoSection;
384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass ExtensionInst;
394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass ExtInstImportInst;
404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass EntryPointInst;
414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass ExecutionModeInst;
424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass EntryPointDefinition;
434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass FunctionDeclaration;
444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass FunctionDefinition;
454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass GlobalSection;
464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass InputWordStream;
474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass Instruction;
484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass MemoryModelInst;
494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niunion VersionNumber {
514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  struct {
524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    uint8_t mLowZero;
534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    uint8_t mMinorNumber;
544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    uint8_t mMajorNumber;
554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    uint8_t mHighZero;
564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  } mMajorMinor;
574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint8_t mBytes[4];
584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mWord;
594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass Module : public Entity {
624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  static Module *getCurrentModule();
644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t nextId() { return mNextId++; }
654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module();
674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module(Builder *b);
694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~Module() {}
714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void Serialize(OutputWordStream &OS) const override;
754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void SerializeHeader(OutputWordStream &OS) const;
774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void registerId(uint32_t id, Instruction *inst) {
794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    mIdTable.insert(std::make_pair(id, inst));
804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void initialize();
834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool resolveIds();
854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto cap : mCapabilities) {
884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(cap);
894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto ext : mExtensions) {
914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(ext);
924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto imp : mExtInstImports) {
944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(imp);
954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mMemoryModel.get());
984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto entry : mEntryPoints) {
1004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(entry);
1014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
1024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto mode : mExecutionModes) {
1044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(mode);
1054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
1064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mDebugInfo.get());
1084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    if (mAnnotations) {
1094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(mAnnotations.get());
1104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
1114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    if (mGlobals) {
1124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(mGlobals.get());
1134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
1144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto def : mFunctionDefinitions) {
1164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(def);
1174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
1184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
1194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  static std::ostream &errs() { return std::cerr; }
1214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addCapability(Capability cap);
1234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *setMemoryModel(AddressingModel am, MemoryModel mm);
1244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addExtInstImport(const char *extName);
1254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addSource(SourceLanguage lang, int version);
1264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addSourceExtension(const char *ext);
127877083d07a7fbce460f7f083bc1d5deef4d9ed47I-Jui (Ray) Sung  Module *addString(const char *ext);
1284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addEntryPoint(EntryPointDefinition *entry);
1294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ExtInstImportInst *getGLExt() const { return mGLExt; }
1314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GlobalSection *getGlobalSection();
1334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Instruction *lookupByName(const char *) const;
1354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionDefinition *
1364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  getFunctionDefinitionFromInstruction(FunctionInst *) const;
1374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionDefinition *lookupFunctionDefinitionByName(const char *name) const;
1384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1393f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  // Find the name of the instruction, e.g., the name of a function (OpFunction
1403f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  // instruction).
1413f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  // The returned string is owned by the OpName instruction, whose first operand
1423f30b6202dd5ad6ff66959131d216405850ed152Yang Ni  // is the instruction being queried on.
1434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const char *lookupNameByInstruction(const Instruction *) const;
1444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  VariableInst *getInvocationId();
1464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  VariableInst *getNumWorkgroups();
1474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Adds a struct type built somewhere else.
1494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addStructType(TypeStructInst *structType);
1504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addVariable(VariableInst *var);
1514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Methods to look up types. Create them if not found.
1534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeVoidInst *getVoidType();
1544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeIntInst *getIntType(int bits, bool isSigned = true);
1554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeIntInst *getUnsignedIntType(int bits);
1564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeFloatInst *getFloatType(int bits);
1574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeVectorInst *getVectorType(Instruction *componentType, int width);
1584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypePointerInst *getPointerType(StorageClass storage,
1594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                  Instruction *pointeeType);
1604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
1614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // This implies that struct types are strictly structural equivalent, i.e.,
1634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // two structs are equivalent i.f.f. their fields are equivalent, recursively.
1644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(Instruction *fieldType[], int numField);
1654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(const std::vector<Instruction *> &fieldType);
1664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(Instruction *field0Type);
1674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(Instruction *field0Type,
1684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                Instruction *field1Type);
1694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(Instruction *field0Type,
1704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                Instruction *field1Type,
1714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                Instruction *field2Type);
1724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TODO: Can function types of different decorations be considered the same?
1744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeFunctionInst *getFunctionType(Instruction *retType,
1754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                    Instruction *const argType[],
1764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                    size_t numArg);
1774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeFunctionInst *getFunctionType(Instruction *retType,
1784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                    const std::vector<Instruction *> &argTypes);
1794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeVoidInst *voidTy);
1814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeIntInst *intTy);
1824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeFloatInst *fpTy);
1834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeVectorInst *vTy);
1844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypePointerInst *ptrTy);
1854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeStructInst *structTy);
1864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(TypeFunctionInst *funcTy);
1874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  size_t getSize(Instruction *inst);
1884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeIntInst *type, int32_t value);
1904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
1914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeFloatInst *type, float value);
1924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
1944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *components[],
1954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              size_t width);
1964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *
1974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  getConstantComposite(Instruction *type,
1984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                       const std::vector<ConstantInst *> &components);
1994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *getConstantComposite(Instruction *type,
2004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp0,
2014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp1);
2024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
2034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp0,
2044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp1,
2054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp2);
2064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
2074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp0,
2084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp1,
2094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp2,
2104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *comp3);
2114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *addFunctionDefinition(FunctionDefinition *func);
2134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void consolidateAnnotations();
2154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
2174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  static Module *mInstance;
2184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mNextId;
2194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::map<uint32_t, Instruction *> mIdTable;
2204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mMagicNumber;
2224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  VersionNumber mVersion;
2234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mGeneratorMagicNumber;
2244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mBound;
2254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mReserved;
2264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<CapabilityInst *> mCapabilities;
2284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<ExtensionInst *> mExtensions;
2294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<ExtInstImportInst *> mExtInstImports;
2304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<MemoryModelInst> mMemoryModel;
2314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<EntryPointInst *> mEntryPointInsts;
2324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<ExecutionModeInst *> mExecutionModes;
2334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<EntryPointDefinition *> mEntryPoints;
2344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<DebugInfoSection> mDebugInfo;
2354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<AnnotationSection> mAnnotations;
2364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<GlobalSection> mGlobals;
2374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<FunctionDefinition *> mFunctionDefinitions;
2384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ExtInstImportInst *mGLExt;
2404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<CapabilityInst *>> mCapabilitiesDeleter;
2424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<ExtensionInst *>> mExtensionsDeleter;
2434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<ExtInstImportInst *>> mExtInstImportsDeleter;
2444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<EntryPointInst *>> mEntryPointInstsDeleter;
2454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<ExecutionModeInst *>> mExecutionModesDeleter;
2464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<EntryPointDefinition *>> mEntryPointsDeleter;
2474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<FunctionDefinition *>>
2484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      mFunctionDefinitionsDeleter;
2494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
2504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nistruct Extent3D {
2524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mWidth;
2534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mHeight;
2544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  uint32_t mDepth;
2554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
2564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass EntryPointDefinition : public Entity {
2584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
2594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition() {}
2604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition(Builder *builder, ExecutionModel execModel,
2614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                       FunctionDefinition *func, const char *name);
2624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~EntryPointDefinition() {
2644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    // Nothing to do here since ~Module() will delete entities referenced here
2654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
2664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *visitor) override {
2684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    visitor->visit(mEntryPointInst);
2694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    // Do not visit the ExecutionMode instructions here. They are linked here
2704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    // for convinience, and for convinience only. They are all grouped, stored,
2714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    // and serialized directly in the module in a section right after all
2724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    // EntryPoint instructions. Visit them from there.
2734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
2744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
2764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition *addToInterface(VariableInst *var);
2784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition *addExecutionMode(ExecutionModeInst *mode) {
2794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    mExecutionModeInsts.push_back(mode);
2804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return this;
2814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
2824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const std::vector<ExecutionModeInst *> &getExecutionModes() const {
2834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return mExecutionModeInsts;
2844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
2854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition *setLocalSize(uint32_t width, uint32_t height,
2874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                     uint32_t depth);
2884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointDefinition *applyExecutionMode(ExecutionModeInst *mode);
2904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointInst *getInstruction() const { return mEntryPointInst; }
2924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
2944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const char *mName;
2954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionInst *mFunction;
2964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ExecutionModel mExecutionModel;
2974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<VariableInst *> mInterface;
2984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Extent3D mLocalSize;
2994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EntryPointInst *mEntryPointInst;
3014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<ExecutionModeInst *> mExecutionModeInsts;
3024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
3034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass DebugInfoSection : public Entity {
3054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
3064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  DebugInfoSection() : mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
3074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  DebugInfoSection(Builder *b)
3084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      : Entity(b), mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
3094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~DebugInfoSection() {}
3114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
3134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  DebugInfoSection *addSource(SourceLanguage lang, int version);
3154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  DebugInfoSection *addSourceExtension(const char *ext);
316877083d07a7fbce460f7f083bc1d5deef4d9ed47I-Jui (Ray) Sung  DebugInfoSection *addString(const char *str);
3174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Instruction *lookupByName(const char *name) const;
3194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const char *lookupNameByInstruction(const Instruction *) const;
3204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
3224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto source : mSources) {
3234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(source);
3244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto name : mNames) {
3264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(name);
3274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
3314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // (OpString|OpSource|OpSourceExtension|OpSourceContinued)*
3324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *> mSources;
3334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // (OpName|OpMemberName)*
3344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *> mNames;
3354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<Instruction *>> mSourcesDeleter;
3374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<Instruction *>> mNamesDeleter;
3384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
3394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass AnnotationSection : public Entity {
3414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
3424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  AnnotationSection();
3434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  AnnotationSection(Builder *b);
3444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~AnnotationSection() {}
3464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
3484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
3504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto inst : mAnnotations) {
3514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(inst);
3524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  template <typename T> void addAnnotations(T begin, T end) {
3564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    mAnnotations.insert<T>(std::end(mAnnotations), begin, end);
3574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *>::const_iterator begin() const {
3604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return mAnnotations.begin();
3614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *>::const_iterator end() const {
3644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return mAnnotations.end();
3654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void clear() { mAnnotations.clear(); }
3684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
3704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *> mAnnotations; // OpDecorate, etc.
3714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<Instruction *>> mAnnotationsDeleter;
3734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
3744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni// Types, constants, and globals
3764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass GlobalSection : public Entity {
3774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
3784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GlobalSection();
3794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GlobalSection(Builder *builder);
3804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~GlobalSection() {}
3824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
3844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
3864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto inst : mGlobalDefs) {
3874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(inst);
3884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    if (mInvocationId) {
3914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(mInvocationId.get());
3924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    if (mNumWorkgroups) {
3954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(mNumWorkgroups.get());
3964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
3974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
3984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
3994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeIntInst *type, int32_t value);
4004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
4014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantInst *getConstant(TypeFloatInst *type, float value);
4024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
4034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              ConstantInst *components[],
4044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                              size_t width);
4054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Methods to look up types. Create them if not found.
4074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeVoidInst *getVoidType();
4084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeIntInst *getIntType(int bits, bool isSigned = true);
4094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeFloatInst *getFloatType(int bits);
4104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeVectorInst *getVectorType(Instruction *componentType, int width);
4114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypePointerInst *getPointerType(StorageClass storage,
4124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                  Instruction *pointeeType);
4134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
4144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // This implies that struct types are strictly structural equivalent, i.e.,
4164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // two structs are equivalent i.f.f. their fields are equivalent, recursively.
4174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeStructInst *getStructType(Instruction *fieldType[], int numField);
4184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TypeStructInst *getStructType(const std::vector<Instruction *>
4194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // &fieldTypes);
4204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TODO: Can function types of different decorations be considered the same?
4224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  TypeFunctionInst *getFunctionType(Instruction *retType,
4234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                    Instruction *const argType[],
4244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                    size_t numArg);
4254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TypeStructInst *addStructType(Instruction *fieldType[], int numField);
4264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GlobalSection *addStructType(TypeStructInst *structType);
4274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GlobalSection *addVariable(VariableInst *var);
4284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  VariableInst *getInvocationId();
4304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  VariableInst *getNumWorkgroups();
4314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
4334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TODO: Add structure to this.
4344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Separate types, constants, variables, etc.
4354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *> mGlobalDefs;
4364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<VariableInst> mInvocationId;
4374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<VariableInst> mNumWorkgroups;
4384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<Instruction *>> mGlobalDefsDeleter;
4404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
4414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass FunctionDeclaration : public Entity {
4434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
4444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~FunctionDeclaration() {}
4454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
4474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
4494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mFunc);
4504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto param : mParams) {
4514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(param);
4524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
4534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mFuncEnd);
4544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
4554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
4574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionInst *mFunc;
4584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<FunctionParameterInst *> mParams;
4594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionEndInst *mFuncEnd;
4604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
4614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass Block : public Entity {
4634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
4644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Block() {}
4654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Block(Builder *b) : Entity(b) {}
4664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~Block() {}
4684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
4704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
4724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto inst : mInsts) {
4734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(inst);
4744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
4754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
4764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Block *addInstruction(Instruction *inst) {
4784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    mInsts.push_back(inst);
4794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return this;
4804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
4814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
4834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Instruction *> mInsts;
4844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
4854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass FunctionDefinition : public Entity {
4874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Nipublic:
4884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionDefinition();
4894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionDefinition(Builder *builder, FunctionInst *func,
4904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                     FunctionEndInst *end);
4914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  virtual ~FunctionDefinition() {}
4934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  bool DeserializeInternal(InputWordStream &IS) override;
4954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
4964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  void accept(IVisitor *v) override {
4974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mFunc.get());
4984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto param : mParams) {
4994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(param);
5004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
5014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    for (auto block : mBlocks) {
5024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      v->visit(block);
5034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    }
5044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    v->visit(mFuncEnd.get());
5054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
5064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionDefinition *addBlock(Block *b) {
5084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    mBlocks.push_back(b);
5094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni    return this;
5104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  }
5114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionInst *getInstruction() const { return mFunc.get(); }
5134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  FunctionParameterInst *getParameter(uint32_t i) const { return mParams[i]; }
5144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Instruction *getReturnType() const;
5164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate:
5184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<FunctionInst> mFunc;
5194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<FunctionParameterInst *> mParams;
5204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::vector<Block *> mBlocks;
5214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<FunctionEndInst> mFuncEnd;
5224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<FunctionParameterInst *>> mParamsDeleter;
5244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ContainerDeleter<std::vector<Block *>> mBlocksDeleter;
5254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni};
5264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace spirit
5284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace android
5294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
5304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#endif // MODULE_H
531