//===- DXILTranslateMetadata.cpp - Pass to emit DXIL metadata -------------===//
//
// 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 "DXILTranslateMetadata.h"
#include "DXILRootSignature.h"
#include "DXILShaderFlags.h"
#include "DirectX.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/DXILMetadataAnalysis.h"
#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/TargetParser/Triple.h"
#include <cstdint>

using namespace llvm;
using namespace llvm::dxil;

namespace {

/// A simple wrapper of DiagnosticInfo that generates module-level diagnostic
/// for the DXILValidateMetadata pass
class DiagnosticInfoValidateMD : public DiagnosticInfo {
private:
  const Twine &Msg;
  const Module &Mod;

public:
  /// \p M is the module for which the diagnostic is being emitted. \p Msg is
  /// the message to show. Note that this class does not copy this message, so
  /// this reference must be valid for the whole life time of the diagnostic.
  DiagnosticInfoValidateMD(const Module &M,
                           const Twine &Msg LLVM_LIFETIME_BOUND,
                           DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {}

  void print(DiagnosticPrinter &DP) const override {
    DP << Mod.getName() << ": " << Msg << '\n';
  }
};

static void reportError(Module &M, Twine Message,
                        DiagnosticSeverity Severity = DS_Error) {
  M.getContext().diagnose(DiagnosticInfoValidateMD(M, Message, Severity));
}

static void reportLoopError(Module &M, Twine Message,
                            DiagnosticSeverity Severity = DS_Error) {
  reportError(M, Twine("Invalid \"llvm.loop\" metadata: ") + Message, Severity);
}

enum class EntryPropsTag {
  ShaderFlags = 0,
  GSState,
  DSState,
  HSState,
  NumThreads,
  AutoBindingSpace,
  RayPayloadSize,
  RayAttribSize,
  ShaderKind,
  MSState,
  ASStateTag,
  WaveSize,
  EntryRootSig,
  WaveRange = 23,
};

} // namespace

static NamedMDNode *emitResourceMetadata(Module &M, DXILResourceMap &DRM,
                                         DXILResourceTypeMap &DRTM) {
  LLVMContext &Context = M.getContext();

  for (ResourceInfo &RI : DRM)
    if (RI.hasBinding() && !RI.hasSymbol())
      RI.createSymbol(M,
                      DRTM[RI.getHandleTy()].createElementStruct(RI.getName()));

  SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
  for (const ResourceInfo &RI : DRM.srvs())
    if (RI.hasBinding())
      SRVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
  for (const ResourceInfo &RI : DRM.uavs())
    if (RI.hasBinding())
      UAVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
  for (const ResourceInfo &RI : DRM.cbuffers())
    if (RI.hasBinding())
      CBufs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
  for (const ResourceInfo &RI : DRM.samplers())
    if (RI.hasBinding())
      Smps.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));

  Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs);
  Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs);
  Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs);
  Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps);

  if (DRM.empty())
    return nullptr;

  NamedMDNode *ResourceMD = M.getOrInsertNamedMetadata("dx.resources");
  ResourceMD->addOperand(
      MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD}));

  return ResourceMD;
}

static StringRef getShortShaderStage(Triple::EnvironmentType Env) {
  switch (Env) {
  case Triple::Pixel:
    return "ps";
  case Triple::Vertex:
    return "vs";
  case Triple::Geometry:
    return "gs";
  case Triple::Hull:
    return "hs";
  case Triple::Domain:
    return "ds";
  case Triple::Compute:
    return "cs";
  case Triple::Library:
    return "lib";
  case Triple::Mesh:
    return "ms";
  case Triple::Amplification:
    return "as";
  case Triple::RootSignature:
    return "rootsig";
  default:
    break;
  }
  llvm_unreachable("Unsupported environment for DXIL generation.");
}

static uint32_t getShaderStage(Triple::EnvironmentType Env) {
  return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel;
}

