//===-------- CompressInstEmitter.cpp - Generator for Compression ---------===//
//
// 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
//
// CompressInstEmitter implements a tablegen-driven CompressPat based
// Instruction Compression mechanism.
//
//===----------------------------------------------------------------------===//
//
// CompressInstEmitter implements a tablegen-driven CompressPat Instruction
// Compression mechanism for generating compressed instructions from the
// expanded instruction form.

// This tablegen backend processes CompressPat declarations in a
// td file and generates all the required checks to validate the pattern
// declarations; validate the input and output operands to generate the correct
// compressed instructions. The checks include validating different types of
// operands; register operands, immediate operands, fixed register and fixed
// immediate inputs.
//
// Example:
// /// Defines a Pat match between compressed and uncompressed instruction.
// /// The relationship and helper function generation are handled by
// /// CompressInstEmitter backend.
// class CompressPat<dag input, dag output, list<Predicate> predicates = []> {
//   /// Uncompressed instruction description.
//   dag Input = input;
//   /// Compressed instruction description.
//   dag Output = output;
//   /// Predicates that must be true for this to match.
//   list<Predicate> Predicates = predicates;
//   /// Duplicate match when tied operand is just different.
//   bit isCompressOnly = false;
// }
//
// let Predicates = [HasStdExtC] in {
// def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
//                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
// }
//
// The <TargetName>GenCompressInstEmitter.inc is an auto-generated header
// file which exports two functions for compressing/uncompressing MCInst
// instructions, plus some helper functions:
//
// bool compressInst(MCInst &OutInst, const MCInst &MI,
//                   const MCSubtargetInfo &STI);
//
// bool uncompressInst(MCInst &OutInst, const MCInst &MI,
//                     const MCSubtargetInfo &STI);
//
// In addition, it exports a function that returns the compressed instruction
// size, or zero when the instruction is not compressible:
//
// unsigned getCompressedSize(const MachineInstr &MI,
//                            const <TargetName>Subtarget &STI);
//
//
// The clients that include this auto-generated header file and
// invoke these functions can compress an instruction before emitting
// it in the target-specific ASM or ELF streamer or can uncompress
// an instruction before printing it when the expanded instruction
// format aliases is favored.

//===----------------------------------------------------------------------===//

#include "Common/CodeGenHwModes.h"
#include "Common/CodeGenInstruction.h"
#include "Common/CodeGenRegisters.h"
#include "Common/CodeGenTarget.h"
#include "Common/InfoByHwMode.h"
#include "Common/SubtargetFeatureInfo.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/CodeGenHelpers.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <limits>
#include <set>
#include <vector>
using namespace llvm;

#define DEBUG_TYPE "compress-inst-emitter"

namespace {
class CompressInstEmitter {
  struct OpData {
    enum MapKind { Operand, Imm, Reg } Kind;
    // Info for an operand.
    struct OpndInfo {
      // Record from the Dag.
      const Record *DagRec;
      // Operand number mapped to.
      unsigned Idx;
      // Tied operand index within the instruction.
      int TiedOpIdx;
    };
    union {
      OpndInfo OpInfo;
      // Integer immediate value.
      int64_t ImmVal;
      // Physical register.
      const Record *RegRec;
    };
  };
  struct ArgData {
    unsigned DAGOpNo;
    unsigned MIOpNo;
  };
  struct CompressPat {
    // The source instruction definition.
    CodeGenInstruction Source;
    // The destination instruction to transform to.
    CodeGenInstruction Dest;
    // Required target features to enable pattern.
    std::vector<const Record *> PatReqFeatures;
    // Maps operands in the Source Instruction to
    // the corresponding Dest instruction operand.
    IndexedMap<OpData> SourceOperandMap;
    // Maps operands in the Dest Instruction
    // to the corresponding Source instruction operand.
    IndexedMap<OpData> DestOperandMap;

    bool IsCompressOnly;
    CompressPat(const CodeGenInstruction &S, const CodeGenInstruction &D,
                std::vector<const Record *> RF,
                const IndexedMap<OpData> &SourceMap,
                const IndexedMap<OpData> &DestMap, bool IsCompressOnly)
        : Source(S), Dest(D), PatReqFeatures(std::move(RF)),
          SourceOperandMap(SourceMap), DestOperandMap(DestMap),
          IsCompressOnly(IsCompressOnly) {}
  };
  enum EmitterType { Compress, Uncompress, CheckCompress };
  const RecordKeeper &Records;
  const CodeGenTarget Target;
  std::vector<CompressPat> CompressPatterns;
  void addDagOperandMapping(const Record *Rec, const DagInit *Dag,
                            const CodeGenInstruction &Inst,
                            IndexedMap<OpData> &OperandMap,
                            StringMap<ArgData> &Operands, bool IsSourceInst,
                            ArrayRef<const Record *> PatPreds);
  void evaluateCompressPat(const Record *Compress);
  void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
  bool validateTypes(const Record *DagOpType, const Record *InstOpType,
                     bool IsSourceInst, ArrayRef<const Record *> PatPreds);
  bool validateRegister(const Record *Reg, const Record *RegClass,
                        ArrayRef<SMLoc> Loc, ArrayRef<const Record *> PatPreds);
  void checkDagOperandMapping(const Record *Rec,
                              const StringMap<ArgData> &DestOperands,
                              const DagInit *SourceDag, const DagInit *DestDag);

