//===- DXILPrettyPrinter.cpp - Print resources for textual DXIL -----------===//
//
// 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 "DXILPrettyPrinter.h"
#include "DXILWriter/DXILDebugInfoMap.h"
#include "DirectX.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::dxil;

static StringRef getRCName(dxil::ResourceClass RC) {
  switch (RC) {
  case dxil::ResourceClass::SRV:
    return "texture";
  case dxil::ResourceClass::UAV:
    return "UAV";
  case dxil::ResourceClass::CBuffer:
    return "cbuffer";
  case dxil::ResourceClass::Sampler:
    return "sampler";
  }
  llvm_unreachable("covered switch");
}

static StringRef getRCPrefix(dxil::ResourceClass RC) {
  switch (RC) {
  case dxil::ResourceClass::SRV:
    return "t";
  case dxil::ResourceClass::UAV:
    return "u";
  case dxil::ResourceClass::CBuffer:
    return "cb";
  case dxil::ResourceClass::Sampler:
    return "s";
  }
  llvm_unreachable("covered switch");
}

static StringRef getFormatName(const dxil::ResourceTypeInfo &RI) {
  if (RI.isTyped()) {
    switch (RI.getTyped().DXILStorageTy) {
    case dxil::ElementType::I1:
      return "i1";
    case dxil::ElementType::I16:
      return "i16";
    case dxil::ElementType::U16:
      return "u16";
    case dxil::ElementType::I32:
      return "i32";
    case dxil::ElementType::U32:
      return "u32";
    case dxil::ElementType::I64:
      return "i64";
    case dxil::ElementType::U64:
      return "u64";
    case dxil::ElementType::F16:
      return "f16";
    case dxil::ElementType::F32:
      return "f32";
    case dxil::ElementType::F64:
      return "f64";
    case dxil::ElementType::SNormF16:
      return "snorm_f16";
    case dxil::ElementType::UNormF16:
      return "unorm_f16";
    case dxil::ElementType::SNormF32:
      return "snorm_f32";
    case dxil::ElementType::UNormF32:
      return "unorm_f32";
    case dxil::ElementType::SNormF64:
      return "snorm_f64";
    case dxil::ElementType::UNormF64:
      return "unorm_f64";
    case dxil::ElementType::PackedS8x32:
      return "p32i8";
    case dxil::ElementType::PackedU8x32:
      return "p32u8";
    case dxil::ElementType::Invalid:
      llvm_unreachable("Invalid ElementType");
    }
    llvm_unreachable("Unhandled ElementType");
  } else if (RI.isStruct())
    return "struct";
  else if (RI.isCBuffer() || RI.isSampler())
    return "NA";
  return "byte";
}

static StringRef getTextureDimName(dxil::ResourceKind RK) {
  switch (RK) {
  case dxil::ResourceKind::Texture1D:
    return "1d";
  case dxil::ResourceKind::Texture2D:
    return "2d";
  case dxil::ResourceKind::Texture3D:
    return "3d";
  case dxil::ResourceKind::TextureCube:
    return "cube";
  case dxil::ResourceKind::Texture1DArray:
    return "1darray";
  case dxil::ResourceKind::Texture2DArray:
    return "2darray";
  case dxil::ResourceKind::TextureCubeArray:
    return "cubearray";
  case dxil::ResourceKind::TBuffer:
    return "tbuffer";
  case dxil::ResourceKind::FeedbackTexture2D:
    return "fbtex2d";
  case dxil::ResourceKind::FeedbackTexture2DArray:
    return "fbtex2darray";
  case dxil::ResourceKind::Texture2DMS:
    return "2dMS";
  case dxil::ResourceKind::Texture2DMSArray:
    return "2darrayMS";
  case dxil::ResourceKind::Invalid:
  case dxil::ResourceKind::NumEntries:
  case dxil::ResourceKind::CBuffer:
  case dxil::ResourceKind::RawBuffer:
  case dxil::ResourceKind::Sampler:
  case dxil::ResourceKind::StructuredBuffer:
  case dxil::ResourceKind::TypedBuffer:
  case dxil::ResourceKind::RTAccelerationStructure:
    llvm_unreachable("Invalid ResourceKind for texture");
  }
  llvm_unreachable("Unhandled ResourceKind");
}