static SmallVector<Metadata *>
getTagValueAsMetadata(EntryPropsTag Tag, uint64_t Value, LLVMContext &Ctx) {
  SmallVector<Metadata *> MDVals;
  MDVals.emplace_back(ConstantAsMetadata::get(
      ConstantInt::get(Type::getInt32Ty(Ctx), static_cast<int>(Tag))));
  switch (Tag) {
  case EntryPropsTag::ShaderFlags:
    MDVals.emplace_back(ConstantAsMetadata::get(
        ConstantInt::get(Type::getInt64Ty(Ctx), Value)));
    break;
  case EntryPropsTag::ShaderKind:
    MDVals.emplace_back(ConstantAsMetadata::get(
        ConstantInt::get(Type::getInt32Ty(Ctx), Value)));
    break;
  case EntryPropsTag::GSState:
  case EntryPropsTag::DSState:
  case EntryPropsTag::HSState:
  case EntryPropsTag::NumThreads:
  case EntryPropsTag::AutoBindingSpace:
  case EntryPropsTag::RayPayloadSize:
  case EntryPropsTag::RayAttribSize:
  case EntryPropsTag::MSState:
  case EntryPropsTag::ASStateTag:
  case EntryPropsTag::WaveSize:
  case EntryPropsTag::EntryRootSig:
  case EntryPropsTag::WaveRange:
    llvm_unreachable("NYI: Unhandled entry property tag");
  }
  return MDVals;
}

static MDTuple *getEntryPropAsMetadata(Module &M, const EntryProperties &EP,
                                       uint64_t EntryShaderFlags,
                                       const ModuleMetadataInfo &MMDI) {
  SmallVector<Metadata *> MDVals;
  LLVMContext &Ctx = EP.Entry->getContext();
  if (EntryShaderFlags != 0)
    MDVals.append(getTagValueAsMetadata(EntryPropsTag::ShaderFlags,
                                        EntryShaderFlags, Ctx));

  if (EP.Entry != nullptr) {
    // FIXME: support more props.
    // See https://github.com/llvm/llvm-project/issues/57948.
    // Add shader kind for lib entries.
    if (MMDI.ShaderProfile == Triple::EnvironmentType::Library &&
        EP.ShaderStage != Triple::EnvironmentType::Library)
      MDVals.append(getTagValueAsMetadata(EntryPropsTag::ShaderKind,
                                          getShaderStage(EP.ShaderStage), Ctx));

    if (EP.ShaderStage == Triple::EnvironmentType::Compute) {
      // Handle mandatory "hlsl.numthreads"
      MDVals.emplace_back(ConstantAsMetadata::get(ConstantInt::get(
          Type::getInt32Ty(Ctx), static_cast<int>(EntryPropsTag::NumThreads))));
      Metadata *NumThreadVals[] = {ConstantAsMetadata::get(ConstantInt::get(
                                       Type::getInt32Ty(Ctx), EP.NumThreadsX)),
                                   ConstantAsMetadata::get(ConstantInt::get(
                                       Type::getInt32Ty(Ctx), EP.NumThreadsY)),
                                   ConstantAsMetadata::get(ConstantInt::get(
                                       Type::getInt32Ty(Ctx), EP.NumThreadsZ))};
      MDVals.emplace_back(MDNode::get(Ctx, NumThreadVals));

      // Handle optional "hlsl.wavesize". The fields are optionally represented
      // if they are non-zero.
      if (EP.WaveSizeMin != 0) {
        bool IsWaveRange = VersionTuple(6, 8) <= MMDI.ShaderModelVersion;
        bool IsWaveSize =
            !IsWaveRange && VersionTuple(6, 6) <= MMDI.ShaderModelVersion;

        if (!IsWaveRange && !IsWaveSize) {
          reportError(M, "Shader model 6.6 or greater is required to specify "
                         "the \"hlsl.wavesize\" function attribute");
          return nullptr;
        }

        // A range is being specified if EP.WaveSizeMax != 0
        if (EP.WaveSizeMax && !IsWaveRange) {
          reportError(
              M, "Shader model 6.8 or greater is required to specify "
                 "wave size range values of the \"hlsl.wavesize\" function "
                 "attribute");
          return nullptr;
        }

        EntryPropsTag Tag =
            IsWaveSize ? EntryPropsTag::WaveSize : EntryPropsTag::WaveRange;
        MDVals.emplace_back(ConstantAsMetadata::get(
            ConstantInt::get(Type::getInt32Ty(Ctx), static_cast<int>(Tag))));

        SmallVector<Metadata *> WaveSizeVals = {ConstantAsMetadata::get(
            ConstantInt::get(Type::getInt32Ty(Ctx), EP.WaveSizeMin))};
        if (IsWaveRange) {
          WaveSizeVals.push_back(ConstantAsMetadata::get(
              ConstantInt::get(Type::getInt32Ty(Ctx), EP.WaveSizeMax)));
          WaveSizeVals.push_back(ConstantAsMetadata::get(
              ConstantInt::get(Type::getInt32Ty(Ctx), EP.WaveSizePref)));
        }

        MDVals.emplace_back(MDNode::get(Ctx, WaveSizeVals));
      }
    }
  }

  if (MDVals.empty())
    return nullptr;
  return MDNode::get(Ctx, MDVals);
}

