/*
 * Copyright 2017, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "module.h"

#include <set>

#include "builder.h"
#include "core_defs.h"
#include "instructions.h"
#include "types_generated.h"
#include "word_stream.h"

namespace android {
namespace spirit {

Module *Module::mInstance = nullptr;

Module *Module::getCurrentModule() {
  if (mInstance == nullptr) {
    return mInstance = new Module();
  }
  return mInstance;
}

Module::Module()
    : mNextId(1), mCapabilitiesDeleter(mCapabilities),
      mExtensionsDeleter(mExtensions), mExtInstImportsDeleter(mExtInstImports),
      mEntryPointInstsDeleter(mEntryPointInsts),
      mExecutionModesDeleter(mExecutionModes),
      mEntryPointsDeleter(mEntryPoints),
      mFunctionDefinitionsDeleter(mFunctionDefinitions) {
  mInstance = this;
}

Module::Module(Builder *b)
    : Entity(b), mNextId(1), mCapabilitiesDeleter(mCapabilities),
      mExtensionsDeleter(mExtensions), mExtInstImportsDeleter(mExtInstImports),
      mEntryPointInstsDeleter(mEntryPointInsts),
      mExecutionModesDeleter(mExecutionModes),
      mEntryPointsDeleter(mEntryPoints),
      mFunctionDefinitionsDeleter(mFunctionDefinitions) {
  mInstance = this;
}

bool Module::resolveIds() {
  auto &table = mIdTable;

  std::unique_ptr<IVisitor> v0(
      CreateInstructionVisitor([&table](Instruction *inst) {
        if (inst->hasResult()) {
          table.insert(std::make_pair(inst->getId(), inst));
        }
      }));
  v0->visit(this);

  mNextId = mIdTable.rbegin()->first + 1;

  int err = 0;
  std::unique_ptr<IVisitor> v(
      CreateInstructionVisitor([&table, &err](Instruction *inst) {
        for (auto ref : inst->getAllIdRefs()) {
          if (ref) {
            auto it = table.find(ref->mId);
            if (it != table.end()) {
              ref->mInstruction = it->second;
            } else {
              std::cout << "Found no instruction for id " << ref->mId
                        << std::endl;
              err++;
            }
          }
        }
      }));
  v->visit(this);
  return err == 0;
}

bool Module::DeserializeInternal(InputWordStream &IS) {
  if (IS.empty()) {
    return false;
  }

  IS >> &mMagicNumber;
  if (mMagicNumber != 0x07230203) {
    errs() << "Wrong Magic Number: " << mMagicNumber;
    return false;
  }

  if (IS.empty()) {
    return false;
  }

  IS >> &mVersion.mWord;
  if (mVersion.mBytes[0] != 0 || mVersion.mBytes[3] != 0) {
    return false;
  }

  if (IS.empty()) {
    return false;
  }

  IS >> &mGeneratorMagicNumber >> &mBound >> &mReserved;

  DeserializeZeroOrMore<CapabilityInst>(IS, mCapabilities);
  DeserializeZeroOrMore<ExtensionInst>(IS, mExtensions);
  DeserializeZeroOrMore<ExtInstImportInst>(IS, mExtInstImports);

  mMemoryModel.reset(Deserialize<MemoryModelInst>(IS));
  if (!mMemoryModel) {
    errs() << "Missing memory model specification.\n";
    return false;
  }

  DeserializeZeroOrMore<EntryPointDefinition>(IS, mEntryPoints);
  DeserializeZeroOrMore<ExecutionModeInst>(IS, mExecutionModes);
  for (auto entry : mEntryPoints) {
    mEntryPointInsts.push_back(entry->getInstruction());
    for (auto mode : mExecutionModes) {
      entry->applyExecutionMode(mode);
    }
  }

  mDebugInfo.reset(Deserialize<DebugInfoSection>(IS));
  mAnnotations.reset(Deserialize<AnnotationSection>(IS));
  mGlobals.reset(Deserialize<GlobalSection>(IS));

  DeserializeZeroOrMore<FunctionDefinition>(IS, mFunctionDefinitions);

  if (mFunctionDefinitions.empty()) {
    errs() << "Missing function definitions.\n";
    for (int i = 0; i < 4; i++) {
      uint32_t w;
      IS >> &w;
      std::cout << std::hex << w << " ";
    }
    std::cout << std::endl;
    return false;
  }

  return true;
}

void Module::initialize() {
  mMagicNumber = 0x07230203;
  mVersion.mMajorMinor = {.mMinorNumber = 1, .mMajorNumber = 1};
  mGeneratorMagicNumber = 0x00070000;
  mBound = 0;
  mReserved = 0;
  mAnnotations.reset(new AnnotationSection());
}

void Module::SerializeHeader(OutputWordStream &OS) const {
  OS << mMagicNumber;
  OS << mVersion.mWord << mGeneratorMagicNumber;
  if (mBound == 0) {
    OS << mIdTable.end()->first + 1;
  } else {
    OS << std::max(mBound, mNextId);
  }
  OS << mReserved;
}

void Module::Serialize(OutputWordStream &OS) const {
  SerializeHeader(OS);
  Entity::Serialize(OS);
}

Module *Module::addCapability(Capability cap) {
  mCapabilities.push_back(mBuilder->MakeCapability(cap));
  return this;
}

Module *Module::setMemoryModel(AddressingModel am, MemoryModel mm) {
  mMemoryModel.reset(mBuilder->MakeMemoryModel(am, mm));
  return this;
}

Module *Module::addExtInstImport(const char *extName) {
  ExtInstImportInst *extInst = mBuilder->MakeExtInstImport(extName);
  mExtInstImports.push_back(extInst);
  if (strcmp(extName, "GLSL.std.450") == 0) {
    mGLExt = extInst;
  }
  return this;
}

Module *Module::addSource(SourceLanguage lang, int version) {
  if (!mDebugInfo) {
    mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
  }
  mDebugInfo->addSource(lang, version);
  return this;
}

Module *Module::addSourceExtension(const char *ext) {
  if (!mDebugInfo) {
    mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
  }
  mDebugInfo->addSourceExtension(ext);
  return this;
}

Module *Module::addString(const char *str) {
  if (!mDebugInfo) {
    mDebugInfo.reset(mBuilder->MakeDebugInfoSection());
  }
  mDebugInfo->addString(str);
  return this;
}

Module *Module::addEntryPoint(EntryPointDefinition *entry) {
  mEntryPoints.push_back(entry);
  auto newModes = entry->getExecutionModes();
  mExecutionModes.insert(mExecutionModes.end(), newModes.begin(),
                         newModes.end());
  return this;
}

GlobalSection *Module::getGlobalSection() {
  if (!mGlobals) {
    mGlobals.reset(new GlobalSection());
  }
  return mGlobals.get();
}

ConstantInst *Module::getConstant(TypeIntInst *type, int32_t value) {
  return getGlobalSection()->getConstant(type, value);
}

ConstantInst *Module::getConstant(TypeIntInst *type, uint32_t value) {
  return getGlobalSection()->getConstant(type, value);
}

ConstantInst *Module::getConstant(TypeFloatInst *type, float value) {
  return getGlobalSection()->getConstant(type, value);
}

ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
                                                    ConstantInst *components[],
                                                    size_t width) {
  return getGlobalSection()->getConstantComposite(type, components, width);
}

ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
                                                    ConstantInst *comp0,
                                                    ConstantInst *comp1,
                                                    ConstantInst *comp2) {
  // TODO: verify that component types are the same and consistent with the
  // resulting vector type
  ConstantInst *comps[] = {comp0, comp1, comp2};
  return getConstantComposite(type, comps, 3);
}

ConstantCompositeInst *Module::getConstantComposite(TypeVectorInst *type,
                                                    ConstantInst *comp0,
                                                    ConstantInst *comp1,
                                                    ConstantInst *comp2,
                                                    ConstantInst *comp3) {
  // TODO: verify that component types are the same and consistent with the
  // resulting vector type
  ConstantInst *comps[] = {comp0, comp1, comp2, comp3};
  return getConstantComposite(type, comps, 4);
}

TypeVoidInst *Module::getVoidType() {
  return getGlobalSection()->getVoidType();
}

TypeIntInst *Module::getIntType(int bits, bool isSigned) {
  return getGlobalSection()->getIntType(bits, isSigned);
}

TypeIntInst *Module::getUnsignedIntType(int bits) {
  return getIntType(bits, false);
}

TypeFloatInst *Module::getFloatType(int bits) {
  return getGlobalSection()->getFloatType(bits);
}

TypeVectorInst *Module::getVectorType(Instruction *componentType, int width) {
  return getGlobalSection()->getVectorType(componentType, width);
}

TypePointerInst *Module::getPointerType(StorageClass storage,
                                        Instruction *pointeeType) {
  return getGlobalSection()->getPointerType(storage, pointeeType);
}

TypeRuntimeArrayInst *Module::getRuntimeArrayType(Instruction *elementType) {
  return getGlobalSection()->getRuntimeArrayType(elementType);
}

TypeStructInst *Module::getStructType(Instruction *fieldType[], int numField) {
  return getGlobalSection()->getStructType(fieldType, numField);
}

TypeStructInst *Module::getStructType(Instruction *fieldType) {
  return getStructType(&fieldType, 1);
}

TypeFunctionInst *Module::getFunctionType(Instruction *retType,
                                          Instruction *const argType[],
                                          size_t numArg) {
  return getGlobalSection()->getFunctionType(retType, argType, numArg);
}

TypeFunctionInst *
Module::getFunctionType(Instruction *retType,
                        const std::vector<Instruction *> &argTypes) {
  return getGlobalSection()->getFunctionType(retType, argTypes.data(),
                                             argTypes.size());
}

size_t Module::getSize(TypeVoidInst *) { return 0; }

size_t Module::getSize(TypeIntInst *intTy) { return intTy->mOperand1 / 8; }

size_t Module::getSize(TypeFloatInst *fpTy) { return fpTy->mOperand1 / 8; }

size_t Module::getSize(TypeVectorInst *vTy) {
  return getSize(vTy->mOperand1.mInstruction) * vTy->mOperand2;
}

size_t Module::getSize(TypePointerInst *) {
  return 4; // TODO: or 8?
}

size_t Module::getSize(TypeStructInst *structTy) {
  size_t sz = 0;
  for (auto ty : structTy->mOperand1) {
    sz += getSize(ty.mInstruction);
  }
  return sz;
}

size_t Module::getSize(TypeFunctionInst *) {
  return 4; // TODO: or 8? Is this just the size of a pointer?
}

size_t Module::getSize(Instruction *inst) {
  switch (inst->getOpCode()) {
  case OpTypeVoid:
    return getSize(static_cast<TypeVoidInst *>(inst));
  case OpTypeInt:
    return getSize(static_cast<TypeIntInst *>(inst));
  case OpTypeFloat:
    return getSize(static_cast<TypeFloatInst *>(inst));
  case OpTypeVector:
    return getSize(static_cast<TypeVectorInst *>(inst));
  case OpTypeStruct:
    return getSize(static_cast<TypeStructInst *>(inst));
  case OpTypeFunction:
    return getSize(static_cast<TypeFunctionInst *>(inst));
  default:
    return 0;
  }
}

Module *Module::addFunctionDefinition(FunctionDefinition *func) {
  mFunctionDefinitions.push_back(func);
  return this;
}

Instruction *Module::lookupByName(const char *name) const {
  return mDebugInfo->lookupByName(name);
}

FunctionDefinition *
Module::getFunctionDefinitionFromInstruction(FunctionInst *inst) const {
  for (auto fdef : mFunctionDefinitions) {
    if (fdef->getInstruction() == inst) {
      return fdef;
    }
  }
  return nullptr;
}

FunctionDefinition *
Module::lookupFunctionDefinitionByName(const char *name) const {
  FunctionInst *inst = static_cast<FunctionInst *>(lookupByName(name));
  return getFunctionDefinitionFromInstruction(inst);
}

const char *Module::lookupNameByInstruction(const Instruction *inst) const {
  return mDebugInfo->lookupNameByInstruction(inst);
}

VariableInst *Module::getInvocationId() {
  return getGlobalSection()->getInvocationId();
}

VariableInst *Module::getNumWorkgroups() {
  return getGlobalSection()->getNumWorkgroups();
}

Module *Module::addStructType(TypeStructInst *structType) {
  getGlobalSection()->addStructType(structType);
  return this;
}

Module *Module::addVariable(VariableInst *var) {
  getGlobalSection()->addVariable(var);
  return this;
}

void Module::consolidateAnnotations() {
  std::vector<Instruction *> annotations(mAnnotations->begin(),
                                      mAnnotations->end());
  std::unique_ptr<IVisitor> v(
      CreateInstructionVisitor([&annotations](Instruction *inst) -> void {
        const auto &ann = inst->getAnnotations();
        annotations.insert(annotations.end(), ann.begin(), ann.end());
      }));
  v->visit(this);
  mAnnotations->clear();
  mAnnotations->addAnnotations(annotations.begin(), annotations.end());
}

EntryPointDefinition::EntryPointDefinition(Builder *builder,
                                           ExecutionModel execModel,
                                           FunctionDefinition *func,
                                           const char *name)
    : Entity(builder), mFunction(func->getInstruction()),
      mExecutionModel(execModel) {
  mName = strndup(name, strlen(name));
  mEntryPointInst = mBuilder->MakeEntryPoint(execModel, mFunction, mName);
}

bool EntryPointDefinition::DeserializeInternal(InputWordStream &IS) {
  if (IS.empty()) {
    return false;
  }

  if ((mEntryPointInst = Deserialize<EntryPointInst>(IS))) {
    return true;
  }

  return false;
}

EntryPointDefinition *
EntryPointDefinition::applyExecutionMode(ExecutionModeInst *mode) {
  if (mode->mOperand1.mInstruction == mFunction) {
    addExecutionMode(mode);
  }
  return this;
}

EntryPointDefinition *EntryPointDefinition::addToInterface(VariableInst *var) {
  mInterface.push_back(var);
  mEntryPointInst->mOperand4.push_back(var);
  return this;
}

EntryPointDefinition *EntryPointDefinition::setLocalSize(uint32_t width,
                                                         uint32_t height,
                                                         uint32_t depth) {
  mLocalSize.mWidth = width;
  mLocalSize.mHeight = height;
  mLocalSize.mDepth = depth;

  auto mode = mBuilder->MakeExecutionMode(mFunction, ExecutionMode::LocalSize);
  mode->addExtraOperand(width)->addExtraOperand(height)->addExtraOperand(depth);

  addExecutionMode(mode);

  return this;
}

bool DebugInfoSection::DeserializeInternal(InputWordStream &IS) {
  while (true) {
    if (auto str = Deserialize<StringInst>(IS)) {
      mSources.push_back(str);
    } else if (auto src = Deserialize<SourceInst>(IS)) {
      mSources.push_back(src);
    } else if (auto srcExt = Deserialize<SourceExtensionInst>(IS)) {
      mSources.push_back(srcExt);
    } else if (auto srcCont = Deserialize<SourceContinuedInst>(IS)) {
      mSources.push_back(srcCont);
    } else {
      break;
    }
  }

  while (true) {
    if (auto name = Deserialize<NameInst>(IS)) {
      mNames.push_back(name);
    } else if (auto memName = Deserialize<MemberNameInst>(IS)) {
      mNames.push_back(memName);
    } else {
      break;
    }
  }

  return true;
}

DebugInfoSection *DebugInfoSection::addSource(SourceLanguage lang,
                                              int version) {
  SourceInst *source = mBuilder->MakeSource(lang, version);
  mSources.push_back(source);
  return this;
}

DebugInfoSection *DebugInfoSection::addSourceExtension(const char *ext) {
  SourceExtensionInst *inst = mBuilder->MakeSourceExtension(ext);
  mSources.push_back(inst);
  return this;
}

DebugInfoSection *DebugInfoSection::addString(const char *str) {
  StringInst *source = mBuilder->MakeString(str);
  mSources.push_back(source);
  return this;
}

Instruction *DebugInfoSection::lookupByName(const char *name) const {
  for (auto inst : mNames) {
    if (inst->getOpCode() == OpName) {
      NameInst *nameInst = static_cast<NameInst *>(inst);
      if (nameInst->mOperand2.compare(name) == 0) {
        return nameInst->mOperand1.mInstruction;
      }
    }
    // Ignore member names
  }
  return nullptr;
}

const char *
DebugInfoSection::lookupNameByInstruction(const Instruction *target) const {
  for (auto inst : mNames) {
    if (inst->getOpCode() == OpName) {
      NameInst *nameInst = static_cast<NameInst *>(inst);
      if (nameInst->mOperand1.mInstruction == target) {
        return nameInst->mOperand2.c_str();
      }
    }
    // Ignore member names
  }
  return nullptr;
}

AnnotationSection::AnnotationSection() : mAnnotationsDeleter(mAnnotations) {}

AnnotationSection::AnnotationSection(Builder *b)
    : Entity(b), mAnnotationsDeleter(mAnnotations) {}

bool AnnotationSection::DeserializeInternal(InputWordStream &IS) {
  while (true) {
    if (auto decor = Deserialize<DecorateInst>(IS)) {
      mAnnotations.push_back(decor);
    } else if (auto decor = Deserialize<MemberDecorateInst>(IS)) {
      mAnnotations.push_back(decor);
    } else if (auto decor = Deserialize<GroupDecorateInst>(IS)) {
      mAnnotations.push_back(decor);
    } else if (auto decor = Deserialize<GroupMemberDecorateInst>(IS)) {
      mAnnotations.push_back(decor);
    } else if (auto decor = Deserialize<DecorationGroupInst>(IS)) {
      mAnnotations.push_back(decor);
    } else {
      break;
    }
  }
  return true;
}

GlobalSection::GlobalSection() : mGlobalDefsDeleter(mGlobalDefs) {}

GlobalSection::GlobalSection(Builder *builder)
    : Entity(builder), mGlobalDefsDeleter(mGlobalDefs) {}

namespace {

template <typename T>
T *findOrCreate(std::function<bool(T *)> criteria, std::function<T *()> factory,
                std::vector<Instruction *> *globals) {
  T *derived;
  for (auto inst : *globals) {
    if (inst->getOpCode() == T::mOpCode) {
      T *derived = static_cast<T *>(inst);
      if (criteria(derived)) {
        return derived;
      }
    }
  }
  derived = factory();
  globals->push_back(derived);
  return derived;
}

} // anonymous namespace

bool GlobalSection::DeserializeInternal(InputWordStream &IS) {
  while (true) {
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS)                                 \
  if (auto typeInst = Deserialize<INST_CLASS>(IS)) {                           \
    mGlobalDefs.push_back(typeInst);                                           \
    continue;                                                                  \
  }
#include "const_inst_dispatches_generated.h"
#include "type_inst_dispatches_generated.h"
#undef HANDLE_INSTRUCTION

    if (auto globalInst = Deserialize<VariableInst>(IS)) {
      // Check if this is function scoped
      if (globalInst->mOperand1 == StorageClass::Function) {
        Module::errs() << "warning: Variable (id = " << globalInst->mResult;
        Module::errs() << ") has function scope in global section.\n";
        // Khronos LLVM-SPIRV convertor emits "Function" storage-class globals.
        // As a workaround, accept such SPIR-V code here, and fix it up later
        // in the rs2spirv compiler by correcting the storage class.
        // In a stricter deserializer, such code should be rejected, and we
        // should return false here.
      }
      mGlobalDefs.push_back(globalInst);
      continue;
    }

    if (auto globalInst = Deserialize<UndefInst>(IS)) {
      mGlobalDefs.push_back(globalInst);
      continue;
    }
    break;
  }
  return true;
}

ConstantInst *GlobalSection::getConstant(TypeIntInst *type, int32_t value) {
  return findOrCreate<ConstantInst>(
      [=](ConstantInst *c) { return c->mOperand1.intValue == value; },
      [=]() -> ConstantInst * {
        LiteralContextDependentNumber cdn = {.intValue = value};
        return mBuilder->MakeConstant(type, cdn);
      },
      &mGlobalDefs);
}

ConstantInst *GlobalSection::getConstant(TypeIntInst *type, uint32_t value) {
  return findOrCreate<ConstantInst>(
      [=](ConstantInst *c) { return c->mOperand1.intValue == (int)value; },
      [=]() -> ConstantInst * {
        LiteralContextDependentNumber cdn = {.intValue = (int)value};
        return mBuilder->MakeConstant(type, cdn);
      },
      &mGlobalDefs);
}

ConstantInst *GlobalSection::getConstant(TypeFloatInst *type, float value) {
  return findOrCreate<ConstantInst>(
      [=](ConstantInst *c) { return c->mOperand1.floatValue == value; },
      [=]() -> ConstantInst * {
        LiteralContextDependentNumber cdn = {.floatValue = value};
        return mBuilder->MakeConstant(type, cdn);
      },
      &mGlobalDefs);
}

ConstantCompositeInst *
GlobalSection::getConstantComposite(TypeVectorInst *type,
                                    ConstantInst *components[], size_t width) {
  return findOrCreate<ConstantCompositeInst>(
      [=](ConstantCompositeInst *c) {
        if (c->mOperand1.size() != width) {
          return false;
        }
        for (size_t i = 0; i < width; i++) {
          if (c->mOperand1[i].mInstruction != components[i]) {
            return false;
          }
        }
        return true;
      },
      [=]() -> ConstantCompositeInst * {
        ConstantCompositeInst *c = mBuilder->MakeConstantComposite(type);
        for (size_t i = 0; i < width; i++) {
          c->mOperand1.push_back(components[i]);
        }
        return c;
      },
      &mGlobalDefs);
}

TypeVoidInst *GlobalSection::getVoidType() {
  return findOrCreate<TypeVoidInst>(
      [=](TypeVoidInst *) -> bool { return true; },
      [=]() -> TypeVoidInst * { return mBuilder->MakeTypeVoid(); },
      &mGlobalDefs);
}

TypeIntInst *GlobalSection::getIntType(int bits, bool isSigned) {
  if (isSigned) {
    switch (bits) {
#define HANDLE_INT_SIZE(INT_TYPE, BITS, SIGNED)                                \
  case BITS: {                                                                 \
    return findOrCreate<TypeIntInst>(                                          \
        [=](TypeIntInst *intTy) -> bool {                                      \
          return intTy->mOperand1 == BITS && intTy->mOperand2 == SIGNED;       \
        },                                                                     \
        [=]() -> TypeIntInst * {                                               \
          return mBuilder->MakeTypeInt(BITS, SIGNED);                          \
        },                                                                     \
        &mGlobalDefs);                                                         \
  }
      HANDLE_INT_SIZE(Int, 8, 1);
      HANDLE_INT_SIZE(Int, 16, 1);
      HANDLE_INT_SIZE(Int, 32, 1);
      HANDLE_INT_SIZE(Int, 64, 1);
    default:
      Module::errs() << "unexpected int type";
    }
  } else {
    switch (bits) {
      HANDLE_INT_SIZE(UInt, 8, 0);
      HANDLE_INT_SIZE(UInt, 16, 0);
      HANDLE_INT_SIZE(UInt, 32, 0);
      HANDLE_INT_SIZE(UInt, 64, 0);
    default:
      Module::errs() << "unexpected int type";
    }
  }
#undef HANDLE_INT_SIZE
  return nullptr;
}

TypeFloatInst *GlobalSection::getFloatType(int bits) {
  switch (bits) {
#define HANDLE_FLOAT_SIZE(BITS)                                                \
  case BITS: {                                                                 \
    return findOrCreate<TypeFloatInst>(                                        \
        [=](TypeFloatInst *floatTy) -> bool {                                  \
          return floatTy->mOperand1 == BITS;                                   \
        },                                                                     \
        [=]() -> TypeFloatInst * { return mBuilder->MakeTypeFloat(BITS); },    \
        &mGlobalDefs);                                                         \
  }
    HANDLE_FLOAT_SIZE(16);
    HANDLE_FLOAT_SIZE(32);
    HANDLE_FLOAT_SIZE(64);
  default:
    Module::errs() << "unexpeced floating point type";
  }
#undef HANDLE_FLOAT_SIZE
  return nullptr;
}

TypeVectorInst *GlobalSection::getVectorType(Instruction *componentType,
                                             int width) {
  // TODO: verify that componentType is basic numeric types

  return findOrCreate<TypeVectorInst>(
      [=](TypeVectorInst *vecTy) -> bool {
        return vecTy->mOperand1.mInstruction == componentType &&
               vecTy->mOperand2 == width;
      },
      [=]() -> TypeVectorInst * {
        return mBuilder->MakeTypeVector(componentType, width);
      },
      &mGlobalDefs);
}

TypePointerInst *GlobalSection::getPointerType(StorageClass storage,
                                               Instruction *pointeeType) {
  return findOrCreate<TypePointerInst>(
      [=](TypePointerInst *type) -> bool {
        return type->mOperand1 == storage &&
               type->mOperand2.mInstruction == pointeeType;
      },
      [=]() -> TypePointerInst * {
        return mBuilder->MakeTypePointer(storage, pointeeType);
      },
      &mGlobalDefs);
}

TypeRuntimeArrayInst *
GlobalSection::getRuntimeArrayType(Instruction *elemType) {
  return findOrCreate<TypeRuntimeArrayInst>(
      [=](TypeRuntimeArrayInst * /*type*/) -> bool {
        // return type->mOperand1.mInstruction == elemType;
        return false;
      },
      [=]() -> TypeRuntimeArrayInst * {
        return mBuilder->MakeTypeRuntimeArray(elemType);
      },
      &mGlobalDefs);
}

