//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
//
// 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 emits information about intrinsic functions.
//
//===----------------------------------------------------------------------===//

#include "Basic/CodeGenIntrinsics.h"
#include "Basic/SequenceToOffsetTable.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <cctype>
#include <map>
#include <optional>
#include <string>
#include <utility>
#include <vector>
using namespace llvm;

static cl::OptionCategory GenIntrinsicCat("Options for -gen-intrinsic-enums");
static cl::opt<std::string>
    IntrinsicPrefix("intrinsic-prefix",
                    cl::desc("Generate intrinsics with this target prefix"),
                    cl::value_desc("target prefix"), cl::cat(GenIntrinsicCat));

namespace {
class IntrinsicEmitter {
  const RecordKeeper &Records;

public:
  IntrinsicEmitter(const RecordKeeper &R) : Records(R) {}

  void run(raw_ostream &OS, bool Enums);

  void EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
  void EmitArgKind(raw_ostream &OS);
  void EmitIITInfo(raw_ostream &OS);
  void EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
  void EmitIntrinsicToNameTable(const CodeGenIntrinsicTable &Ints,
                                raw_ostream &OS);
  void EmitIntrinsicToOverloadTable(const CodeGenIntrinsicTable &Ints,
                                    raw_ostream &OS);
  void EmitGenerator(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
  void EmitAttributes(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
  void EmitIntrinsicToBuiltinMap(const CodeGenIntrinsicTable &Ints,
                                 bool IsClang, raw_ostream &OS);
};

// Helper class to use with `TableGen::Emitter::OptClass`.
template <bool Enums> class IntrinsicEmitterOpt : public IntrinsicEmitter {
public:
  IntrinsicEmitterOpt(const RecordKeeper &R) : IntrinsicEmitter(R) {}
  void run(raw_ostream &OS) { IntrinsicEmitter::run(OS, Enums); }
};

} // End anonymous namespace

//===----------------------------------------------------------------------===//
// IntrinsicEmitter Implementation
//===----------------------------------------------------------------------===//

void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) {
  emitSourceFileHeader("Intrinsic Function Source Fragment", OS);

  CodeGenIntrinsicTable Ints(Records);

  if (Enums) {
    // Emit the enum information.
    EmitEnumInfo(Ints, OS);

    // Emit ArgKind for Intrinsics.h.
    EmitArgKind(OS);
  } else {
    // Emit IIT_Info constants.
    EmitIITInfo(OS);

    // Emit the target metadata.
    EmitTargetInfo(Ints, OS);

    // Emit the intrinsic ID -> name table.
    EmitIntrinsicToNameTable(Ints, OS);

    // Emit the intrinsic ID -> overload table.
    EmitIntrinsicToOverloadTable(Ints, OS);

    // Emit the intrinsic declaration generator.
    EmitGenerator(Ints, OS);

    // Emit the intrinsic parameter attributes.
    EmitAttributes(Ints, OS);

    // Emit code to translate Clang builtins into LLVM intrinsics.
    EmitIntrinsicToBuiltinMap(Ints, true, OS);

    // Emit code to translate MS builtins into LLVM intrinsics.
    EmitIntrinsicToBuiltinMap(Ints, false, OS);
  }
}

void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
                                    raw_ostream &OS) {
  // Find the TargetSet for which to generate enums. There will be an initial
  // set with an empty target prefix which will include target independent
  // intrinsics like dbg.value.
  using TargetSet = CodeGenIntrinsicTable::TargetSet;
  const TargetSet *Set = nullptr;
  for (const auto &Target : Ints.getTargets()) {
    if (Target.Name == IntrinsicPrefix) {
      Set = &Target;
      break;
    }
  }
  if (!Set) {
    // The first entry is for target independent intrinsics, so drop it.
    auto KnowTargets = Ints.getTargets().drop_front();
    PrintFatalError([KnowTargets](raw_ostream &OS) {
      OS << "tried to generate intrinsics for unknown target "
         << IntrinsicPrefix << "\nKnown targets are: ";
      interleaveComma(KnowTargets, OS,
                      [&OS](const TargetSet &Target) { OS << Target.Name; });
      OS << '\n';
    });
  }

  // Generate a complete header for target specific intrinsics.
  if (IntrinsicPrefix.empty()) {
    OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
  } else {
    std::string UpperPrefix = StringRef(IntrinsicPrefix).upper();
    OS << formatv("#ifndef LLVM_IR_INTRINSIC_{}_ENUMS_H\n", UpperPrefix);
    OS << formatv("#define LLVM_IR_INTRINSIC_{}_ENUMS_H\n", UpperPrefix);
    OS << "namespace llvm::Intrinsic {\n";
    OS << formatv("enum {}Intrinsics : unsigned {{\n", UpperPrefix);
  }

  OS << "// Enum values for intrinsics.\n";
  bool First = true;
  for (const auto &Int : Ints[*Set]) {
    OS << "    " << Int.EnumName;

    // Assign a value to the first intrinsic in this target set so that all
    // intrinsic ids are distinct.
    if (First) {
      OS << " = " << Set->Offset + 1;
      First = false;
    }

    OS << ", ";
    if (Int.EnumName.size() < 40)
      OS.indent(40 - Int.EnumName.size());
    OS << formatv(" // {}\n", Int.Name);
  }

  // Emit num_intrinsics into the target neutral enum.
  if (IntrinsicPrefix.empty()) {
    OS << formatv("    num_intrinsics = {}\n", Ints.size() + 1);
    OS << "#endif\n\n";
  } else {
    OS << R"(}; // enum
} // namespace llvm::Intrinsic
#endif

)";
  }
}