namespace {
struct FormatResourceDimension
    : public llvm::FormatAdapter<const dxil::ResourceTypeInfo &> {
  FormatResourceDimension(const dxil::ResourceTypeInfo &RI, bool HasCounter)
      : llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI),
        HasCounter(HasCounter) {}

  bool HasCounter;

  void format(llvm::raw_ostream &OS, StringRef Style) {
    dxil::ResourceKind RK = Item.getResourceKind();
    switch (RK) {
    default: {
      OS << getTextureDimName(RK);
      if (Item.isMultiSample())
        OS << Item.getMultiSampleCount();
      break;
    }
    case dxil::ResourceKind::RawBuffer:
    case dxil::ResourceKind::StructuredBuffer:
      if (!Item.isUAV())
        OS << "r/o";
      else if (HasCounter)
        OS << "r/w+cnt";
      else
        OS << "r/w";
      break;
    case dxil::ResourceKind::TypedBuffer:
      OS << "buf";
      break;
    case dxil::ResourceKind::CBuffer:
      OS << "NA";
      break;
    case dxil::ResourceKind::RTAccelerationStructure:
      // TODO: dxc would print "ras" here. Can/should this happen?
      llvm_unreachable("RTAccelerationStructure printing is not implemented");
    }
  }
};

struct FormatBindingID
    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
  dxil::ResourceClass RC;

  explicit FormatBindingID(const dxil::ResourceInfo &RI,
                           const dxil::ResourceTypeInfo &RTI)
      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),
        RC(RTI.getResourceClass()) {}

  void format(llvm::raw_ostream &OS, StringRef Style) {
    OS << getRCPrefix(RC).upper() << Item.getBinding().BindingID;
  }
};

struct FormatBindingLocation
    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
  dxil::ResourceClass RC;

  explicit FormatBindingLocation(const dxil::ResourceInfo &RI,
                                 const dxil::ResourceTypeInfo &RTI)
      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),
        RC(RTI.getResourceClass()) {}

  void format(llvm::raw_ostream &OS, StringRef Style) {
    const auto &Binding = Item.getBinding();
    OS << getRCPrefix(RC) << Binding.LowerBound;
    if (Binding.Space)
      OS << ",space" << Binding.Space;
  }
};

struct FormatBindingSize
    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
  explicit FormatBindingSize(const dxil::ResourceInfo &RI)
      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}

  void format(llvm::raw_ostream &OS, StringRef Style) {
    uint32_t Size = Item.getBinding().Size;
    if (Size == 0)
      OS << "unbounded";
    else
      OS << Size;
  }
};

} // namespace

static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,
                                 DXILResourceTypeMap &DRTM) {
  // Column widths are arbitrary but match the widths DXC uses.
  OS << ";\n; Resource Bindings:\n;\n";
  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", "Name",
                "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");
  OS << formatv(
      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "", "",
      "", "", "", "", "");

  // TODO: Do we want to sort these by binding or something like that?
  for (const dxil::ResourceInfo &RI : DRM) {
    if (!RI.hasBinding())
      continue;
    const dxil::ResourceTypeInfo &RTI = DRTM[RI.getHandleTy()];

    dxil::ResourceClass RC = RTI.getResourceClass();
    StringRef Name(RI.getName());
    StringRef Type(getRCName(RC));
    StringRef Format(getFormatName(RTI));
    FormatResourceDimension Dim(RTI, RI.hasCounter());
    FormatBindingID ID(RI, RTI);
    FormatBindingLocation Bind(RI, RTI);
    FormatBindingSize Count(RI);
    OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", Name,
                  Type, Format, Dim, ID, Bind, Count);
  }
  OS << ";\n";
}

