//===- RISCVVEmitter.cpp - Generate riscv_vector.h for use with clang -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting riscv_vector.h which
// includes a declaration and definition of each intrinsic functions specified
// in https://github.com/riscv/rvv-intrinsic-doc.
//
// See also the documentation in include/clang/Basic/riscv_vector.td.
//
//===----------------------------------------------------------------------===//

#include "clang/Support/RISCVVIntrinsicUtils.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <numeric>

using namespace llvm;
using namespace clang::RISCV;

namespace {
struct SemaRecord {
  // Intrinsic name, e.g. vadd_vv
  std::string Name;

  // Overloaded intrinsic name, could be empty if can be computed from Name
  // e.g. vadd
  std::string OverloadedName;

  // Supported type, mask of BasicType.
  unsigned TypeRangeMask;

  // Supported LMUL.
  unsigned Log2LMULMask;

  // Required extensions for this intrinsic.
  unsigned RequiredExtensions;

  // Prototype for this intrinsic.
  SmallVector<PrototypeDescriptor> Prototype;

  // Suffix of intrinsic name.
  SmallVector<PrototypeDescriptor> Suffix;

  // Suffix of overloaded intrinsic name.
  SmallVector<PrototypeDescriptor> OverloadedSuffix;

  // BitMask for supported policies.
  uint16_t PolicyBitMask;

  // Number of field, large than 1 if it's segment load/store.
  unsigned NF;

  bool HasMasked :1;
  bool HasVL :1;
  bool HasMaskedOffOperand :1;
  bool IsPrototypeDefaultTU : 1;
  bool HasTailPolicy : 1;
  bool HasMaskPolicy : 1;
  uint8_t UnMaskedPolicyScheme : 2;
  uint8_t MaskedPolicyScheme : 2;
};

// Compressed function signature table.
class SemaSignatureTable {
private:
  std::vector<PrototypeDescriptor> SignatureTable;

  void insert(ArrayRef<PrototypeDescriptor> Signature);

public:
  static constexpr unsigned INVALID_INDEX = ~0U;

  // Create compressed signature table from SemaRecords.
  void init(ArrayRef<SemaRecord> SemaRecords);

  // Query the Signature, return INVALID_INDEX if not found.
  unsigned getIndex(ArrayRef<PrototypeDescriptor> Signature);

  /// Print signature table in RVVHeader Record to \p OS
  void print(raw_ostream &OS);
};

class RVVEmitter {
private:
  RecordKeeper &Records;

public:
  RVVEmitter(RecordKeeper &R) : Records(R) {}

  /// Emit riscv_vector.h
  void createHeader(raw_ostream &o);

  /// Emit all the __builtin prototypes and code needed by Sema.
  void createBuiltins(raw_ostream &o);

  /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
  void createCodeGen(raw_ostream &o);

  /// Emit all the information needed by SemaRISCVVectorLookup.cpp.
  /// We've large number of intrinsic function for RVV, creating a customized
  /// could speed up the compilation time.
  void createSema(raw_ostream &o);

private:
  /// Create all intrinsics and add them to \p Out and SemaRecords.
  void createRVVIntrinsics(std::vector<std::unique_ptr<RVVIntrinsic>> &Out,
                           std::vector<SemaRecord> *SemaRecords = nullptr);
  /// Create all intrinsic records and SemaSignatureTable from SemaRecords.
  void createRVVIntrinsicRecords(std::vector<RVVIntrinsicRecord> &Out,
                                 SemaSignatureTable &SST,
                                 ArrayRef<SemaRecord> SemaRecords);

  /// Print HeaderCode in RVVHeader Record to \p Out
  void printHeaderCode(raw_ostream &OS);
};

} // namespace

static BasicType ParseBasicType(char c) {
  switch (c) {
  case 'c':
    return BasicType::Int8;
    break;
  case 's':
    return BasicType::Int16;
    break;
  case 'i':
    return BasicType::Int32;
    break;
  case 'l':
    return BasicType::Int64;
    break;
  case 'x':
    return BasicType::Float16;
    break;
  case 'f':
    return BasicType::Float32;
    break;
  case 'd':
    return BasicType::Float64;
    break;

  default:
    return BasicType::Unknown;
  }
}