TypeStructInst *GlobalSection::getStructType(Instruction *fieldType[],
                                             int numField) {
  TypeStructInst *structTy = mBuilder->MakeTypeStruct();
  for (int i = 0; i < numField; i++) {
    structTy->mOperand1.push_back(fieldType[i]);
  }
  mGlobalDefs.push_back(structTy);
  return structTy;
}

TypeFunctionInst *GlobalSection::getFunctionType(Instruction *retType,
                                                 Instruction *const argType[],
                                                 size_t numArg) {
  return findOrCreate<TypeFunctionInst>(
      [=](TypeFunctionInst *type) -> bool {
        if (type->mOperand1.mInstruction != retType ||
            type->mOperand2.size() != numArg) {
          return false;
        }
        for (size_t i = 0; i < numArg; i++) {
          if (type->mOperand2[i].mInstruction != argType[i]) {
            return false;
          }
        }
        return true;
      },
      [=]() -> TypeFunctionInst * {
        TypeFunctionInst *funcTy = mBuilder->MakeTypeFunction(retType);
        for (size_t i = 0; i < numArg; i++) {
          funcTy->mOperand2.push_back(argType[i]);
        }
        return funcTy;
      },
      &mGlobalDefs);
}

GlobalSection *GlobalSection::addStructType(TypeStructInst *structType) {
  mGlobalDefs.push_back(structType);
  return this;
}