static MDTuple *constructEntryMetadata(const Function *EntryFn,
                                       MDTuple *Signatures, MDNode *Resources,
                                       MDTuple *Properties, LLVMContext &Ctx) {
  // Each entry point metadata record specifies:
  //  * reference to the entry point function global symbol
  //  * unmangled name
  //  * list of signatures
  //  * list of resources
  //  * list of tag-value pairs of shader capabilities and other properties
  Metadata *MDVals[5];
  MDVals[0] =
      EntryFn ? ValueAsMetadata::get(const_cast<Function *>(EntryFn)) : nullptr;
  MDVals[1] = MDString::get(Ctx, EntryFn ? EntryFn->getName() : "");
  MDVals[2] = Signatures;
  MDVals[3] = Resources;
  MDVals[4] = Properties;
  return MDNode::get(Ctx, MDVals);
}

static MDTuple *emitEntryMD(Module &M, const EntryProperties &EP,
                            MDTuple *Signatures, MDNode *MDResources,
                            const uint64_t EntryShaderFlags,
                            const ModuleMetadataInfo &MMDI) {
  MDTuple *Properties = getEntryPropAsMetadata(M, EP, EntryShaderFlags, MMDI);
  return constructEntryMetadata(EP.Entry, Signatures, MDResources, Properties,
                                EP.Entry->getContext());
}

static void emitValidatorVersionMD(Module &M, const ModuleMetadataInfo &MMDI) {
  if (MMDI.ValidatorVersion.empty())
    return;

  LLVMContext &Ctx = M.getContext();
  IRBuilder<> IRB(Ctx);
  Metadata *MDVals[2];
  MDVals[0] =
      ConstantAsMetadata::get(IRB.getInt32(MMDI.ValidatorVersion.getMajor()));
  MDVals[1] = ConstantAsMetadata::get(
      IRB.getInt32(MMDI.ValidatorVersion.getMinor().value_or(0)));
  NamedMDNode *ValVerNode = M.getOrInsertNamedMetadata("dx.valver");
  // Set validator version obtained from DXIL Metadata Analysis pass
  ValVerNode->clearOperands();
  ValVerNode->addOperand(MDNode::get(Ctx, MDVals));
}

static void emitShaderModelVersionMD(Module &M,
                                     const ModuleMetadataInfo &MMDI) {
  LLVMContext &Ctx = M.getContext();
  IRBuilder<> IRB(Ctx);
  Metadata *SMVals[3];
  VersionTuple SM = MMDI.ShaderModelVersion;
  SMVals[0] = MDString::get(Ctx, getShortShaderStage(MMDI.ShaderProfile));
  SMVals[1] = ConstantAsMetadata::get(IRB.getInt32(SM.getMajor()));
  SMVals[2] = ConstantAsMetadata::get(IRB.getInt32(SM.getMinor().value_or(0)));
  NamedMDNode *SMMDNode = M.getOrInsertNamedMetadata("dx.shaderModel");
  SMMDNode->addOperand(MDNode::get(Ctx, SMVals));
}

static void emitDXILVersionTupleMD(Module &M, const ModuleMetadataInfo &MMDI) {
  LLVMContext &Ctx = M.getContext();
  IRBuilder<> IRB(Ctx);
  VersionTuple DXILVer = MMDI.DXILVersion;
  Metadata *DXILVals[2];
  DXILVals[0] = ConstantAsMetadata::get(IRB.getInt32(DXILVer.getMajor()));
  DXILVals[1] =
      ConstantAsMetadata::get(IRB.getInt32(DXILVer.getMinor().value_or(0)));
  NamedMDNode *DXILVerMDNode = M.getOrInsertNamedMetadata("dx.version");
  DXILVerMDNode->addOperand(MDNode::get(Ctx, DXILVals));
}