  void createInstOperandMapping(const Record *Rec, const DagInit *SourceDag,
                                const DagInit *DestDag,
                                IndexedMap<OpData> &SourceOperandMap,
                                IndexedMap<OpData> &DestOperandMap,
                                StringMap<ArgData> &SourceOperands,
                                const CodeGenInstruction &DestInst);

public:
  CompressInstEmitter(const RecordKeeper &R) : Records(R), Target(R) {}

  void run(raw_ostream &OS);
};
} // End anonymous namespace.

bool CompressInstEmitter::validateRegister(const Record *Reg,
                                           const Record *RegClass,
                                           ArrayRef<SMLoc> Loc,
                                           ArrayRef<const Record *> PatPreds) {
  assert((Reg->isSubClassOf("Register") ||
          Reg->isSubClassOf("RegisterByHwMode")) &&
         "Reg record should be a Register");
  assert(RegClass->isSubClassOf("RegisterClassLike") &&
         "RegClass record should be RegisterClassLike");

  if (const Record *RC =
          Target.getHwModes().resolveModeSelect(RegClass, PatPreds))
    RegClass = RC;
  if (const Record *R = Target.getHwModes().resolveModeSelect(Reg, PatPreds))
    Reg = R;

  return Target.getRegBank().regClassContainsReg(RegClass, Reg, Loc);
}

bool CompressInstEmitter::validateTypes(const Record *DagOpType,
                                        const Record *InstOpType,
                                        bool IsSourceInst,
                                        ArrayRef<const Record *> PatPreds) {
  if (DagOpType == InstOpType)
    return true;

  const Record *ResolvedDag =
      Target.getHwModes().resolveModeSelect(DagOpType, PatPreds);
  const Record *ResolvedInst =
      Target.getHwModes().resolveModeSelect(InstOpType, PatPreds);

  if (ResolvedDag && ResolvedInst) {
    DagOpType = ResolvedDag;
    InstOpType = ResolvedInst;
  } else if (DagOpType->isSubClassOf("RegClassByHwMode") &&
             InstOpType->isSubClassOf("RegClassByHwMode")) {
    RegClassByHwMode DagRC(DagOpType, Target.getRegBank());
    RegClassByHwMode InstRC(InstOpType, Target.getRegBank());
    const CodeGenHwModes &CGH = Target.getHwModes();
    HwModePredicates PatPredsSet(PatPreds);
    bool HasCompatibleMode = false;
    for (const auto &[Mode, DagClass] : DagRC) {
      if (CGH.getModePredicates(Mode).conflictsWith(PatPredsSet))
        continue;
      if (!InstRC.hasMode(Mode))
        return false;
      const CodeGenRegisterClass *InstClass = InstRC.get(Mode);
      if (!InstClass->hasSubClass(DagClass))
        return false;
      HasCompatibleMode = true;
    }
    for (const auto &[Mode, InstClass] : InstRC) {
      if (CGH.getModePredicates(Mode).conflictsWith(PatPredsSet))
        continue;
      if (!DagRC.hasMode(Mode))
        return false;
    }
    return HasCompatibleMode;
  } else if (DagOpType->isSubClassOf("HwModeSelect") ||
             InstOpType->isSubClassOf("HwModeSelect")) {
    return false;
  }

  // Concrete check (when resolved uniquely).
  if (DagOpType == InstOpType)
    return true;

  if (DagOpType->isSubClassOf("RegisterClass") &&
      InstOpType->isSubClassOf("RegisterClass")) {
    const CodeGenRegisterClass &RC = Target.getRegisterClass(InstOpType);
    const CodeGenRegisterClass &SubRC = Target.getRegisterClass(DagOpType);
    return RC.hasSubClass(&SubRC);
  }

  // At this point either or both types are not registers, reject the pattern.
  if (DagOpType->isSubClassOf("RegisterClass") ||
      InstOpType->isSubClassOf("RegisterClass"))
    return false;

  // Let further validation happen when compress()/uncompress() functions are
  // invoked.
  LLVM_DEBUG(dbgs() << (IsSourceInst ? "Input" : "Output")
                    << " Dag Operand Type: '" << DagOpType->getName()
                    << "' and "
                    << "Instruction Operand Type: '" << InstOpType->getName()
                    << "' can't be checked at pattern validation time!\n");
  return true;
}

static bool validateArgsTypes(const Init *Arg1, const Init *Arg2) {
  return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
}

