//===- MIR2Vec.cpp - Implementation of MIR2Vec ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
// Exceptions. See the LICENSE file for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the MIR2Vec algorithm for Machine IR embeddings.
///
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MIR2Vec.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Regex.h"

using namespace llvm;
using namespace mir2vec;

#define DEBUG_TYPE "mir2vec"

STATISTIC(MIRVocabMissCounter,
          "Number of lookups to MIR entities not present in the vocabulary");
STATISTIC(MIRClasslessRegCounter,
          "Number of register operands with no register class");

namespace llvm {
namespace mir2vec {
cl::OptionCategory MIR2VecCategory("MIR2Vec Options");

// FIXME: Use a default vocab when not specified
static cl::opt<std::string>
    VocabFile("mir2vec-vocab-path",
              cl::desc("Path to the vocabulary file for MIR2Vec"), cl::init(""),
              cl::cat(MIR2VecCategory));
cl::opt<float> OpcWeight("mir2vec-opc-weight", cl::init(1.0),
                         cl::desc("Weight for machine opcode embeddings"),
                         cl::cat(MIR2VecCategory));
cl::opt<float>
    CommonOperandWeight("mir2vec-common-operand-weight", cl::init(1.0),
                        cl::desc("Weight for common operand embeddings"),
                        cl::cat(MIR2VecCategory));
cl::opt<float>
    RegOperandWeight("mir2vec-reg-operand-weight", cl::init(1.0),
                     cl::desc("Weight for register operand embeddings"),
                     cl::cat(MIR2VecCategory));
cl::opt<MIR2VecKind> MIR2VecEmbeddingKind(
    "mir2vec-kind",
    cl::values(clEnumValN(MIR2VecKind::Symbolic, "symbolic",
                          "Generate symbolic embeddings for MIR")),
    cl::init(MIR2VecKind::Symbolic), cl::desc("MIR2Vec embedding kind"),
    cl::cat(MIR2VecCategory));

static cl::opt<bool> PrintAllVocabEntries(
    "mir2vec-print-all-vocab-entries", cl::init(false),
    cl::desc("Print all vocabulary entries including zero embeddings"),
    cl::cat(MIR2VecCategory));

} // namespace mir2vec
} // namespace llvm

//===----------------------------------------------------------------------===//
// Vocabulary
//===----------------------------------------------------------------------===//

MIRVocabulary::MIRVocabulary(VocabMap &&OpcodeMap, VocabMap &&CommonOperandMap,
                             VocabMap &&PhysicalRegisterMap,
                             VocabMap &&VirtualRegisterMap,
                             const TargetInstrInfo &TII,
                             const TargetRegisterInfo &TRI,
                             const MachineRegisterInfo &MRI)
    : TII(TII), TRI(TRI), MRI(MRI) {
  buildCanonicalOpcodeMapping();
  unsigned CanonicalOpcodeCount = UniqueBaseOpcodeNames.size();
  assert(CanonicalOpcodeCount > 0 &&
         "No canonical opcodes found for target - invalid vocabulary");

  buildRegisterOperandMapping();

  // Define layout of vocabulary sections
  Layout.OpcodeBase = 0;
  Layout.CommonOperandBase = CanonicalOpcodeCount;
  // We expect same classes for physical and virtual registers
  Layout.PhyRegBase = Layout.CommonOperandBase + std::size(CommonOperandNames);
  Layout.VirtRegBase = Layout.PhyRegBase + RegisterOperandNames.size();

  generateStorage(OpcodeMap, CommonOperandMap, PhysicalRegisterMap,
                  VirtualRegisterMap);
  Layout.TotalEntries = Storage.size();
}

Expected<MIRVocabulary>
MIRVocabulary::create(VocabMap &&OpcodeMap, VocabMap &&CommonOperandMap,
                      VocabMap &&PhyRegMap, VocabMap &&VirtRegMap,
                      const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
                      const MachineRegisterInfo &MRI) {
  if (OpcodeMap.empty() || CommonOperandMap.empty() || PhyRegMap.empty() ||
      VirtRegMap.empty())
    return createStringError(errc::invalid_argument,
                             "Empty vocabulary entries provided");

  MIRVocabulary Vocab(std::move(OpcodeMap), std::move(CommonOperandMap),
                      std::move(PhyRegMap), std::move(VirtRegMap), TII, TRI,
                      MRI);

  // Validate Storage after construction
  if (!Vocab.Storage.isValid())
    return createStringError(errc::invalid_argument,
                             "Failed to create valid vocabulary storage");
  Vocab.ZeroEmbedding = Embedding(Vocab.Storage.getDimension(), 0.0);
  return std::move(Vocab);
}

