//===- DXILSignatureAnalysis.cpp - Semantic signatures --------------------===//
//
// 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 "DXILSignatureAnalysis.h"
#include "DirectX.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/DXILMetadataAnalysis.h"
#include "llvm/Frontend/HLSL/SemanticSignaturePacking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsDirectX.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/DXContainerPSVInfo.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include <array>
#include <set>

using namespace llvm;
using namespace llvm::dxil;
using namespace llvm::hlsl;

static Error signatureError(const Twine &Message) {
  return createStringError(inconvertibleErrorCode(), Message);
}

static bool isSignatureAccess(const IntrinsicInst &I) {
  return I.getIntrinsicID() == Intrinsic::dx_load_input ||
         I.getIntrinsicID() == Intrinsic::dx_store_output;
}

// Validate widths before fromMetadata extracts integer values or narrows them.
static Error checkElementNode(const MDNode *Node) {
  if (!Node || Node->getNumOperands() != 13)
    return signatureError("expected a 13-operand signature element");
  for (unsigned I = 0; I != 13; ++I) {
    if (I == 1 || I == 4)
      continue;
    auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(Node->getOperand(I));
    unsigned Width = (I == 7 || (I >= 9 && I <= 11)) ? 8 : 32;
    if (!CI || CI->getBitWidth() != Width)
      return signatureError("expected i" + Twine(Width) + " at operand " +
                            Twine(I));
  }
  if (!isa_and_nonnull<MDString>(Node->getOperand(1)))
    return signatureError("expected semantic name string");
  auto *Indices = dyn_cast_or_null<MDNode>(Node->getOperand(4));
  if (!Indices)
    return signatureError("expected semantic indices node");
  for (const MDOperand &Index : Indices->operands()) {
    auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(Index);
    if (!CI || CI->getBitWidth() != 32)
      return signatureError("expected i32 semantic index");
  }
  return Error::success();
}

static bool isIntegerComponent(ElementType Type) {
  return Type == ElementType::I1 || Type == ElementType::I16 ||
         Type == ElementType::U16 || Type == ElementType::I32 ||
         Type == ElementType::U32;
}

static Error diagnoseSemanticType(const SemanticSignatureElement &E) {
  switch (E.SemanticKind) {
  case dxbc::PSV::SemanticKind::Position:
    if (E.Rows != 1 || E.Cols != 4 ||
        (E.CompType != ElementType::F16 && E.CompType != ElementType::F32))
      return signatureError(
          "SV_Position requires one row of four floating-point components");
    break;
  case dxbc::PSV::SemanticKind::VertexID:
    if (E.Rows != 1 || E.Cols != 1 ||
        (E.CompType != ElementType::I16 && E.CompType != ElementType::U16 &&
         E.CompType != ElementType::I32 && E.CompType != ElementType::U32))
      return signatureError(
          "SV_VertexID requires a scalar 16- or 32-bit integer");
    break;
  case dxbc::PSV::SemanticKind::InstanceID:
    if (E.Rows != 1 || E.Cols != 1 ||
        (E.CompType != ElementType::U16 && E.CompType != ElementType::U32))
      return signatureError(
          "SV_InstanceID requires a scalar 16- or 32-bit unsigned integer");
    break;
  case dxbc::PSV::SemanticKind::ShadingRate:
    if (E.Rows != 1 || E.Cols != 1 ||
        (E.CompType != ElementType::U16 && E.CompType != ElementType::U32))
      return signatureError(
          "SV_ShadingRate requires a scalar 16- or 32-bit unsigned integer");
    break;
  case dxbc::PSV::SemanticKind::Barycentrics:
    if (E.Rows != 1 || E.Cols != 3 ||
        (E.CompType != ElementType::F16 && E.CompType != ElementType::F32))
      return signatureError("SV_Barycentrics requires one row of three 16- or "
                            "32-bit floating-point components");
    break;
  default:
    break;
  }
  return Error::success();
}