/// The patterns in the Dag contain different types of operands:
/// Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
/// operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
/// maps Dag operands to its corresponding instruction operands. For register
/// operands and fixed registers it expects the Dag operand type to be contained
/// in the instantiated instruction operand type. For immediate operands and
/// immediates no validation checks are enforced at pattern validation time.
void CompressInstEmitter::addDagOperandMapping(
    const Record *Rec, const DagInit *Dag, const CodeGenInstruction &Inst,
    IndexedMap<OpData> &OperandMap, StringMap<ArgData> &Operands,
    bool IsSourceInst, ArrayRef<const Record *> PatPreds) {
  unsigned NumMIOperands = 0;
  if (!Inst.Operands.empty())
    NumMIOperands =
        Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands;
  OperandMap.grow(NumMIOperands);

  // Tied operands are not represented in the DAG so we count them separately.
  unsigned DAGOpNo = 0;
  unsigned OpNo = 0;
  for (const auto &Opnd : Inst.Operands) {
    int TiedOpIdx = Opnd.getTiedRegister();
    if (-1 != TiedOpIdx) {
      assert((unsigned)TiedOpIdx < OpNo);
      // Set the entry in OperandMap for the tied operand we're skipping.
      OperandMap[OpNo] = OperandMap[TiedOpIdx];
      ++OpNo;

      // Source instructions can have at most 1 tied operand.
      if (IsSourceInst && (OpNo - DAGOpNo > 1))
        PrintFatalError(Rec->getLoc(),
                        "Input operands for Inst '" + Inst.getName() +
                            "' and input Dag operand count mismatch");

      continue;
    }
    for (unsigned SubOp = 0; SubOp != Opnd.MINumOperands;
         ++SubOp, ++OpNo, ++DAGOpNo) {
      const Record *OpndRec = Opnd.Rec;
      if (Opnd.MINumOperands > 1)
        OpndRec = cast<DefInit>(Opnd.MIOperandInfo->getArg(SubOp))->getDef();

      if (DAGOpNo >= Dag->getNumArgs())
        PrintFatalError(Rec->getLoc(), "Inst '" + Inst.getName() +
                                           "' and Dag operand count mismatch");

      if (const auto *DI = dyn_cast<DefInit>(Dag->getArg(DAGOpNo))) {
        if (DI->getDef()->isSubClassOf("Register") ||
            DI->getDef()->isSubClassOf("RegisterByHwMode")) {
          // Check if the fixed register belongs to the Register class.
          if (!validateRegister(DI->getDef(), OpndRec, Rec->getLoc(), PatPreds))
            PrintFatalError(Rec->getLoc(),
                            "Error in Dag '" + Dag->getAsString() +
                                "': Register '" + DI->getDef()->getName() +
                                "' is not in register class '" +
                                OpndRec->getName() + "'");
          OperandMap[OpNo].Kind = OpData::Reg;
          OperandMap[OpNo].RegRec = DI->getDef();
          continue;
        }
        // Validate that Dag operand type matches the type defined in the
        // corresponding instruction. Operands in the input and output Dag
        // patterns are allowed to be a subclass of the type specified in the
        // corresponding instruction operand instead of being an exact match.
        if (!validateTypes(DI->getDef(), OpndRec, IsSourceInst, PatPreds))
          PrintFatalError(Rec->getLoc(),
                          "Error in Dag '" + Dag->getAsString() +
                              "'. Operand '" + Dag->getArgNameStr(DAGOpNo) +
                              "' has type '" + DI->getDef()->getName() +
                              "' which does not match the type '" +
                              OpndRec->getName() +
                              "' in the corresponding instruction operand!");

        OperandMap[OpNo].Kind = OpData::Operand;
        OperandMap[OpNo].OpInfo.DagRec = DI->getDef();
        OperandMap[OpNo].OpInfo.TiedOpIdx = -1;

        // Create a mapping between the operand name in the Dag (e.g. $rs1) and
        // its index in the list of Dag operands and check that operands with
        // the same name have the same type. For example in 'C_ADD $rs1, $rs2'
        // we generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand
        // appears twice in the same Dag (tied in the compressed instruction),
        // we note the previous index in the TiedOpIdx field.
        StringRef ArgName = Dag->getArgNameStr(DAGOpNo);
        if (ArgName.empty())
          continue;

        if (IsSourceInst) {
          auto It = Operands.find(ArgName);
          if (It != Operands.end()) {
            OperandMap[OpNo].OpInfo.TiedOpIdx = It->getValue().MIOpNo;
            if (OperandMap[It->getValue().MIOpNo].OpInfo.DagRec != DI->getDef())
              PrintFatalError(Rec->getLoc(),
                              "Input Operand '" + ArgName +
                                  "' has a mismatched tied operand!");
          }
        }

        Operands[ArgName] = {DAGOpNo, OpNo};
      } else if (const auto *II = dyn_cast<IntInit>(Dag->getArg(DAGOpNo))) {
        // Validate that corresponding instruction operand expects an immediate.
        if (!OpndRec->isSubClassOf("Operand"))
          PrintFatalError(Rec->getLoc(), "Error in Dag '" + Dag->getAsString() +
                                             "' Found immediate: '" +
                                             II->getAsString() +
                                             "' but corresponding instruction "
                                             "operand expected a register!");
        // No pattern validation check possible for values of fixed immediate.
        OperandMap[OpNo].Kind = OpData::Imm;
        OperandMap[OpNo].ImmVal = II->getValue();
        LLVM_DEBUG(
            dbgs() << "  Found immediate '" << II->getValue() << "' at "
                   << (IsSourceInst ? "input " : "output ")
                   << "Dag. No validation time check possible for values of "
                      "fixed immediate.\n");
      } else {
        llvm_unreachable("Unhandled CompressPat argument type!");
      }
    }
  }

  // We shouldn't have extra Dag operands.
  if (DAGOpNo != Dag->getNumArgs())
    PrintFatalError(Rec->getLoc(), "Inst '" + Inst.getName() +
                                       "' and Dag operand count mismatch");
}

