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

S. Bharadwaj Yadavalli via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 19 10:05:25 PDT 2024


================
@@ -58,25 +89,257 @@ static void emitResourceMetadata(Module &M, const DXILResourceMap &DRM,
   }
 
   if (!HasResources)
-    return;
+    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";
+  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;
+}
+
+namespace {
+enum EntryPropsTag {
+  ShaderFlagsTag = 0,
+  GSStateTag,
+  DSStateTag,
+  HSStateTag,
+  NumThreadsTag,
+  AutoBindingSpaceTag,
+  RayPayloadSizeTag,
+  RayAttribSizeTag,
+  ShaderKindTag,
+  MSStateTag,
+  ASStateTag,
+  WaveSizeTag,
+  EntryRootSigTag,
+};
+} // namespace
+
+static SmallVector<Metadata *>
+getTagValueAsMetadata(EntryPropsTag Tag, uint64_t Value, LLVMContext &Ctx) {
+  SmallVector<Metadata *> MDVals;
+  MDVals.emplace_back(
+      ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), Tag)));
+  switch (Tag) {
+  case ShaderFlagsTag:
+    MDVals.emplace_back(ConstantAsMetadata::get(
+        ConstantInt::get(Type::getInt64Ty(Ctx), Value)));
+    break;
+  case ShaderKindTag:
+    MDVals.emplace_back(ConstantAsMetadata::get(
+        ConstantInt::get(Type::getInt32Ty(Ctx), Value)));
+    break;
+  default:
+    llvm_unreachable("NYI: Unhandled entry property tag");
+  }
+  return MDVals;
+}
+
+static MDTuple *
+getEntryPropAsMetadata(const EntryProperties &EP, uint64_t EntryShaderFlags,
+                       const Triple::EnvironmentType ShaderProfile) {
+  SmallVector<Metadata *> MDVals;
+  LLVMContext &Ctx = EP.Entry->getContext();
+  if (EntryShaderFlags != 0)
+    MDVals.append(getTagValueAsMetadata(ShaderFlagsTag, 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 (ShaderProfile == Triple::EnvironmentType::Library &&
+        EP.ShaderStage != Triple::EnvironmentType::Library)
+      MDVals.append(getTagValueAsMetadata(ShaderKindTag,
+                                          getShaderStage(EP.ShaderStage), Ctx));
+
+    if (EP.ShaderStage == Triple::EnvironmentType::Compute) {
+      MDVals.emplace_back(ConstantAsMetadata::get(
+          ConstantInt::get(Type::getInt32Ty(Ctx), NumThreadsTag)));
+      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));
+    }
+  }
+  if (MDVals.empty())
+    return nullptr;
+  return MDNode::get(Ctx, MDVals);
+}
+
+// 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
+
+MDTuple *constructEntryMetadata(const Function *EntryFn, MDTuple *Signatures,
+                                MDNode *Resources, MDTuple *Properties,
+                                LLVMContext &Ctx) {
+  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(const EntryProperties &EP, MDTuple *Signatures,
+                            MDNode *MDResources,
+                            const uint64_t EntryShaderFlags,
+                            const Triple::EnvironmentType ShaderProfile) {
+  MDTuple *Properties =
+      getEntryPropAsMetadata(EP, EntryShaderFlags, ShaderProfile);
+  return constructEntryMetadata(EP.Entry, Signatures, MDResources, Properties,
+                                EP.Entry->getContext());
+}
+
+static void emitValidatorVersionMD(Module &M, const ModuleMetadataInfo &MMDI) {
+  if (!MMDI.ValidatorVersion.empty()) {
----------------
bharadwajy wrote:

> It doesn't make a big difference here, but it's best to use early returns to avoid unnecessary nesting. So,
> 
> ```c++
>   if (MMDI.ValidatorVersion.empty())
>     return;
> ```

Changed.

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


More information about the llvm-commits mailing list