static Error diagnoseSemanticIndex(const SemanticSignatureElement &E) {
  switch (E.SemanticKind) {
  case dxbc::PSV::SemanticKind::Target:
    if (E.Rows != 1 || E.SemanticIndices.front() >= 8)
      return signatureError(
          "pixel targets require one row and an index within 0-7");
    break;
  case dxbc::PSV::SemanticKind::VertexID:
    if (E.SemanticIndices.front() != 0)
      return signatureError("SV_VertexID requires semantic index 0");
    break;
  case dxbc::PSV::SemanticKind::Barycentrics:
    if (E.SemanticIndices.front() != 0)
      return signatureError("SV_Barycentrics requires semantic index 0");
    break;
  default:
    break;
  }
  return Error::success();
}

static Error
diagnoseSemanticShaderModel(const SemanticSignatureElement &E,
                            const VersionTuple &ShaderModelVersion) {
  switch (E.SemanticKind) {
  case dxbc::PSV::SemanticKind::Barycentrics:
    if (ShaderModelVersion < VersionTuple(6, 1))
      return signatureError("SV_Barycentrics requires shader model 6.1");
    break;
  default:
    break;
  }
  return Error::success();
}

static Error parseSignature(Metadata *MD,
                            SmallVectorImpl<SemanticSignatureElement> &Out,
                            ModuleSignatureInfo &Info,
                            Triple::EnvironmentType Stage, IOType IO,
                            const VersionTuple &ShaderModelVersion,
                            bool Native16, unsigned &Extent) {
  if (!MD)
    return Error::success();
  auto *List = dyn_cast<MDNode>(MD);
  if (!List)
    return signatureError("expected a signature element list or null");

  std::set<std::pair<std::string, uint32_t>> Semantics;
  constexpr unsigned MaxAllocatedElements = MaxSignatureRows * 4;
  unsigned NumAllocated = 0;
  std::array<uint8_t, MaxSignatureRows> AllocatedColumns = {};
  std::array<dxbc::PSV::InterpolationMode, MaxSignatureRows> RowModes = {};
  std::array<bool, MaxSignatureRows> RowNative16 = {};
  for (const MDOperand &Op : List->operands()) {
    auto *Node = dyn_cast_or_null<MDNode>(Op);
    if (Error Err = checkElementNode(Node))
      return Err;
    auto Parsed = SemanticSignatureElement::fromMetadata(Node);
    if (!Parsed)
      return Parsed.takeError();
    SemanticSignatureElement E = std::move(*Parsed);
    if (E.SigId != Out.size())
      return signatureError("signature IDs must be dense and in list order");
    if (Stage != Triple::Vertex && Stage != Triple::Pixel)
      return signatureError("nonempty signatures are currently supported only "
                            "for vertex and pixel entries");
    if (!E.Rows || E.Rows > MaxSignatureRows)
      return signatureError("signature row count must be within 1-32");
    if (E.SemanticName.empty() || E.SemanticName.contains('\0'))
      return signatureError("invalid semantic name");
    if (E.CompType != ElementType::F16 && E.CompType != ElementType::F32 &&
        !isIntegerComponent(E.CompType))
      return signatureError("unsupported signature component type");
    if (E.GSStream != 0)
      return signatureError("nonzero stream requires a geometry output");
    auto NamedKind = getSemanticKind(E.SemanticName);
    auto Interpretation = getInterpretationKind(NamedKind, Stage, IO);
    if (Interpretation == SemanticInterpretation::Invalid)
      return signatureError("invalid or unsupported semantic for this stage "
                            "and signature category");
    if (Interpretation == SemanticInterpretation::NotAllocated)
      return signatureError("semantic accessed by a dedicated intrinsic must "
                            "not appear in an input/output signature");
    auto ExpectedKind = Interpretation == SemanticInterpretation::Arbitrary
                            ? dxbc::PSV::SemanticKind::Arbitrary
                            : NamedKind;
    if (E.SemanticKind != ExpectedKind)
      return signatureError("semantic name and kind disagree at this signature "
                            "point");
    if (Interpretation == SemanticInterpretation::NotPacked) {
      if (E.isAllocated())
        return signatureError(
            "SV_Barycentrics must not have an allocated location");
    } else {
      if (!E.isAllocated())
        return signatureError("signature element " + Twine(E.SigId) + " ('" +
                              E.SemanticName + "') has no allocated location");
      if (E.StartRow >= MaxSignatureRows ||
          E.Rows > MaxSignatureRows - E.StartRow || E.StartCol + E.Cols > 4)
        return signatureError(
            "allocated signature element exceeds register bounds");
    }
    if (E.InterpMode == dxbc::PSV::InterpolationMode::Invalid)
      return signatureError("invalid interpolation mode");

    for (uint32_t Index : E.SemanticIndices)
      if (!Semantics.emplace(E.SemanticName.upper(), Index).second)
        return signatureError("duplicate semantic name and index");
    if (Error Err = diagnoseSemanticType(E))
      return Err;
    if (Error Err = diagnoseSemanticIndex(E))
      return Err;
    if (Error Err = diagnoseSemanticShaderModel(E, ShaderModelVersion))
      return Err;
    if (E.SemanticKind == dxbc::PSV::SemanticKind::Barycentrics) {
      using Mode = dxbc::PSV::InterpolationMode;
      if (E.InterpMode == Mode::Undefined || E.InterpMode == Mode::Constant)
        return signatureError("SV_Barycentrics requires perspective or "
                              "noperspective interpolation");
    }

    if (Stage == Triple::Vertex && IO == IOType::In &&
        (E.StartRow != Extent || E.StartCol != 0))
      return signatureError("vertex inputs require stacked locations in "
                            "signature order (element " +
                            Twine(E.SigId) + ")");
    if (Interpretation == SemanticInterpretation::Target &&
        (E.StartRow != E.SemanticIndices.front() || E.StartCol != 0))
      return signatureError("pixel target location must match its semantic "
                            "index at column 0");
    if (Stage == Triple::Pixel && IO == IOType::In &&
        isIntegerComponent(E.CompType) &&
        E.InterpMode != dxbc::PSV::InterpolationMode::Constant)
      return signatureError(
          "integer pixel inputs require constant interpolation");

    if (E.isAllocated()) {
      if (++NumAllocated > MaxAllocatedElements)
        return signatureError("too many signature elements");
      // Co-packed elements must obey row constraints, even when their component
      // masks do not overlap. Min-precision types occupy 32-bit components.
      bool IsNative16 = Native16 && (E.CompType == ElementType::F16 ||
                                     E.CompType == ElementType::I16 ||
                                     E.CompType == ElementType::U16);
      uint8_t Mask = E.getDeclaredMask();
      for (unsigned Row = E.StartRow; Row != E.StartRow + E.Rows; ++Row) {
        if (AllocatedColumns[Row] & Mask)
          return signatureError("signature elements overlap at row " +
                                Twine(Row) + " (element " + Twine(E.SigId) +
                                ")");
        if (AllocatedColumns[Row] && RowModes[Row] != E.InterpMode)
          return signatureError(
              "signature elements have different interpolation "
              "modes at row " +
              Twine(Row) + " (element " + Twine(E.SigId) + ")");
        if (AllocatedColumns[Row] && RowNative16[Row] != IsNative16)
          return signatureError("signature elements have different component "
                                "widths at row " +
                                Twine(Row) + " (element " + Twine(E.SigId) +
                                ")");
        AllocatedColumns[Row] |= Mask;
        RowModes[Row] = E.InterpMode;
        RowNative16[Row] = IsNative16;
      }
      Extent = std::max(Extent, E.StartRow + E.Rows);
    }
    E.SemanticName = Info.Names.insert(E.SemanticName).first->getKey();

    // Access masks will be recomputed so reset to 0 here.
    E.UsageMask = 0;
    E.DynIndexMask = 0;
    Out.push_back(std::move(E));
  }
  return Error::success();
}