// Check that all names in the source DAG appear in the destionation DAG.
void CompressInstEmitter::checkDagOperandMapping(
    const Record *Rec, const StringMap<ArgData> &DestOperands,
    const DagInit *SourceDag, const DagInit *DestDag) {

  for (unsigned I = 0; I < SourceDag->getNumArgs(); ++I) {
    // Skip fixed immediates and registers, they were handled in
    // addDagOperandMapping.
    StringRef ArgName = SourceDag->getArgNameStr(I);
    if (ArgName.empty())
      continue;

    auto It = DestOperands.find(ArgName);
    if (It == DestOperands.end())
      PrintFatalError(Rec->getLoc(), "Operand " + ArgName +
                                         " defined in Input Dag but not used in"
                                         " Output Dag!");
    // Input Dag operand types must match output Dag operand type.
    if (!validateArgsTypes(DestDag->getArg(It->getValue().DAGOpNo),
                           SourceDag->getArg(I)))
      PrintFatalError(Rec->getLoc(), "Type mismatch between Input and "
                                     "Output Dag operand '" +
                                         ArgName + "'!");
  }
}

/// Map operand names in the Dag to their index in both corresponding input and
/// output instructions. Validate that operands defined in the input are
/// used in the output pattern while populating the maps.
void CompressInstEmitter::createInstOperandMapping(
    const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
    IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
    StringMap<ArgData> &SourceOperands, const CodeGenInstruction &DestInst) {
  // TiedCount keeps track of the number of operands skipped in Inst
  // operands list to get to the corresponding Dag operand.
  unsigned TiedCount = 0;
  LLVM_DEBUG(dbgs() << "  Operand mapping:\n  Source   Dest\n");
  unsigned OpNo = 0;
  for (const auto &Operand : DestInst.Operands) {
    int TiedInstOpIdx = Operand.getTiedRegister();
    if (TiedInstOpIdx != -1) {
      ++TiedCount;
      assert((unsigned)TiedInstOpIdx < OpNo);
      DestOperandMap[OpNo] = DestOperandMap[TiedInstOpIdx];
      if (DestOperandMap[OpNo].Kind == OpData::Operand)
        // No need to fill the SourceOperandMap here since it was mapped to
        // destination operand 'TiedInstOpIdx' in a previous iteration.
        LLVM_DEBUG(dbgs() << "    " << DestOperandMap[OpNo].OpInfo.Idx
                          << " ====> " << OpNo
                          << "  Dest operand tied with operand '"
                          << TiedInstOpIdx << "'\n");
      ++OpNo;
      continue;
    }

    for (unsigned SubOp = 0; SubOp != Operand.MINumOperands; ++SubOp, ++OpNo) {
      // Skip fixed immediates and registers, they were handled in
      // addDagOperandMapping.
      if (DestOperandMap[OpNo].Kind != OpData::Operand)
        continue;

      unsigned DagArgIdx = OpNo - TiedCount;
      StringRef ArgName = DestDag->getArgNameStr(DagArgIdx);
      auto SourceOp = SourceOperands.find(ArgName);
      if (SourceOp == SourceOperands.end())
        PrintFatalError(Rec->getLoc(),
                        "Output Dag operand '" + ArgName +
                            "' has no matching input Dag operand.");

      assert(ArgName ==
                 SourceDag->getArgNameStr(SourceOp->getValue().DAGOpNo) &&
             "Incorrect operand mapping detected!\n");

      unsigned SourceOpNo = SourceOp->getValue().MIOpNo;
      DestOperandMap[OpNo].OpInfo.Idx = SourceOpNo;
      SourceOperandMap[SourceOpNo].OpInfo.Idx = OpNo;
      LLVM_DEBUG(dbgs() << "    " << SourceOpNo << " ====> " << OpNo << "\n");
    }
  }
}