std::string MIRVocabulary::extractBaseOpcodeName(StringRef InstrName) {
  // Extract base instruction name using regex to capture letters and
  // underscores Examples: "ADD32rr" -> "ADD", "ARITH_FENCE" -> "ARITH_FENCE"
  //
  // TODO: Consider more sophisticated extraction:
  // - Handle complex prefixes like "AVX1_SETALLONES" correctly (Currently, it
  // would naively map to "AVX")
  // - Extract width suffixes (8,16,32,64) as separate features
  // - Capture addressing mode suffixes (r,i,m,ri,etc.) for better analysis
  // (Currently, instances like "MOV32mi" map to "MOV", but "ADDPDrr" would map
  // to "ADDPDrr")

  assert(!InstrName.empty() && "Instruction name should not be empty");

  // Use regex to extract initial sequence of letters and underscores
  static const Regex BaseOpcodeRegex("([a-zA-Z_]+)");
  SmallVector<StringRef, 2> Matches;

  if (BaseOpcodeRegex.match(InstrName, &Matches) && Matches.size() > 1) {
    StringRef Match = Matches[1];
    // Trim trailing underscores
    while (!Match.empty() && Match.back() == '_')
      Match = Match.drop_back();
    return Match.str();
  }

  // Fallback to original name if no pattern matches
  return InstrName.str();
}

unsigned MIRVocabulary::getCanonicalIndexForBaseName(StringRef BaseName) const {
  assert(!UniqueBaseOpcodeNames.empty() && "Canonical mapping not built");
  auto It = std::find(UniqueBaseOpcodeNames.begin(),
                      UniqueBaseOpcodeNames.end(), BaseName.str());
  assert(It != UniqueBaseOpcodeNames.end() &&
         "Base name not found in unique opcodes");
  return std::distance(UniqueBaseOpcodeNames.begin(), It);
}

unsigned MIRVocabulary::getCanonicalOpcodeIndex(unsigned Opcode) const {
  auto BaseOpcode = extractBaseOpcodeName(TII.getName(Opcode));
  return getCanonicalIndexForBaseName(BaseOpcode);
}

unsigned
MIRVocabulary::getCanonicalIndexForOperandName(StringRef OperandName) const {
  auto It = std::find(std::begin(CommonOperandNames),
                      std::end(CommonOperandNames), OperandName);
  assert(It != std::end(CommonOperandNames) &&
         "Operand name not found in common operands");
  return Layout.CommonOperandBase +
         std::distance(std::begin(CommonOperandNames), It);
}

unsigned
MIRVocabulary::getCanonicalIndexForRegisterClass(StringRef RegName,
                                                 bool IsPhysical) const {
  auto It = std::find(RegisterOperandNames.begin(), RegisterOperandNames.end(),
                      RegName);
  assert(It != RegisterOperandNames.end() &&
         "Register name not found in register operands");
  unsigned LocalIndex = std::distance(RegisterOperandNames.begin(), It);
  return (IsPhysical ? Layout.PhyRegBase : Layout.VirtRegBase) + LocalIndex;
}