static Error analyzeAccess(const IntrinsicInst &I, EntrySignature &Sig) {
  bool Input = I.getIntrinsicID() == Intrinsic::dx_load_input;
  auto &Elements = Input ? Sig.Inputs : Sig.Outputs;
  auto *ID = dyn_cast<ConstantInt>(I.getArgOperand(0));
  auto *Col = dyn_cast<ConstantInt>(I.getArgOperand(2));
  StringRef Category = Input ? "input" : "output";
  assert(ID && "signature ID is marked as ImmArg and must be constant");
  if (ID->getZExtValue() >= Elements.size())
    return signatureError(Category +
                          " signature: signature access has an invalid element "
                          "ID " +
                          Twine(ID->getZExtValue()));
  auto &E = Elements[ID->getZExtValue()];
  auto AccessError = [&](const Twine &Message) {
    return signatureError(Category + " signature element " + Twine(E.SigId) +
                          " ('" + E.SemanticName + "'): " + Message);
  };
  Type *Ty = Input ? I.getType() : I.getArgOperand(3)->getType();
  unsigned Width = 1;
  if (auto *VT = dyn_cast<FixedVectorType>(Ty)) {
    Width = VT->getNumElements();
    Ty = VT->getElementType();
  }
  if (!Col || Col->getZExtValue() >= E.Cols ||
      Width > E.Cols - Col->getZExtValue())
    return AccessError("signature access has an invalid component index");
  auto *Row = dyn_cast<ConstantInt>(I.getArgOperand(1));
  if (Row && Row->getZExtValue() >= E.Rows)
    return AccessError("signature access has an invalid row index");
  if (!Row && E.Rows == 1)
    return AccessError(
        "dynamic indexing requires a multi-row signature element");
  bool CorrectType = false;
  switch (E.CompType) {
  case ElementType::F16:
    CorrectType = Ty->isHalfTy();
    break;
  case ElementType::F32:
    CorrectType = Ty->isFloatTy();
    break;
  case ElementType::I16:
  case ElementType::U16:
    CorrectType = Ty->isIntegerTy(16);
    break;
  case ElementType::I1:
    // Boolean signature elements use the i32 load/store overload.
    CorrectType = Ty->isIntegerTy(32);
    break;
  case ElementType::I32:
  case ElementType::U32:
    CorrectType = Ty->isIntegerTy(32);
    break;
  default:
    llvm_unreachable("invalid signature component type");
  }
  if (!CorrectType)
    return AccessError("signature access type disagrees with its element");
  uint8_t Mask = ((1U << Width) - 1) << Col->getZExtValue();
  E.UsageMask |= Mask << E.getStartColOrZero();
  if (!Row)
    E.DynIndexMask |= Mask;
  return Error::success();
}