/// Validates the CompressPattern and create operand mapping.
/// These are the checks to validate a CompressPat pattern declarations.
/// Error out with message under these conditions:
/// - Dag Input opcode is an expanded instruction and Dag Output opcode is a
///   compressed instruction.
/// - Operands in Dag Input must be all used in Dag Output.
///   Register Operand type in Dag Input Type must be contained in the
///   corresponding Source Instruction type.
/// - Register Operand type in Dag Input must be the same as in Dag Ouput.
/// - Register Operand type in Dag Output must be the same as the
///   corresponding Destination Inst type.
/// - Immediate Operand type in Dag Input must be the same as in Dag Ouput.
/// - Immediate Operand type in Dag Ouput must be the same as the corresponding
///   Destination Instruction type.
/// - Fixed register must be contained in the corresponding Source Instruction
///   type.
/// - Fixed register must be contained in the corresponding Destination
///   Instruction type.
/// Warning message printed under these conditions:
/// - Fixed immediate in Dag Input or Dag Ouput cannot be checked at this time
///   and generate warning.
/// - Immediate operand type in Dag Input differs from the corresponding Source
///   Instruction type and generate a warning.
void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
  // Validate input Dag operands.
  const DagInit *SourceDag = Rec->getValueAsDag("Input");
  assert(SourceDag && "Missing 'Input' in compress pattern!");
  LLVM_DEBUG(dbgs() << "Input: " << *SourceDag << "\n");

  // Checking we are transforming from compressed to uncompressed instructions.
  const Record *SourceOperator = SourceDag->getOperatorAsDef(Rec->getLoc());
  CodeGenInstruction SourceInst(SourceOperator);

  // Validate output Dag operands.
  const DagInit *DestDag = Rec->getValueAsDag("Output");
  assert(DestDag && "Missing 'Output' in compress pattern!");
  LLVM_DEBUG(dbgs() << "Output: " << *DestDag << "\n");

  const Record *DestOperator = DestDag->getOperatorAsDef(Rec->getLoc());
  CodeGenInstruction DestInst(DestOperator);

  if (SourceOperator->getValueAsInt("Size") <=
      DestOperator->getValueAsInt("Size"))
    PrintFatalError(
        Rec->getLoc(),
        "Compressed instruction '" + DestOperator->getName() +
            "'is not strictly smaller than the uncompressed instruction '" +
            SourceOperator->getName() + "' !");

  // Get the target features for the CompressPat.
  std::vector<const Record *> PatReqFeatures;
  std::vector<const Record *> RF = Rec->getValueAsListOfDefs("Predicates");
  copy_if(RF, std::back_inserter(PatReqFeatures), [](const Record *R) {
    return R->getValueAsBit("AssemblerMatcherPredicate");
  });

  // Fill the mapping from the source to destination instructions.

  IndexedMap<OpData> SourceOperandMap;
  // Map from arg name to DAG operand number and MI operand number.
  StringMap<ArgData> SourceOperands;
  // Create a mapping between source Dag operands and source Inst operands.
  addDagOperandMapping(Rec, SourceDag, SourceInst, SourceOperandMap,
                       SourceOperands, /*IsSourceInst*/ true, PatReqFeatures);

  IndexedMap<OpData> DestOperandMap;
  // Map from arg name to DAG operand number and MI operand number.
  StringMap<ArgData> DestOperands;
  // Create a mapping between destination Dag operands and destination Inst
  // operands.
  addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap, DestOperands,
                       /*IsSourceInst*/ false, PatReqFeatures);

  checkDagOperandMapping(Rec, DestOperands, SourceDag, DestDag);
  // Create operand mapping between the source and destination instructions.
  createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
                           DestOperandMap, SourceOperands, DestInst);

  CompressPatterns.emplace_back(SourceInst, DestInst, std::move(PatReqFeatures),
                                SourceOperandMap, DestOperandMap,
                                Rec->getValueAsBit("isCompressOnly"));
}

static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap,
                              std::vector<const Record *> &Predicates,
                              const Record *Rec, StringRef Name) {
  unsigned &Entry = PredicateMap[Rec];
  if (Entry)
    return Entry;

  if (!Rec->isValueUnset(Name)) {
    Predicates.push_back(Rec);
    Entry = Predicates.size();
    return Entry;
  }

  PrintFatalError(Rec->getLoc(), "No " + Name +
                                     " predicate on this operand at all: '" +
                                     Rec->getName() + "'");
  return 0;
}

static void printPredicates(ArrayRef<const Record *> Predicates, StringRef Name,
                            raw_ostream &OS) {
  for (unsigned I = 0; I < Predicates.size(); ++I) {
    StringRef Pred = Predicates[I]->getValueAsString(Name);
    Pred = Pred.trim();
    OS.indent(2) << "case " << I + 1 << ": {\n";
    OS.indent(4) << "// " << Predicates[I]->getName() << "\n";
    OS.indent(4) << Pred << "\n";
    OS.indent(2) << "}\n";
  }
}

static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
                             StringRef CodeStr, unsigned CompressedSize,
                             bool ReturnSize) {
  CombinedStream.indent(4) << "if (" << CondStr << ") {\n";
  CombinedStream << CodeStr;
  CombinedStream.indent(4) << "  return "
                           << (ReturnSize ? std::to_string(CompressedSize)
                                          : "true")
                           << ";\n";
  CombinedStream.indent(4) << "} // if\n";
}