void emitCodeGenSwitchBody(const RVVIntrinsic *RVVI, raw_ostream &OS) {
  if (!RVVI->getIRName().empty())
    OS << "  ID = Intrinsic::riscv_" + RVVI->getIRName() + ";\n";
  if (RVVI->getNF() >= 2)
    OS << "  NF = " + utostr(RVVI->getNF()) + ";\n";
  // We had initialized DefaultPolicy as TU/TUMU in CodeGen function.
  if (RVVI->getDefaultPolicy() != Policy::TU &&
      RVVI->getDefaultPolicy() != Policy::TUMU && !RVVI->hasPassthruOperand() &&
      !RVVI->hasManualCodegen() && RVVI->hasVL())
    OS << "  DefaultPolicy = " << RVVI->getDefaultPolicyBits() << ";\n";

  if (RVVI->hasManualCodegen()) {
    OS << "  DefaultPolicy = " << RVVI->getDefaultPolicyBits() << ";\n";
    OS << RVVI->getManualCodegen();
    OS << "break;\n";
    return;
  }

  // Cast pointer operand of vector load intrinsic.
  for (const auto &I : enumerate(RVVI->getInputTypes())) {
    if (I.value()->isPointer()) {
      assert(RVVI->getIntrinsicTypes().front() == -1 &&
             "RVVI should be vector load intrinsic.");
      OS << "  Ops[" << I.index() << "] = Builder.CreateBitCast(Ops[";
      OS << I.index() << "], ResultType->getPointerTo());\n";
    }
  }

  if (RVVI->isMasked()) {
    if (RVVI->hasVL()) {
      OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);\n";
      if (RVVI->hasPolicyOperand())
        OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(),"
              " DefaultPolicy));\n";
      if (RVVI->hasMaskedOffOperand() &&
          RVVI->getDefaultPolicy() == Policy::TAMA)
        OS << "  Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));\n";
      // Masked reduction cases.
      if (!RVVI->hasMaskedOffOperand() && RVVI->hasPassthruOperand() &&
          RVVI->getDefaultPolicy() == Policy::TAMA)
        OS << "  Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));\n";
    } else {
      OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());\n";
    }
  } else {
    if (RVVI->hasPolicyOperand())
      OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(), "
            "DefaultPolicy));\n";
    else if (RVVI->hasPassthruOperand() &&
             RVVI->getDefaultPolicy() == Policy::TA)
      OS << "  Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));\n";
  }

  OS << "  IntrinsicTypes = {";
  ListSeparator LS;
  for (const auto &Idx : RVVI->getIntrinsicTypes()) {
    if (Idx == -1)
      OS << LS << "ResultType";
    else
      OS << LS << "Ops[" << Idx << "]->getType()";
  }

  // VL could be i64 or i32, need to encode it in IntrinsicTypes. VL is
  // always last operand.
  if (RVVI->hasVL())
    OS << ", Ops.back()->getType()";
  OS << "};\n";
  OS << "  break;\n";
}

//===----------------------------------------------------------------------===//
// SemaSignatureTable implementation
//===----------------------------------------------------------------------===//
void SemaSignatureTable::init(ArrayRef<SemaRecord> SemaRecords) {
  // Sort signature entries by length, let longer signature insert first, to
  // make it more possible to reuse table entries, that can reduce ~10% table
  // size.
  struct Compare {
    bool operator()(const SmallVector<PrototypeDescriptor> &A,
                    const SmallVector<PrototypeDescriptor> &B) const {
      if (A.size() != B.size())
        return A.size() > B.size();

      size_t Len = A.size();
      for (size_t i = 0; i < Len; ++i) {
        if (A[i] != B[i])
          return A[i] < B[i];
      }

      return false;
    }
  };

  std::set<SmallVector<PrototypeDescriptor>, Compare> Signatures;
  auto InsertToSignatureSet =
      [&](const SmallVector<PrototypeDescriptor> &Signature) {
        if (Signature.empty())
          return;

        Signatures.insert(Signature);
      };

  assert(!SemaRecords.empty());

  llvm::for_each(SemaRecords, [&](const SemaRecord &SR) {
    InsertToSignatureSet(SR.Prototype);
    InsertToSignatureSet(SR.Suffix);
    InsertToSignatureSet(SR.OverloadedSuffix);
  });

  llvm::for_each(Signatures, [this](auto &Sig) { insert(Sig); });
}

void SemaSignatureTable::insert(ArrayRef<PrototypeDescriptor> Signature) {
  if (getIndex(Signature) != INVALID_INDEX)
    return;

  // Insert Signature into SignatureTable if not found in the table.
  SignatureTable.insert(SignatureTable.begin(), Signature.begin(),
                        Signature.end());
}

