//===-- llvm/CodeGen/MachineModuleInfo.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 "llvm/CodeGen/MachineModuleSlotTracker.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/DebugInfoMetadata.h"

using namespace llvm;

bool MachineModuleSlotTracker::shouldPrintDebugLocationInline(
    const DILocation *DL) const {
  return InlineDebugLocations.contains(DL);
}

void MachineModuleSlotTracker::collectMachineFunctionMetadata(
    SmallVectorImpl<const MDNode *> &Metadata, const MachineFunction &MF,
    SmallVectorImpl<const MDNode *> *DebugLocations) const {
  for (const MachineBasicBlock &MBB : MF)
    for (const MachineInstr &MI : MBB.instrs()) {
      if (DebugLocations)
        if (DebugLoc DL = MI.getDebugLoc())
          DebugLocations->push_back(DL.getAsMDNode());

      if (MDNode *N = MI.getHeapAllocMarker())
        Metadata.push_back(N);
      if (MDNode *N = MI.getPCSections())
        Metadata.push_back(N);
      if (MDNode *N = MI.getMMRAMetadata())
        Metadata.push_back(N);

      for (const MachineOperand &MO : MI.operands())
        if (MO.isMetadata())
          Metadata.push_back(MO.getMetadata());

      for (const MachineMemOperand *MMO : MI.memoperands()) {
        AAMDNodes AAInfo = MMO->getAAInfo();
        if (AAInfo.TBAA)
          Metadata.push_back(AAInfo.TBAA);
        if (AAInfo.TBAAStruct)
          Metadata.push_back(AAInfo.TBAAStruct);
        if (AAInfo.Scope)
          Metadata.push_back(AAInfo.Scope);
        if (AAInfo.NoAlias)
          Metadata.push_back(AAInfo.NoAlias);
        if (AAInfo.NoAliasAddrSpace)
          Metadata.push_back(AAInfo.NoAliasAddrSpace);
        if (const MDNode *N = MMO->getRanges())
          Metadata.push_back(N);
        if (const MDNode *N = MMO->getMemCacheHint())
          Metadata.push_back(N);
      }
    }

  for (const MachineFunction::VariableDbgInfo &DebugVar :
       MF.getVariableDbgInfo()) {
    Metadata.push_back(DebugVar.Var);
    if (DebugLocations)
      DebugLocations->push_back(DebugVar.Loc);
  }
}

void MachineModuleSlotTracker::collectMachineMDNodes(
    MachineMDNodeListType &L) const {
  L.insert(L.end(), MachineMDNodes.begin(), MachineMDNodes.end());
}

void MachineModuleSlotTracker::renumberMetadataForAssembly() {
  if (!TheMF)
    return;

  SmallVector<const MDNode *, 16> Metadata;
  collectMachineFunctionMetadata(Metadata, *TheMF);
  MachineMDNodes.clear();
  ModuleSlotTracker::renumberMetadataForAssembly(Metadata, &MachineMDNodes);
}

MachineModuleSlotTracker::MachineModuleSlotTracker(MFGetterFnT Fn,
                                                   const MachineFunction *MF)
    : ModuleSlotTracker(MF->getFunction().getParent()),
      TheMF(Fn(MF->getFunction())) {
  if (!TheMF)
    return;

  SmallVector<const MDNode *, 16> Metadata;
  SmallVector<const MDNode *, 16> DebugLocations;
  collectMachineFunctionMetadata(Metadata, *TheMF, &DebugLocations);
  collectAdditionalMetadata(Metadata, MachineMDNodes);

  if (DebugLocations.empty())
    return;

  MachineMDNodeListType DebugMetadataNodes;
  collectAdditionalMetadata(DebugLocations, DebugMetadataNodes);
  SmallPtrSet<const MDNode *, 16> MachineMetadata;
  for (const auto &Entry : MachineMDNodes)
    MachineMetadata.insert(Entry.second);

  for (const auto &Entry : DebugMetadataNodes)
    if (isa<DILocation>(Entry.second) &&
        !MachineMetadata.contains(Entry.second))
      InlineDebugLocations.insert(cast<DILocation>(Entry.second));
}

MachineModuleSlotTracker::~MachineModuleSlotTracker() = default;