static void buildDependencyMap(EntrySignature &Sig) {
  // Each output vector needs four component bits, so one 32-bit word holds
  // eight vectors. Adding seven rounds up to include a partially filled word.
  unsigned Words = (Sig.OutputVectors + 7) / 8;
  Sig.InputOutputMap.assign(Sig.InputVectors * 4 * Words, 0);
  // Conservatively connect every accessed input component to every written
  // output component. This includes control, memory, call, and dynamic-index
  // dependencies without incorrectly claiming that unknown dependencies are
  // absent. Unused components and padding remain zero. Both DXIL and PSV use
  // this same map; a more precise dependency analysis can refine it later.
  for (const auto &Input : Sig.Inputs) {
    if (!Input.isAllocated())
      continue;
    for (unsigned IR = 0; IR != Input.Rows; ++IR)
      for (unsigned IC = 0; IC != 4; ++IC) {
        if (!(Input.UsageMask & (1U << IC)))
          continue;
        unsigned Base = ((Input.StartRow + IR) * 4 + IC) * Words;
        for (const auto &Output : Sig.Outputs)
          for (unsigned OR = 0; OR != Output.Rows; ++OR)
            for (unsigned OC = 0; OC != 4; ++OC) {
              if (!(Output.UsageMask & (1U << OC)))
                continue;
              unsigned Bit = (Output.StartRow + OR) * 4 + OC;
              Sig.InputOutputMap[Base + Bit / 32] |= 1U << (Bit % 32);
            }
      }
  }
}