unsigned SemaSignatureTable::getIndex(ArrayRef<PrototypeDescriptor> Signature) {
  // Empty signature could be point into any index since there is length
  // field when we use, so just always point it to 0.
  if (Signature.empty())
    return 0;

  // Checking Signature already in table or not.
  if (Signature.size() < SignatureTable.size()) {
    size_t Bound = SignatureTable.size() - Signature.size() + 1;
    for (size_t Index = 0; Index < Bound; ++Index) {
      if (equal(Signature.begin(), Signature.end(),
                SignatureTable.begin() + Index))
        return Index;
    }
  }

  return INVALID_INDEX;
}

void SemaSignatureTable::print(raw_ostream &OS) {
  for (const auto &Sig : SignatureTable)
    OS << "PrototypeDescriptor(" << static_cast<int>(Sig.PT) << ", "
       << static_cast<int>(Sig.VTM) << ", " << static_cast<int>(Sig.TM)
       << "),\n";
}

//===----------------------------------------------------------------------===//
// RVVEmitter implementation
//===----------------------------------------------------------------------===//
void RVVEmitter::createHeader(raw_ostream &OS) {

  OS << "/*===---- riscv_vector.h - RISC-V V-extension RVVIntrinsics "
        "-------------------===\n"
        " *\n"
        " *\n"
        " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
        "Exceptions.\n"
        " * See https://llvm.org/LICENSE.txt for license information.\n"
        " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
        " *\n"
        " *===-----------------------------------------------------------------"
        "------===\n"
        " */\n\n";

  OS << "#ifndef __RISCV_VECTOR_H\n";
  OS << "#define __RISCV_VECTOR_H\n\n";

  OS << "#include <stdint.h>\n";
  OS << "#include <stddef.h>\n\n";

  OS << "#ifndef __riscv_vector\n";
  OS << "#error \"Vector intrinsics require the vector extension.\"\n";
  OS << "#endif\n\n";

  OS << "#ifdef __cplusplus\n";
  OS << "extern \"C\" {\n";
  OS << "#endif\n\n";

  OS << "#pragma clang riscv intrinsic vector\n\n";

  printHeaderCode(OS);

  auto printType = [&](auto T) {
    OS << "typedef " << T->getClangBuiltinStr() << " " << T->getTypeStr()
       << ";\n";
  };

  constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3};
  // Print RVV boolean types.
  for (int Log2LMUL : Log2LMULs) {
    auto T = RVVType::computeType(BasicType::Int8, Log2LMUL,
                                  PrototypeDescriptor::Mask);
    if (T)
      printType(T.value());
  }
  // Print RVV int/float types.
  for (char I : StringRef("csil")) {
    BasicType BT = ParseBasicType(I);
    for (int Log2LMUL : Log2LMULs) {
      auto T = RVVType::computeType(BT, Log2LMUL, PrototypeDescriptor::Vector);
      if (T) {
        printType(T.value());
        auto UT = RVVType::computeType(
            BT, Log2LMUL,
            PrototypeDescriptor(BaseTypeModifier::Vector,
                                VectorTypeModifier::NoModifier,
                                TypeModifier::UnsignedInteger));
        printType(UT.value());
      }
    }
  }
  OS << "#if defined(__riscv_zvfh)\n";
  for (int Log2LMUL : Log2LMULs) {
    auto T = RVVType::computeType(BasicType::Float16, Log2LMUL,
                                  PrototypeDescriptor::Vector);
    if (T)
      printType(T.value());
  }
  OS << "#endif\n";

  OS << "#if (__riscv_v_elen_fp >= 32)\n";
  for (int Log2LMUL : Log2LMULs) {
    auto T = RVVType::computeType(BasicType::Float32, Log2LMUL,
                                  PrototypeDescriptor::Vector);
    if (T)
      printType(T.value());
  }
  OS << "#endif\n";

  OS << "#if (__riscv_v_elen_fp >= 64)\n";
  for (int Log2LMUL : Log2LMULs) {
    auto T = RVVType::computeType(BasicType::Float64, Log2LMUL,
                                  PrototypeDescriptor::Vector);
    if (T)
      printType(T.value());
  }
  OS << "#endif\n\n";

  OS << "#define __riscv_v_intrinsic_overloading 1\n";

  OS << "\n#ifdef __cplusplus\n";
  OS << "}\n";
  OS << "#endif // __cplusplus\n";
  OS << "#endif // __RISCV_VECTOR_H\n";
}