std::string MIRVocabulary::getStringKey(unsigned Pos) const {
  assert(Pos < Layout.TotalEntries && "Position out of bounds in vocabulary");

  // Handle opcodes section
  if (Pos < Layout.CommonOperandBase) {
    // Convert canonical index back to base opcode name
    auto It = UniqueBaseOpcodeNames.begin();
    std::advance(It, Pos);
    assert(It != UniqueBaseOpcodeNames.end() &&
           "Canonical index out of bounds in opcode section");
    return *It;
  }

  auto getLocalIndex = [](unsigned Pos, size_t BaseOffset, size_t Bound,
                          const char *Msg) {
    unsigned LocalIndex = Pos - BaseOffset;
    assert(LocalIndex < Bound && Msg);
    return LocalIndex;
  };

  // Handle common operands section
  if (Pos < Layout.PhyRegBase) {
    unsigned LocalIndex = getLocalIndex(
        Pos, Layout.CommonOperandBase, std::size(CommonOperandNames),
        "Local index out of bounds in common operands");
    return CommonOperandNames[LocalIndex].str();
  }

  // Handle physical registers section
  if (Pos < Layout.VirtRegBase) {
    unsigned LocalIndex =
        getLocalIndex(Pos, Layout.PhyRegBase, RegisterOperandNames.size(),
                      "Local index out of bounds in physical registers");
    return "PhyReg_" + RegisterOperandNames[LocalIndex];
  }

  // Handle virtual registers section
  unsigned LocalIndex =
      getLocalIndex(Pos, Layout.VirtRegBase, RegisterOperandNames.size(),
                    "Local index out of bounds in virtual registers");
  return "VirtReg_" + RegisterOperandNames[LocalIndex];
}

void MIRVocabulary::generateStorage(const VocabMap &OpcodeMap,
                                    const VocabMap &CommonOperandsMap,
                                    const VocabMap &PhyRegMap,
                                    const VocabMap &VirtRegMap) {

  // Helper for handling missing entities in the vocabulary.
  // Currently, we use a zero vector. In the future, we will throw an error to
  // ensure that *all* known entities are present in the vocabulary.
  auto handleMissingEntity = [](StringRef Key) {
    LLVM_DEBUG(errs() << "MIR2Vec: Missing vocabulary entry for " << Key
                      << "; using zero vector. This will result in an error "
                         "in the future.\n");
    ++MIRVocabMissCounter;
  };

  // Initialize opcode embeddings section
  unsigned EmbeddingDim = OpcodeMap.begin()->second.size();
  std::vector<Embedding> OpcodeEmbeddings(Layout.CommonOperandBase,
                                          Embedding(EmbeddingDim));

  // Populate opcode embeddings using canonical mapping
  for (auto COpcodeName : UniqueBaseOpcodeNames) {
    if (auto It = OpcodeMap.find(COpcodeName); It != OpcodeMap.end()) {
      auto COpcodeIndex = getCanonicalIndexForBaseName(COpcodeName);
      assert(COpcodeIndex < Layout.CommonOperandBase &&
             "Canonical index out of bounds");
      OpcodeEmbeddings[COpcodeIndex] = It->second;
    } else {
      handleMissingEntity(COpcodeName);
    }
  }

  // Initialize common operand embeddings section
  std::vector<Embedding> CommonOperandEmbeddings(std::size(CommonOperandNames),
                                                 Embedding(EmbeddingDim));
  unsigned OperandIndex = 0;
  for (const auto &CommonOperandName : CommonOperandNames) {
    if (auto It = CommonOperandsMap.find(CommonOperandName.str());
        It != CommonOperandsMap.end()) {
      CommonOperandEmbeddings[OperandIndex] = It->second;
    } else {
      handleMissingEntity(CommonOperandName);
    }
    ++OperandIndex;
  }

  // Helper lambda for creating register operand embeddings
  auto createRegisterEmbeddings = [&](const VocabMap &RegMap) {
    std::vector<Embedding> RegEmbeddings(TRI.getNumRegClasses(),
                                         Embedding(EmbeddingDim));
    unsigned RegOperandIndex = 0;
    for (const auto &RegOperandName : RegisterOperandNames) {
      if (auto It = RegMap.find(RegOperandName); It != RegMap.end())
        RegEmbeddings[RegOperandIndex] = It->second;
      else
        handleMissingEntity(RegOperandName);
      ++RegOperandIndex;
    }
    return RegEmbeddings;
  };

  // Initialize register operand embeddings sections
  std::vector<Embedding> PhyRegEmbeddings = createRegisterEmbeddings(PhyRegMap);
  std::vector<Embedding> VirtRegEmbeddings =
      createRegisterEmbeddings(VirtRegMap);

  // Scale the vocabulary sections based on the provided weights
  auto scaleVocabSection = [](std::vector<Embedding> &Embeddings,
                              double Weight) {
    for (auto &Embedding : Embeddings)
      Embedding *= Weight;
  };
  scaleVocabSection(OpcodeEmbeddings, OpcWeight);
  scaleVocabSection(CommonOperandEmbeddings, CommonOperandWeight);
  scaleVocabSection(PhyRegEmbeddings, RegOperandWeight);
  scaleVocabSection(VirtRegEmbeddings, RegOperandWeight);

  std::vector<std::vector<Embedding>> Sections(
      static_cast<unsigned>(Section::MaxSections));
  Sections[static_cast<unsigned>(Section::Opcodes)] =
      std::move(OpcodeEmbeddings);
  Sections[static_cast<unsigned>(Section::CommonOperands)] =
      std::move(CommonOperandEmbeddings);
  Sections[static_cast<unsigned>(Section::PhyRegisters)] =
      std::move(PhyRegEmbeddings);
  Sections[static_cast<unsigned>(Section::VirtRegisters)] =
      std::move(VirtRegEmbeddings);

  Storage = ir2vec::VocabStorage(std::move(Sections));
}

