[llvm] [HLSL][RootSignature] Implement serialized dump of Descriptor Tables (PR #138326)

Finn Plummer via llvm-commits llvm-commits at lists.llvm.org
Fri May 9 09:53:02 PDT 2025


https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/138326

>From 6dd49d475eac2a8ce12dad68d2edb4d08f9a88f5 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 2 May 2025 17:37:57 +0000
Subject: [PATCH 1/6] get infra setup

---
 .../llvm/Frontend/HLSL/HLSLRootSignature.h    |  3 ++
 llvm/lib/Frontend/HLSL/CMakeLists.txt         |  1 +
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp  | 25 ++++++++++++++++
 llvm/unittests/Frontend/CMakeLists.txt        |  2 ++
 .../Frontend/HLSLRootSignatureDumpTest.cpp    | 30 +++++++++++++++++++
 5 files changed, 61 insertions(+)
 create mode 100644 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
 create mode 100644 llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 818caccfe1998..6d1120c091007 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -15,6 +15,7 @@
 #define LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H
 
 #include "llvm/Support/DXILABI.h"
+#include "llvm/Support/raw_ostream.h"
 #include <variant>
 
 namespace llvm {
@@ -86,6 +87,8 @@ struct DescriptorTableClause {
       break;
     }
   }
+
+  void dump(raw_ostream &OS) const;
 };
 
 // Models RootElement : DescriptorTable | DescriptorTableClause