static Expected<ModuleSignatureInfo>
analyzeModule(Module &M, const ModuleMetadataInfo &MMI) {
  ModuleSignatureInfo Info;
  if (NamedMDNode *Table = M.getNamedMetadata("dx.semantic.signatures")) {
    for (const MDNode *Record : Table->operands()) {
      if (Record->getNumOperands() != 3)
        return signatureError(
            "expected an entry/input/output signature triple");
      auto *VAM = dyn_cast_or_null<ValueAsMetadata>(Record->getOperand(0));
      auto *F = VAM ? dyn_cast<Function>(VAM->getValue()) : nullptr;
      if (!F || F->getParent() != &M || F->isDeclaration())
        return signatureError(
            "signature entry must be a defined function in the module");
      auto EP =
          llvm::find_if(MMI.EntryPropertyVec,
                        [F](const EntryProperties &E) { return E.Entry == F; });
      if (EP == MMI.EntryPropertyVec.end())
        return signatureError("signature function is not a shader entry");
      if (Info.Entries.contains(F))
        return signatureError("duplicate signature record for entry '" +
                              F->getName() + "'");
      EntrySignature Sig;
      Sig.Stage = EP->ShaderStage;
      if (auto *Native = mdconst::dyn_extract_or_null<ConstantInt>(
              M.getModuleFlag("dx.nativelowprec")))
        Sig.UseNative16Bit = !Native->isZero();
      if (Sig.UseNative16Bit && MMI.ShaderModelVersion < VersionTuple(6, 2))
        return signatureError(
            "native 16-bit signatures require shader model 6.2");
      auto AddContext = [&](Error Err, StringRef Category) -> Error {
        return signatureError("entry '" + F->getName() + "' " + Category +
                              " signature: " + toString(std::move(Err)));
      };
      if (Error Err = parseSignature(
              Record->getOperand(1), Sig.Inputs, Info, Sig.Stage, IOType::In,
              MMI.ShaderModelVersion, Sig.UseNative16Bit, Sig.InputVectors))
        return AddContext(std::move(Err), "input");
      if (Error Err = parseSignature(
              Record->getOperand(2), Sig.Outputs, Info, Sig.Stage, IOType::Out,
              MMI.ShaderModelVersion, Sig.UseNative16Bit, Sig.OutputVectors))
        return AddContext(std::move(Err), "output");
      for (const Instruction &I : instructions(F))
        if (auto *II = dyn_cast<IntrinsicInst>(&I);
            II && isSignatureAccess(*II))
          if (Error Err = analyzeAccess(*II, Sig))
            return signatureError("entry '" + F->getName() +
                                  "': " + toString(std::move(Err)));
      buildDependencyMap(Sig);
      Info.Entries.try_emplace(F, std::move(Sig));
    }
  }
  // Signature IDs are local to an entry. Do not guess which entry a helper's
  // accesses belong to, even if that helper happens to have a single caller.
  for (const Function &F : M)
    if (!Info.Entries.contains(&F))
      for (const Instruction &I : instructions(F))
        if (auto *II = dyn_cast<IntrinsicInst>(&I);
            II && isSignatureAccess(*II))
          return signatureError("signature access in function '" + F.getName() +
                                "' has no entry signature metadata");
  return std::move(Info);
}

static ModuleSignatureInfo collectSignatures(Module &M,
                                             const ModuleMetadataInfo &MMI) {
  auto Result = analyzeModule(M, MMI);
  if (!Result) {
    M.getContext().emitError("Invalid semantic signature: " +
                             toString(Result.takeError()));
    return ModuleSignatureInfo();
  }
  return std::move(*Result);
}