GlobalSection *GlobalSection::addVariable(VariableInst *var) {
  mGlobalDefs.push_back(var);
  return this;
}

VariableInst *GlobalSection::getInvocationId() {
  if (mInvocationId) {
    return mInvocationId.get();
  }

  TypeIntInst *UIntTy = getIntType(32, false);
  TypeVectorInst *V3UIntTy = getVectorType(UIntTy, 3);
  TypePointerInst *V3UIntPtrTy = getPointerType(StorageClass::Input, V3UIntTy);

  VariableInst *InvocationId =
      mBuilder->MakeVariable(V3UIntPtrTy, StorageClass::Input);
  InvocationId->decorate(Decoration::BuiltIn)
      ->addExtraOperand(static_cast<uint32_t>(BuiltIn::GlobalInvocationId));

  mInvocationId.reset(InvocationId);

  return InvocationId;
}

VariableInst *GlobalSection::getNumWorkgroups() {
  if (mNumWorkgroups) {
    return mNumWorkgroups.get();
  }

  TypeIntInst *UIntTy = getIntType(32, false);
  TypeVectorInst *V3UIntTy = getVectorType(UIntTy, 3);
  TypePointerInst *V3UIntPtrTy = getPointerType(StorageClass::Input, V3UIntTy);

  VariableInst *GNum = mBuilder->MakeVariable(V3UIntPtrTy, StorageClass::Input);
  GNum->decorate(Decoration::BuiltIn)
      ->addExtraOperand(static_cast<uint32_t>(BuiltIn::NumWorkgroups));

  mNumWorkgroups.reset(GNum);

  return GNum;
}