void RVVEmitter::createBuiltins(raw_ostream &OS) {
  std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
  createRVVIntrinsics(Defs);

  // Map to keep track of which builtin names have already been emitted.
  StringMap<RVVIntrinsic *> BuiltinMap;

  OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n";
  OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, "
        "ATTRS, \"zve32x\")\n";
  OS << "#endif\n";
  for (auto &Def : Defs) {
    auto P =
        BuiltinMap.insert(std::make_pair(Def->getBuiltinName(), Def.get()));
    if (!P.second) {
      // Verf that this would have produced the same builtin definition.
      if (P.first->second->hasBuiltinAlias() != Def->hasBuiltinAlias())
        PrintFatalError("Builtin with same name has different hasAutoDef");
      else if (!Def->hasBuiltinAlias() &&
               P.first->second->getBuiltinTypeStr() != Def->getBuiltinTypeStr())
        PrintFatalError("Builtin with same name has different type string");
      continue;
    }
    OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getBuiltinName() << ",\"";
    if (!Def->hasBuiltinAlias())
      OS << Def->getBuiltinTypeStr();
    OS << "\", \"n\")\n";
  }
  OS << "#undef RISCVV_BUILTIN\n";
}

void RVVEmitter::createCodeGen(raw_ostream &OS) {
  std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
  createRVVIntrinsics(Defs);
  // IR name could be empty, use the stable sort preserves the relative order.
  llvm::stable_sort(Defs, [](const std::unique_ptr<RVVIntrinsic> &A,
                             const std::unique_ptr<RVVIntrinsic> &B) {
    if (A->getIRName() == B->getIRName())
      return (A->getDefaultPolicy() < B->getDefaultPolicy());
    return (A->getIRName() < B->getIRName());
  });

  // Map to keep track of which builtin names have already been emitted.
  StringMap<RVVIntrinsic *> BuiltinMap;

  // Print switch body when the ir name, ManualCodegen or policy changes from
  // previous iteration.
  RVVIntrinsic *PrevDef = Defs.begin()->get();
  for (auto &Def : Defs) {
    StringRef CurIRName = Def->getIRName();
    if (CurIRName != PrevDef->getIRName() ||
        (Def->getManualCodegen() != PrevDef->getManualCodegen()) ||
        (Def->getDefaultPolicy() != PrevDef->getDefaultPolicy())) {
      emitCodeGenSwitchBody(PrevDef, OS);
    }
    PrevDef = Def.get();

    auto P =
        BuiltinMap.insert(std::make_pair(Def->getBuiltinName(), Def.get()));
    if (P.second) {
      OS << "case RISCVVector::BI__builtin_rvv_" << Def->getBuiltinName()
         << ":\n";
      continue;
    }

    if (P.first->second->getIRName() != Def->getIRName())
      PrintFatalError("Builtin with same name has different IRName");
    else if (P.first->second->getManualCodegen() != Def->getManualCodegen())
      PrintFatalError("Builtin with same name has different ManualCodegen");
    else if (P.first->second->getNF() != Def->getNF())
      PrintFatalError("Builtin with same name has different NF");
    else if (P.first->second->isMasked() != Def->isMasked())
      PrintFatalError("Builtin with same name has different isMasked");
    else if (P.first->second->hasVL() != Def->hasVL())
      PrintFatalError("Builtin with same name has different hasVL");
    else if (P.first->second->getPolicyScheme() != Def->getPolicyScheme())
      PrintFatalError("Builtin with same name has different getPolicyScheme");
    else if (P.first->second->getIntrinsicTypes() != Def->getIntrinsicTypes())
      PrintFatalError("Builtin with same name has different IntrinsicTypes");
  }
  emitCodeGenSwitchBody(Defs.back().get(), OS);
  OS << "\n";
}