void IntrinsicEmitter::EmitArgKind(raw_ostream &OS) {
  if (!IntrinsicPrefix.empty())
    return;
  OS << "// llvm::Intrinsic::IITDescriptor::ArgKind.\n";
  OS << "#ifdef GET_INTRINSIC_ARGKIND\n";
  if (const auto RecArgKind = Records.getDef("ArgKind")) {
    for (const auto &RV : RecArgKind->getValues())
      OS << "    AK_" << RV.getName() << " = " << *RV.getValue() << ",\n";
  } else {
    OS << "#error \"ArgKind is not defined\"\n";
  }
  OS << "#endif\n\n";
}

void IntrinsicEmitter::EmitIITInfo(raw_ostream &OS) {
  OS << "#ifdef GET_INTRINSIC_IITINFO\n";
  std::array<StringRef, 256> RecsByNumber;
  auto IIT_Base = Records.getAllDerivedDefinitionsIfDefined("IIT_Base");
  for (const Record *Rec : IIT_Base) {
    auto Number = Rec->getValueAsInt("Number");
    assert(0 <= Number && Number < (int)RecsByNumber.size() &&
           "IIT_Info.Number should be uint8_t");
    assert(RecsByNumber[Number].empty() && "Duplicate IIT_Info.Number");
    RecsByNumber[Number] = Rec->getName();
  }
  if (IIT_Base.size() > 0) {
    for (unsigned I = 0, E = RecsByNumber.size(); I < E; ++I)
      if (!RecsByNumber[I].empty())
        OS << "  " << RecsByNumber[I] << " = " << I << ",\n";
  } else {
    OS << "#error \"class IIT_Base is not defined\"\n";
  }
  OS << "#endif\n\n";
}

void IntrinsicEmitter::EmitTargetInfo(const CodeGenIntrinsicTable &Ints,
                                      raw_ostream &OS) {
  OS << R"(// Target mapping.
#ifdef GET_INTRINSIC_TARGET_DATA
struct IntrinsicTargetInfo {
  StringLiteral Name;
  size_t Offset;
  size_t Count;
};
static constexpr IntrinsicTargetInfo TargetInfos[] = {
)";
  for (const auto [Name, Offset, Count] : Ints.getTargets())
    OS << formatv("  {{\"{}\", {}, {}},\n", Name, Offset, Count);
  OS << R"(};
#endif

)";
}