bool FunctionDeclaration::DeserializeInternal(InputWordStream &IS) {
  if (!Deserialize<FunctionInst>(IS)) {
    return false;
  }

  DeserializeZeroOrMore<FunctionParameterInst>(IS, mParams);

  if (!Deserialize<FunctionEndInst>(IS)) {
    return false;
  }

  return true;
}

template <> Instruction *Deserialize(InputWordStream &IS) {
  Instruction *inst;

  switch ((*IS) & 0xFFFF) {
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS)                                 \
  case OPCODE:                                                                 \
    inst = Deserialize<INST_CLASS>(IS);                                        \
    break;
#include "instruction_dispatches_generated.h"
#undef HANDLE_INSTRUCTION
  default:
    Module::errs() << "unrecognized instruction";
    inst = nullptr;
  }

  return inst;
}

bool Block::DeserializeInternal(InputWordStream &IS) {
  Instruction *inst;
  while (((*IS) & 0xFFFF) != OpFunctionEnd &&
         (inst = Deserialize<Instruction>(IS))) {
    mInsts.push_back(inst);
    if (inst->getOpCode() == OpBranch ||
        inst->getOpCode() == OpBranchConditional ||
        inst->getOpCode() == OpSwitch || inst->getOpCode() == OpKill ||
        inst->getOpCode() == OpReturn || inst->getOpCode() == OpReturnValue ||
        inst->getOpCode() == OpUnreachable) {
      break;
    }
  }
  return !mInsts.empty();
}

FunctionDefinition::FunctionDefinition()
    : mParamsDeleter(mParams), mBlocksDeleter(mBlocks) {}

FunctionDefinition::FunctionDefinition(Builder *builder, FunctionInst *func,
                                       FunctionEndInst *end)
    : Entity(builder), mFunc(func), mFuncEnd(end), mParamsDeleter(mParams),
      mBlocksDeleter(mBlocks) {}

bool FunctionDefinition::DeserializeInternal(InputWordStream &IS) {
  mFunc.reset(Deserialize<FunctionInst>(IS));
  if (!mFunc) {
    return false;
  }

  DeserializeZeroOrMore<FunctionParameterInst>(IS, mParams);
  DeserializeZeroOrMore<Block>(IS, mBlocks);

  mFuncEnd.reset(Deserialize<FunctionEndInst>(IS));
  if (!mFuncEnd) {
    return false;
  }

  return true;
}

Instruction *FunctionDefinition::getReturnType() const {
  return mFunc->mResultType.mInstruction;
}

} // namespace spirit
} // namespace android
