//===- 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>
#include <optional>

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.
  uint32_t RequiredExtensions;

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

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

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

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

  bool HasMasked :1;
  bool HasVL :1;
  bool HasMaskedOffOperand :1;
  bool HasTailPolicy : 1;
  bool HasMaskPolicy : 1;
  bool HasFRMRoundModeOp : 1;
  bool IsTuple : 1;
  LLVM_PREFERRED_TYPE(PolicyScheme)
  uint8_t UnMaskedPolicyScheme : 2;
  LLVM_PREFERRED_TYPE(PolicyScheme)
  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;
  RVVTypeCache TypeCache;

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;
  case 'y':
    return BasicType::BFloat16;
    break;
  default:
    return BasicType::Unknown;
  }
}

static VectorTypeModifier getTupleVTM(unsigned NF) {
  assert(2 <= NF && NF <= 8 && "2 <= NF <= 8");
  return static_cast<VectorTypeModifier>(
      static_cast<uint8_t>(VectorTypeModifier::Tuple2) + (NF - 2));
}

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";

  OS << "  PolicyAttrs = " << RVVI->getPolicyAttrsBits() << ";\n";

  if (RVVI->hasManualCodegen()) {
    OS << "IsMasked = " << (RVVI->isMasked() ? "true" : "false") << ";\n";
    OS << RVVI->getManualCodegen();
    OS << "break;\n";
    return;
  }

  for (const auto &I : enumerate(RVVI->getInputTypes())) {
    if (I.value()->isPointer()) {
      assert(RVVI->getIntrinsicTypes().front() == -1 &&
             "RVVI should be vector load intrinsic.");
    }
  }

  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(),"
              " PolicyAttrs));\n";
      if (RVVI->hasMaskedOffOperand() && RVVI->getPolicyAttrs().isTAMAPolicy())
        OS << "  Ops.insert(Ops.begin(), "
              "llvm::PoisonValue::get(ResultType));\n";
      // Masked reduction cases.
      if (!RVVI->hasMaskedOffOperand() && RVVI->hasPassthruOperand() &&
          RVVI->getPolicyAttrs().isTAMAPolicy())
        OS << "  Ops.insert(Ops.begin(), "
              "llvm::PoisonValue::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(), "
            "PolicyAttrs));\n";
    else if (RVVI->hasPassthruOperand() && RVVI->getPolicyAttrs().isTAPolicy())
      OS << "  Ops.insert(Ops.begin(), llvm::PoisonValue::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());

  for (const SemaRecord &SR : SemaRecords) {
    InsertToSignatureSet(SR.Prototype);
    InsertToSignatureSet(SR.Suffix);
    InsertToSignatureSet(SR.OverloadedSuffix);
  }

  for (auto &Sig : Signatures)
    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 << "#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 = TypeCache.computeType(BasicType::Int8, Log2LMUL,
                                   PrototypeDescriptor::Mask);
    if (T)
      printType(*T);
  }
  // Print RVV int/float types.
  for (char I : StringRef("csil")) {
    BasicType BT = ParseBasicType(I);
    for (int Log2LMUL : Log2LMULs) {
      auto T = TypeCache.computeType(BT, Log2LMUL, PrototypeDescriptor::Vector);
      if (T) {
        printType(*T);
        auto UT = TypeCache.computeType(
            BT, Log2LMUL,
            PrototypeDescriptor(BaseTypeModifier::Vector,
                                VectorTypeModifier::NoModifier,
                                TypeModifier::UnsignedInteger));
        printType(*UT);
      }
      for (int NF = 2; NF <= 8; ++NF) {
        auto TupleT = TypeCache.computeType(
            BT, Log2LMUL,
            PrototypeDescriptor(BaseTypeModifier::Vector, getTupleVTM(NF),
                                TypeModifier::SignedInteger));
        auto TupleUT = TypeCache.computeType(
            BT, Log2LMUL,
            PrototypeDescriptor(BaseTypeModifier::Vector, getTupleVTM(NF),
                                TypeModifier::UnsignedInteger));
        if (TupleT)
          printType(*TupleT);
        if (TupleUT)
          printType(*TupleUT);
      }
    }
  }

  for (BasicType BT : {BasicType::Float16, BasicType::Float32,
                       BasicType::Float64, BasicType::BFloat16}) {
    for (int Log2LMUL : Log2LMULs) {
      auto T = TypeCache.computeType(BT, Log2LMUL, PrototypeDescriptor::Vector);
      if (T)
        printType(*T);
      for (int NF = 2; NF <= 8; ++NF) {
        auto TupleT = TypeCache.computeType(
            BT, Log2LMUL,
            PrototypeDescriptor(BaseTypeModifier::Vector, getTupleVTM(NF),
                                (BT == BasicType::BFloat16
                                     ? TypeModifier::BFloat
                                     : TypeModifier::Float)));
        if (TupleT)
          printType(*TupleT);
      }
    }
  }

  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->getPolicyAttrs() < B->getPolicyAttrs());
    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->getPolicyAttrs() != PrevDef->getPolicyAttrs())) {
      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->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 SupportOverloading = R->getValueAsBit("SupportOverloading");
    bool HasBuiltinAlias = R->getValueAsBit("HasBuiltinAlias");
    StringRef ManualCodegen = R->getValueAsString("ManualCodegen");
    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");
    bool IsTuple = R->getValueAsBit("IsTuple");
    bool HasFRMRoundModeOp = R->getValueAsBit("HasFRMRoundModeOp");

    const Policy DefaultPolicy;
    SmallVector<Policy> SupportedUnMaskedPolicies =
        RVVIntrinsic::getSupportedUnMaskedPolicies();
    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, UnMaskedPolicyScheme,
        DefaultPolicy, IsTuple);
    llvm::SmallVector<PrototypeDescriptor> MaskedPrototype;
    if (HasMasked)
      MaskedPrototype = RVVIntrinsic::computeBuiltinTypes(
          BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL, NF,
          MaskedPolicyScheme, DefaultPolicy, IsTuple);

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

        auto SuffixStr =
            RVVIntrinsic::getSuffixStr(TypeCache, BT, Log2LMUL, SuffixDesc);
        auto OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
            TypeCache, 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,
            DefaultPolicy, HasFRMRoundModeOp));
        if (UnMaskedPolicyScheme != PolicyScheme::SchemeNone)
          for (auto P : SupportedUnMaskedPolicies) {
            SmallVector<PrototypeDescriptor> PolicyPrototype =
                RVVIntrinsic::computeBuiltinTypes(
                    BasicPrototype, /*IsMasked=*/false,
                    /*HasMaskedOffOperand=*/false, HasVL, NF,
                    UnMaskedPolicyScheme, P, IsTuple);
            std::optional<RVVTypes> PolicyTypes =
                TypeCache.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, IntrinsicTypes, RequiredFeatures,
                NF, P, HasFRMRoundModeOp));
          }
        if (!HasMasked)
          continue;
        // Create a masked intrinsic
        std::optional<RVVTypes> MaskTypes =
            TypeCache.computeTypes(BT, Log2LMUL, NF, MaskedPrototype);
        Out.push_back(std::make_unique<RVVIntrinsic>(
            Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName,
            /*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme,
            SupportOverloading, HasBuiltinAlias, ManualCodegen, *MaskTypes,
            IntrinsicTypes, RequiredFeatures, NF, DefaultPolicy,
            HasFRMRoundModeOp));
        if (MaskedPolicyScheme == PolicyScheme::SchemeNone)
          continue;
        for (auto P : SupportedMaskedPolicies) {
          SmallVector<PrototypeDescriptor> PolicyPrototype =
              RVVIntrinsic::computeBuiltinTypes(
                  BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
                  NF, MaskedPolicyScheme, P, IsTuple);
          std::optional<RVVTypes> PolicyTypes =
              TypeCache.computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
          Out.push_back(std::make_unique<RVVIntrinsic>(
              Name, SuffixStr, OverloadedName, OverloadedSuffixStr,
              MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
              MaskedPolicyScheme, SupportOverloading, HasBuiltinAlias,
              ManualCodegen, *PolicyTypes, IntrinsicTypes, RequiredFeatures, NF,
              P, HasFRMRoundModeOp));
        }
      } // 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("Zvfhmin", RVV_REQ_Zvfhmin)
              .Case("Xsfvcp", RVV_REQ_Xsfvcp)
              .Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf)
              .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq)
              .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod)
              .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq)
              .Case("Zvbb", RVV_REQ_Zvbb)
              .Case("Zvbc", RVV_REQ_Zvbc)
              .Case("Zvkb", RVV_REQ_Zvkb)
              .Case("Zvkg", RVV_REQ_Zvkg)
              .Case("Zvkned", RVV_REQ_Zvkned)
              .Case("Zvknha", RVV_REQ_Zvknha)
              .Case("Zvknhb", RVV_REQ_Zvknhb)
              .Case("Zvksed", RVV_REQ_Zvksed)
              .Case("Zvksh", RVV_REQ_Zvksh)
              .Case("Zvfbfwma", RVV_REQ_Zvfbfwma)
              .Case("Zvfbfmin", RVV_REQ_Zvfbfmin)
              .Case("Experimental", RVV_REQ_Experimental)
              .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.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);
    SR.IsTuple = IsTuple;
    SR.HasFRMRoundModeOp = HasFRMRoundModeOp;

    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.HasTailPolicy = SR.HasTailPolicy;
    R.HasMaskPolicy = SR.HasMaskPolicy;
    R.UnMaskedPolicyScheme = SR.UnMaskedPolicyScheme;
    R.MaskedPolicyScheme = SR.MaskedPolicyScheme;
    R.IsTuple = SR.IsTuple;
    R.HasFRMRoundModeOp = SR.HasFRMRoundModeOp;

    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