void IntrinsicEmitter::EmitIntrinsicToNameTable(
    const CodeGenIntrinsicTable &Ints, raw_ostream &OS) {
  // Built up a table of the intrinsic names.
  constexpr StringLiteral NotIntrinsic = "not_intrinsic";
  StringToOffsetTable Table;
  Table.GetOrAddStringOffset(NotIntrinsic);
  for (const auto &Int : Ints)
    Table.GetOrAddStringOffset(Int.Name);

  OS << R"(// Intrinsic ID to name table.
#ifdef GET_INTRINSIC_NAME_TABLE
// Note that entry #0 is the invalid intrinsic!

)";

  Table.EmitStringLiteralDef(OS, "static constexpr char IntrinsicNameTable[]",
                             /*Indent=*/"");

  OS << R"(
static constexpr unsigned IntrinsicNameOffsetTable[] = {
)";

  OS << formatv("  {}, // {}\n", Table.GetStringOffset(NotIntrinsic),
                NotIntrinsic);
  for (const auto &Int : Ints)
    OS << formatv("  {}, // {}\n", Table.GetStringOffset(Int.Name), Int.Name);

  OS << R"(
}; // IntrinsicNameOffsetTable

#endif

)";
}

void IntrinsicEmitter::EmitIntrinsicToOverloadTable(
    const CodeGenIntrinsicTable &Ints, raw_ostream &OS) {
  OS << R"(// Intrinsic ID to overload bitset.
#ifdef GET_INTRINSIC_OVERLOAD_TABLE
static constexpr uint8_t OTable[] = {
  0
  )";
  for (auto [I, Int] : enumerate(Ints)) {
    // Add one to the index so we emit a null bit for the invalid #0 intrinsic.
    size_t Idx = I + 1;

    if (Idx % 8 == 0)
      OS << ",\n  0";
    if (Int.isOverloaded)
      OS << " | (1<<" << Idx % 8 << ')';
  }
  OS << "\n};\n\n";
  // OTable contains a true bit at the position if the intrinsic is overloaded.
  OS << "return (OTable[id/8] & (1 << (id%8))) != 0;\n";
  OS << "#endif\n\n";
}

using TypeSigTy = SmallVector<unsigned char>;

/// Computes type signature of the intrinsic \p Int.
static TypeSigTy ComputeTypeSignature(const CodeGenIntrinsic &Int) {
  TypeSigTy TypeSig;
  const Record *TypeInfo = Int.TheDef->getValueAsDef("TypeInfo");
  const ListInit *TypeList = TypeInfo->getValueAsListInit("TypeSig");

  for (const auto *TypeListEntry : TypeList->getValues())
    TypeSig.emplace_back(cast<IntInit>(TypeListEntry)->getValue());
  return TypeSig;
}

// Pack the type signature into 32-bit fixed encoding word.
static std::optional<uint32_t> encodePacked(const TypeSigTy &TypeSig) {
  if (TypeSig.size() > 8)
    return std::nullopt;

  uint32_t Result = 0;
  for (unsigned char C : reverse(TypeSig)) {
    if (C > 15)
      return std::nullopt;
    Result = (Result << 4) | C;
  }
  return Result;
}