namespace {
class DXILModuleSlotTracker : public ModuleSlotTracker {
public:
  using ModuleSlotTracker::ModuleSlotTracker;
  using ModuleSlotTracker::renumberMetadataForAssembly;
};

class DXILAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
private:
  ModuleSlotTracker &MST;
  AbstractSlotTrackerStorage &STS;
  const DXILDebugInfoMap &DI;
  DenseSet<const MDNode *> &EmittedMDNodes;

public:
  DXILAssemblyAnnotationWriter(ModuleSlotTracker &MST,
                               AbstractSlotTrackerStorage &STS,
                               const DXILDebugInfoMap &DI,
                               DenseSet<const MDNode *> &EmittedMDNodes)
      : MST(MST), STS(STS), DI(DI), EmittedMDNodes(EmittedMDNodes) {}

  void emitInstructionAnnot(const Instruction *OrigI,
                            formatted_raw_ostream &os) override {
    if (const Instruction *I = &DI.getDXILInstruction(*OrigI); I != OrigI) {
      os << "; DXIL: to be replaced with: ";
      I->print(os, MST);
      os << "\n";
    }
  }

  void emitMDNodeAnnot(const MDNode *N, formatted_raw_ostream &os) override {
    EmittedMDNodes.insert(N);

    if (const Metadata *NewMD = DI.MDReplace.lookup(N)) {
      if (const auto *NewN = dyn_cast<MDNode>(NewMD))
        STS.createMetadataSlot(NewN);

      os << "; DXIL: ";
      N->printAsOperand(os, MST);
      os << ": to be replaced by: ";
      NewMD->printAsOperand(os, MST);
      os << "\n";
      return;
    }

    if (const Metadata *ExtraMD = DI.MDExtra.lookup(N)) {
      if (const auto *ExtraN = dyn_cast<MDNode>(ExtraMD))
        STS.createMetadataSlot(ExtraN);

      os << "; DXIL: ";
      N->printAsOperand(os, MST);
      os << ": additional data: ";
      ExtraMD->printAsOperand(os, MST);
      os << "\n";
      return;
    }
  }
};
} // namespace

static SmallVector<const MDNode *>
collectAdditionalMetadata(Module &M, const DXILDebugInfoMap &DI) {
  // Annotation metadata follows module metadata in the order its keys print.
  // Follow replacement graphs to preserve that order in canonical output.
  M.renumberMetadataForAssembly();

  ModuleSlotTracker MST(&M);
  AbstractSlotTrackerStorage *STS = nullptr;
  MST.setProcessHook(
      [&](AbstractSlotTrackerStorage *STS_, const Module *) { STS = STS_; });
  MDNode::get(M.getContext(), {})->print(llvm::nulls(), MST);
  assert(STS && "Slot tracker storage should have been initialised");

  DenseSet<const Metadata *> ReplacementMetadata;
  for (auto [_, Replacement] : DI.MDReplace)
    ReplacementMetadata.insert(Replacement);

  SmallVector<std::pair<unsigned, const MDNode *>> OriginalNodes;
  DenseSet<const MDNode *> Queued;
  auto AddOriginal = [&](const Metadata *MD) {
    const auto *N = dyn_cast<MDNode>(MD);
    if (!N || ReplacementMetadata.contains(N) || !Queued.insert(N).second)
      return;
    OriginalNodes.emplace_back(STS->getMetadataSlot(N), N);
  };
  for (auto [Original, _] : DI.MDReplace)
    AddOriginal(Original);
  for (auto [Original, _] : DI.MDExtra)
    AddOriginal(Original);
  llvm::sort(OriginalNodes);

  SmallVector<const MDNode *> Worklist;
  for (auto [_, N] : OriginalNodes)
    Worklist.push_back(N);

  SmallVector<const MDNode *> AdditionalMetadata;
  auto AddAdditional = [&](const Metadata *MD) {
    const auto *Root = dyn_cast_or_null<MDNode>(MD);
    if (!Root || Queued.contains(Root))
      return;

    AdditionalMetadata.push_back(Root);
    SmallVector<const MDNode *> Nodes = {Root};
    while (!Nodes.empty()) {
      const MDNode *N = Nodes.pop_back_val();
      if (!Queued.insert(N).second)
        continue;
      Worklist.push_back(N);
      for (const MDOperand &Op : llvm::reverse(N->operands()))
        if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
          Nodes.push_back(OpNode);
    }
  };

  for (size_t I = 0; I != Worklist.size(); ++I) {
    const MDNode *N = Worklist[I];
    if (const Metadata *Replacement = DI.MDReplace.lookup(N)) {
      AddAdditional(Replacement);
      continue;
    }
    AddAdditional(DI.MDExtra.lookup(N));
  }
  return AdditionalMetadata;
}