void RVVEmitter::createRVVIntrinsics(
    std::vector<std::unique_ptr<RVVIntrinsic>> &Out,
    std::vector<SemaRecord> *SemaRecords) {
  std::vector<Record *> RV = Records.getAllDerivedDefinitions("RVVBuiltin");
  for (auto *R : RV) {
    StringRef Name = R->getValueAsString("Name");
    StringRef SuffixProto = R->getValueAsString("Suffix");
    StringRef OverloadedName = R->getValueAsString("OverloadedName");
    StringRef OverloadedSuffixProto = R->getValueAsString("OverloadedSuffix");
    StringRef Prototypes = R->getValueAsString("Prototype");
    StringRef TypeRange = R->getValueAsString("TypeRange");
    bool HasMasked = R->getValueAsBit("HasMasked");
    bool HasMaskedOffOperand = R->getValueAsBit("HasMaskedOffOperand");
    bool HasVL = R->getValueAsBit("HasVL");
    Record *MPSRecord = R->getValueAsDef("MaskedPolicyScheme");
    auto MaskedPolicyScheme =
        static_cast<PolicyScheme>(MPSRecord->getValueAsInt("Value"));
    Record *UMPSRecord = R->getValueAsDef("UnMaskedPolicyScheme");
    auto UnMaskedPolicyScheme =
        static_cast<PolicyScheme>(UMPSRecord->getValueAsInt("Value"));
    std::vector<int64_t> Log2LMULList = R->getValueAsListOfInts("Log2LMUL");
    bool HasTailPolicy = R->getValueAsBit("HasTailPolicy");
    bool HasMaskPolicy = R->getValueAsBit("HasMaskPolicy");
    bool IsPrototypeDefaultTU = R->getValueAsBit("IsPrototypeDefaultTU");
    bool SupportOverloading = R->getValueAsBit("SupportOverloading");
    bool HasBuiltinAlias = R->getValueAsBit("HasBuiltinAlias");
    StringRef ManualCodegen = R->getValueAsString("ManualCodegen");
    StringRef MaskedManualCodegen = R->getValueAsString("MaskedManualCodegen");
    std::vector<int64_t> IntrinsicTypes =
        R->getValueAsListOfInts("IntrinsicTypes");
    std::vector<StringRef> RequiredFeatures =
        R->getValueAsListOfStrings("RequiredFeatures");
    StringRef IRName = R->getValueAsString("IRName");
    StringRef MaskedIRName = R->getValueAsString("MaskedIRName");
    unsigned NF = R->getValueAsInt("NF");

    // If unmasked builtin supports policy, they should be TU or TA.
    SmallVector<Policy> SupportedUnMaskedPolicies = {Policy::TU, Policy::TA};
    SmallVector<Policy> SupportedMaskedPolicies =
        RVVIntrinsic::getSupportedMaskedPolicies(HasTailPolicy, HasMaskPolicy);

    // Parse prototype and create a list of primitive type with transformers
    // (operand) in Prototype. Prototype[0] is output operand.
    SmallVector<PrototypeDescriptor> BasicPrototype =
        parsePrototypes(Prototypes);

    SmallVector<PrototypeDescriptor> SuffixDesc = parsePrototypes(SuffixProto);
    SmallVector<PrototypeDescriptor> OverloadedSuffixDesc =
        parsePrototypes(OverloadedSuffixProto);

    // Compute Builtin types
    auto Prototype = RVVIntrinsic::computeBuiltinTypes(
        BasicPrototype, /*IsMasked=*/false,
        /*HasMaskedOffOperand=*/false, HasVL, NF, IsPrototypeDefaultTU,
        UnMaskedPolicyScheme);
    auto MaskedPrototype = RVVIntrinsic::computeBuiltinTypes(
        BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL, NF,
        IsPrototypeDefaultTU, MaskedPolicyScheme);

    // Create Intrinsics for each type and LMUL.
    for (char I : TypeRange) {
      for (int Log2LMUL : Log2LMULList) {
        BasicType BT = ParseBasicType(I);
        Optional<RVVTypes> Types =
            RVVType::computeTypes(BT, Log2LMUL, NF, Prototype);
        // Ignored to create new intrinsic if there are any illegal types.
        if (!Types)
          continue;

        auto SuffixStr = RVVIntrinsic::getSuffixStr(BT, Log2LMUL, SuffixDesc);
        auto OverloadedSuffixStr =
            RVVIntrinsic::getSuffixStr(BT, Log2LMUL, OverloadedSuffixDesc);
        // Create a unmasked intrinsic
        Out.push_back(std::make_unique<RVVIntrinsic>(
            Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
            /*IsMasked=*/false, /*HasMaskedOffOperand=*/false, HasVL,
            UnMaskedPolicyScheme, SupportOverloading, HasBuiltinAlias,
            ManualCodegen, *Types, IntrinsicTypes, RequiredFeatures, NF,
            Policy::PolicyNone, IsPrototypeDefaultTU));
        if (UnMaskedPolicyScheme != PolicyScheme::SchemeNone)
          for (auto P : SupportedUnMaskedPolicies) {
            SmallVector<PrototypeDescriptor> PolicyPrototype =
                RVVIntrinsic::computeBuiltinTypes(
                    BasicPrototype, /*IsMasked=*/false,
                    /*HasMaskedOffOperand=*/false, HasVL, NF,
                    IsPrototypeDefaultTU, UnMaskedPolicyScheme, P);
            Optional<RVVTypes> PolicyTypes =
                RVVType::computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
            Out.push_back(std::make_unique<RVVIntrinsic>(
                Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
                /*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL,
                UnMaskedPolicyScheme, SupportOverloading, HasBuiltinAlias,
                ManualCodegen, PolicyTypes.value(), IntrinsicTypes,
                RequiredFeatures, NF, P, IsPrototypeDefaultTU));
          }
        if (!HasMasked)
          continue;
        // Create a masked intrinsic
        Optional<RVVTypes> MaskTypes =
            RVVType::computeTypes(BT, Log2LMUL, NF, Prototype);
        Out.push_back(std::make_unique<RVVIntrinsic>(
            Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName,
            /*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme,
            SupportOverloading, HasBuiltinAlias, MaskedManualCodegen,
            MaskTypes.value(), IntrinsicTypes, RequiredFeatures, NF,
            Policy::PolicyNone, IsPrototypeDefaultTU));
        if (MaskedPolicyScheme == PolicyScheme::SchemeNone)
          continue;
        for (auto P : SupportedMaskedPolicies) {
          SmallVector<PrototypeDescriptor> PolicyPrototype =
              RVVIntrinsic::computeBuiltinTypes(
                  BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
                  NF, IsPrototypeDefaultTU, MaskedPolicyScheme, P);
          Optional<RVVTypes> PolicyTypes =
              RVVType::computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
          Out.push_back(std::make_unique<RVVIntrinsic>(
              Name, SuffixStr, OverloadedName, OverloadedSuffixStr,
              MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
              MaskedPolicyScheme, SupportOverloading, HasBuiltinAlias,
              MaskedManualCodegen, PolicyTypes.value(), IntrinsicTypes,
              RequiredFeatures, NF, P, IsPrototypeDefaultTU));
        }
      } // End for Log2LMULList
    }   // End for TypeRange

    // We don't emit vsetvli and vsetvlimax for SemaRecord.
    // They are written in riscv_vector.td and will emit those marco define in
    // riscv_vector.h
    if (Name == "vsetvli" || Name == "vsetvlimax")
      continue;

    if (!SemaRecords)
      continue;

    // Create SemaRecord
    SemaRecord SR;
    SR.Name = Name.str();
    SR.OverloadedName = OverloadedName.str();
    BasicType TypeRangeMask = BasicType::Unknown;
    for (char I : TypeRange)
      TypeRangeMask |= ParseBasicType(I);

    SR.TypeRangeMask = static_cast<unsigned>(TypeRangeMask);

    unsigned Log2LMULMask = 0;
    for (int Log2LMUL : Log2LMULList)
      Log2LMULMask |= 1 << (Log2LMUL + 3);

    SR.Log2LMULMask = Log2LMULMask;

    SR.RequiredExtensions = 0;
    for (auto RequiredFeature : RequiredFeatures) {
      RVVRequire RequireExt = StringSwitch<RVVRequire>(RequiredFeature)
                                  .Case("RV64", RVV_REQ_RV64)
                                  .Case("FullMultiply", RVV_REQ_FullMultiply)
                                  .Default(RVV_REQ_None);
      assert(RequireExt != RVV_REQ_None && "Unrecognized required feature?");
      SR.RequiredExtensions |= RequireExt;
    }

    SR.NF = NF;
    SR.HasMasked = HasMasked;
    SR.HasVL = HasVL;
    SR.HasMaskedOffOperand = HasMaskedOffOperand;
    SR.IsPrototypeDefaultTU = IsPrototypeDefaultTU;
    SR.HasTailPolicy = HasTailPolicy;
    SR.HasMaskPolicy = HasMaskPolicy;
    SR.UnMaskedPolicyScheme = static_cast<uint8_t>(UnMaskedPolicyScheme);
    SR.MaskedPolicyScheme = static_cast<uint8_t>(MaskedPolicyScheme);
    SR.Prototype = std::move(BasicPrototype);
    SR.Suffix = parsePrototypes(SuffixProto);
    SR.OverloadedSuffix = parsePrototypes(OverloadedSuffixProto);

    SemaRecords->push_back(SR);
  }
}

void RVVEmitter::printHeaderCode(raw_ostream &OS) {
  std::vector<Record *> RVVHeaders =
      Records.getAllDerivedDefinitions("RVVHeader");
  for (auto *R : RVVHeaders) {
    StringRef HeaderCodeStr = R->getValueAsString("HeaderCode");
    OS << HeaderCodeStr.str();
  }
}

void RVVEmitter::createRVVIntrinsicRecords(std::vector<RVVIntrinsicRecord> &Out,
                                           SemaSignatureTable &SST,
                                           ArrayRef<SemaRecord> SemaRecords) {
  SST.init(SemaRecords);

  for (const auto &SR : SemaRecords) {
    Out.emplace_back(RVVIntrinsicRecord());
    RVVIntrinsicRecord &R = Out.back();
    R.Name = SR.Name.c_str();
    R.OverloadedName = SR.OverloadedName.c_str();
    R.PrototypeIndex = SST.getIndex(SR.Prototype);
    R.SuffixIndex = SST.getIndex(SR.Suffix);
    R.OverloadedSuffixIndex = SST.getIndex(SR.OverloadedSuffix);
    R.PrototypeLength = SR.Prototype.size();
    R.SuffixLength = SR.Suffix.size();
    R.OverloadedSuffixSize = SR.OverloadedSuffix.size();
    R.RequiredExtensions = SR.RequiredExtensions;
    R.TypeRangeMask = SR.TypeRangeMask;
    R.Log2LMULMask = SR.Log2LMULMask;
    R.NF = SR.NF;
    R.HasMasked = SR.HasMasked;
    R.HasVL = SR.HasVL;
    R.HasMaskedOffOperand = SR.HasMaskedOffOperand;
    R.IsPrototypeDefaultTU = SR.IsPrototypeDefaultTU;
    R.HasTailPolicy = SR.HasTailPolicy;
    R.HasMaskPolicy = SR.HasMaskPolicy;
    R.UnMaskedPolicyScheme = SR.UnMaskedPolicyScheme;
    R.MaskedPolicyScheme = SR.MaskedPolicyScheme;

    assert(R.PrototypeIndex !=
           static_cast<uint16_t>(SemaSignatureTable::INVALID_INDEX));
    assert(R.SuffixIndex !=
           static_cast<uint16_t>(SemaSignatureTable::INVALID_INDEX));
    assert(R.OverloadedSuffixIndex !=
           static_cast<uint16_t>(SemaSignatureTable::INVALID_INDEX));
  }
}

void RVVEmitter::createSema(raw_ostream &OS) {
  std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
  std::vector<RVVIntrinsicRecord> RVVIntrinsicRecords;
  SemaSignatureTable SST;
  std::vector<SemaRecord> SemaRecords;

  createRVVIntrinsics(Defs, &SemaRecords);

  createRVVIntrinsicRecords(RVVIntrinsicRecords, SST, SemaRecords);

  // Emit signature table for SemaRISCVVectorLookup.cpp.
  OS << "#ifdef DECL_SIGNATURE_TABLE\n";
  SST.print(OS);
  OS << "#endif\n";

  // Emit RVVIntrinsicRecords for SemaRISCVVectorLookup.cpp.
  OS << "#ifdef DECL_INTRINSIC_RECORDS\n";
  for (const RVVIntrinsicRecord &Record : RVVIntrinsicRecords)
    OS << Record;
  OS << "#endif\n";
}

namespace clang {
void EmitRVVHeader(RecordKeeper &Records, raw_ostream &OS) {
  RVVEmitter(Records).createHeader(OS);
}

void EmitRVVBuiltins(RecordKeeper &Records, raw_ostream &OS) {
  RVVEmitter(Records).createBuiltins(OS);
}

void EmitRVVBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
  RVVEmitter(Records).createCodeGen(OS);
}

void EmitRVVBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
  RVVEmitter(Records).createSema(OS);
}

} // End namespace clang