void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints,
                                     raw_ostream &OS) {
  // Note: the code below can be switched to use 32-bit fixed encoding by
  // flipping the flag below.
  constexpr bool Use16BitFixedEncoding = true;
  using FixedEncodingTy =
      std::conditional_t<Use16BitFixedEncoding, uint16_t, uint32_t>;
  constexpr unsigned FixedEncodingBits = sizeof(FixedEncodingTy) * CHAR_BIT;
  // Mask with all bits 1 except the most significant bit.
  const unsigned Mask = (1U << (FixedEncodingBits - 1)) - 1;
  const unsigned MSBPostion = FixedEncodingBits - 1;
  StringRef FixedEncodingTypeName =
      Use16BitFixedEncoding ? "uint16_t" : "uint32_t";

  // If we can compute a 16/32-bit fixed encoding for this intrinsic, do so and
  // capture it in this vector, otherwise store a ~0U.
  std::vector<FixedEncodingTy> FixedEncodings;
  SequenceToOffsetTable<TypeSigTy> LongEncodingTable;

  FixedEncodings.reserve(Ints.size());

  // Compute the unique argument type info.
  for (const CodeGenIntrinsic &Int : Ints) {
    // Get the signature for the intrinsic.
    TypeSigTy TypeSig = ComputeTypeSignature(Int);

    // Check to see if we can encode it into a 16/32 bit word.
    std::optional<uint32_t> Result = encodePacked(TypeSig);
    if (Result && (*Result & Mask) == Result) {
      FixedEncodings.push_back(static_cast<FixedEncodingTy>(*Result));
      continue;
    }

    LongEncodingTable.add(TypeSig);

    // This is a placehold that we'll replace after the table is laid out.
    FixedEncodings.push_back(static_cast<FixedEncodingTy>(~0U));
  }

  LongEncodingTable.layout();

  OS << formatv(R"(// Global intrinsic function declaration type table.
#ifdef GET_INTRINSIC_GENERATOR_GLOBAL
static constexpr {} IIT_Table[] = {{
  )",
                FixedEncodingTypeName);

  unsigned MaxOffset = 0;
  for (auto [Idx, FixedEncoding, Int] : enumerate(FixedEncodings, Ints)) {
    if ((Idx & 7) == 7)
      OS << "\n  ";

    // If the entry fit in the table, just emit it.
    if ((FixedEncoding & Mask) == FixedEncoding) {
      OS << "0x" << Twine::utohexstr(FixedEncoding) << ", ";
      continue;
    }

    TypeSigTy TypeSig = ComputeTypeSignature(Int);
    unsigned Offset = LongEncodingTable.get(TypeSig);
    MaxOffset = std::max(MaxOffset, Offset);

    // Otherwise, emit the offset into the long encoding table.  We emit it this
    // way so that it is easier to read the offset in the .def file.
    OS << formatv("(1U<<{}) | {}, ", MSBPostion, Offset);
  }

  OS << "0\n};\n\n";

  // verify that all offsets will fit in 16/32 bits.
  if ((MaxOffset & Mask) != MaxOffset)
    PrintFatalError("Offset of long encoding table exceeds encoding bits");

  // Emit the shared table of register lists.
  OS << "static constexpr unsigned char IIT_LongEncodingTable[] = {\n";
  if (!LongEncodingTable.empty())
    LongEncodingTable.emit(
        OS, [](raw_ostream &OS, unsigned char C) { OS << (unsigned)C; });
  OS << "  255\n};\n";
  OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL
}

/// Returns the effective MemoryEffects for intrinsic \p Int.
static MemoryEffects getEffectiveME(const CodeGenIntrinsic &Int) {
  MemoryEffects ME = Int.ME;
  // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
  if (ME.doesNotAccessMemory() && Int.hasSideEffects)
    ME = MemoryEffects::unknown();
  return ME;
}

static bool compareFnAttributes(const CodeGenIntrinsic *L,
                                const CodeGenIntrinsic *R) {
  auto TieBoolAttributes = [](const CodeGenIntrinsic *I) -> auto {
    // Sort throwing intrinsics after non-throwing intrinsics.
    return std::tie(I->canThrow, I->isNoDuplicate, I->isNoMerge, I->isNoReturn,
                    I->isNoCallback, I->isNoSync, I->isNoFree, I->isWillReturn,
                    I->isCold, I->isConvergent, I->isSpeculatable,
                    I->hasSideEffects, I->isStrictFP);
  };

  auto TieL = TieBoolAttributes(L);
  auto TieR = TieBoolAttributes(R);

  if (TieL != TieR)
    return TieL < TieR;

  // Try to order by readonly/readnone attribute.
  uint32_t LME = getEffectiveME(*L).toIntValue();
  uint32_t RME = getEffectiveME(*R).toIntValue();
  if (LME != RME)
    return LME > RME;

  return false;
}

/// Returns true if \p Int has a non-empty set of function attributes. Note that
/// NoUnwind = !canThrow, so we need to negate it's sense to test if the
// intrinsic has NoUnwind attribute.
static bool hasFnAttributes(const CodeGenIntrinsic &Int) {
  return !Int.canThrow || Int.isNoReturn || Int.isNoCallback || Int.isNoSync ||
         Int.isNoFree || Int.isWillReturn || Int.isCold || Int.isNoDuplicate ||
         Int.isNoMerge || Int.isConvergent || Int.isSpeculatable ||
         Int.isStrictFP || getEffectiveME(Int) != MemoryEffects::unknown();
}

namespace {
struct FnAttributeComparator {
  bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
    return compareFnAttributes(L, R);
  }
};

struct AttributeComparator {
  bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
    // Order all intrinsics with no functiona attributes before all intrinsics
    // with function attributes.
    bool HasFnAttrLHS = hasFnAttributes(*L);
    bool HasFnAttrRHS = hasFnAttributes(*R);

    // Order by argument attributes if function `hasFnAttributes` is equal.
    // This is reliable because each side is already sorted internally.
    return std::tie(HasFnAttrLHS, L->ArgumentAttributes) <
           std::tie(HasFnAttrRHS, R->ArgumentAttributes);
  }
};
} // End anonymous namespace