static MDTuple *emitTopLevelLibraryNode(Module &M, MDNode *RMD,
                                        uint64_t ShaderFlags) {
  LLVMContext &Ctx = M.getContext();
  MDTuple *Properties = nullptr;
  if (ShaderFlags != 0) {
    SmallVector<Metadata *> MDVals;
    MDVals.append(
        getTagValueAsMetadata(EntryPropsTag::ShaderFlags, ShaderFlags, Ctx));
    Properties = MDNode::get(Ctx, MDVals);
  }
  // Library has an entry metadata with resource table metadata and all other
  // MDNodes as null.
  return constructEntryMetadata(nullptr, nullptr, RMD, Properties, Ctx);
}

static void translateBranchMetadata(Module &M, Instruction *BBTerminatorInst) {
  MDNode *HlslControlFlowMD =
      BBTerminatorInst->getMetadata("hlsl.controlflow.hint");

  if (!HlslControlFlowMD)
    return;

  assert(HlslControlFlowMD->getNumOperands() == 2 &&
         "invalid operands for hlsl.controlflow.hint");

  MDBuilder MDHelper(M.getContext());

  llvm::Metadata *HintsStr = MDHelper.createString("dx.controlflow.hints");
  llvm::Metadata *HintsValue = MDHelper.createConstant(
      mdconst::extract<ConstantInt>(HlslControlFlowMD->getOperand(1)));

  MDNode *MDNode = llvm::MDNode::get(M.getContext(), {HintsStr, HintsValue});

  BBTerminatorInst->setMetadata("dx.controlflow.hints", MDNode);
  BBTerminatorInst->setMetadata("hlsl.controlflow.hint", nullptr);
}

// Determines if the metadata node will be compatible with DXIL's loop metadata
// representation.
//
// Reports an error for compatible metadata that is ill-formed.
static bool isLoopMDCompatible(Module &M, Metadata *MD) {
  // DXIL only accepts the following loop hints:
  std::array<StringLiteral, 3> ValidHintNames = {"llvm.loop.unroll.count",
                                                 "llvm.loop.unroll.disable",
                                                 "llvm.loop.unroll.full"};

  MDNode *HintMD = dyn_cast<MDNode>(MD);
  if (!HintMD || HintMD->getNumOperands() == 0)
    return false;

  auto *HintStr = dyn_cast<MDString>(HintMD->getOperand(0));
  if (!HintStr)
    return false;

  if (!llvm::is_contained(ValidHintNames, HintStr->getString()))
    return false;

  auto ValidCountNode = [](MDNode *CountMD) -> bool {
    if (CountMD->getNumOperands() == 2)
      if (auto *Count = dyn_cast<ConstantAsMetadata>(CountMD->getOperand(1)))
        if (isa<ConstantInt>(Count->getValue()))
          return true;
    return false;
  };

  if (HintStr->getString() == "llvm.loop.unroll.count") {
    if (!ValidCountNode(HintMD)) {
      reportLoopError(M, "\"llvm.loop.unroll.count\" must have 2 operands and "
                         "the second must be a constant integer");
      return false;
    }
  } else if (HintMD->getNumOperands() != 1) {
    reportLoopError(
        M, "\"llvm.loop.unroll.disable\" and \"llvm.loop.unroll.full\" "
           "must be provided as a single operand");
    return false;
  }

  return true;
}

static void translateLoopMetadata(Module &M, Instruction *I, MDNode *BaseMD) {
  // A distinct node has the self-referential form: !0 = !{ !0, ... }
  auto IsDistinctNode = [](MDNode *Node) -> bool {
    return Node && Node->getNumOperands() != 0 && Node == Node->getOperand(0);
  };

  // Set metadata to null to remove empty/ill-formed metadata from instruction
  if (BaseMD->getNumOperands() == 0 || !IsDistinctNode(BaseMD))
    return I->setMetadata("llvm.loop", nullptr);

  // It is valid to have a chain of self-refential loop metadata nodes, as
  // below. We will collapse these into just one when we reconstruct the
  // metadata.
  //
  // Eg:
  // !0 = !{!0, !1}
  // !1 = !{!1, !2}
  // !2 = !{!"llvm.loop.unroll.disable"}
  //
  // So, traverse down a potential self-referential chain
  while (1 < BaseMD->getNumOperands() &&
         IsDistinctNode(dyn_cast<MDNode>(BaseMD->getOperand(1))))
    BaseMD = dyn_cast<MDNode>(BaseMD->getOperand(1));

  // To reconstruct a distinct node we create a temporary node that we will
  // then update to create a self-reference.
  llvm::TempMDTuple TempNode = llvm::MDNode::getTemporary(M.getContext(), {});
  SmallVector<Metadata *> CompatibleOperands = {TempNode.get()};

  // Iterate and reconstruct the metadata nodes that contains any hints,
  // stripping any unrecognized metadata.
  ArrayRef<MDOperand> Operands = BaseMD->operands();
  for (auto &Op : Operands.drop_front())
    if (isLoopMDCompatible(M, Op.get()))
      CompatibleOperands.push_back(Op.get());

  if (2 < CompatibleOperands.size())
    reportLoopError(M, "Provided conflicting hints");

  MDNode *CompatibleLoopMD = MDNode::get(M.getContext(), CompatibleOperands);
  TempNode->replaceAllUsesWith(CompatibleLoopMD);

  I->setMetadata("llvm.loop", CompatibleLoopMD);
}

