[llvm] [DXIL] Consume Metadata Analysis information in passes (PR #108034)

S. Bharadwaj Yadavalli via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 12 17:17:23 PDT 2024


================
@@ -1,335 +0,0 @@
-//===- DXILMetadata.cpp - DXIL Metadata helper objects --------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file This file contains helper objects for working with DXIL metadata.
-///
-//===----------------------------------------------------------------------===//
-
-#include "DXILMetadata.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/VersionTuple.h"
-#include "llvm/TargetParser/Triple.h"
-
-using namespace llvm;
-using namespace llvm::dxil;
-
-ValidatorVersionMD::ValidatorVersionMD(Module &M)
-    : Entry(M.getOrInsertNamedMetadata("dx.valver")) {}
-
-void ValidatorVersionMD::update(VersionTuple ValidatorVer) {
-  auto &Ctx = Entry->getParent()->getContext();
-  IRBuilder<> B(Ctx);
-  Metadata *MDVals[2];
-  MDVals[0] = ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMajor()));
-  MDVals[1] =
-      ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMinor().value_or(0)));
-
-  if (isEmpty())
-    Entry->addOperand(MDNode::get(Ctx, MDVals));
-  else
-    Entry->setOperand(0, MDNode::get(Ctx, MDVals));
-}
-
-bool ValidatorVersionMD::isEmpty() { return Entry->getNumOperands() == 0; }
-
-VersionTuple ValidatorVersionMD::getAsVersionTuple() {
-  if (isEmpty())
-    return VersionTuple(1, 0);
-  auto *ValVerMD = cast<MDNode>(Entry->getOperand(0));
-  auto *MajorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(0));
-  auto *MinorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(1));
-  return VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue());
-}
-
-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";
-  default:
-    break;
-  }
-  llvm_unreachable("Unsupported environment for DXIL generation.");
-  return "";
-}
-
-void dxil::createShaderModelMD(Module &M) {
-  NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.shaderModel");
-  Triple TT(M.getTargetTriple());
-  VersionTuple Ver = TT.getOSVersion();
-  LLVMContext &Ctx = M.getContext();
-  IRBuilder<> B(Ctx);
-
-  Metadata *Vals[3];
-  Vals[0] = MDString::get(Ctx, getShortShaderStage(TT.getEnvironment()));
-  Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor()));
-  Vals[2] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0)));
-  Entry->addOperand(MDNode::get(Ctx, Vals));
-}
-
-void dxil::createDXILVersionMD(Module &M) {
-  Triple TT(Triple::normalize(M.getTargetTriple()));
-  VersionTuple Ver = TT.getDXILVersion();
-  LLVMContext &Ctx = M.getContext();
-  IRBuilder<> B(Ctx);
-  NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
-  Metadata *Vals[2];
-  Vals[0] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor()));
-  Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0)));
-  Entry->addOperand(MDNode::get(Ctx, Vals));
-}
-
-static uint32_t getShaderStage(Triple::EnvironmentType Env) {
-  return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel;
-}
-
-namespace {
-
-struct EntryProps {
-  Triple::EnvironmentType ShaderKind;
-  // FIXME: support more shader profiles.
-  // See https://github.com/llvm/llvm-project/issues/57927.
-  struct {
-    unsigned NumThreads[3];
-  } CS;
-
-  EntryProps(Function &F, Triple::EnvironmentType ModuleShaderKind)
-      : ShaderKind(ModuleShaderKind) {
-
-    if (ShaderKind == Triple::EnvironmentType::Library) {
-      Attribute EntryAttr = F.getFnAttribute("hlsl.shader");
-      StringRef EntryProfile = EntryAttr.getValueAsString();
-      Triple T("", "", "", EntryProfile);
-      ShaderKind = T.getEnvironment();
-    }
-
-    if (ShaderKind == Triple::EnvironmentType::Compute) {
-      auto NumThreadsStr =
-          F.getFnAttribute("hlsl.numthreads").getValueAsString();
-      SmallVector<StringRef> NumThreads;
-      NumThreadsStr.split(NumThreads, ',');
-      assert(NumThreads.size() == 3 && "invalid numthreads");
-      auto Zip =
-          llvm::zip(NumThreads, MutableArrayRef<unsigned>(CS.NumThreads));
-      for (auto It : Zip) {
-        StringRef Str = std::get<0>(It);
-        APInt V;
-        [[maybe_unused]] bool Result = Str.getAsInteger(10, V);
-        assert(!Result && "Failed to parse numthreads");
-
-        unsigned &Num = std::get<1>(It);
-        Num = V.getLimitedValue();
-      }
-    }
-  }
-
-  MDTuple *emitDXILEntryProps(uint64_t RawShaderFlag, LLVMContext &Ctx,
-                              bool IsLib) {
-    std::vector<Metadata *> MDVals;
-
-    if (RawShaderFlag != 0)
-      appendShaderFlags(MDVals, RawShaderFlag, Ctx);
-
-    // Add shader kind for lib entrys.
-    if (IsLib && ShaderKind != Triple::EnvironmentType::Library)
-      appendShaderKind(MDVals, Ctx);
-
-    if (ShaderKind == Triple::EnvironmentType::Compute)
-      appendNumThreads(MDVals, Ctx);
-    // FIXME: support more props.
-    // See https://github.com/llvm/llvm-project/issues/57948.
-    return MDNode::get(Ctx, MDVals);
-  }
-
-  static MDTuple *emitEntryPropsForEmptyEntry(uint64_t RawShaderFlag,
-                                              LLVMContext &Ctx) {
-    if (RawShaderFlag == 0)
-      return nullptr;
-
-    std::vector<Metadata *> MDVals;
-
-    appendShaderFlags(MDVals, RawShaderFlag, Ctx);
-    // FIXME: support more props.
-    // See https://github.com/llvm/llvm-project/issues/57948.
-    return MDNode::get(Ctx, MDVals);
-  }
-
-private:
-  enum EntryPropsTag {
-    ShaderFlagsTag = 0,
-    GSStateTag,
-    DSStateTag,
-    HSStateTag,
-    NumThreadsTag,
-    AutoBindingSpaceTag,
-    RayPayloadSizeTag,
-    RayAttribSizeTag,
-    ShaderKindTag,
-    MSStateTag,
-    ASStateTag,
-    WaveSizeTag,
-    EntryRootSigTag,
-  };
-
-  void appendNumThreads(std::vector<Metadata *> &MDVals, LLVMContext &Ctx) {
-    MDVals.emplace_back(ConstantAsMetadata::get(
-        ConstantInt::get(Type::getInt32Ty(Ctx), NumThreadsTag)));
-
-    std::vector<Metadata *> NumThreadVals;
-    for (auto Num : ArrayRef<unsigned>(CS.NumThreads))
-      NumThreadVals.emplace_back(ConstantAsMetadata::get(
-          ConstantInt::get(Type::getInt32Ty(Ctx), Num)));
-    MDVals.emplace_back(MDNode::get(Ctx, NumThreadVals));
-  }
-
-  static void appendShaderFlags(std::vector<Metadata *> &MDVals,
-                                uint64_t RawShaderFlag, LLVMContext &Ctx) {
-    MDVals.emplace_back(ConstantAsMetadata::get(
-        ConstantInt::get(Type::getInt32Ty(Ctx), ShaderFlagsTag)));
-    MDVals.emplace_back(ConstantAsMetadata::get(
-        ConstantInt::get(Type::getInt64Ty(Ctx), RawShaderFlag)));
-  }
-
-  void appendShaderKind(std::vector<Metadata *> &MDVals, LLVMContext &Ctx) {
-    MDVals.emplace_back(ConstantAsMetadata::get(
-        ConstantInt::get(Type::getInt32Ty(Ctx), ShaderKindTag)));
-    MDVals.emplace_back(ConstantAsMetadata::get(
-        ConstantInt::get(Type::getInt32Ty(Ctx), getShaderStage(ShaderKind))));
-  }
-};
-
-class EntryMD {
-  Function &F;
-  LLVMContext &Ctx;
-  EntryProps Props;
-
-public:
-  EntryMD(Function &F, Triple::EnvironmentType ModuleShaderKind)
-      : F(F), Ctx(F.getContext()), Props(F, ModuleShaderKind) {}
-
-  MDTuple *emitEntryTuple(MDTuple *Resources, uint64_t RawShaderFlag) {
-    // FIXME: add signature for profile other than CS.
-    // See https://github.com/llvm/llvm-project/issues/57928.
-    MDTuple *Signatures = nullptr;
-    return emitDXILEntryPointTuple(
-        &F, F.getName().str(), Signatures, Resources,
-        Props.emitDXILEntryProps(RawShaderFlag, Ctx, /*IsLib*/ false), Ctx);
-  }
-
-  MDTuple *emitEntryTupleForLib(uint64_t RawShaderFlag) {
-    // FIXME: add signature for profile other than CS.
-    // See https://github.com/llvm/llvm-project/issues/57928.
-    MDTuple *Signatures = nullptr;
-    return emitDXILEntryPointTuple(
-        &F, F.getName().str(), Signatures,
-        /*entry in lib doesn't need resources metadata*/ nullptr,
-        Props.emitDXILEntryProps(RawShaderFlag, Ctx, /*IsLib*/ true), Ctx);
-  }
-
-  // Library will have empty entry metadata which only store the resource table
-  // metadata.
-  static MDTuple *emitEmptyEntryForLib(MDTuple *Resources,
-                                       uint64_t RawShaderFlag,
-                                       LLVMContext &Ctx) {
-    return emitDXILEntryPointTuple(
-        nullptr, "", nullptr, Resources,
-        EntryProps::emitEntryPropsForEmptyEntry(RawShaderFlag, Ctx), Ctx);
-  }
-
-private:
-  static MDTuple *emitDXILEntryPointTuple(Function *Fn, const std::string &Name,
-                                          MDTuple *Signatures,
-                                          MDTuple *Resources,
-                                          MDTuple *Properties,
-                                          LLVMContext &Ctx) {
-    Metadata *MDVals[5];
-    MDVals[0] = Fn ? ValueAsMetadata::get(Fn) : nullptr;
-    MDVals[1] = MDString::get(Ctx, Name.c_str());
-    MDVals[2] = Signatures;
-    MDVals[3] = Resources;
-    MDVals[4] = Properties;
-    return MDNode::get(Ctx, MDVals);
-  }
-};
-} // namespace
-
-void dxil::createEntryMD(Module &M, const uint64_t ShaderFlags) {
-  SmallVector<Function *> EntryList;
-  for (auto &F : M.functions()) {
-    if (!F.hasFnAttribute("hlsl.shader"))
-      continue;
-    EntryList.emplace_back(&F);
-  }
-
-  // If there are no entries, do nothing. This is mostly to allow for writing
-  // tests with no actual entry functions.
-  if (EntryList.empty())
-    return;
----------------
bharadwajy wrote:

> It looks like you dropped this convenient behaviour and went back to crashing when we have no entry functions in a non-library shader.

Fixed.

https://github.com/llvm/llvm-project/pull/108034


More information about the llvm-commits mailing list