/// Returns the name of the IR enum for argument attribute kind \p Kind.
static StringRef getArgAttrEnumName(CodeGenIntrinsic::ArgAttrKind Kind) {
  switch (Kind) {
  case CodeGenIntrinsic::NoCapture:
    return "NoCapture";
  case CodeGenIntrinsic::NoAlias:
    return "NoAlias";
  case CodeGenIntrinsic::NoUndef:
    return "NoUndef";
  case CodeGenIntrinsic::NonNull:
    return "NonNull";
  case CodeGenIntrinsic::Returned:
    return "Returned";
  case CodeGenIntrinsic::ReadOnly:
    return "ReadOnly";
  case CodeGenIntrinsic::WriteOnly:
    return "WriteOnly";
  case CodeGenIntrinsic::ReadNone:
    return "ReadNone";
  case CodeGenIntrinsic::ImmArg:
    return "ImmArg";
  case CodeGenIntrinsic::Alignment:
    return "Alignment";
  case CodeGenIntrinsic::Dereferenceable:
    return "Dereferenceable";
  }
  llvm_unreachable("Unknown CodeGenIntrinsic::ArgAttrKind enum");
}

/// EmitAttributes - This emits the Intrinsic::getAttributes method.
void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
                                      raw_ostream &OS) {
  OS << R"(// Add parameter attributes that are not common to all intrinsics.
#ifdef GET_INTRINSIC_ATTRIBUTES
static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
  switch (ID) {
  default: llvm_unreachable("Invalid attribute set number");)";
  // Compute unique argument attribute sets.
  std::map<SmallVector<CodeGenIntrinsic::ArgAttribute, 0>, unsigned>
      UniqArgAttributes;
  for (const CodeGenIntrinsic &Int : Ints) {
    for (auto &Attrs : Int.ArgumentAttributes) {
      if (Attrs.empty())
        continue;

      unsigned ID = UniqArgAttributes.size();
      if (!UniqArgAttributes.try_emplace(Attrs, ID).second)
        continue;

      assert(is_sorted(Attrs) && "Argument attributes are not sorted");

      OS << formatv(R"(
  case {}:
    return AttributeSet::get(C, {{
)",
                    ID);
      for (const CodeGenIntrinsic::ArgAttribute &Attr : Attrs) {
        StringRef AttrName = getArgAttrEnumName(Attr.Kind);
        if (Attr.Kind == CodeGenIntrinsic::Alignment ||
            Attr.Kind == CodeGenIntrinsic::Dereferenceable)
          OS << formatv("      Attribute::get(C, Attribute::{}, {}),\n",
                        AttrName, Attr.Value);
        else
          OS << formatv("      Attribute::get(C, Attribute::{}),\n", AttrName);
      }
      OS << "    });";
    }
  }
  OS << R"(
  }
} // getIntrinsicArgAttributeSet
)";

  // Compute unique function attribute sets.
  std::map<const CodeGenIntrinsic *, unsigned, FnAttributeComparator>
      UniqFnAttributes;
  OS << R"(