static void prettyPrint(raw_ostream &OS, Module &M, const DXILResourceMap &DRM,
                        DXILResourceTypeMap &DRTM) {
  formatted_raw_ostream FOS(OS);

  prettyPrintResources(FOS, DRM, DRTM);

  const DXILDebugInfoMap DI = collectDXILDebugInfo(M);
  SmallVector<const MDNode *> AdditionalMetadata =
      collectAdditionalMetadata(M, DI);
  DXILModuleSlotTracker MST(&M);
  MST.renumberMetadataForAssembly(AdditionalMetadata);
  AbstractSlotTrackerStorage *STS = nullptr;
  MST.setProcessHook(
      [&](AbstractSlotTrackerStorage *STS_, const Module *) { STS = STS_; });
  // Force initialisation. ModuleSlotTracker does not have a dedicated function
  // for this so trigger it through a dummy print.
  MDNode::get(M.getContext(), {})->print(llvm::nulls(), MST);
  assert(STS && "Slot tracker storage should have been initialised");

  DenseSet<const MDNode *> EmittedMDNodes;
  DXILAssemblyAnnotationWriter DAAW(MST, *STS, DI, EmittedMDNodes);
  M.print(FOS, &DAAW);

  ModuleSlotTracker::MachineMDNodeListType MDNodes;
  MST.collectMDNodes(MDNodes);
  std::sort(MDNodes.begin(), MDNodes.end(),
            [](const std::pair<unsigned, const MDNode *> &A,
               const std::pair<unsigned, const MDNode *> &B) {
              return A.first < B.first;
            });
  for (auto [_, MDNode] : MDNodes) {
    if (EmittedMDNodes.contains(MDNode))
      continue;
    DAAW.emitMDNodeAnnot(MDNode, FOS);
    MDNode->print(FOS, MST);
    FOS << "\n";
  }
}

PreservedAnalyses DXILPrettyPrinterPass::run(Module &M,
                                             ModuleAnalysisManager &MAM) {
  const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
  DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M);
  prettyPrint(OS, M, DRM, DRTM);
  return PreservedAnalyses::all();
}

namespace {
class DXILPrettyPrinterLegacy : public llvm::ModulePass {
  raw_ostream &OS; // raw_ostream to print to.

public:
  static char ID;

  explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {}

  StringRef getPassName() const override { return "DXIL Pretty Printer"; }

  bool runOnModule(Module &M) override;
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<DXILResourceTypeWrapperPass>();
    AU.addRequired<DXILResourceWrapperPass>();
  }
};
} // namespace

char DXILPrettyPrinterLegacy::ID = 0;
INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
                      "DXIL Pretty Printer", true, false)
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
                    "DXIL Pretty Printer", true, false)

bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {
  const DXILResourceMap &DRM =
      getAnalysis<DXILResourceWrapperPass>().getResourceMap();
  DXILResourceTypeMap &DRTM =
      getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
  prettyPrint(OS, M, DRM, DRTM);
  return false;
}

ModulePass *llvm::createDXILPrettyPrinterLegacyPass(raw_ostream &OS) {
  return new DXILPrettyPrinterLegacy(OS);
}