void MIRVocabulary::buildCanonicalOpcodeMapping() {
  // Check if already built
  if (!UniqueBaseOpcodeNames.empty())
    return;

  // Build mapping from opcodes to canonical base opcode indices
  for (unsigned Opcode = 0; Opcode < TII.getNumOpcodes(); ++Opcode) {
    std::string BaseOpcode = extractBaseOpcodeName(TII.getName(Opcode));
    UniqueBaseOpcodeNames.insert(BaseOpcode);
  }

  LLVM_DEBUG(dbgs() << "MIR2Vec: Built canonical mapping for target with "
                    << UniqueBaseOpcodeNames.size()
                    << " unique base opcodes\n");
}

void MIRVocabulary::buildRegisterOperandMapping() {
  // Check if already built
  if (!RegisterOperandNames.empty())
    return;

  for (unsigned RC = 0; RC < TRI.getNumRegClasses(); ++RC) {
    const TargetRegisterClass *RegClass = TRI.getRegClass(RC);
    if (!RegClass)
      continue;

    // Get the register class name
    StringRef ClassName = TRI.getRegClassName(RegClass);
    RegisterOperandNames.push_back(ClassName.str());
  }
}

unsigned MIRVocabulary::getCommonOperandIndex(
    MachineOperand::MachineOperandType OperandType) const {
  assert(OperandType != MachineOperand::MO_Register &&
         "Expected non-register operand type");
  assert(OperandType > MachineOperand::MO_Register &&
         OperandType < MachineOperand::MO_Last && "Operand type out of bounds");
  return static_cast<unsigned>(OperandType) - 1;
}

std::optional<unsigned>
MIRVocabulary::getRegisterOperandIndex(Register Reg) const {
  assert(!RegisterOperandNames.empty() && "Register operand mapping not built");
  assert(Reg.isValid() && "Invalid register; not expected here");
  assert((Reg.isPhysical() || Reg.isVirtual()) &&
         "Expected a physical or virtual register");

  const TargetRegisterClass *RegClass = nullptr;

  // For physical registers, use TRI to get minimal register class as a
  // physical register can belong to multiple classes. For virtual
  // registers, use MRI to uniquely identify the assigned register class.
  if (Reg.isPhysical())
    RegClass = TRI.getMinimalPhysRegClass(Reg);
  else
    RegClass = MRI.getRegClassOrNull(Reg);

  // Not every register belongs to a register class. This can happen for
  // physical registers, e.g. X86's $mxcsr and $fpcw or AMDGPU's $mode, for
  // which getMinimalPhysRegClass() returns nullptr. It can also happen for
  // generic virtual registers that have not yet been through (or completed)
  // GlobalISel's register bank selection, and thus carry an LLT or a
  // RegisterBank instead of a TargetRegisterClass, for which
  // getRegClassOrNull() returns nullptr.
  // TODO: Avoid special-casing these registers at every use site. Classless
  // registers currently fall back to a zero embedding in operator[] and to
  // VirtRegBase in getEntityIDForRegister(), which is the same ad-hoc handling
  // the invalid/stack-slot cases already get. Give them a real vocabulary
  // representation instead -- e.g. an explicit "no register class" entry, or
  // keying generic vregs on their LLT/RegisterBank -- so that the lookup is
  // total and the callers need no fallbacks.
  if (!RegClass) {
    LLVM_DEBUG(errs() << "MIR2Vec: No register class for register " << Reg.id()
                      << "; using zero vector.\n");
    ++MIRClasslessRegCounter;
    return std::nullopt;
  }

  return RegClass->getID();
}