static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
  switch (ID) {
    default: llvm_unreachable("Invalid attribute set number");)";

  for (const CodeGenIntrinsic &Int : Ints) {
    if (!hasFnAttributes(Int))
      continue;
    unsigned ID = UniqFnAttributes.size();
    if (!UniqFnAttributes.try_emplace(&Int, ID).second)
      continue;
    OS << formatv(R"(
  case {}:
    return AttributeSet::get(C, {{
)",
                  ID);
    auto addAttribute = [&OS](StringRef Attr) {
      OS << formatv("      Attribute::get(C, Attribute::{}),\n", Attr);
    };
    if (!Int.canThrow)
      addAttribute("NoUnwind");
    if (Int.isNoReturn)
      addAttribute("NoReturn");
    if (Int.isNoCallback)
      addAttribute("NoCallback");
    if (Int.isNoSync)
      addAttribute("NoSync");
    if (Int.isNoFree)
      addAttribute("NoFree");
    if (Int.isWillReturn)
      addAttribute("WillReturn");
    if (Int.isCold)
      addAttribute("Cold");
    if (Int.isNoDuplicate)
      addAttribute("NoDuplicate");
    if (Int.isNoMerge)
      addAttribute("NoMerge");
    if (Int.isConvergent)
      addAttribute("Convergent");
    if (Int.isSpeculatable)
      addAttribute("Speculatable");
    if (Int.isStrictFP)
      addAttribute("StrictFP");

    const MemoryEffects ME = getEffectiveME(Int);
    if (ME != MemoryEffects::unknown()) {
      OS << formatv("      // {}\n", ME);
      OS << formatv("      Attribute::getWithMemoryEffects(C, "
                    "MemoryEffects::createFromIntValue({})),\n",
                    ME.toIntValue());
    }
    OS << "    });";
  }
  OS << R"(
  }
} // getIntrinsicFnAttributeSet

AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
)";

  // Compute the maximum number of attribute arguments and the map. For function
  // attributes, we only consider whether the intrinsics has any function
  // arguments or not.
  std::map<const CodeGenIntrinsic *, unsigned, AttributeComparator>
      UniqAttributes;
  for (const CodeGenIntrinsic &Int : Ints) {
    unsigned ID = UniqAttributes.size();
    UniqAttributes.try_emplace(&Int, ID);
  }

  // Assign a 16-bit packed ID for each intrinsic. The lower 8-bits will be its
  // "argument attribute ID" (index in UniqAttributes) and upper 8 bits will be
  // its "function attribute ID" (index in UniqFnAttributes).
  if (UniqAttributes.size() > 256)
    PrintFatalError("Too many unique argument attributes for table!");
  if (UniqFnAttributes.size() > 256)
    PrintFatalError("Too many unique function attributes for table!");

  // Emit an array of AttributeList.  Most intrinsics will have at least one
  // entry, for the function itself (index ~1), which is usually nounwind.
  OS << "  static constexpr uint16_t IntrinsicsToAttributesMap[] = {";
  for (const CodeGenIntrinsic &Int : Ints) {
    uint16_t FnAttrIndex = hasFnAttributes(Int) ? UniqFnAttributes[&Int] : 0;
    OS << formatv("\n    {} << 8 | {}, // {}", FnAttrIndex,
                  UniqAttributes[&Int], Int.Name);
  }

  OS << formatv(R"(
  };
  if (id == 0)
    return AttributeList();

  uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
  uint8_t FnAttrID = PackedID >> 8;
  switch(PackedID & 0xFF) {{
    default: llvm_unreachable("Invalid attribute number");
)");

  for (const auto [IntPtr, UniqueID] : UniqAttributes) {
    OS << formatv("  case {}:\n", UniqueID);
    const CodeGenIntrinsic &Int = *IntPtr;

    // Keep track of the number of attributes we're writing out.
    unsigned NumAttrs =
        llvm::count_if(Int.ArgumentAttributes,
                       [](const auto &Attrs) { return !Attrs.empty(); });
    NumAttrs += hasFnAttributes(Int);
    if (NumAttrs == 0) {
      OS << "    return AttributeList();\n";
      continue;
    }

    OS << "    return AttributeList::get(C, {\n";
    ListSeparator LS(",\n");
    for (const auto &[AttrIdx, Attrs] : enumerate(Int.ArgumentAttributes)) {
      if (Attrs.empty())
        continue;

      unsigned ArgAttrID = UniqArgAttributes.find(Attrs)->second;
      OS << LS
         << formatv("      {{{}, getIntrinsicArgAttributeSet(C, {})}", AttrIdx,
                    ArgAttrID);
    }

    if (hasFnAttributes(Int)) {
      OS << LS
         << "      {AttributeList::FunctionIndex, "
            "getIntrinsicFnAttributeSet(C, FnAttrID)}";
    }
    OS << "\n    });\n";
  }

  OS << R"(  }
}
#endif // GET_INTRINSIC_ATTRIBUTES

)";
}