static MDNode *emitSignature(LLVMContext &Ctx,
                             ArrayRef<SemanticSignatureElement> Elements,
                             VersionTuple ValidatorVersion) {
  if (Elements.empty())
    return nullptr;
  auto I32 = [&](uint32_t V) {
    return ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), V));
  };
  auto I8 = [&](uint8_t V) {
    return ConstantAsMetadata::get(ConstantInt::get(Type::getInt8Ty(Ctx), V));
  };
  SmallVector<Metadata *> Nodes;
  for (const auto &E : Elements) {
    SmallVector<Metadata *> Indices, Props;
    for (uint32_t Index : E.SemanticIndices)
      Indices.push_back(I32(Index));
    if (E.GSStream)
      Props.append({I32(0), I32(E.GSStream)});
    if (E.DynIndexMask)
      Props.append({I32(2), I32(E.DynIndexMask)});
    if (E.UsageMask &&
        (ValidatorVersion.empty() || ValidatorVersion == VersionTuple(0, 0) ||
         ValidatorVersion >= VersionTuple(1, 5)))
      Props.append({I32(3), I32(E.UsageMask >> E.getStartColOrZero())});
    Nodes.push_back(MDNode::get(
        Ctx, {I32(E.SigId), MDString::get(Ctx, E.SemanticName),
              I8(static_cast<uint8_t>(E.CompType)),
              I8(static_cast<uint8_t>(E.SemanticKind)),
              MDNode::get(Ctx, Indices), I8(static_cast<uint8_t>(E.InterpMode)),
              I32(E.Rows), I8(E.Cols), I32(E.StartRow), I8(E.StartCol),
              Props.empty() ? nullptr : MDNode::get(Ctx, Props)}));
  }
  return MDNode::get(Ctx, Nodes);
}

static dxbc::SigComponentType getComponentType(ElementType Type, bool Legacy) {
  switch (Type) {
  case ElementType::I1:
    return Legacy ? dxbc::SigComponentType::Unknown
                  : dxbc::SigComponentType::UInt32;
  case ElementType::I16:
    return dxbc::SigComponentType::SInt16;
  case ElementType::U16:
    return dxbc::SigComponentType::UInt16;
  case ElementType::I32:
    return dxbc::SigComponentType::SInt32;
  case ElementType::U32:
    return dxbc::SigComponentType::UInt32;
  case ElementType::F16:
    return dxbc::SigComponentType::Float16;
  case ElementType::F32:
    return dxbc::SigComponentType::Float32;
  default:
    llvm_unreachable("invalid signature component type");
  }
}

static dxbc::D3DSystemValue getSystemValue(dxbc::PSV::SemanticKind Kind) {
  using KindTy = dxbc::PSV::SemanticKind;
  switch (Kind) {
  case KindTy::Arbitrary:
    return dxbc::D3DSystemValue::Undefined;
  case KindTy::VertexID:
    return dxbc::D3DSystemValue::VertexID;
  case KindTy::InstanceID:
    return dxbc::D3DSystemValue::InstanceID;
  case KindTy::Position:
    return dxbc::D3DSystemValue::Position;
  case KindTy::IsFrontFace:
    return dxbc::D3DSystemValue::IsFrontFace;
  case KindTy::ClipDistance:
    return dxbc::D3DSystemValue::ClipDistance;
  case KindTy::CullDistance:
    return dxbc::D3DSystemValue::CullDistance;
  case KindTy::Target:
    return dxbc::D3DSystemValue::Target;
  case KindTy::ShadingRate:
    return dxbc::D3DSystemValue::ShadingRate;
  case KindTy::Barycentrics:
    return dxbc::D3DSystemValue::Barycentrics;
  default:
    llvm_unreachable("validated vertex/pixel signature semantic");
  }
}