Expected<MIRVocabulary> MIRVocabulary::createDummyVocabForTest(
    const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
    const MachineRegisterInfo &MRI, unsigned Dim) {
  assert(Dim > 0 && "Dimension must be greater than zero");

  float DummyVal = 0.1f;

  VocabMap DummyOpcMap, DummyOperandMap, DummyPhyRegMap, DummyVirtRegMap;

  // Process opcodes directly without creating temporary vocabulary
  for (unsigned Opcode = 0; Opcode < TII.getNumOpcodes(); ++Opcode) {
    std::string BaseOpcode = extractBaseOpcodeName(TII.getName(Opcode));
    if (DummyOpcMap.count(BaseOpcode) == 0) { // Only add if not already present
      DummyOpcMap[BaseOpcode] = Embedding(Dim, DummyVal);
      DummyVal += 0.1f;
    }
  }

  // Add common operands
  for (const auto &CommonOperandName : CommonOperandNames) {
    DummyOperandMap[CommonOperandName.str()] = Embedding(Dim, DummyVal);
    DummyVal += 0.1f;
  }

  // Process register classes directly
  for (unsigned RC = 0; RC < TRI.getNumRegClasses(); ++RC) {
    const TargetRegisterClass *RegClass = TRI.getRegClass(RC);
    if (!RegClass)
      continue;

    std::string ClassName = TRI.getRegClassName(RegClass);
    DummyPhyRegMap[ClassName] = Embedding(Dim, DummyVal);
    DummyVirtRegMap[ClassName] = Embedding(Dim, DummyVal);
    DummyVal += 0.1f;
  }

  // Create vocabulary directly without temporary instance
  return MIRVocabulary::create(
      std::move(DummyOpcMap), std::move(DummyOperandMap),
      std::move(DummyPhyRegMap), std::move(DummyVirtRegMap), TII, TRI, MRI);
}

//===----------------------------------------------------------------------===//
// MIR2VecVocabProvider and MIR2VecVocabLegacyAnalysis
//===----------------------------------------------------------------------===//

Expected<mir2vec::MIRVocabulary>
MIR2VecVocabProvider::getVocabulary(const Module &M) {
  VocabMap OpcVocab, CommonOperandVocab, PhyRegVocabMap, VirtRegVocabMap;

  if (Error Err = readVocabulary(OpcVocab, CommonOperandVocab, PhyRegVocabMap,
                                 VirtRegVocabMap))
    return std::move(Err);

  for (const auto &F : M) {
    if (F.isDeclaration())
      continue;

    if (auto *MF = MMI.getMachineFunction(F)) {
      auto &Subtarget = MF->getSubtarget();
      if (const auto *TII = Subtarget.getInstrInfo())
        if (const auto *TRI = Subtarget.getRegisterInfo())
          return mir2vec::MIRVocabulary::create(
              std::move(OpcVocab), std::move(CommonOperandVocab),
              std::move(PhyRegVocabMap), std::move(VirtRegVocabMap), *TII, *TRI,
              MF->getRegInfo());
    }
  }
  return createStringError(errc::invalid_argument,
                           "No machine functions found in module");
}