using InstructionMDList = std::array<unsigned, 7>;

static InstructionMDList getCompatibleInstructionMDs(llvm::Module &M) {
  return {
      M.getMDKindID("dx.nonuniform"),    M.getMDKindID("dx.controlflow.hints"),
      M.getMDKindID("dx.precise"),       llvm::LLVMContext::MD_range,
      llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_noalias,
      M.getMDKindID("llvm.loop")};
}

static void translateInstructionMetadata(Module &M) {
  // construct allowlist of valid metadata node kinds
  InstructionMDList DXILCompatibleMDs = getCompatibleInstructionMDs(M);
  unsigned char MDLoopKind = M.getContext().getMDKindID("llvm.loop");

  for (Function &F : M) {
    for (BasicBlock &BB : F) {
      // This needs to be done first so that "hlsl.controlflow.hints" isn't
      // removed in the allow-list below
      if (auto *I = BB.getTerminator())
        translateBranchMetadata(M, I);

      for (auto &I : make_early_inc_range(BB)) {
        if (isa<UncondBrInst, CondBrInst>(I))
          if (MDNode *LoopMD = I.getMetadata(MDLoopKind))
            translateLoopMetadata(M, &I, LoopMD);
        I.dropUnknownNonDebugMetadata(DXILCompatibleMDs);
      }
    }
  }
}

static void cleanModuleFlags(Module &M) {
  NamedMDNode *MDFlags = M.getModuleFlagsMetadata();
  if (!MDFlags)
    return;

  SmallVector<llvm::Module::ModuleFlagEntry> FlagEntries;
  M.getModuleFlagsMetadata(FlagEntries);
  bool Updated = false;
  for (auto &Flag : FlagEntries) {
    // llvm 3.7 only supports behavior up to AppendUnique.
    if (Flag.Behavior <= Module::ModFlagBehavior::AppendUnique)
      continue;
    Flag.Behavior = Module::ModFlagBehavior::Warning;
    Updated = true;
  }

  if (!Updated)
    return;

  MDFlags->eraseFromParent();

  for (auto &Flag : FlagEntries)
    M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
}

using GlobalMDList = std::array<StringLiteral, 11>;

// The following are compatible with DXIL but not emit with clang, they can
// be added when applicable:
// dx.typeAnnotations, dx.viewIDState, dx.dxrPayloadAnnotations
static GlobalMDList CompatibleNamedModuleMDs = {
    "llvm.ident",        "llvm.module.flags",
    "dx.resources",      "dx.valver",
    "dx.shaderModel",    "dx.version",
    "dx.entryPoints",    "dx.source.contents",
    "dx.source.defines", "dx.source.mainFileName",
    "dx.source.args"};

