//===- Patterns.cpp --------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "Patterns.h"
#include "Basic/CodeGenIntrinsics.h"
#include "CXXPredicates.h"
#include "CodeExpander.h"
#include "CodeExpansions.h"
#include "Common/CodeGenInstruction.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

namespace llvm {
namespace gi {

//===- PatternType --------------------------------------------------------===//

std::optional<PatternType> PatternType::get(ArrayRef<SMLoc> DiagLoc,
                                            const Record *R, Twine DiagCtx) {
  assert(R);
  if (R->isSubClassOf("ValueType")) {
    PatternType PT(PT_ValueType);
    PT.Data.Def = R;
    return PT;
  }

  if (R->isSubClassOf(TypeOfClassName)) {
    auto RawOpName = R->getValueAsString("OpName");
    if (!RawOpName.starts_with("$")) {
      PrintError(DiagLoc, DiagCtx + ": invalid operand name format '" +
                              RawOpName + "' in " + TypeOfClassName +
                              ": expected '$' followed by an operand name");
      return std::nullopt;
    }

    PatternType PT(PT_TypeOf);
    PT.Data.Str = RawOpName.drop_front(1);
    return PT;
  }

  if (R->isSubClassOf(VariadicClassName)) {
    const int64_t Min = R->getValueAsInt("MinArgs");
    const int64_t Max = R->getValueAsInt("MaxArgs");

    if (Min == 0) {
      PrintError(
          DiagLoc,
          DiagCtx +
              ": minimum number of arguments must be greater than zero in " +
              VariadicClassName);
      return std::nullopt;
    }

    if (Max <= Min && Max != 0) {
      PrintError(DiagLoc, DiagCtx + ": maximum number of arguments (" +
                              Twine(Max) +
                              ") must be zero, or greater "
                              "than the minimum number of arguments (" +
                              Twine(Min) + ") in " + VariadicClassName);
      return std::nullopt;
    }

    PatternType PT(PT_VariadicPack);
    PT.Data.VPTI = {unsigned(Min), unsigned(Max)};
    return PT;
  }

  PrintError(DiagLoc, DiagCtx + ": unknown type '" + R->getName() + "'");
  return std::nullopt;
}

PatternType PatternType::getTypeOf(StringRef OpName) {
  PatternType PT(PT_TypeOf);
  PT.Data.Str = OpName;
  return PT;
}

StringRef PatternType::getTypeOfOpName() const {
  assert(isTypeOf());
  return Data.Str;
}

const Record *PatternType::getLLTRecord() const {
  assert(isLLT());
  return Data.Def;
}

VariadicPackTypeInfo PatternType::getVariadicPackTypeInfo() const {
  assert(isVariadicPack());
  return Data.VPTI;
}

bool PatternType::operator==(const PatternType &Other) const {
  if (Kind != Other.Kind)
    return false;

  switch (Kind) {
  case PT_None:
    return true;
  case PT_ValueType:
    return Data.Def == Other.Data.Def;
  case PT_TypeOf:
    return Data.Str == Other.Data.Str;
  case PT_VariadicPack:
    return Data.VPTI == Other.Data.VPTI;
  }

  llvm_unreachable("Unknown Type Kind");
}

std::string PatternType::str() const {
  switch (Kind) {
  case PT_None:
    return "";
  case PT_ValueType:
    return Data.Def->getName().str();
  case PT_TypeOf:
    return (TypeOfClassName + "<$" + getTypeOfOpName() + ">").str();
  case PT_VariadicPack:
    return (VariadicClassName + "<" + Twine(Data.VPTI.Min) + "," +
            Twine(Data.VPTI.Max) + ">")
        .str();
  }

  llvm_unreachable("Unknown type!");
}

//===- Pattern ------------------------------------------------------------===//

void Pattern::dump() const { return print(dbgs()); }

const char *Pattern::getKindName() const {
  switch (Kind) {
  case K_AnyOpcode:
    return "AnyOpcodePattern";
  case K_CXX:
    return "CXXPattern";
  case K_CodeGenInstruction:
    return "CodeGenInstructionPattern";
  case K_PatFrag:
    return "PatFragPattern";
  case K_Builtin:
    return "BuiltinPattern";
  }

  llvm_unreachable("unknown pattern kind!");
}

void Pattern::printImpl(raw_ostream &OS, bool PrintName,
                        function_ref<void()> ContentPrinter) const {
  OS << "(" << getKindName() << " ";
  if (PrintName)
    OS << "name:" << getName() << " ";
  ContentPrinter();
  OS << ")";
}

//===- AnyOpcodePattern ---------------------------------------------------===//

void AnyOpcodePattern::print(raw_ostream &OS, bool PrintName) const {
  printImpl(OS, PrintName, [&OS, this]() {
    OS << "["
       << join(map_range(Insts,
                         [](const auto *I) { return I->TheDef->getName(); }),
               ", ")
       << "]";
  });
}

//===- CXXPattern ---------------------------------------------------------===//

CXXPattern::CXXPattern(const StringInit &Code, StringRef Name)
    : CXXPattern(Code.getAsUnquotedString(), Name) {}

const CXXPredicateCode &
CXXPattern::expandCode(const CodeExpansions &CE, ArrayRef<SMLoc> Locs,
                       function_ref<void(raw_ostream &)> AddComment) const {
  assert(!IsApply && "'apply' CXX patterns should be handled differently!");

  std::string Result;
  raw_string_ostream OS(Result);

  if (AddComment)
    AddComment(OS);

  CodeExpander Expander(RawCode, CE, Locs, /*ShowExpansions*/ false);
  Expander.emit(OS);
  return CXXPredicateCode::getMatchCode(std::move(Result));
}

void CXXPattern::print(raw_ostream &OS, bool PrintName) const {
  printImpl(OS, PrintName, [&OS, this] {
    OS << (IsApply ? "apply" : "match") << " code:\"";
    printEscapedString(getRawCode(), OS);
    OS << "\"";
  });
}

//===- InstructionOperand -------------------------------------------------===//

std::string InstructionOperand::describe() const {
  if (!hasImmValue())
    return "MachineOperand $" + getOperandName().str() + "";
  std::string Str = "imm " + std::to_string(getImmValue());
  if (isNamedImmediate())
    Str += ":$" + getOperandName().str() + "";
  return Str;
}

void InstructionOperand::print(raw_ostream &OS) const {
  if (isDef())
    OS << "<def>";

  bool NeedsColon = true;
  if (Type) {
    if (hasImmValue())
      OS << "(" << Type.str() << " " << getImmValue() << ")";
    else
      OS << Type.str();
  } else if (hasImmValue())
    OS << getImmValue();
  else
    NeedsColon = false;

  if (isNamedOperand())
    OS << (NeedsColon ? ":" : "") << "$" << getOperandName();
}

void InstructionOperand::dump() const { return print(dbgs()); }

//===- InstructionPattern -------------------------------------------------===//

bool InstructionPattern::diagnoseAllSpecialTypes(ArrayRef<SMLoc> Loc,
                                                 Twine Msg) const {
  bool HasDiag = false;
  for (const auto &[Idx, Op] : enumerate(operands())) {
    if (Op.getType().isSpecial()) {
      PrintError(Loc, Msg);
      PrintNote(Loc, "operand " + Twine(Idx) + " of '" + getName() +
                         "' has type '" + Op.getType().str() + "'");
      HasDiag = true;
    }
  }
  return HasDiag;
}

void InstructionPattern::reportUnreachable(ArrayRef<SMLoc> Locs) const {
  PrintError(Locs, "pattern '" + getName() + "' ('" + getInstName() +
                       "') is unreachable from the pattern root!");
}

bool InstructionPattern::checkSemantics(ArrayRef<SMLoc> Loc) {
  unsigned NumExpectedOperands = getNumInstOperands();

  if (isVariadic()) {
    if (Operands.size() < NumExpectedOperands) {
      PrintError(Loc, +"'" + getInstName() + "' expected at least " +
                          Twine(NumExpectedOperands) + " operands, got " +
                          Twine(Operands.size()));
      return false;
    }
  } else if (NumExpectedOperands != Operands.size()) {
    PrintError(Loc, +"'" + getInstName() + "' expected " +
                        Twine(NumExpectedOperands) + " operands, got " +
                        Twine(Operands.size()));
    return false;
  }

  unsigned OpIdx = 0;
  unsigned NumDefs = getNumInstDefs();
  for (auto &Op : Operands)
    Op.setIsDef(OpIdx++ < NumDefs);

  return true;
}

void InstructionPattern::print(raw_ostream &OS, bool PrintName) const {
  printImpl(OS, PrintName, [&OS, this] {
    OS << getInstName() << " operands:[";
    StringRef Sep;
    for (const auto &Op : Operands) {
      OS << Sep;
      Op.print(OS);
      Sep = ", ";
    }
    OS << "]";

    printExtras(OS);
  });
}

//===- OperandTable -------------------------------------------------------===//

bool OperandTable::addPattern(InstructionPattern *P,
                              function_ref<void(StringRef)> DiagnoseRedef) {
  for (const auto &Op : P->named_operands()) {
    StringRef OpName = Op.getOperandName();

    // We always create an entry in the OperandTable, even for uses.
    // Uses of operands that don't have a def (= live-ins) will remain with a
    // nullptr as the Def.
    //
    // This allows us tell whether an operand exists in a pattern or not. If
    // there is no entry for it, it doesn't exist, if there is an entry, it's
    // used/def'd at least once.
    auto &Def = Table[OpName];

    if (!Op.isDef())
      continue;

    if (Def) {
      DiagnoseRedef(OpName);
      return false;
    }

    Def = P;
  }

  return true;
}

void OperandTable::print(raw_ostream &OS, StringRef Name,
                         StringRef Indent) const {
  OS << Indent << "(OperandTable ";
  if (!Name.empty())
    OS << Name << " ";
  if (Table.empty()) {
    OS << "<empty>)\n";
    return;
  }

  SmallVector<StringRef, 0> Keys(Table.keys());
  sort(Keys);

  OS << '\n';
  for (const auto &Key : Keys) {
    const auto *Def = Table.at(Key);
    OS << Indent << "  " << Key << " -> "
       << (Def ? Def->getName() : "<live-in>") << '\n';
  }
  OS << Indent << ")\n";
}

void OperandTable::dump() const { print(dbgs()); }

//===- MIFlagsInfo --------------------------------------------------------===//

void MIFlagsInfo::addSetFlag(const Record *R) {
  SetF.insert(R->getValueAsString("EnumName"));
}

void MIFlagsInfo::addUnsetFlag(const Record *R) {
  UnsetF.insert(R->getValueAsString("EnumName"));
}

void MIFlagsInfo::addCopyFlag(StringRef InstName) { CopyF.insert(InstName); }

//===- CodeGenInstructionPattern ------------------------------------------===//

bool CodeGenInstructionPattern::is(StringRef OpcodeName) const {
  return I.TheDef->getName() == OpcodeName;
}

bool CodeGenInstructionPattern::isVariadic() const {
  return !isIntrinsic() && I.Operands.isVariadic;
}

bool CodeGenInstructionPattern::hasVariadicDefs() const {
  // Note: we cannot use variadicOpsAreDefs, it's not set for
  // GenericInstructions.
  if (!isVariadic())
    return false;

  if (I.variadicOpsAreDefs)
    return true;

  const DagInit *OutOps = I.TheDef->getValueAsDag("OutOperandList");
  if (OutOps->arg_empty())
    return false;

  auto *LastArgTy = dyn_cast<DefInit>(OutOps->getArg(OutOps->arg_size() - 1));
  return LastArgTy && LastArgTy->getDef()->getName() == "variable_ops";
}

unsigned CodeGenInstructionPattern::getNumInstDefs() const {
  if (isIntrinsic())
    return IntrinInfo->IS.RetTys.size();

  if (!isVariadic() || !hasVariadicDefs())
    return I.Operands.NumDefs;
  unsigned NumOuts = I.Operands.size() - I.Operands.NumDefs;
  assert(Operands.size() > NumOuts);
  return std::max<unsigned>(I.Operands.NumDefs, Operands.size() - NumOuts);
}

unsigned CodeGenInstructionPattern::getNumInstOperands() const {
  if (isIntrinsic())
    return IntrinInfo->IS.RetTys.size() + IntrinInfo->IS.ParamTys.size();

  unsigned NumCGIOps = I.Operands.size();
  return isVariadic() ? std::max<unsigned>(NumCGIOps, Operands.size())
                      : NumCGIOps;
}

MIFlagsInfo &CodeGenInstructionPattern::getOrCreateMIFlagsInfo() {
  if (!FI)
    FI = std::make_unique<MIFlagsInfo>();
  return *FI;
}

StringRef CodeGenInstructionPattern::getInstName() const {
  return I.TheDef->getName();
}

void CodeGenInstructionPattern::printExtras(raw_ostream &OS) const {
  if (isIntrinsic())
    OS << " intrinsic(@" << IntrinInfo->Name << ")";

  if (!FI)
    return;

  OS << " (MIFlags";
  if (!FI->set_flags().empty())
    OS << " (set " << join(FI->set_flags(), ", ") << ")";
  if (!FI->unset_flags().empty())
    OS << " (unset " << join(FI->unset_flags(), ", ") << ")";
  if (!FI->copy_flags().empty())
    OS << " (copy " << join(FI->copy_flags(), ", ") << ")";
  OS << ')';
}

//===- OperandTypeChecker -------------------------------------------------===//

bool OperandTypeChecker::check(
    InstructionPattern &P,
    std::function<bool(const PatternType &)> VerifyTypeOfOperand) {
  Pats.push_back(&P);

  for (auto &Op : P.operands()) {
    const auto Ty = Op.getType();
    if (!Ty)
      continue;

    if (Ty.isTypeOf() && !VerifyTypeOfOperand(Ty))
      return false;

    if (!Op.isNamedOperand())
      continue;

    StringRef OpName = Op.getOperandName();
    auto &Info = Types[OpName];
    if (!Info.Type) {
      Info.Type = Ty;
      Info.PrintTypeSrcNote = [this, OpName, Ty, &P]() {
        PrintSeenWithTypeIn(P, OpName, Ty);
      };
      continue;
    }

    if (Info.Type != Ty) {
      PrintError(DiagLoc, "conflicting types for operand '" +
                              Op.getOperandName() + "': '" + Info.Type.str() +
                              "' vs '" + Ty.str() + "'");
      PrintSeenWithTypeIn(P, OpName, Ty);
      Info.PrintTypeSrcNote();
      return false;
    }
  }

  return true;
}

void OperandTypeChecker::propagateTypes() {
  for (auto *Pat : Pats) {
    for (auto &Op : Pat->named_operands()) {
      if (auto &Info = Types[Op.getOperandName()]; Info.Type)
        Op.setType(Info.Type);
    }
  }
}

void OperandTypeChecker::PrintSeenWithTypeIn(InstructionPattern &P,
                                             StringRef OpName,
                                             PatternType Ty) const {
  PrintNote(DiagLoc, "'" + OpName + "' seen with type '" + Ty.str() + "' in '" +
                         P.getName() + "'");
}

StringRef PatFrag::getParamKindStr(ParamKind OK) {
  switch (OK) {
  case PK_Root:
    return "root";
  case PK_MachineOperand:
    return "machine_operand";
  case PK_Imm:
    return "imm";
  }

  llvm_unreachable("Unknown operand kind!");
}

//===- PatFrag -----------------------------------------------------------===//

PatFrag::PatFrag(const Record &Def) : Def(Def) {
  assert(Def.isSubClassOf(ClassName));
}

StringRef PatFrag::getName() const { return Def.getName(); }

ArrayRef<SMLoc> PatFrag::getLoc() const { return Def.getLoc(); }

void PatFrag::addInParam(StringRef Name, ParamKind Kind) {
  Params.emplace_back(Param{Name, Kind});
}

iterator_range<PatFrag::ParamIt> PatFrag::in_params() const {
  return {Params.begin() + NumOutParams, Params.end()};
}

void PatFrag::addOutParam(StringRef Name, ParamKind Kind) {
  assert(NumOutParams == Params.size() &&
         "Adding out-param after an in-param!");
  Params.emplace_back(Param{Name, Kind});
  ++NumOutParams;
}

iterator_range<PatFrag::ParamIt> PatFrag::out_params() const {
  return {Params.begin(), Params.begin() + NumOutParams};
}

unsigned PatFrag::num_roots() const {
  return count_if(out_params(),
                  [&](const auto &P) { return P.Kind == PK_Root; });
}

unsigned PatFrag::getParamIdx(StringRef Name) const {
  for (const auto &[Idx, Op] : enumerate(Params)) {
    if (Op.Name == Name)
      return Idx;
  }

  return -1;
}

bool PatFrag::checkSemantics() {
  for (const auto &Alt : Alts) {
    for (const auto &Pat : Alt.Pats) {
      switch (Pat->getKind()) {
      case Pattern::K_AnyOpcode:
        PrintError("wip_match_opcode cannot be used in " + ClassName);
        return false;
      case Pattern::K_Builtin:
        PrintError("Builtin instructions cannot be used in " + ClassName);
        return false;
      case Pattern::K_CXX:
        continue;
      case Pattern::K_CodeGenInstruction:
        // TODO: Allow VarArgs?
        if (cast<CodeGenInstructionPattern>(Pat.get())->diagnoseAllSpecialTypes(
                Def.getLoc(), PatternType::SpecialTyClassName +
                                  " is not supported in " + ClassName))
          return false;
        continue;
      case Pattern::K_PatFrag:
        // TODO: It's just that the emitter doesn't handle it but technically
        // there is no reason why we can't. We just have to be careful with
        // operand mappings, it could get complex.
        PrintError("nested " + ClassName + " are not supported");
        return false;
      }
    }
  }

  StringSet<> SeenOps;
  for (const auto &Op : in_params()) {
    if (SeenOps.count(Op.Name)) {
      PrintError("duplicate parameter '" + Op.Name + "'");
      return false;
    }

    // Check this operand is NOT defined in any alternative's patterns.
    for (const auto &Alt : Alts) {
      if (Alt.OpTable.lookup(Op.Name).Def) {
        PrintError("input parameter '" + Op.Name + "' cannot be redefined!");
        return false;
      }
    }

    if (Op.Kind == PK_Root) {
      PrintError("input parameterr '" + Op.Name + "' cannot be a root!");
      return false;
    }

    SeenOps.insert(Op.Name);
  }

  for (const auto &Op : out_params()) {
    if (Op.Kind != PK_Root && Op.Kind != PK_MachineOperand) {
      PrintError("output parameter '" + Op.Name +
                 "' must be 'root' or 'gi_mo'");
      return false;
    }

    if (SeenOps.count(Op.Name)) {
      PrintError("duplicate parameter '" + Op.Name + "'");
      return false;
    }

    // Check this operand is defined in all alternative's patterns.
    for (const auto &Alt : Alts) {
      const auto *OpDef = Alt.OpTable.getDef(Op.Name);
      if (!OpDef) {
        PrintError("output parameter '" + Op.Name +
                   "' must be defined by all alternative patterns in '" +
                   Def.getName() + "'");
        return false;
      }

      if (Op.Kind == PK_Root && OpDef->getNumInstDefs() != 1) {
        // The instruction that defines the root must have a single def.
        // Otherwise we'd need to support multiple roots and it gets messy.
        //
        // e.g. this is not supported:
        //   (pattern (G_UNMERGE_VALUES $x, $root, $vec))
        PrintError("all instructions that define root '" + Op.Name + "' in '" +
                   Def.getName() + "' can only have a single output operand");
        return false;
      }
    }

    SeenOps.insert(Op.Name);
  }

  if (num_out_params() != 0 && num_roots() == 0) {
    PrintError(ClassName + " must have one root in its 'out' operands");
    return false;
  }

  if (num_roots() > 1) {
    PrintError(ClassName + " can only have one root");
    return false;
  }

  // TODO: find unused params

  const auto CheckTypeOf = [&](const PatternType &) -> bool {
    llvm_unreachable("GITypeOf should have been rejected earlier!");
  };

  // Now, typecheck all alternatives.
  for (auto &Alt : Alts) {
    OperandTypeChecker OTC(Def.getLoc());
    for (auto &Pat : Alt.Pats) {
      if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
        if (!OTC.check(*IP, CheckTypeOf))
          return false;
      }
    }
    OTC.propagateTypes();
  }