void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
                                                  EmitterType EType) {
  const Record *AsmWriter = Target.getAsmWriter();
  if (!AsmWriter->getValueAsInt("PassSubtarget"))
    PrintFatalError(AsmWriter->getLoc(),
                    "'PassSubtarget' is false. SubTargetInfo object is needed "
                    "for target features.");

  StringRef TargetName = Target.getName();

  // Sort entries in CompressPatterns to handle instructions that can have more
  // than one candidate for compression\uncompression, e.g ADD can be
  // transformed to a C_ADD or a C_MV. When emitting 'uncompress()' function the
  // source and destination are flipped and the sort key needs to change
  // accordingly.
  llvm::stable_sort(CompressPatterns, [EType](const CompressPat &LHS,
                                              const CompressPat &RHS) {
    if (EType == EmitterType::Compress || EType == EmitterType::CheckCompress)
      return LHS.Source.getName() < RHS.Source.getName();
    return LHS.Dest.getName() < RHS.Dest.getName();
  });

  // A list of MCOperandPredicates for all operands in use, and the reverse map.
  std::vector<const Record *> MCOpPredicates;
  DenseMap<const Record *, unsigned> MCOpPredicateMap;
  // A list of ImmLeaf Predicates for all operands in use, and the reverse map.
  std::vector<const Record *> ImmLeafPredicates;
  DenseMap<const Record *, unsigned> ImmLeafPredicateMap;

  std::string F;
  std::string FH;
  raw_string_ostream Func(F);
  raw_string_ostream FuncH(FH);

  auto GetEmitterGuard = [EType]() -> StringRef {
    switch (EType) {
    case EmitterType::Compress:
      return "GEN_COMPRESS_INSTR";
    case EmitterType::Uncompress:
      return "GEN_UNCOMPRESS_INSTR";
    case EmitterType::CheckCompress:
      return "GEN_CHECK_COMPRESS_INSTR";
    }
    llvm_unreachable("Invalid emitter type");
  };

  IfDefEmitter IfDef(OS, GetEmitterGuard());

  if (EType == EmitterType::Compress) {
    FuncH << "static bool compressInst(MCInst &OutInst,\n";
    FuncH.indent(25) << "const MCInst &MI,\n";
    FuncH.indent(25) << "const MCSubtargetInfo &STI) {\n";
  } else if (EType == EmitterType::Uncompress) {
    FuncH << "static bool uncompressInst(MCInst &OutInst,\n";
    FuncH.indent(27) << "const MCInst &MI,\n";
    FuncH.indent(27) << "const MCSubtargetInfo &STI) {\n";
  } else if (EType == EmitterType::CheckCompress) {
    FuncH << "static unsigned getCompressedSize(const MachineInstr &MI,\n";
    FuncH.indent(34) << "const " << TargetName << "Subtarget &STI) {\n";
    FuncH.indent(2)
        << "// Returns the compressed size, or zero if not compressible.\n";
  }
  // HwModeId is used if we have any RegClassByHwMode patterns
  if (!Target.getAllRegClassByHwMode().empty())
    FuncH.indent(2) << "[[maybe_unused]] unsigned HwModeId = "
                    << "STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);\n";

  if (CompressPatterns.empty()) {
    OS << FH;
    OS.indent(2) << "return "
                 << (EType == EmitterType::CheckCompress ? "0" : "false")
                 << ";\n}\n";
    return;
  }

  std::string CaseString;
  raw_string_ostream CaseStream(CaseString);
  StringRef PrevOp;
  StringRef CurOp;
  CaseStream << "  switch (MI.getOpcode()) {\n";
  CaseStream << "  default: return "
             << (EType == EmitterType::CheckCompress ? "0" : "false") << ";\n";

  bool CompressOrCheck =
      EType == EmitterType::Compress || EType == EmitterType::CheckCompress;
  bool CompressOrUncompress =
      EType == EmitterType::Compress || EType == EmitterType::Uncompress;
  std::string ValidatorName =
      CompressOrUncompress
          ? (TargetName + "ValidateMCOperandFor" +
             (EType == EmitterType::Compress ? "Compress" : "Uncompress"))
                .str()
          : "";

  for (const auto &CompressPat : CompressPatterns) {
    if (EType == EmitterType::Uncompress && CompressPat.IsCompressOnly)
      continue;

    std::string CondString;
    std::string CodeString;
    raw_string_ostream CondStream(CondString);
    raw_string_ostream CodeStream(CodeString);
    const CodeGenInstruction &Source =
        CompressOrCheck ? CompressPat.Source : CompressPat.Dest;
    const CodeGenInstruction &Dest =
        CompressOrCheck ? CompressPat.Dest : CompressPat.Source;
    const IndexedMap<OpData> &SourceOperandMap =
        CompressOrCheck ? CompressPat.SourceOperandMap
                        : CompressPat.DestOperandMap;
    const IndexedMap<OpData> &DestOperandMap =
        CompressOrCheck ? CompressPat.DestOperandMap
                        : CompressPat.SourceOperandMap;

    CurOp = Source.getName();
    // Check current and previous opcode to decide to continue or end a case.
    if (CurOp != PrevOp) {
      if (!PrevOp.empty()) {
        CaseStream.indent(4) << "break;\n";
        CaseStream.indent(2) << "} // case " + PrevOp + "\n";
      }
      CaseStream.indent(2) << "case " + TargetName + "::" + CurOp + ": {\n";
    }

    std::set<SubtargetFeatureLiteral> FeaturesSet;
    std::set<std::set<SubtargetFeatureLiteral>> AnyOfFeatureSets;
    // Add CompressPat required features.
    getRequiredFeatures(FeaturesSet, AnyOfFeatureSets,
                        CompressPat.PatReqFeatures);

    // Add Dest instruction required features.
    std::vector<const Record *> ReqFeatures;
    std::vector<const Record *> RF =
        Dest.TheDef->getValueAsListOfDefs("Predicates");
    copy_if(RF, std::back_inserter(ReqFeatures), [](const Record *R) {
      return R->getValueAsBit("AssemblerMatcherPredicate");
    });
    getRequiredFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures);

    ListSeparator CondSep(" &&\n        ");

    // Emit checks for all required features.
    for (const auto &Op : FeaturesSet) {
      StringRef Not = Op.IsNot ? "!" : "";
      CondStream << CondSep << Not << "STI.getFeatureBits()[" << TargetName
                 << "::" << Op.Feature << "]";
    }

    // Emit checks for all required feature groups.
    for (const auto &Set : AnyOfFeatureSets) {
      CondStream << CondSep << "(";
      for (const auto &Op : Set) {
        bool IsLast = &Op == &*Set.rbegin();
        StringRef Not = Op.IsNot ? "!" : "";
        CondStream << Not << "STI.getFeatureBits()[" << TargetName
                   << "::" << Op.Feature << "]";
        if (!IsLast)
          CondStream << " || ";
      }
      CondStream << ")";
    }

    // Start Source Inst operands validation.
    unsigned OpNo = 0;
    for (const auto &SourceOperand : Source.Operands) {
      for (unsigned SubOp = 0; SubOp != SourceOperand.MINumOperands; ++SubOp) {
        // Check for fixed immediates\registers in the source instruction.
        switch (SourceOperandMap[OpNo].Kind) {
        case OpData::Operand:
          if (SourceOperandMap[OpNo].OpInfo.TiedOpIdx != -1) {
            if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClassLike"))
              CondStream << CondSep << "MI.getOperand(" << OpNo
                         << ").isReg() && MI.getOperand("
                         << SourceOperandMap[OpNo].OpInfo.TiedOpIdx
                         << ").isReg()" << CondSep << "(MI.getOperand(" << OpNo
                         << ").getReg() == MI.getOperand("
                         << SourceOperandMap[OpNo].OpInfo.TiedOpIdx
                         << ").getReg())";
            else
              PrintFatalError("Unexpected tied operand types!");
          }

          // We don't need to do anything for source instruction operand checks.
          break;
        case OpData::Imm:
          CondStream << CondSep << "MI.getOperand(" << OpNo << ").isImm()"
                     << CondSep << "(MI.getOperand(" << OpNo
                     << ").getImm() == " << SourceOperandMap[OpNo].ImmVal
                     << ")";
          break;
        case OpData::Reg: {
          const Record *Reg = SourceOperandMap[OpNo].RegRec;
          CondStream << CondSep << "MI.getOperand(" << OpNo << ").isReg()"
                     << CondSep << "(MI.getOperand(" << OpNo
                     << ").getReg() == ";
          if (Reg->isSubClassOf("RegisterByHwMode")) {
            RegisterByHwMode(Reg, Target.getRegBank())
                .emitResolverCall(CondStream, "HwModeId");
          } else {
            CondStream << TargetName << "::" << Reg->getName();
          }
          CondStream << ")";
          break;
        }
        }
        ++OpNo;
      }
    }
    CodeStream.indent(6) << "// " << Dest.AsmString << "\n";
    if (CompressOrUncompress)
      CodeStream.indent(6) << "OutInst.setOpcode(" << TargetName
                           << "::" << Dest.getName() << ");\n";
    OpNo = 0;
    for (const auto &DestOperand : Dest.Operands) {
      CodeStream.indent(6) << "// Operand: " << DestOperand.Name << "\n";

      for (unsigned SubOp = 0; SubOp != DestOperand.MINumOperands; ++SubOp) {
        const Record *DestRec = DestOperand.Rec;

        if (DestOperand.MINumOperands > 1)
          DestRec =
              cast<DefInit>(DestOperand.MIOperandInfo->getArg(SubOp))->getDef();

        switch (DestOperandMap[OpNo].Kind) {
        case OpData::Operand: {
          unsigned OpIdx = DestOperandMap[OpNo].OpInfo.Idx;
          const Record *DagRec = DestOperandMap[OpNo].OpInfo.DagRec;
          // Check that the operand in the Source instruction fits
          // the type for the Dest instruction.
          if (auto *ClassRec = Target.getAsRegClassLike(DagRec)) {
            // This is a register operand. Check the register class.
            // Don't check register class if this is a tied operand, it was done
            // for the operand it's tied to.
            if (DestOperand.getTiedRegister() == -1) {
              CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isReg()";
              if (EType == EmitterType::CheckCompress)
                CondStream << " && MI.getOperand(" << OpIdx
                           << ").getReg().isPhysical()";
              CondStream << CondSep << "get" << TargetName
                         << "MCRegisterClass(";
              if (ClassRec->isSubClassOf("RegClassByHwMode")) {
                CondStream << TargetName << "RegClassByHwModeTables[HwModeId]["
                           << TargetName << "::" << ClassRec->getName() << "]";
              } else {
                CondStream << TargetName << "::" << ClassRec->getName()
                           << "RegClassID";
              }
              CondStream << ").contains(MI.getOperand(" << OpIdx
                         << ").getReg())";
            }

            if (CompressOrUncompress)
              CodeStream.indent(6)
                  << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
          } else {
            // Handling immediate operands.
            if (CompressOrUncompress) {
              unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
                                             DagRec, "MCOperandPredicate");
              CondStream << CondSep << ValidatorName << "("
                         << "MI.getOperand(" << OpIdx << "), STI, " << Entry
                         << " /* " << DagRec->getName() << " */)";
              // Also check DestRec if different than DagRec.
              if (DagRec != DestRec) {
                Entry = getPredicates(MCOpPredicateMap, MCOpPredicates, DestRec,
                                      "MCOperandPredicate");
                CondStream << CondSep << ValidatorName << "("
                           << "MI.getOperand(" << OpIdx << "), STI, " << Entry
                           << " /* " << DestRec->getName() << " */)";
              }
            } else {
              unsigned Entry =
                  getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DagRec,
                                "ImmediateCode");
              CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isImm()";
              CondStream << CondSep << TargetName << "ValidateMachineOperand("
                         << "MI.getOperand(" << OpIdx << "), &STI, " << Entry
                         << " /* " << DagRec->getName() << " */)";
              if (DagRec != DestRec) {
                Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
                                      DestRec, "ImmediateCode");
                CondStream << CondSep << "MI.getOperand(" << OpIdx
                           << ").isImm()";
                CondStream << CondSep << TargetName << "ValidateMachineOperand("
                           << "MI.getOperand(" << OpIdx << "), &STI, " << Entry
                           << " /* " << DestRec->getName() << " */)";
              }
            }
            if (CompressOrUncompress)
              CodeStream.indent(6)
                  << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
          }
          break;
        }
        case OpData::Imm: {
          if (CompressOrUncompress) {
            unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
                                           DestRec, "MCOperandPredicate");
            CondStream << CondSep << ValidatorName << "("
                       << "MCOperand::createImm(" << DestOperandMap[OpNo].ImmVal
                       << "), STI, " << Entry << " /* " << DestRec->getName()
                       << " */)";
          } else {
            unsigned Entry =
                getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DestRec,
                              "ImmediateCode");
            CondStream << CondSep << TargetName
                       << "ValidateMachineOperand(MachineOperand::CreateImm("
                       << DestOperandMap[OpNo].ImmVal << "), &STI, " << Entry
                       << " /* " << DestRec->getName() << " */)";
          }
          if (CompressOrUncompress)
            CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm("
                                 << DestOperandMap[OpNo].ImmVal << "));\n";
        } break;
        case OpData::Reg: {
          if (CompressOrUncompress) {
            // Fixed register has been validated at pattern validation time.
            const Record *Reg = DestOperandMap[OpNo].RegRec;
            CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createReg(";
            if (Reg->isSubClassOf("RegisterByHwMode")) {
              RegisterByHwMode(Reg, Target.getRegBank())
                  .emitResolverCall(CodeStream, "HwModeId");
            } else {
              CodeStream << TargetName << "::" << Reg->getName();
            }
            CodeStream << "));\n";
          }
        } break;
        }
        ++OpNo;
      }
    }
    if (CompressOrUncompress)
      CodeStream.indent(6) << "OutInst.setLoc(MI.getLoc());\n";
    mergeCondAndCode(CaseStream, CondString, CodeString,
                     Dest.TheDef->getValueAsInt("Size"),
                     EType == EmitterType::CheckCompress);
    PrevOp = CurOp;
  }
  Func << CaseString;
  Func.indent(4) << "break;\n";
  // Close brace for the last case.
  Func.indent(2) << "} // case " << CurOp << "\n";
  Func.indent(2) << "} // switch\n";
  Func.indent(2) << "return "
                 << (EType == EmitterType::CheckCompress ? "0" : "false")
                 << ";\n}\n";

  if (!MCOpPredicates.empty()) {
    auto IndentLength = ValidatorName.size() + 13;
    OS << "static bool " << ValidatorName << "(const MCOperand &MCOp,\n";
    OS.indent(IndentLength) << "const MCSubtargetInfo &STI,\n";
    OS.indent(IndentLength) << "unsigned PredicateIndex) {\n";
    OS << "  switch (PredicateIndex) {\n"
       << "  default:\n"
       << "    llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
       << "    break;\n";

    printPredicates(MCOpPredicates, "MCOperandPredicate", OS);

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

  if (!ImmLeafPredicates.empty()) {
    auto IndentLength = TargetName.size() + 35;
    OS << "static bool " << TargetName
       << "ValidateMachineOperand(const MachineOperand &MO,\n";
    OS.indent(IndentLength)
        << "const " << TargetName << "Subtarget *Subtarget,\n";
    OS.indent(IndentLength)
        << "unsigned PredicateIndex) {\n"
        << "  int64_t Imm = MO.getImm();\n"
        << "  switch (PredicateIndex) {\n"
        << "  default:\n"
        << "    llvm_unreachable(\"Unknown ImmLeaf Predicate kind\");\n"
        << "    break;\n";

    printPredicates(ImmLeafPredicates, "ImmediateCode", OS);

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

  OS << FH;
  OS << F;
}

void CompressInstEmitter::run(raw_ostream &OS) {
  // Process the CompressPat definitions, validating them as we do so.
  for (const Record *Pat : Records.getAllDerivedDefinitions("CompressPat"))
    evaluateCompressPat(Pat);

  // Emit file header.
  emitSourceFileHeader("Compress instruction Source Fragment", OS, Records);
  // Generate compressInst() function.
  emitCompressInstEmitter(OS, EmitterType::Compress);
  // Generate uncompressInst() function.
  emitCompressInstEmitter(OS, EmitterType::Uncompress);
  // Generate getCompressedSize() function.
  emitCompressInstEmitter(OS, EmitterType::CheckCompress);
}

static TableGen::Emitter::OptClass<CompressInstEmitter>
    X("gen-compress-inst-emitter", "Generate compressed instructions.");