void IntrinsicEmitter::EmitIntrinsicToBuiltinMap(
    const CodeGenIntrinsicTable &Ints, bool IsClang, raw_ostream &OS) {
  StringRef CompilerName = IsClang ? "Clang" : "MS";
  StringRef UpperCompilerName = IsClang ? "CLANG" : "MS";

  // map<TargetPrefix, pair<map<BuiltinName, EnumName>, CommonPrefix>.
  // Note that we iterate over both the maps in the code below and both
  // iterations need to iterate in sorted key order. For the inner map, entries
  // need to be emitted in the sorted order of `BuiltinName` with `CommonPrefix`
  // rempved, because we use std::lower_bound to search these entries. For the
  // outer map as well, entries need to be emitted in sorter order of
  // `TargetPrefix` as we use std::lower_bound to search these entries.
  using BIMEntryTy =
      std::pair<std::map<StringRef, StringRef>, std::optional<StringRef>>;
  std::map<StringRef, BIMEntryTy> BuiltinMap;

  for (const CodeGenIntrinsic &Int : Ints) {
    StringRef BuiltinName = IsClang ? Int.ClangBuiltinName : Int.MSBuiltinName;
    if (BuiltinName.empty())
      continue;
    // Get the map for this target prefix.
    auto &[Map, CommonPrefix] = BuiltinMap[Int.TargetPrefix];

    if (!Map.insert({BuiltinName, Int.EnumName}).second)
      PrintFatalError(Int.TheDef->getLoc(),
                      "Intrinsic '" + Int.TheDef->getName() + "': duplicate " +
                          CompilerName + " builtin name!");

    // Update common prefix.
    if (!CommonPrefix) {
      // For the first builtin for this target, initialize the common prefix.
      CommonPrefix = BuiltinName;
      continue;
    }

    // Update the common prefix. Note that this assumes that `take_front` will
    // never set the `Data` pointer in CommonPrefix to nullptr.
    const char *Mismatch = mismatch(*CommonPrefix, BuiltinName).first;
    *CommonPrefix = CommonPrefix->take_front(Mismatch - CommonPrefix->begin());
  }

  // Populate the string table with the names of all the builtins after
  // removing this common prefix.
  StringToOffsetTable Table;
  for (const auto &[TargetPrefix, Entry] : BuiltinMap) {
    auto &[Map, CommonPrefix] = Entry;
    for (auto &[BuiltinName, EnumName] : Map) {
      StringRef Suffix = BuiltinName.substr(CommonPrefix->size());
      Table.GetOrAddStringOffset(Suffix);
    }
  }

  OS << formatv(R"(
// Get the LLVM intrinsic that corresponds to a builtin. This is used by the
// C front-end. The builtin name is passed in as BuiltinName, and a target
// prefix (e.g. 'ppc') is passed in as TargetPrefix.
#ifdef GET_LLVM_INTRINSIC_FOR_{}_BUILTIN
Intrinsic::ID
Intrinsic::getIntrinsicFor{}Builtin(StringRef TargetPrefix, 
                                      StringRef BuiltinName) {{
  using namespace Intrinsic;
)",
                UpperCompilerName, CompilerName);

  if (BuiltinMap.empty()) {
    OS << formatv(R"(
  return not_intrinsic;
  }
#endif  // GET_LLVM_INTRINSIC_FOR_{}_BUILTIN
)",
                  UpperCompilerName);
    return;
  }

  if (!Table.empty()) {
    Table.EmitStringLiteralDef(OS, "static constexpr char BuiltinNames[]");

    OS << R"(
  struct BuiltinEntry {
    ID IntrinsicID;
    unsigned StrTabOffset;
    const char *getName() const { return &BuiltinNames[StrTabOffset]; }
    bool operator<(StringRef RHS) const {
      return strncmp(getName(), RHS.data(), RHS.size()) < 0;
    }
  };

)";
  }

  // Emit a per target table of bultin names.
  bool HasTargetIndependentBuiltins = false;
  StringRef TargetIndepndentCommonPrefix;
  for (const auto &[TargetPrefix, Entry] : BuiltinMap) {
    const auto &[Map, CommonPrefix] = Entry;
    if (!TargetPrefix.empty()) {
      OS << formatv("  // Builtins for {0}.\n", TargetPrefix);
    } else {
      OS << "  // Target independent builtins.\n";
      HasTargetIndependentBuiltins = true;
      TargetIndepndentCommonPrefix = *CommonPrefix;
    }

    // Emit the builtin table for this target prefix.
    OS << formatv("  static constexpr BuiltinEntry {}Names[] = {{\n",
                  TargetPrefix);
    for (const auto &[BuiltinName, EnumName] : Map) {
      StringRef Suffix = BuiltinName.substr(CommonPrefix->size());
      OS << formatv("    {{{}, {}}, // {}\n", EnumName,
                    *Table.GetStringOffset(Suffix), BuiltinName);
    }
    OS << formatv("  }; // {}Names\n\n", TargetPrefix);
  }

  // After emitting the builtin tables for all targets, emit a lookup table for
  // all targets. We will use binary search, similar to the table for builtin
  // names to lookup into this table.
  OS << R"(
  struct TargetEntry {
    StringLiteral TargetPrefix;
    ArrayRef<BuiltinEntry> Names;
    StringLiteral CommonPrefix;
    bool operator<(StringRef RHS) const {
      return TargetPrefix < RHS;
    };
  };
  static constexpr TargetEntry TargetTable[] = {
)";

  for (const auto &[TargetPrefix, Entry] : BuiltinMap) {
    const auto &[Map, CommonPrefix] = Entry;
    if (TargetPrefix.empty())
      continue;
    OS << formatv(R"(    {{"{0}", {0}Names, "{1}"},)", TargetPrefix,
                  CommonPrefix)
       << "\n";
  }
  OS << "  };\n";

  // Now for the actual lookup, first check the target independent table if
  // we emitted one.
  if (HasTargetIndependentBuiltins) {
    OS << formatv(R"(
  // Check if it's a target independent builtin.
  // Copy the builtin name so we can use it in consume_front without clobbering
  // if for the lookup in the target specific table.
  StringRef Suffix = BuiltinName;
  if (Suffix.consume_front("{}")) {{
    auto II = lower_bound(Names, Suffix);
    if (II != std::end(Names) && II->getName() == Suffix)
      return II->IntrinsicID;
  }
)",
                  TargetIndepndentCommonPrefix);
  }

  // If a target independent builtin was not found, lookup the target specific.
  OS << formatv(R"(
  auto TI = lower_bound(TargetTable, TargetPrefix);
  if (TI == std::end(TargetTable) || TI->TargetPrefix != TargetPrefix)
    return not_intrinsic;
  // This is the last use of BuiltinName, so no need to copy before using it in
  // consume_front.
  if (!BuiltinName.consume_front(TI->CommonPrefix))
    return not_intrinsic;
  auto II = lower_bound(TI->Names, BuiltinName);
  if (II == std::end(TI->Names) || II->getName() != BuiltinName)
    return not_intrinsic;
  return II->IntrinsicID;
}
#endif // GET_LLVM_INTRINSIC_FOR_{}_BUILTIN

)",
                UpperCompilerName);
}

static TableGen::Emitter::OptClass<IntrinsicEmitterOpt</*Enums=*/true>>
    X("gen-intrinsic-enums", "Generate intrinsic enums");

static TableGen::Emitter::OptClass<IntrinsicEmitterOpt</*Enums=*/false>>
    Y("gen-intrinsic-impl", "Generate intrinsic implementation code");