  return true;
}

bool PatFrag::handleUnboundInParam(StringRef ParamName, StringRef ArgName,
                                   ArrayRef<SMLoc> DiagLoc) const {
  // The parameter must be a live-in of all alternatives for this to work.
  // Otherwise, we risk having unbound parameters being used (= crashes).
  //
  // Examples:
  //
  // in (ins $y), (patterns (G_FNEG $dst, $y), "return matchFnegOp(${y})")
  //    even if $y is unbound, we'll lazily bind it when emitting the G_FNEG.
  //
  // in (ins $y), (patterns "return matchFnegOp(${y})")
  //    if $y is unbound when this fragment is emitted, C++ code expansion will
  //    fail.
  for (const auto &Alt : Alts) {
    auto &OT = Alt.OpTable;
    if (!OT.lookup(ParamName).Found) {
      llvm::PrintError(DiagLoc, "operand '" + ArgName + "' (for parameter '" +
                                    ParamName + "' of '" + getName() +
                                    "') cannot be unbound");
      PrintNote(
          DiagLoc,
          "one or more alternatives of '" + getName() + "' do not bind '" +
              ParamName +
              "' to an instruction operand; either use a bound operand or "
              "ensure '" +
              Def.getName() + "' binds '" + ParamName +
              "' in all alternatives");
      return false;
    }
  }

  return true;
}

bool PatFrag::buildOperandsTables() {
  // enumerate(...) doesn't seem to allow lvalues so we need to count the old
  // way.
  unsigned Idx = 0;

  const auto DiagnoseRedef = [this, &Idx](StringRef OpName) {
    PrintError("Operand '" + OpName +
               "' is defined multiple times in patterns of alternative #" +
               std::to_string(Idx));
  };

  for (auto &Alt : Alts) {
    for (auto &Pat : Alt.Pats) {
      auto *IP = dyn_cast<InstructionPattern>(Pat.get());
      if (!IP)
        continue;

      if (!Alt.OpTable.addPattern(IP, DiagnoseRedef))
        return false;
    }

    ++Idx;
  }

  return true;
}

void PatFrag::print(raw_ostream &OS, StringRef Indent) const {
  OS << Indent << "(PatFrag name:" << getName() << '\n';
  if (!in_params().empty()) {
    OS << Indent << "  (ins ";
    printParamsList(OS, in_params());
    OS << ")\n";
  }

  if (!out_params().empty()) {
    OS << Indent << "  (outs ";
    printParamsList(OS, out_params());
    OS << ")\n";
  }

  // TODO: Dump OperandTable as well.
  OS << Indent << "  (alternatives [\n";
  for (const auto &Alt : Alts) {
    OS << Indent << "    [\n";
    for (const auto &Pat : Alt.Pats) {
      OS << Indent << "      ";
      Pat->print(OS, /*PrintName=*/true);
      OS << ",\n";
    }
    OS << Indent << "    ],\n";
  }
  OS << Indent << "  ])\n";

  OS << Indent << ')';
}

void PatFrag::dump() const { print(dbgs()); }

void PatFrag::printParamsList(raw_ostream &OS, iterator_range<ParamIt> Params) {
  OS << '['
     << join(map_range(Params,
                       [](auto &O) {
                         return (O.Name + ":" + getParamKindStr(O.Kind)).str();
                       }),
             ", ")
     << ']';
}

void PatFrag::PrintError(Twine Msg) const { llvm::PrintError(&Def, Msg); }

ArrayRef<InstructionOperand> PatFragPattern::getApplyDefsNeeded() const {
  assert(PF.num_roots() == 1);
  // Only roots need to be redef.
  for (auto [Idx, Param] : enumerate(PF.out_params())) {
    if (Param.Kind == PatFrag::PK_Root)
      return getOperand(Idx);
  }
  llvm_unreachable("root not found!");
}

//===- PatFragPattern -----------------------------------------------------===//

bool PatFragPattern::checkSemantics(ArrayRef<SMLoc> DiagLoc) {
  if (!InstructionPattern::checkSemantics(DiagLoc))
    return false;

  for (const auto &[Idx, Op] : enumerate(Operands)) {
    switch (PF.getParam(Idx).Kind) {
    case PatFrag::PK_Imm:
      if (!Op.hasImmValue()) {
        PrintError(DiagLoc, "expected operand " + std::to_string(Idx) +
                                " of '" + getInstName() +
                                "' to be an immediate; got " + Op.describe());
        return false;
      }
      if (Op.isNamedImmediate()) {
        PrintError(DiagLoc, "operand " + std::to_string(Idx) + " of '" +
                                getInstName() +
                                "' cannot be a named immediate");
        return false;
      }
      break;
    case PatFrag::PK_Root:
    case PatFrag::PK_MachineOperand:
      if (!Op.isNamedOperand() || Op.isNamedImmediate()) {
        PrintError(DiagLoc, "expected operand " + std::to_string(Idx) +
                                " of '" + getInstName() +
                                "' to be a MachineOperand; got " +
                                Op.describe());
        return false;
      }
      break;
    }
  }

  return true;
}

bool PatFragPattern::mapInputCodeExpansions(const CodeExpansions &ParentCEs,
                                            CodeExpansions &PatFragCEs,
                                            ArrayRef<SMLoc> DiagLoc) const {
  for (const auto &[Idx, Op] : enumerate(operands())) {
    StringRef ParamName = PF.getParam(Idx).Name;

    // Operands to a PFP can only be named, or be an immediate, but not a named
    // immediate.
    assert(!Op.isNamedImmediate());

    if (Op.isNamedOperand()) {
      StringRef ArgName = Op.getOperandName();
      // Map it only if it's been defined.
      auto It = ParentCEs.find(ArgName);
      if (It == ParentCEs.end()) {
        if (!PF.handleUnboundInParam(ParamName, ArgName, DiagLoc))
          return false;
      } else
        PatFragCEs.declare(ParamName, It->second);
      continue;
    }

    if (Op.hasImmValue()) {
      PatFragCEs.declare(ParamName, std::to_string(Op.getImmValue()));
      continue;
    }

    llvm_unreachable("Unknown Operand Type!");
  }

  return true;
}

//===- BuiltinPattern -----------------------------------------------------===//

BuiltinPattern::BuiltinInfo BuiltinPattern::getBuiltinInfo(const Record &Def) {
  assert(Def.isSubClassOf(ClassName));

  StringRef Name = Def.getName();
  for (const auto &KBI : KnownBuiltins) {
    if (KBI.DefName == Name)
      return KBI;
  }

  PrintFatalError(Def.getLoc(),
                  "Unimplemented " + ClassName + " def '" + Name + "'");
}

bool BuiltinPattern::checkSemantics(ArrayRef<SMLoc> Loc) {
  if (!InstructionPattern::checkSemantics(Loc))
    return false;

  // For now all builtins just take names, no immediates.
  for (const auto &[Idx, Op] : enumerate(operands())) {
    if (!Op.isNamedOperand() || Op.isNamedImmediate()) {
      PrintError(Loc, "expected operand " + std::to_string(Idx) + " of '" +
                          getInstName() + "' to be a name");
      return false;
    }
  }

  return true;
}

} // namespace gi
} // namespace llvm