static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
                                    DXILResourceTypeMap &DRTM,
                                    const ModuleShaderFlags &ShaderFlags,
                                    const ModuleMetadataInfo &MMDI) {
  LLVMContext &Ctx = M.getContext();
  IRBuilder<> IRB(Ctx);
  SmallVector<MDNode *> EntryFnMDNodes;

  emitValidatorVersionMD(M, MMDI);
  emitShaderModelVersionMD(M, MMDI);
  emitDXILVersionTupleMD(M, MMDI);
  NamedMDNode *NamedResourceMD = emitResourceMetadata(M, DRM, DRTM);
  auto *ResourceMD =
      (NamedResourceMD != nullptr) ? NamedResourceMD->getOperand(0) : nullptr;
  // FIXME: Add support to construct Signatures
  // See https://github.com/llvm/llvm-project/issues/57928
  MDTuple *Signatures = nullptr;

  if (MMDI.ShaderProfile == Triple::EnvironmentType::Library) {
    // Get the combined shader flag mask of all functions in the library to be
    // used as shader flags mask value associated with top-level library entry
    // metadata.
    uint64_t CombinedMask = ShaderFlags.getCombinedFlags();
    EntryFnMDNodes.emplace_back(
        emitTopLevelLibraryNode(M, ResourceMD, CombinedMask));
  } else if (1 < MMDI.EntryPropertyVec.size())
    reportError(M, "Non-library shader: One and only one entry expected");

  for (const EntryProperties &EntryProp : MMDI.EntryPropertyVec) {
    uint64_t EntryShaderFlags = 0;
    if (MMDI.ShaderProfile != Triple::EnvironmentType::Library) {
      EntryShaderFlags = ShaderFlags.getFunctionFlags(EntryProp.Entry);
      if (EntryProp.ShaderStage != MMDI.ShaderProfile)
        reportError(
            M, "Shader stage '" +
                   Twine(getShortShaderStage(EntryProp.ShaderStage)) +
                   "' for entry '" + Twine(EntryProp.Entry->getName()) +
                   "' different from specified target profile '" +
                   Twine(Triple::getEnvironmentTypeName(MMDI.ShaderProfile) +
                         "'"));
    }
    EntryFnMDNodes.emplace_back(emitEntryMD(
        M, EntryProp, Signatures, ResourceMD, EntryShaderFlags, MMDI));
  }

  NamedMDNode *EntryPointsNamedMD =
      M.getOrInsertNamedMetadata("dx.entryPoints");
  for (auto *Entry : EntryFnMDNodes)
    EntryPointsNamedMD->addOperand(Entry);

  cleanModuleFlags(M);

  // Finally, strip all module metadata that is not explicitly specified in the
  // allow-list
  SmallVector<NamedMDNode *> ToStrip;

  for (NamedMDNode &NamedMD : M.named_metadata())
    if (!NamedMD.getName().starts_with("llvm.dbg.") &&
        !llvm::is_contained(CompatibleNamedModuleMDs, NamedMD.getName()))
      ToStrip.push_back(&NamedMD);

  for (NamedMDNode *NamedMD : ToStrip)
    NamedMD->eraseFromParent();
}

PreservedAnalyses DXILTranslateMetadata::run(Module &M,
                                             ModuleAnalysisManager &MAM) {
  DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
  DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M);
  const ModuleShaderFlags &ShaderFlags = MAM.getResult<ShaderFlagsAnalysis>(M);
  const dxil::ModuleMetadataInfo MMDI = MAM.getResult<DXILMetadataAnalysis>(M);

  translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI);
  translateInstructionMetadata(M);

  return PreservedAnalyses::all();
}

void DXILTranslateMetadataLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<DXILResourceTypeWrapperPass>();
  AU.addRequired<DXILResourceWrapperPass>();
  AU.addRequired<ShaderFlagsAnalysisWrapper>();
  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
  AU.addRequired<RootSignatureAnalysisWrapper>();

  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
  AU.addPreserved<DXILResourceBindingWrapperPass>();
  AU.addPreserved<DXILResourceWrapperPass>();
  AU.addPreserved<RootSignatureAnalysisWrapper>();
  AU.addPreserved<ShaderFlagsAnalysisWrapper>();
}

bool DXILTranslateMetadataLegacy::runOnModule(Module &M) {
  DXILResourceMap &DRM =
      getAnalysis<DXILResourceWrapperPass>().getResourceMap();
  DXILResourceTypeMap &DRTM =
      getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
  const ModuleShaderFlags &ShaderFlags =
      getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags();
  dxil::ModuleMetadataInfo MMDI =
      getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();

  translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI);
  translateInstructionMetadata(M);
  return true;
}

char DXILTranslateMetadataLegacy::ID = 0;

ModulePass *llvm::createDXILTranslateMetadataLegacyPass() {
  return new DXILTranslateMetadataLegacy();
}

INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
                      "DXIL Translate Metadata", false, false)
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper)
INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
                    "DXIL Translate Metadata", false, false)