Error MIR2VecVocabProvider::readVocabulary(VocabMap &OpcodeVocab,
                                           VocabMap &CommonOperandVocab,
                                           VocabMap &PhyRegVocabMap,
                                           VocabMap &VirtRegVocabMap) {
  if (VocabFile.empty())
    return createStringError(
        errc::invalid_argument,
        "MIR2Vec vocabulary file path not specified; set it "
        "using --mir2vec-vocab-path");

  auto BufOrError = MemoryBuffer::getFileOrSTDIN(VocabFile, /*IsText=*/true);
  if (!BufOrError)
    return createFileError(VocabFile, BufOrError.getError());

  auto Content = BufOrError.get()->getBuffer();

  Expected<json::Value> ParsedVocabValue = json::parse(Content);
  if (!ParsedVocabValue)
    return ParsedVocabValue.takeError();

  unsigned OpcodeDim = 0, CommonOperandDim = 0, PhyRegOperandDim = 0,
           VirtRegOperandDim = 0;
  if (auto Err = ir2vec::VocabStorage::parseVocabSection(
          "Opcodes", *ParsedVocabValue, OpcodeVocab, OpcodeDim))
    return Err;

  if (auto Err = ir2vec::VocabStorage::parseVocabSection(
          "CommonOperands", *ParsedVocabValue, CommonOperandVocab,
          CommonOperandDim))
    return Err;

  if (auto Err = ir2vec::VocabStorage::parseVocabSection(
          "PhysicalRegisters", *ParsedVocabValue, PhyRegVocabMap,
          PhyRegOperandDim))
    return Err;

  if (auto Err = ir2vec::VocabStorage::parseVocabSection(
          "VirtualRegisters", *ParsedVocabValue, VirtRegVocabMap,
          VirtRegOperandDim))
    return Err;

  // All sections must have the same embedding dimension
  if (!(OpcodeDim == CommonOperandDim && CommonOperandDim == PhyRegOperandDim &&
        PhyRegOperandDim == VirtRegOperandDim)) {
    return createStringError(
        errc::illegal_byte_sequence,
        "MIR2Vec vocabulary sections have different dimensions");
  }

  return Error::success();
}

