//===- 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 "DXILSignatureAnalysis.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(M);
  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(M);
  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(M);
  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
      translateBranchMetadata(M, BB.getTerminator());

      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, 12>;

// The following are compatible with DXIL but not emit with clang, they can
// be added when applicable:
// dx.typeAnnotations, 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",    "dx.viewIdState"};

static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
                                    DXILResourceTypeMap &DRTM,
                                    const ModuleShaderFlags &ShaderFlags,
                                    const ModuleMetadataInfo &MMDI,
                                    const ModuleSignatureInfo &SignatureInfo) {
  LLVMContext &Ctx = M.getContext();
  IRBuilder<> IRB(M);
  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;

  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) +
                         "'"));
    }
    MDTuple *Signatures = nullptr;
    if (const EntrySignature *Sig = SignatureInfo.get(EntryProp.Entry)) {
      Signatures = Sig->getAsMetadata(Ctx, MMDI.ValidatorVersion);
      // This module-level dependency state describes a single shader, not a
      // concatenation of the independent signatures in a library.
      if (MMDI.ShaderProfile != Triple::Library &&
          (MMDI.ValidatorVersion.empty() ||
           MMDI.ValidatorVersion == VersionTuple(0, 0) ||
           MMDI.ValidatorVersion >= VersionTuple(1, 1)) &&
          (Sig->InputVectors || Sig->OutputVectors)) {
        auto State = Sig->getDependencyState();
        auto *StateMD = M.getOrInsertNamedMetadata("dx.viewIdState");
        StateMD->clearOperands();
        StateMD->addOperand(MDNode::get(
            Ctx, ConstantAsMetadata::get(ConstantDataArray::get(Ctx, State))));
      }
    }
    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);

  const auto &SignatureInfo = MAM.getResult<SignatureAnalysis>(M);
  translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI, SignatureInfo);
  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.addRequired<SignatureAnalysisWrapper>();

  AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
  AU.addPreserved<DXILResourceBindingWrapperPass>();
  AU.addPreserved<DXILResourceWrapperPass>();
  AU.addPreserved<RootSignatureAnalysisWrapper>();
  AU.addPreserved<SignatureAnalysisWrapper>();
  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();

  const auto &SignatureInfo =
      getAnalysis<SignatureAnalysisWrapper>().getSignatureInfo();
  translateGlobalMetadata(M, DRM, DRTM, ShaderFlags, MMDI, SignatureInfo);
  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(SignatureAnalysisWrapper)
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata",
                    "DXIL Translate Metadata", false, false)