// The DXIL reader normalizes system-value semantic names when loading module
// metadata. The validator then recreates ISG1/OSG1 from those normalized names
// and compares the parts byte-for-byte, so the container must use the same
// spelling even if HLSL (or the source metadata) used a different casing.
static StringRef getContainerSemanticName(const SemanticSignatureElement &E) {
  using Kind = dxbc::PSV::SemanticKind;
  switch (E.SemanticKind) {
  case Kind::Arbitrary:
    return E.SemanticName;
  case Kind::VertexID:
    return "SV_VertexID";
  case Kind::InstanceID:
    return "SV_InstanceID";
  case Kind::Position:
    return "SV_Position";
  case Kind::IsFrontFace:
    return "SV_IsFrontFace";
  case Kind::ClipDistance:
    return "SV_ClipDistance";
  case Kind::CullDistance:
    return "SV_CullDistance";
  case Kind::Target:
    return "SV_Target";
  case Kind::ShadingRate:
    return "SV_ShadingRate";
  case Kind::Barycentrics:
    return "SV_Barycentrics";
  default:
    llvm_unreachable("validated vertex/pixel signature semantic");
  }
}

static void buildSignature(mcdxbc::Signature &Sig,
                           ArrayRef<SemanticSignatureElement> Elements,
                           bool Input, bool Native16, bool Legacy) {
  for (const auto &E : Elements) {
    uint8_t Mask = E.getDeclaredMask();
    uint8_t ExclusiveMask =
        Input ? E.getAlwaysReadsMask() : E.getNeverWritesMask();
    if (Legacy)
      ExclusiveMask = Input ? 0 : static_cast<uint8_t>(~Mask);
    for (auto [Row, Index] : enumerate(E.SemanticIndices))
      Sig.addParam(E.GSStream, getContainerSemanticName(E), Index,
                   getSystemValue(E.SemanticKind),
                   getComponentType(E.CompType, Legacy),
                   E.isAllocated() ? E.StartRow + Row : UnallocatedRow, Mask,
                   ExclusiveMask, E.getMinPrecision(!Native16));
  }
}

static void buildPSVElements(SmallVectorImpl<mcdxbc::PSVSignatureElement> &Dest,
                             ArrayRef<SemanticSignatureElement> Elements,
                             bool Legacy) {
  for (const auto &E : Elements) {
    auto Type = getComponentType(E.CompType, Legacy);
    // SigComponentType and PSV ComponentType share COMPONENT_TYPE definitions.
    Dest.push_back(
        {E.SemanticKind == dxbc::PSV::SemanticKind::Arbitrary ? E.SemanticName
                                                              : StringRef(),
         E.SemanticIndices,
         E.isAllocated() ? static_cast<uint8_t>(E.StartRow) : uint8_t(0),
         E.Cols, E.getStartColOrZero(), E.isAllocated(), E.SemanticKind,
         static_cast<dxbc::PSV::ComponentType>(Type), E.InterpMode,
         E.DynIndexMask, static_cast<uint8_t>(E.GSStream)});
  }
}

MDTuple *EntrySignature::getAsMetadata(LLVMContext &Ctx,
                                       VersionTuple ValidatorVersion) const {
  if (Inputs.empty() && Outputs.empty())
    return nullptr;
  return MDNode::get(Ctx,
                     {emitSignature(Ctx, Inputs, ValidatorVersion),
                      emitSignature(Ctx, Outputs, ValidatorVersion), nullptr});
}

void EntrySignature::buildSignatures(mcdxbc::Signature &Input,
                                     mcdxbc::Signature &Output,
                                     VersionTuple ValidatorVersion) const {
  bool Legacy = !ValidatorVersion.empty() &&
                ValidatorVersion != VersionTuple(0, 0) &&
                ValidatorVersion < VersionTuple(1, 5);
  buildSignature(Input, Inputs, true, UseNative16Bit, Legacy);
  buildSignature(Output, Outputs, false, UseNative16Bit, Legacy);
}