char MIR2VecVocabLegacyAnalysis::ID = 0;
INITIALIZE_PASS_BEGIN(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
                      "MIR2Vec Vocabulary Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(MachineModuleInfoWrapperPass)
INITIALIZE_PASS_END(MIR2VecVocabLegacyAnalysis, "mir2vec-vocab-analysis",
                    "MIR2Vec Vocabulary Analysis", false, true)

StringRef MIR2VecVocabLegacyAnalysis::getPassName() const {
  return "MIR2Vec Vocabulary Analysis";
}

//===----------------------------------------------------------------------===//
// MIREmbedder and its subclasses
//===----------------------------------------------------------------------===//

std::unique_ptr<MIREmbedder> MIREmbedder::create(MIR2VecKind Mode,
                                                 const MachineFunction &MF,
                                                 const MIRVocabulary &Vocab) {
  switch (Mode) {
  case MIR2VecKind::Symbolic:
    return std::make_unique<SymbolicMIREmbedder>(MF, Vocab);
  }
  return nullptr;
}

Embedding MIREmbedder::computeEmbeddings(const MachineBasicBlock &MBB) const {
  Embedding MBBVector(Dimension, 0);

  // Get instruction info for opcode name resolution
  const auto &Subtarget = MF.getSubtarget();
  const auto *TII = Subtarget.getInstrInfo();
  if (!TII) {
    MF.getFunction().getContext().emitError(
        "MIR2Vec: No TargetInstrInfo available; cannot compute embeddings");
    return MBBVector;
  }

  // Process each machine instruction in the basic block
  for (const auto &MI : MBB) {
    // Skip debug instructions and other metadata
    if (MI.isDebugInstr())
      continue;
    MBBVector += computeEmbeddings(MI);
  }

  return MBBVector;
}

Embedding MIREmbedder::computeEmbeddings() const {
  Embedding MFuncVector(Dimension, 0);

  if (MF.empty())
    return MFuncVector;

  // Consider all reachable machine basic blocks in the function
  for (const auto *MBB : depth_first(&MF))
    MFuncVector += computeEmbeddings(*MBB);
  return MFuncVector;
}

SymbolicMIREmbedder::SymbolicMIREmbedder(const MachineFunction &MF,
                                         const MIRVocabulary &Vocab)
    : MIREmbedder(MF, Vocab) {}

std::unique_ptr<SymbolicMIREmbedder>
SymbolicMIREmbedder::create(const MachineFunction &MF,
                            const MIRVocabulary &Vocab) {
  return std::make_unique<SymbolicMIREmbedder>(MF, Vocab);
}

Embedding SymbolicMIREmbedder::computeEmbeddings(const MachineInstr &MI) const {
  // Skip debug instructions and other metadata
  if (MI.isDebugInstr())
    return Embedding(Dimension, 0);

  // Opcode embedding
  Embedding InstructionEmbedding = Vocab[MI.getOpcode()];

  // Add operand contributions
  for (const MachineOperand &MO : MI.operands())
    InstructionEmbedding += Vocab[MO];

  return InstructionEmbedding;
}

//===----------------------------------------------------------------------===//
// Printer Passes
//===----------------------------------------------------------------------===//

char MIR2VecVocabPrinterLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(MIR2VecVocabPrinterLegacyPass, "print-mir2vec-vocab",
                      "MIR2Vec Vocabulary Printer Pass", false, true)
INITIALIZE_PASS_DEPENDENCY(MIR2VecVocabLegacyAnalysis)
INITIALIZE_PASS_DEPENDENCY(MachineModuleInfoWrapperPass)
INITIALIZE_PASS_END(MIR2VecVocabPrinterLegacyPass, "print-mir2vec-vocab",
                    "MIR2Vec Vocabulary Printer Pass", false, true)

bool MIR2VecVocabPrinterLegacyPass::runOnMachineFunction(MachineFunction &MF) {
  return false;
}

bool MIR2VecVocabPrinterLegacyPass::doFinalization(Module &M) {
  auto &Analysis = getAnalysis<MIR2VecVocabLegacyAnalysis>();
  auto MIR2VecVocabOrErr = Analysis.getMIR2VecVocabulary(M);

  if (!MIR2VecVocabOrErr) {
    OS << "MIR2Vec Vocabulary Printer: Failed to get vocabulary - "
       << toString(MIR2VecVocabOrErr.takeError()) << "\n";
    return false;
  }

  auto &MIR2VecVocab = *MIR2VecVocabOrErr;
  unsigned Pos = 0;
  for (const auto &Entry : MIR2VecVocab) {
    // Skip zero embeddings to avoid printing entries not in the vocabulary.
    // This makes the output stable across changes to the opcode list.
    if (PrintAllVocabEntries || !Entry.isZero()) {
      OS << "Key: " << MIR2VecVocab.getStringKey(Pos) << ": ";
      Entry.print(OS);
    }
    ++Pos;
  }

  return false;
}

MachineFunctionPass *
llvm::createMIR2VecVocabPrinterLegacyPass(raw_ostream &OS) {
  return new MIR2VecVocabPrinterLegacyPass(OS);
}

char MIR2VecPrinterLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(MIR2VecPrinterLegacyPass, "print-mir2vec",
                      "MIR2Vec Embedder Printer Pass", false, true)
INITIALIZE_PASS_DEPENDENCY(MIR2VecVocabLegacyAnalysis)
INITIALIZE_PASS_DEPENDENCY(MachineModuleInfoWrapperPass)
INITIALIZE_PASS_END(MIR2VecPrinterLegacyPass, "print-mir2vec",
                    "MIR2Vec Embedder Printer Pass", false, true)

bool MIR2VecPrinterLegacyPass::runOnMachineFunction(MachineFunction &MF) {
  auto &Analysis = getAnalysis<MIR2VecVocabLegacyAnalysis>();
  auto VocabOrErr =
      Analysis.getMIR2VecVocabulary(*MF.getFunction().getParent());
  assert(VocabOrErr && "Failed to get MIR2Vec vocabulary");
  auto &MIRVocab = *VocabOrErr;

  auto Emb = mir2vec::MIREmbedder::create(MIR2VecEmbeddingKind, MF, MIRVocab);
  if (!Emb) {
    OS << "Error creating MIR2Vec embeddings for function " << MF.getName()
       << "\n";
    return false;
  }

  OS << "MIR2Vec embeddings for machine function " << MF.getName() << ":\n";
  OS << "Machine Function vector: ";
  Emb->getMFunctionVector().print(OS);

  OS << "Machine basic block vectors:\n";
  for (const MachineBasicBlock &MBB : MF) {
    OS << "Machine basic block: " << MBB.getFullName() << ":\n";
    Emb->getMBBVector(MBB).print(OS);
  }

  OS << "Machine instruction vectors:\n";
  for (const MachineBasicBlock &MBB : MF) {
    for (const MachineInstr &MI : MBB) {
      // Skip debug instructions as they are not
      // embedded
      if (MI.isDebugInstr())
        continue;

      OS << "Machine instruction: ";
      MI.print(OS);
      Emb->getMInstVector(MI).print(OS);
    }
  }

  return false;
}

MachineFunctionPass *llvm::createMIR2VecPrinterLegacyPass(raw_ostream &OS) {
  return new MIR2VecPrinterLegacyPass(OS);
}