diff --git a/llvm/lib/Frontend/HLSL/CMakeLists.txt b/llvm/lib/Frontend/HLSL/CMakeLists.txt
index 07a0c845ceef6..dd987544fe80b 100644
--- a/llvm/lib/Frontend/HLSL/CMakeLists.txt
+++ b/llvm/lib/Frontend/HLSL/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_llvm_component_library(LLVMFrontendHLSL
   CBuffer.cpp
   HLSLResource.cpp
+  HLSLRootSignature.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
new file mode 100644
index 0000000000000..6a343ff0cc7bd
--- /dev/null
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -0,0 +1,25 @@
+//===- HLSLRootSignature.cpp - HLSL Root Signature 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 helpers for working with HLSL Root Signatures.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
+
+namespace llvm {
+namespace hlsl {
+namespace rootsig {
+
+void DescriptorTableClause::dump(raw_ostream &OS) const {
+  OS << "Clause!";
+}
+
+} // namespace rootsig
+} // namespace hlsl
+} // namespace llvm
diff --git a/llvm/unittests/Frontend/CMakeLists.txt b/llvm/unittests/Frontend/CMakeLists.txt
index 85e113816e3bc..2119642769e3d 100644
--- a/llvm/unittests/Frontend/CMakeLists.txt
+++ b/llvm/unittests/Frontend/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   Analysis
   Core
+  FrontendHLSL
   FrontendOpenACC
   FrontendOpenMP
   Passes
@@ -10,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_llvm_unittest(LLVMFrontendTests
+  HLSLRootSignatureDumpTest.cpp
   OpenACCTest.cpp
   OpenMPContextTest.cpp
   OpenMPIRBuilderTest.cpp
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
new file mode 100644
index 0000000000000..eef52da983660
--- /dev/null
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -0,0 +1,30 @@
+//===-------- HLSLRootSignatureDumpTest.cpp - RootSignature dump tests ----===//
+//
+// 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 "llvm/Frontend/HLSL/HLSLRootSignature.h"
+#include "gtest/gtest.h"
+
+using namespace llvm::hlsl::rootsig;
+
+namespace {
+
+TEST(HLSLRootSignatureTest, DescriptorTablesDump) {
+  // Default clause
+  DescriptorTableClause Clause;
+  Clause.Type = ClauseType::CBuffer;
+  Clause.Reg = { RegisterType::BReg, 0 };
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  Clause.dump(OS);
+  OS.flush();
+
+  EXPECT_EQ(Out, "Clause!");
+}
+
+} // namespace

>From 51483dd7474f61710d283d0f58ef72a58224acf4 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 2 May 2025 18:36:19 +0000
Subject: [PATCH 2/6] implement support for dumping descriptor table clauses

---
 .../llvm/Frontend/HLSL/HLSLRootSignature.h    |  2 +
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp  | 94 ++++++++++++++++++-
 .../Frontend/HLSLRootSignatureDumpTest.cpp    | 74 ++++++++++++++-
 3 files changed, 166 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 6d1120c091007..fd8986f5797de 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -53,6 +53,8 @@ enum class RegisterType { BReg, TReg, UReg, SReg };
 struct Register {
   RegisterType ViewType;
   uint32_t Number;
+
+  void dump(raw_ostream &OS) const;
 };
 
 // Models the end of a descriptor table and stores its visibility
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 6a343ff0cc7bd..931eba9b617d5 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -11,13 +11,105 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Frontend/HLSL/HLSLRootSignature.h"
+#include "llvm/ADT/bit.h"
 
 namespace llvm {
 namespace hlsl {
 namespace rootsig {
 
+static void dumpRegType(raw_ostream& OS, RegisterType Type) {
+  switch (Type) {
+  case RegisterType::BReg:
+    OS << "b";
+    break;
+  case RegisterType::TReg:
+    OS << "t";
+    break;
+  case RegisterType::UReg:
+    OS << "u";
+    break;
+  case RegisterType::SReg:
+    OS << "s";
+    break;
+  }
+}
+
+void Register::dump(raw_ostream &OS) const {
+  dumpRegType(OS, ViewType);
+  OS << Number;
+}
+
+static void dumpClauseType(raw_ostream& OS, ClauseType Type) {
+  switch (Type) {
+  case ClauseType::CBuffer:
+    OS << "CBV";
+    break;
+  case ClauseType::SRV:
+    OS << "SRV";
+    break;
+  case ClauseType::UAV:
+    OS << "UAV";
+    break;
+  case ClauseType::Sampler:
+    OS << "Sampler";
+    break;
+  }
+}
+
+static void dumpDescriptorRangeFlag(raw_ostream &OS, unsigned Bit) {
+  switch (static_cast<DescriptorRangeFlags>(Bit)) {
+    case DescriptorRangeFlags::DescriptorsVolatile:
+      OS << "DescriptorsVolatile";
+      break;
+    case DescriptorRangeFlags::DataVolatile:
+      OS << "DataVolatile";
+      break;
+    case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
+      OS << "DataStaticWhileSetAtExecute";
+      break;
+    case DescriptorRangeFlags::DataStatic:
+      OS << "DataStatic";
+      break;
+    case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
+      OS << "DescriptorsStaticKeepingBufferBoundsChecks";
+      break;
+    default:
+      OS << "invalid: " << Bit;
+      break;
+  }
+}
+
+static void dumpDescriptorRangeFlags(raw_ostream &OS, DescriptorRangeFlags Flags) {
+  bool FlagSet = false;
+  unsigned Remaining = llvm::to_underlying(Flags);
+  while (Remaining) {
+    unsigned Bit = 1u << llvm::countr_zero(Remaining);
+    if (Remaining & Bit) {
+      if (FlagSet)
+        OS << " | ";
+      dumpDescriptorRangeFlag(OS, Bit);
+      FlagSet = true;
+    }
+    Remaining &= ~Bit;
+  }
+  if (!FlagSet)
+    OS << "None";
+}
+
 void DescriptorTableClause::dump(raw_ostream &OS) const {
-  OS << "Clause!";
+  dumpClauseType(OS, Type);
+  OS << "(";
+  Reg.dump(OS);
+  OS << ", numDescriptors = " << NumDescriptors;
+  OS << ", space = " << Space;
+  OS << ", offset = ";
+  if (Offset == DescriptorTableOffsetAppend)
+    OS << "DESCRIPTOR_TABLE_OFFSET_APPEND";
+  else
+    OS << Offset;
+  OS << ", flags = ";
+  dumpDescriptorRangeFlags(OS, Flags);
+  OS << ")";
 }
 
 } // namespace rootsig
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index eef52da983660..cfdebe2619b7b 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -13,18 +13,86 @@ using namespace llvm::hlsl::rootsig;
 
 namespace {
 
-TEST(HLSLRootSignatureTest, DescriptorTablesDump) {
-  // Default clause
+TEST(HLSLRootSignatureTest, DescriptorCBVClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::CBuffer;
   Clause.Reg = { RegisterType::BReg, 0 };
+  Clause.setDefaultFlags();
 
   std::string Out;
   llvm::raw_string_ostream OS(Out);
   Clause.dump(OS);
   OS.flush();
 
-  EXPECT_EQ(Out, "Clause!");
+  std::string Expected =
+    "CBV(b0, numDescriptors = 1, space = 0, "
+    "offset = DESCRIPTOR_TABLE_OFFSET_APPEND, "
+    "flags = DataStaticWhileSetAtExecute)";
+  EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
+  DescriptorTableClause Clause;
+  Clause.Type = ClauseType::SRV;
+  Clause.Reg = { RegisterType::TReg, 0 };
+  Clause.NumDescriptors = 2;
+  Clause.Space = 42;
+  Clause.Offset = 3;
+  Clause.Flags = DescriptorRangeFlags::None;
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  Clause.dump(OS);
+  OS.flush();
+
+  std::string Expected =
+    "SRV(t0, numDescriptors = 2, space = 42, offset = 3, flags = None)";
+  EXPECT_EQ(Out, Expected);
+}
+
+
+TEST(HLSLRootSignatureTest, DescriptorUAVClauseDump) {
+  DescriptorTableClause Clause;
+  Clause.Type = ClauseType::UAV;
+  Clause.Reg = { RegisterType::UReg, 0 };
+  Clause.NumDescriptors = 2;
+  Clause.Space = 42;
+  Clause.Offset = 3;
+  Clause.Flags = DescriptorRangeFlags::ValidFlags;
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  Clause.dump(OS);
+  OS.flush();
+
+  std::string Expected =
+    "UAV(u0, numDescriptors = 2, space = 42, offset = 3, flags = "
+    "DescriptorsVolatile | "
+    "DataVolatile | "
+    "DataStaticWhileSetAtExecute | "
+    "DataStatic | "
+    "DescriptorsStaticKeepingBufferBoundsChecks)";
+  EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
+  DescriptorTableClause Clause;
+  Clause.Type = ClauseType::Sampler;
+  Clause.Reg = { RegisterType::SReg, 0 };
+  Clause.NumDescriptors = 2;
+  Clause.Space = 42;
+  Clause.Offset = 3;
+  Clause.Flags = DescriptorRangeFlags::ValidSamplerFlags;
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  Clause.dump(OS);
+  OS.flush();
+
+  std::string Expected =
+    "Sampler(s0, numDescriptors = 2, space = 42, offset = 3, "
+    "flags = DescriptorsVolatile)";
+  EXPECT_EQ(Out, Expected);
 }
 
 } // namespace

>From 2bdbbc66f0797c97fa0579d94fe0cff793cdd2c1 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 2 May 2025 18:51:11 +0000
Subject: [PATCH 3/6] implement support for dumping descriptor table struct

---
 .../llvm/Frontend/HLSL/HLSLRootSignature.h    |  2 ++
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp  | 36 +++++++++++++++++++
 .../Frontend/HLSLRootSignatureDumpTest.cpp    | 15 ++++++++
 3 files changed, 53 insertions(+)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index fd8986f5797de..6d3ecd166f461 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -61,6 +61,8 @@ struct Register {
 struct DescriptorTable {
   ShaderVisibility Visibility = ShaderVisibility::All;
   uint32_t NumClauses = 0; // The number of clauses in the table
+
+  void dump(raw_ostream &OS) const;
 };
 
 static const uint32_t NumDescriptorsUnbounded = 0xffffffff;
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 931eba9b617d5..09af204a18376 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -39,6 +39,42 @@ void Register::dump(raw_ostream &OS) const {
   OS << Number;
 }
 
+static void dumpVisibility(raw_ostream &OS, ShaderVisibility Visibility) {
+  switch (Visibility) {
+    case ShaderVisibility::All:
+      OS << "All";
+      break;
+    case ShaderVisibility::Vertex:
+      OS << "Vertex";
+      break;
+    case ShaderVisibility::Hull:
+      OS << "Hull";
+      break;
+    case ShaderVisibility::Domain:
+      OS << "Domain";
+      break;
+    case ShaderVisibility::Geometry:
+      OS << "Geometry";
+      break;
+    case ShaderVisibility::Pixel:
+      OS << "Pixel";
+      break;
+    case ShaderVisibility::Amplification:
+      OS << "Amplification";
+      break;
+    case ShaderVisibility::Mesh:
+      OS << "Mesh";
+      break;
+  }
+}
+
+void DescriptorTable::dump(raw_ostream &OS) const {
+  OS << "DescriptorTable(numClauses = " << NumClauses;
+  OS << ", visibility = ";
+  dumpVisibility(OS, Visibility);
+  OS << ")";
+}
+
 static void dumpClauseType(raw_ostream& OS, ClauseType Type) {
   switch (Type) {
   case ClauseType::CBuffer:
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index cfdebe2619b7b..790171410a419 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -95,4 +95,19 @@ TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
   EXPECT_EQ(Out, Expected);
 }
 
+TEST(HLSLRootSignatureTest, DescriptorTableDump) {
+  DescriptorTable Table;
+  Table.NumClauses = 4;
+  Table.Visibility = ShaderVisibility::Geometry;
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  Table.dump(OS);
+  OS.flush();
+
+  std::string Expected =
+    "DescriptorTable(numClauses = 4, visibility = Geometry)";
+  EXPECT_EQ(Out, Expected);
+}
+
 } // namespace

>From 81692d69da20e30230f2d6a4b21b20f491111581 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 2 May 2025 18:51:23 +0000
Subject: [PATCH 4/6] nfc: change some test values around or something

---
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp     |  2 +-
 .../Frontend/HLSLRootSignatureDumpTest.cpp       | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 09af204a18376..0e5b14aca72e8 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -140,7 +140,7 @@ void DescriptorTableClause::dump(raw_ostream &OS) const {
   OS << ", space = " << Space;
   OS << ", offset = ";
   if (Offset == DescriptorTableOffsetAppend)
-    OS << "DESCRIPTOR_TABLE_OFFSET_APPEND";
+    OS << "DescriptorTableOffsetAppend";
   else
     OS << Offset;
   OS << ", flags = ";
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index 790171410a419..dbc1e7618a978 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -26,7 +26,7 @@ TEST(HLSLRootSignatureTest, DescriptorCBVClauseDump) {
 
   std::string Expected =
     "CBV(b0, numDescriptors = 1, space = 0, "
-    "offset = DESCRIPTOR_TABLE_OFFSET_APPEND, "
+    "offset = DescriptorTableOffsetAppend, "
     "flags = DataStaticWhileSetAtExecute)";
   EXPECT_EQ(Out, Expected);
 }
@@ -54,10 +54,10 @@ TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
 TEST(HLSLRootSignatureTest, DescriptorUAVClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::UAV;
-  Clause.Reg = { RegisterType::UReg, 0 };
-  Clause.NumDescriptors = 2;
-  Clause.Space = 42;
-  Clause.Offset = 3;
+  Clause.Reg = { RegisterType::UReg, 92374 };
+  Clause.NumDescriptors = 3298;
+  Clause.Space = 932847;
+  Clause.Offset = 1;
   Clause.Flags = DescriptorRangeFlags::ValidFlags;
 
   std::string Out;
@@ -66,7 +66,7 @@ TEST(HLSLRootSignatureTest, DescriptorUAVClauseDump) {
   OS.flush();
 
   std::string Expected =
-    "UAV(u0, numDescriptors = 2, space = 42, offset = 3, flags = "
+    "UAV(u92374, numDescriptors = 3298, space = 932847, offset = 1, flags = "
     "DescriptorsVolatile | "
     "DataVolatile | "
     "DataStaticWhileSetAtExecute | "
@@ -81,7 +81,7 @@ TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
   Clause.Reg = { RegisterType::SReg, 0 };
   Clause.NumDescriptors = 2;
   Clause.Space = 42;
-  Clause.Offset = 3;
+  Clause.Offset = DescriptorTableOffsetAppend;
   Clause.Flags = DescriptorRangeFlags::ValidSamplerFlags;
 
   std::string Out;
@@ -90,7 +90,7 @@ TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
   OS.flush();
 
   std::string Expected =
-    "Sampler(s0, numDescriptors = 2, space = 42, offset = 3, "
+    "Sampler(s0, numDescriptors = 2, space = 42, offset = DescriptorTableOffsetAppend, "
     "flags = DescriptorsVolatile)";
   EXPECT_EQ(Out, Expected);
 }

>From 7070ca0d72a0046699b1f1e4adee737a701cf44c Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 2 May 2025 19:11:21 +0000
Subject: [PATCH 5/6] clang-format

---
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp  | 91 ++++++++++---------
 .../Frontend/HLSLRootSignatureDumpTest.cpp    | 38 ++++----
 2 files changed, 64 insertions(+), 65 deletions(-)

diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 0e5b14aca72e8..a5f0313138521 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -17,7 +17,7 @@ namespace llvm {
 namespace hlsl {
 namespace rootsig {
 
-static void dumpRegType(raw_ostream& OS, RegisterType Type) {
+static void dumpRegType(raw_ostream &OS, RegisterType Type) {
   switch (Type) {
   case RegisterType::BReg:
     OS << "b";
@@ -41,30 +41,30 @@ void Register::dump(raw_ostream &OS) const {
 
 static void dumpVisibility(raw_ostream &OS, ShaderVisibility Visibility) {
   switch (Visibility) {
-    case ShaderVisibility::All:
-      OS << "All";
-      break;
-    case ShaderVisibility::Vertex:
-      OS << "Vertex";
-      break;
-    case ShaderVisibility::Hull:
-      OS << "Hull";
-      break;
-    case ShaderVisibility::Domain:
-      OS << "Domain";
-      break;
-    case ShaderVisibility::Geometry:
-      OS << "Geometry";
-      break;
-    case ShaderVisibility::Pixel:
-      OS << "Pixel";
-      break;
-    case ShaderVisibility::Amplification:
-      OS << "Amplification";
-      break;
-    case ShaderVisibility::Mesh:
-      OS << "Mesh";
-      break;
+  case ShaderVisibility::All:
+    OS << "All";
+    break;
+  case ShaderVisibility::Vertex:
+    OS << "Vertex";
+    break;
+  case ShaderVisibility::Hull:
+    OS << "Hull";
+    break;
+  case ShaderVisibility::Domain:
+    OS << "Domain";
+    break;
+  case ShaderVisibility::Geometry:
+    OS << "Geometry";
+    break;
+  case ShaderVisibility::Pixel:
+    OS << "Pixel";
+    break;
+  case ShaderVisibility::Amplification:
+    OS << "Amplification";
+    break;
+  case ShaderVisibility::Mesh:
+    OS << "Mesh";
+    break;
   }
 }
 
@@ -75,7 +75,7 @@ void DescriptorTable::dump(raw_ostream &OS) const {
   OS << ")";
 }
 
-static void dumpClauseType(raw_ostream& OS, ClauseType Type) {
+static void dumpClauseType(raw_ostream &OS, ClauseType Type) {
   switch (Type) {
   case ClauseType::CBuffer:
     OS << "CBV";
@@ -94,28 +94,29 @@ static void dumpClauseType(raw_ostream& OS, ClauseType Type) {
 
 static void dumpDescriptorRangeFlag(raw_ostream &OS, unsigned Bit) {
   switch (static_cast<DescriptorRangeFlags>(Bit)) {
-    case DescriptorRangeFlags::DescriptorsVolatile:
-      OS << "DescriptorsVolatile";
-      break;
-    case DescriptorRangeFlags::DataVolatile:
-      OS << "DataVolatile";
-      break;
-    case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
-      OS << "DataStaticWhileSetAtExecute";
-      break;
-    case DescriptorRangeFlags::DataStatic:
-      OS << "DataStatic";
-      break;
-    case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
-      OS << "DescriptorsStaticKeepingBufferBoundsChecks";
-      break;
-    default:
-      OS << "invalid: " << Bit;
-      break;
+  case DescriptorRangeFlags::DescriptorsVolatile:
+    OS << "DescriptorsVolatile";
+    break;
+  case DescriptorRangeFlags::DataVolatile:
+    OS << "DataVolatile";
+    break;
+  case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
+    OS << "DataStaticWhileSetAtExecute";
+    break;
+  case DescriptorRangeFlags::DataStatic:
+    OS << "DataStatic";
+    break;
+  case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
+    OS << "DescriptorsStaticKeepingBufferBoundsChecks";
+    break;
+  default:
+    OS << "invalid: " << Bit;
+    break;
   }
 }
 
-static void dumpDescriptorRangeFlags(raw_ostream &OS, DescriptorRangeFlags Flags) {
+static void dumpDescriptorRangeFlags(raw_ostream &OS,
+                                     DescriptorRangeFlags Flags) {
   bool FlagSet = false;
   unsigned Remaining = llvm::to_underlying(Flags);
   while (Remaining) {
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index dbc1e7618a978..ba1fbfd1f8708 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -16,7 +16,7 @@ namespace {
 TEST(HLSLRootSignatureTest, DescriptorCBVClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::CBuffer;
-  Clause.Reg = { RegisterType::BReg, 0 };
+  Clause.Reg = {RegisterType::BReg, 0};
   Clause.setDefaultFlags();
 
   std::string Out;
@@ -24,17 +24,16 @@ TEST(HLSLRootSignatureTest, DescriptorCBVClauseDump) {
   Clause.dump(OS);
   OS.flush();
 
-  std::string Expected =
-    "CBV(b0, numDescriptors = 1, space = 0, "
-    "offset = DescriptorTableOffsetAppend, "
-    "flags = DataStaticWhileSetAtExecute)";
+  std::string Expected = "CBV(b0, numDescriptors = 1, space = 0, "
+                         "offset = DescriptorTableOffsetAppend, "
+                         "flags = DataStaticWhileSetAtExecute)";
   EXPECT_EQ(Out, Expected);
 }
 
 TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::SRV;
-  Clause.Reg = { RegisterType::TReg, 0 };
+  Clause.Reg = {RegisterType::TReg, 0};
   Clause.NumDescriptors = 2;
   Clause.Space = 42;
   Clause.Offset = 3;
@@ -46,15 +45,14 @@ TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
   OS.flush();
 
   std::string Expected =
-    "SRV(t0, numDescriptors = 2, space = 42, offset = 3, flags = None)";
+      "SRV(t0, numDescriptors = 2, space = 42, offset = 3, flags = None)";
   EXPECT_EQ(Out, Expected);
 }
 
-
 TEST(HLSLRootSignatureTest, DescriptorUAVClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::UAV;
-  Clause.Reg = { RegisterType::UReg, 92374 };
+  Clause.Reg = {RegisterType::UReg, 92374};
   Clause.NumDescriptors = 3298;
   Clause.Space = 932847;
   Clause.Offset = 1;
@@ -66,19 +64,19 @@ TEST(HLSLRootSignatureTest, DescriptorUAVClauseDump) {
   OS.flush();
 
   std::string Expected =
-    "UAV(u92374, numDescriptors = 3298, space = 932847, offset = 1, flags = "
-    "DescriptorsVolatile | "
-    "DataVolatile | "
-    "DataStaticWhileSetAtExecute | "
-    "DataStatic | "
-    "DescriptorsStaticKeepingBufferBoundsChecks)";
+      "UAV(u92374, numDescriptors = 3298, space = 932847, offset = 1, flags = "
+      "DescriptorsVolatile | "
+      "DataVolatile | "
+      "DataStaticWhileSetAtExecute | "
+      "DataStatic | "
+      "DescriptorsStaticKeepingBufferBoundsChecks)";
   EXPECT_EQ(Out, Expected);
 }
 
 TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
   DescriptorTableClause Clause;
   Clause.Type = ClauseType::Sampler;
-  Clause.Reg = { RegisterType::SReg, 0 };
+  Clause.Reg = {RegisterType::SReg, 0};
   Clause.NumDescriptors = 2;
   Clause.Space = 42;
   Clause.Offset = DescriptorTableOffsetAppend;
@@ -89,9 +87,9 @@ TEST(HLSLRootSignatureTest, DescriptorSamplerClauseDump) {
   Clause.dump(OS);
   OS.flush();
 
-  std::string Expected =
-    "Sampler(s0, numDescriptors = 2, space = 42, offset = DescriptorTableOffsetAppend, "
-    "flags = DescriptorsVolatile)";
+  std::string Expected = "Sampler(s0, numDescriptors = 2, space = 42, offset = "
+                         "DescriptorTableOffsetAppend, "
+                         "flags = DescriptorsVolatile)";
   EXPECT_EQ(Out, Expected);
 }
 
@@ -106,7 +104,7 @@ TEST(HLSLRootSignatureTest, DescriptorTableDump) {
   OS.flush();
 
   std::string Expected =
-    "DescriptorTable(numClauses = 4, visibility = Geometry)";
+      "DescriptorTable(numClauses = 4, visibility = Geometry)";
   EXPECT_EQ(Out, Expected);
 }
 

>From c3bd361a28a1f5c08294c2a7cd4054a8164fb71f Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 9 May 2025 16:52:03 +0000
Subject: [PATCH 6/6] review: change to using static << operator

- nicely improves code readability
---
 .../llvm/Frontend/HLSL/HLSLRootSignature.h    |  2 -
 llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp  | 83 +++++++++----------
 2 files changed, 40 insertions(+), 45 deletions(-)

diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 6d3ecd166f461..76ce74d51b301 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -53,8 +53,6 @@ enum class RegisterType { BReg, TReg, UReg, SReg };
 struct Register {
   RegisterType ViewType;
   uint32_t Number;
-
-  void dump(raw_ostream &OS) const;
 };
 
 // Models the end of a descriptor table and stores its visibility
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index a5f0313138521..34273ef74aa3c 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -17,8 +17,8 @@ namespace llvm {
 namespace hlsl {
 namespace rootsig {
 
-static void dumpRegType(raw_ostream &OS, RegisterType Type) {
-  switch (Type) {
+static raw_ostream &operator<<(raw_ostream &OS, const Register &Reg) {
+  switch (Reg.ViewType) {
   case RegisterType::BReg:
     OS << "b";
     break;
@@ -32,14 +32,12 @@ static void dumpRegType(raw_ostream &OS, RegisterType Type) {
     OS << "s";
     break;
   }
+  OS << Reg.Number;
+  return OS;
 }
 
-void Register::dump(raw_ostream &OS) const {
-  dumpRegType(OS, ViewType);
-  OS << Number;
-}
-
-static void dumpVisibility(raw_ostream &OS, ShaderVisibility Visibility) {
+static raw_ostream &operator<<(raw_ostream &OS,
+                               const ShaderVisibility &Visibility) {
   switch (Visibility) {
   case ShaderVisibility::All:
     OS << "All";
@@ -66,16 +64,16 @@ static void dumpVisibility(raw_ostream &OS, ShaderVisibility Visibility) {
     OS << "Mesh";
     break;
   }
+
+  return OS;
 }
 
 void DescriptorTable::dump(raw_ostream &OS) const {
   OS << "DescriptorTable(numClauses = " << NumClauses;
-  OS << ", visibility = ";
-  dumpVisibility(OS, Visibility);
-  OS << ")";
+  OS << ", visibility = " << Visibility << ")";
 }
 
-static void dumpClauseType(raw_ostream &OS, ClauseType Type) {
+static raw_ostream &operator<<(raw_ostream &OS, const ClauseType &Type) {
   switch (Type) {
   case ClauseType::CBuffer:
     OS << "CBV";
@@ -90,33 +88,12 @@ static void dumpClauseType(raw_ostream &OS, ClauseType Type) {
     OS << "Sampler";
     break;
   }
-}
 
-static void dumpDescriptorRangeFlag(raw_ostream &OS, unsigned Bit) {
-  switch (static_cast<DescriptorRangeFlags>(Bit)) {
-  case DescriptorRangeFlags::DescriptorsVolatile:
-    OS << "DescriptorsVolatile";
-    break;
-  case DescriptorRangeFlags::DataVolatile:
-    OS << "DataVolatile";
-    break;
-  case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
-    OS << "DataStaticWhileSetAtExecute";
-    break;
-  case DescriptorRangeFlags::DataStatic:
-    OS << "DataStatic";
-    break;
-  case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
-    OS << "DescriptorsStaticKeepingBufferBoundsChecks";
-    break;
-  default:
-    OS << "invalid: " << Bit;
-    break;
-  }
+  return OS;
 }
 
-static void dumpDescriptorRangeFlags(raw_ostream &OS,
-                                     DescriptorRangeFlags Flags) {
+static raw_ostream &operator<<(raw_ostream &OS,
+                               const DescriptorRangeFlags &Flags) {
   bool FlagSet = false;
   unsigned Remaining = llvm::to_underlying(Flags);
   while (Remaining) {
@@ -124,19 +101,41 @@ static void dumpDescriptorRangeFlags(raw_ostream &OS,
     if (Remaining & Bit) {
       if (FlagSet)
         OS << " | ";
-      dumpDescriptorRangeFlag(OS, Bit);
+
+      switch (static_cast<DescriptorRangeFlags>(Bit)) {
+      case DescriptorRangeFlags::DescriptorsVolatile:
+        OS << "DescriptorsVolatile";
+        break;
+      case DescriptorRangeFlags::DataVolatile:
+        OS << "DataVolatile";
+        break;
+      case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
+        OS << "DataStaticWhileSetAtExecute";
+        break;
+      case DescriptorRangeFlags::DataStatic:
+        OS << "DataStatic";
+        break;
+      case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
+        OS << "DescriptorsStaticKeepingBufferBoundsChecks";
+        break;
+      default:
+        OS << "invalid: " << Bit;
+        break;
+      }
+
       FlagSet = true;
     }
     Remaining &= ~Bit;
   }
+
   if (!FlagSet)
     OS << "None";
+
+  return OS;
 }
 
 void DescriptorTableClause::dump(raw_ostream &OS) const {
-  dumpClauseType(OS, Type);
-  OS << "(";
-  Reg.dump(OS);
+  OS << Type << "(" << Reg;
   OS << ", numDescriptors = " << NumDescriptors;
   OS << ", space = " << Space;
   OS << ", offset = ";
@@ -144,9 +143,7 @@ void DescriptorTableClause::dump(raw_ostream &OS) const {
     OS << "DescriptorTableOffsetAppend";
   else
     OS << Offset;
-  OS << ", flags = ";
-  dumpDescriptorRangeFlags(OS, Flags);
-  OS << ")";
+  OS << ", flags = " << Flags << ")";
 }
 
 } // namespace rootsig



More information about the llvm-commits mailing list