void EntrySignature::updatePSV(mcdxbc::PSVRuntimeInfo &PSV,
                               VersionTuple ValidatorVersion) const {
  bool Legacy = !ValidatorVersion.empty() &&
                ValidatorVersion != VersionTuple(0, 0) &&
                ValidatorVersion < VersionTuple(1, 5);
  buildPSVElements(PSV.InputElements, Inputs, Legacy);
  buildPSVElements(PSV.OutputElements, Outputs, Legacy);
  PSV.BaseData.SigInputVectors = InputVectors;
  PSV.BaseData.SigOutputVectors[0] = OutputVectors;
  PSV.InputOutputMap[0] = InputOutputMap;
  if (Stage == Triple::Vertex)
    PSV.BaseData.StageInfo.VS.OutputPositionPresent =
        llvm::any_of(Outputs, [](const auto &E) {
          return E.SemanticKind == dxbc::PSV::SemanticKind::Position;
        });
  if (Stage == Triple::Pixel)
    PSV.BaseData.StageInfo.PS.SampleFrequency =
        llvm::any_of(Inputs, [](const auto &E) {
          return E.InterpMode == dxbc::PSV::InterpolationMode::LinearSample ||
                 E.InterpMode ==
                     dxbc::PSV::InterpolationMode::LinearNoperspectiveSample;
        });
}

SmallVector<uint32_t> EntrySignature::getDependencyState() const {
  SmallVector<uint32_t> State = {InputVectors * 4, OutputVectors * 4};
  llvm::append_range(State, InputOutputMap);
  return State;
}

void EntrySignature::print(raw_ostream &OS) const {
  auto Print = [&](StringRef Name, ArrayRef<SemanticSignatureElement> Elements,
                   unsigned Vectors) {
    OS << "  " << Name << ": " << Elements.size() << " elements, " << Vectors
       << " vectors\n";
    for (const auto &E : Elements)
      OS << "    " << E.SigId << ": " << E.SemanticName << " rows=" << E.Rows
         << " cols=" << unsigned(E.Cols) << " at " << E.StartRow << ":"
         << unsigned(E.StartCol) << " usage=" << unsigned(E.UsageMask)
         << " dynamic=" << unsigned(E.DynIndexMask) << '\n';
  };
  Print("Inputs", Inputs, InputVectors);
  Print("Outputs", Outputs, OutputVectors);
}

void ModuleSignatureInfo::print(raw_ostream &OS, const Module &M) const {
  for (const Function &F : M)
    if (const auto *Sig = get(&F)) {
      OS << "Semantic signatures for '" << F.getName() << "':\n";
      Sig->print(OS);
    }
}

AnalysisKey SignatureAnalysis::Key;
ModuleSignatureInfo SignatureAnalysis::run(Module &M,
                                           ModuleAnalysisManager &AM) {
  return collectSignatures(M, AM.getResult<DXILMetadataAnalysis>(M));
}

PreservedAnalyses SignatureAnalysisPrinter::run(Module &M,
                                                ModuleAnalysisManager &AM) {
  AM.getResult<SignatureAnalysis>(M).print(OS, M);
  return PreservedAnalyses::all();
}

bool SignatureAnalysisWrapper::runOnModule(Module &M) {
  Info = std::make_unique<ModuleSignatureInfo>(collectSignatures(
      M, getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata()));
  return false;
}

void SignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<DXILMetadataAnalysisWrapperPass>();
}

void SignatureAnalysisWrapper::print(raw_ostream &OS, const Module *M) const {
  if (Info)
    Info->print(OS, *M);
}

char SignatureAnalysisWrapper::ID;
INITIALIZE_PASS_BEGIN(SignatureAnalysisWrapper, "dxil-signature-analysis",
                      "DXIL Semantic Signature Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass)
INITIALIZE_PASS_END(SignatureAnalysisWrapper, "dxil-signature-analysis",
                    "DXIL Semantic Signature Analysis", false, true)
