Skip to content

[HLSL] Move Resource Instance Properties from TypeInfo #135259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 14, 2025

Conversation

V-FEXrt
Copy link
Contributor

@V-FEXrt V-FEXrt commented Apr 10, 2025

Fixes #134741

Moves Resource Instance properties from type info into resource info as described in https://github.com/llvm/wg-hlsl/blob/main/proposals/0022-resource-instance-analysis.md

@llvmbot
Copy link
Member

llvmbot commented Apr 10, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Ashley Coleman (V-FEXrt)

Changes

Fixes #134741

Moves Resource Instance properties from type info into resource info as described in https://github.com/llvm/wg-hlsl/blob/main/proposals/0022-resource-instance-analysis.md


Full diff: https://github.com/llvm/llvm-project/pull/135259.diff

6 Files Affected:

  • (modified) llvm/include/llvm/Analysis/DXILResource.h (+14-27)
  • (modified) llvm/lib/Analysis/DXILResource.cpp (+13-15)
  • (modified) llvm/lib/Target/DirectX/DXContainerGlobals.cpp (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp (+2-2)
  • (modified) llvm/test/Analysis/DXILResource/buffer-frombinding.ll (+15-15)
  • (modified) llvm/unittests/Analysis/DXILResourceTest.cpp (+21-21)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index ff7961c9ad51c..6ff4e2fb56006 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -222,19 +222,11 @@ class LayoutExtType : public TargetExtType {
 class ResourceTypeInfo {
 public:
   struct UAVInfo {
-    bool GloballyCoherent;
-    bool HasCounter;
     bool IsROV;
 
-    bool operator==(const UAVInfo &RHS) const {
-      return std::tie(GloballyCoherent, HasCounter, IsROV) ==
-             std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
-    }
+    bool operator==(const UAVInfo &RHS) const { return IsROV == RHS.IsROV; }
     bool operator!=(const UAVInfo &RHS) const { return !(*this == RHS); }
-    bool operator<(const UAVInfo &RHS) const {
-      return std::tie(GloballyCoherent, HasCounter, IsROV) <
-             std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
-    }
+    bool operator<(const UAVInfo &RHS) const { return IsROV < RHS.IsROV; }
   };
 
   struct StructInfo {
@@ -272,23 +264,14 @@ class ResourceTypeInfo {
 private:
   TargetExtType *HandleTy;
 
-  // GloballyCoherent and HasCounter aren't really part of the type and need to
-  // be determined by analysis, so they're just provided directly by the
-  // DXILResourceTypeMap when we construct these.
-  bool GloballyCoherent;
-  bool HasCounter;
-
   dxil::ResourceClass RC;
   dxil::ResourceKind Kind;
 
 public:
   ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC,
-                   const dxil::ResourceKind Kind, bool GloballyCoherent = false,
-                   bool HasCounter = false);
-  ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false,
-                   bool HasCounter = false)
-      : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
-                         GloballyCoherent, HasCounter) {}
+                   const dxil::ResourceKind Kind);
+  ResourceTypeInfo(TargetExtType *HandleTy)
+      : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
 
   TargetExtType *getHandleTy() const { return HandleTy; }
   StructType *createElementStruct();
@@ -314,9 +297,6 @@ class ResourceTypeInfo {
   dxil::ResourceClass getResourceClass() const { return RC; }
   dxil::ResourceKind getResourceKind() const { return Kind; }
 
-  void setGloballyCoherent(bool V) { GloballyCoherent = V; }
-  void setHasCounter(bool V) { HasCounter = V; }
-
   bool operator==(const ResourceTypeInfo &RHS) const;
   bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
   bool operator<(const ResourceTypeInfo &RHS) const;
@@ -353,13 +333,20 @@ class ResourceInfo {
   GlobalVariable *Symbol = nullptr;
 
 public:
+  bool GloballyCoherent;
+  bool HasCounter;
+
   ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
                uint32_t Size, TargetExtType *HandleTy,
-               GlobalVariable *Symbol = nullptr)
+               GlobalVariable *Symbol = nullptr, bool GloballyCoherent = false,
+               bool HasCounter = false)
       : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy),
-        Symbol(Symbol) {}
+        Symbol(Symbol), GloballyCoherent(GloballyCoherent),
+        HasCounter(HasCounter) {}
 
   void setBindingID(unsigned ID) { Binding.RecordID = ID; }
+  void setGloballyCoherent(bool V) { GloballyCoherent = V; }
+  void setHasCounter(bool V) { HasCounter = V; }
 
   const ResourceBinding &getBinding() const { return Binding; }
   TargetExtType *getHandleTy() const { return HandleTy; }
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index b4bd43206b6e4..d4f0127a931dc 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -179,10 +179,8 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) {
 
 ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
                                    const dxil::ResourceClass RC_,
-                                   const dxil::ResourceKind Kind_,
-                                   bool GloballyCoherent, bool HasCounter)
-    : HandleTy(HandleTy), GloballyCoherent(GloballyCoherent),
-      HasCounter(HasCounter) {
+                                   const dxil::ResourceKind Kind_)
+    : HandleTy(HandleTy) {
   // If we're provided a resource class and kind, trust them.
   if (Kind_ != dxil::ResourceKind::Invalid) {
     RC = RC_;
@@ -377,7 +375,7 @@ static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty) {
 
 ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const {
   assert(isUAV() && "Not a UAV");
-  return {GloballyCoherent, HasCounter, isROV(Kind, HandleTy)};
+  return {isROV(Kind, HandleTy)};
 }
 
 uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const {
@@ -469,8 +467,7 @@ uint32_t ResourceTypeInfo::getMultiSampleCount() const {
 }
 
 bool ResourceTypeInfo::operator==(const ResourceTypeInfo &RHS) const {
-  return std::tie(HandleTy, GloballyCoherent, HasCounter) ==
-         std::tie(RHS.HandleTy, RHS.GloballyCoherent, RHS.HasCounter);
+  return std::tie(HandleTy) == std::tie(RHS.HandleTy);
 }
 
 bool ResourceTypeInfo::operator<(const ResourceTypeInfo &RHS) const {
@@ -510,9 +507,7 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const {
   } else {
     if (isUAV()) {
       UAVInfo UAVFlags = getUAV();
-      OS << "  Globally Coherent: " << UAVFlags.GloballyCoherent << "\n"
-         << "  HasCounter: " << UAVFlags.HasCounter << "\n"
-         << "  IsROV: " << UAVFlags.IsROV << "\n";
+      OS << "  IsROV: " << UAVFlags.IsROV << "\n";
     }
     if (isMultiSample())
       OS << "  Sample Count: " << getMultiSampleCount() << "\n";
@@ -577,8 +572,8 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
 
     if (RTI.isUAV()) {
       ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV();
-      MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
-      MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
+      MDVals.push_back(getBoolMD(GloballyCoherent));
+      MDVals.push_back(getBoolMD(HasCounter));
       MDVals.push_back(getBoolMD(UAVFlags.IsROV));
     } else {
       // All SRVs include sample count in the metadata, but it's only meaningful
@@ -619,10 +614,10 @@ ResourceInfo::getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const {
   ResourceTypeInfo::UAVInfo UAVFlags =
       IsUAV ? RTI.getUAV() : ResourceTypeInfo::UAVInfo{};
   bool IsROV = IsUAV && UAVFlags.IsROV;
-  bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
+  bool IsGloballyCoherent = IsUAV && GloballyCoherent;
   uint8_t SamplerCmpOrHasCounter = 0;
   if (IsUAV)
-    SamplerCmpOrHasCounter = UAVFlags.HasCounter;
+    SamplerCmpOrHasCounter = HasCounter;
   else if (RTI.isSampler())
     SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison;
 
@@ -671,6 +666,9 @@ void ResourceInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI,
      << "    Lower Bound: " << Binding.LowerBound << "\n"
      << "    Size: " << Binding.Size << "\n";
 
+  OS << "  Globally Coherent: " << GloballyCoherent << "\n";
+  OS << "  HasCounter: " << HasCounter << "\n";
+
   RTI.print(OS, DL);
 }
 
@@ -767,7 +765,7 @@ void DXILResourceMap::populate(Module &M, DXILResourceTypeMap &DRTM) {
 void DXILResourceMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
                             const DataLayout &DL) const {
   for (unsigned I = 0, E = Infos.size(); I != E; ++I) {
-    OS << "Binding " << I << ":\n";
+    OS << "Resource " << I << ":\n";
     const dxil::ResourceInfo &RI = Infos[I];
     RI.print(OS, DRTM[RI.getHandleTy()], DL);
     OS << "\n";
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 27451074581ee..9576dd4a5e27b 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -229,7 +229,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
 
     dxil::ResourceTypeInfo &TypeInfo = DRTM[RI.getHandleTy()];
     dxbc::PSV::ResourceType ResType;
-    if (TypeInfo.getUAV().HasCounter)
+    if (RI.HasCounter)
       ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
     else if (TypeInfo.isStruct())
       ResType = dxbc::PSV::ResourceType::UAVStructured;
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 88e23479cba2a..095e79832f39f 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -155,8 +155,8 @@ struct FormatResourceDimension
     case dxil::ResourceKind::StructuredBuffer:
       if (!Item.isUAV())
         OS << "r/o";
-      else if (Item.getUAV().HasCounter)
-        OS << "r/w+cnt";
+      //      else if (Item.getUAV().HasCounter)
+      //        OS << "r/w+cnt";
       else
         OS << "r/w";
       break;
diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index 9b4d7722b72ac..b8f092ab4e514 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -7,7 +7,7 @@ define void @test_typedbuffer() {
   %srv0 = call target("dx.RawBuffer", void, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
           i32 1, i32 8, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[SRV0:[0-9]+]]:
+  ; CHECK: Resource [[SRV0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 1
@@ -21,7 +21,7 @@ define void @test_typedbuffer() {
   %srv1 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
           i32 4, i32 2, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[SRV1:[0-9]+]]:
+  ; CHECK: Resource [[SRV1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 4
@@ -36,7 +36,7 @@ define void @test_typedbuffer() {
   %srv2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_0_0t(
           i32 5, i32 3, i32 24, i32 0, i1 false)
-  ; CHECK: Binding [[SRV2:[0-9]+]]:
+  ; CHECK: Resource [[SRV2:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 2
   ; CHECK:     Space: 5
@@ -51,16 +51,16 @@ define void @test_typedbuffer() {
   %uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
       @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0t(
           i32 2, i32 7, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[UAV0:[0-9]+]]:
+  ; CHECK: Resource [[UAV0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 2
   ; CHECK:     Lower Bound: 7
   ; CHECK:     Size: 1
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: i32
   ; CHECK:   Element Count: 1
@@ -69,16 +69,16 @@ define void @test_typedbuffer() {
   %uav1 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
               @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
                   i32 3, i32 5, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[UAV1:[0-9]+]]:
+  ; CHECK: Resource [[UAV1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 3
   ; CHECK:     Lower Bound: 5
   ; CHECK:     Size: 1
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
@@ -92,23 +92,23 @@ define void @test_typedbuffer() {
   %uav2_2 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
               @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
                   i32 4, i32 0, i32 10, i32 5, i1 false)
-  ; CHECK: Binding [[UAV2:[0-9]+]]:
+  ; CHECK: Resource [[UAV2:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 2
   ; CHECK:     Space: 4
   ; CHECK:     Lower Bound: 0
   ; CHECK:     Size: 10
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
 
   %cb0 = call target("dx.CBuffer", {float})
       @llvm.dx.resource.handlefrombinding(i32 1, i32 0, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[CB0:[0-9]+]]:
+  ; CHECK: Resource [[CB0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 1
@@ -120,7 +120,7 @@ define void @test_typedbuffer() {
 
   %cb1 = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
       @llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[CB1:[0-9]+]]:
+  ; CHECK: Resource [[CB1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 1
@@ -130,7 +130,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Kind: CBuffer
   ; CHECK:   CBuffer size: 4
 
-  ; CHECK-NOT: Binding {{[0-9]+}}:
+  ; CHECK-NOT: Resource {{[0-9]+}}:
 
   ret void
 }
diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp
index 6f25983801fc3..3a7c7ab6efd92 100644
--- a/llvm/unittests/Analysis/DXILResourceTest.cpp
+++ b/llvm/unittests/Analysis/DXILResourceTest.cpp
@@ -114,8 +114,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     ResourceTypeInfo RTI(llvm::TargetExtType::get(
         Context, "dx.RawBuffer", Int8Ty, {/*IsWriteable=*/1, /*IsROV=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     EXPECT_EQ(RTI.getResourceKind(), ResourceKind::RawBuffer);
 
@@ -128,6 +126,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(1, GV, "BufferOut", 2, 3, 1, 11, false, false, false,
                            nullptr));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // struct BufType0 { int i; float f; double d; };
@@ -268,27 +268,28 @@ TEST(DXILResource, AnnotationsAndMetadata) {
   // globallycoherent RWTexture2D<int2> OutputTexture : register(u0, space2);
   {
     ResourceTypeInfo RTI(llvm::TargetExtType::get(
-                             Context, "dx.Texture", Int32x2Ty,
-                             {/*IsWriteable=*/1,
-                              /*IsROV=*/0, /*IsSigned=*/1,
-                              llvm::to_underlying(ResourceKind::Texture2D)}),
-                         /*GloballyCoherent=*/true, /*HasCounter=*/false);
+        Context, "dx.Texture", Int32x2Ty,
+        {/*IsWriteable=*/1,
+         /*IsROV=*/0, /*IsSigned=*/1,
+         llvm::to_underlying(ResourceKind::Texture2D)}));
 
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, true);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2D);
 
     ResourceInfo RI(
         /*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1,
-        RTI.getHandleTy());
+        RTI.getHandleTy(),
+        /*Symbol=*/nullptr, /*GloballyCoherent=*/true, /*HasCounter=*/false);
     GlobalVariable *GV =
         RI.createSymbol(M, RTI.createElementStruct(), "OutputTexture");
     EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x00005002U, 0x00000204U);
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "OutputTexture", 2, 0, 1, 2, true, false,
                            false, TestMD.get(0, 4)));
+
+    EXPECT_EQ(RI.GloballyCoherent, true);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // RasterizerOrderedBuffer<float4> ROB;
@@ -297,8 +298,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
         Context, "dx.TypedBuffer", Floatx4Ty,
         {/*IsWriteable=*/1, /*IsROV=*/1, /*IsSigned=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, true);
     ASSERT_EQ(RTI.isTyped(), true);
     EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32);
@@ -313,19 +312,17 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "ROB", 0, 0, 1, 10, false, false, true,
                            TestMD.get(0, 9)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // RWStructuredBuffer<ParticleMotion> g_OutputBuffer : register(u2);
   {
     StructType *BufType1 = StructType::create(
         Context, {Floatx3Ty, FloatTy, Int32Ty}, "ParticleMotion");
-    ResourceTypeInfo RTI(
-        llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType1,
-                                 {/*IsWriteable=*/1, /*IsROV=*/0}),
-        /*GloballyCoherent=*/false, /*HasCounter=*/true);
+    ResourceTypeInfo RTI(llvm::TargetExtType::get(
+        Context, "dx.RawBuffer", BufType1, {/*IsWriteable=*/1, /*IsROV=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, true);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     ASSERT_EQ(RTI.isStruct(), true);
     EXPECT_EQ(RTI.getStruct(DL).Stride, 20u);
@@ -334,13 +331,16 @@ TEST(DXILResource, AnnotationsAndMetadata) {
 
     ResourceInfo RI(
         /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1,
-        RTI.getHandleTy());
+        RTI.getHandleTy(),
+        /*Symbol=*/nullptr, /*GloballyCoherent=*/false, /*HasCounter=*/true);
     GlobalVariable *GV =
         RI.createSymbol(M, RTI.createElementStruct(), "g_OutputBuffer");
     EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x0000920cU, 0x00000014U);
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "g_OutputBuffer", 0, 2, 1, 12, false, true,
                            false, TestMD.get(1, 20)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, true);
   }
 
   // RWTexture2DMSArray<uint, 8> g_rw_t2dmsa;
@@ -350,8 +350,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
         {/*IsWriteable=*/1, /*SampleCount=*/8, /*IsSigned=*/0,
          llvm::to_underlying(ResourceKind::Texture2DMSArray)}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     ASSERT_EQ(RTI.isTyped(), true);
     EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::U32);
@@ -369,6 +367,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "g_rw_t2dmsa", 0, 0, 1, 8, false, false,
                            false, TestMD.get(0, 5)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // cbuffer cb0 { float4 g_X; float4 g_Y; }

@llvmbot
Copy link
Member

llvmbot commented Apr 10, 2025

@llvm/pr-subscribers-backend-directx

Author: Ashley Coleman (V-FEXrt)

Changes

Fixes #134741

Moves Resource Instance properties from type info into resource info as described in https://github.com/llvm/wg-hlsl/blob/main/proposals/0022-resource-instance-analysis.md


Full diff: https://github.com/llvm/llvm-project/pull/135259.diff

6 Files Affected:

  • (modified) llvm/include/llvm/Analysis/DXILResource.h (+14-27)
  • (modified) llvm/lib/Analysis/DXILResource.cpp (+13-15)
  • (modified) llvm/lib/Target/DirectX/DXContainerGlobals.cpp (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp (+2-2)
  • (modified) llvm/test/Analysis/DXILResource/buffer-frombinding.ll (+15-15)
  • (modified) llvm/unittests/Analysis/DXILResourceTest.cpp (+21-21)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index ff7961c9ad51c..6ff4e2fb56006 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -222,19 +222,11 @@ class LayoutExtType : public TargetExtType {
 class ResourceTypeInfo {
 public:
   struct UAVInfo {
-    bool GloballyCoherent;
-    bool HasCounter;
     bool IsROV;
 
-    bool operator==(const UAVInfo &RHS) const {
-      return std::tie(GloballyCoherent, HasCounter, IsROV) ==
-             std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
-    }
+    bool operator==(const UAVInfo &RHS) const { return IsROV == RHS.IsROV; }
     bool operator!=(const UAVInfo &RHS) const { return !(*this == RHS); }
-    bool operator<(const UAVInfo &RHS) const {
-      return std::tie(GloballyCoherent, HasCounter, IsROV) <
-             std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
-    }
+    bool operator<(const UAVInfo &RHS) const { return IsROV < RHS.IsROV; }
   };
 
   struct StructInfo {
@@ -272,23 +264,14 @@ class ResourceTypeInfo {
 private:
   TargetExtType *HandleTy;
 
-  // GloballyCoherent and HasCounter aren't really part of the type and need to
-  // be determined by analysis, so they're just provided directly by the
-  // DXILResourceTypeMap when we construct these.
-  bool GloballyCoherent;
-  bool HasCounter;
-
   dxil::ResourceClass RC;
   dxil::ResourceKind Kind;
 
 public:
   ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC,
-                   const dxil::ResourceKind Kind, bool GloballyCoherent = false,
-                   bool HasCounter = false);
-  ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false,
-                   bool HasCounter = false)
-      : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
-                         GloballyCoherent, HasCounter) {}
+                   const dxil::ResourceKind Kind);
+  ResourceTypeInfo(TargetExtType *HandleTy)
+      : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
 
   TargetExtType *getHandleTy() const { return HandleTy; }
   StructType *createElementStruct();
@@ -314,9 +297,6 @@ class ResourceTypeInfo {
   dxil::ResourceClass getResourceClass() const { return RC; }
   dxil::ResourceKind getResourceKind() const { return Kind; }
 
-  void setGloballyCoherent(bool V) { GloballyCoherent = V; }
-  void setHasCounter(bool V) { HasCounter = V; }
-
   bool operator==(const ResourceTypeInfo &RHS) const;
   bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
   bool operator<(const ResourceTypeInfo &RHS) const;
@@ -353,13 +333,20 @@ class ResourceInfo {
   GlobalVariable *Symbol = nullptr;
 
 public:
+  bool GloballyCoherent;
+  bool HasCounter;
+
   ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
                uint32_t Size, TargetExtType *HandleTy,
-               GlobalVariable *Symbol = nullptr)
+               GlobalVariable *Symbol = nullptr, bool GloballyCoherent = false,
+               bool HasCounter = false)
       : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy),
-        Symbol(Symbol) {}
+        Symbol(Symbol), GloballyCoherent(GloballyCoherent),
+        HasCounter(HasCounter) {}
 
   void setBindingID(unsigned ID) { Binding.RecordID = ID; }
+  void setGloballyCoherent(bool V) { GloballyCoherent = V; }
+  void setHasCounter(bool V) { HasCounter = V; }
 
   const ResourceBinding &getBinding() const { return Binding; }
   TargetExtType *getHandleTy() const { return HandleTy; }
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index b4bd43206b6e4..d4f0127a931dc 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -179,10 +179,8 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) {
 
 ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
                                    const dxil::ResourceClass RC_,
-                                   const dxil::ResourceKind Kind_,
-                                   bool GloballyCoherent, bool HasCounter)
-    : HandleTy(HandleTy), GloballyCoherent(GloballyCoherent),
-      HasCounter(HasCounter) {
+                                   const dxil::ResourceKind Kind_)
+    : HandleTy(HandleTy) {
   // If we're provided a resource class and kind, trust them.
   if (Kind_ != dxil::ResourceKind::Invalid) {
     RC = RC_;
@@ -377,7 +375,7 @@ static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty) {
 
 ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const {
   assert(isUAV() && "Not a UAV");
-  return {GloballyCoherent, HasCounter, isROV(Kind, HandleTy)};
+  return {isROV(Kind, HandleTy)};
 }
 
 uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const {
@@ -469,8 +467,7 @@ uint32_t ResourceTypeInfo::getMultiSampleCount() const {
 }
 
 bool ResourceTypeInfo::operator==(const ResourceTypeInfo &RHS) const {
-  return std::tie(HandleTy, GloballyCoherent, HasCounter) ==
-         std::tie(RHS.HandleTy, RHS.GloballyCoherent, RHS.HasCounter);
+  return std::tie(HandleTy) == std::tie(RHS.HandleTy);
 }
 
 bool ResourceTypeInfo::operator<(const ResourceTypeInfo &RHS) const {
@@ -510,9 +507,7 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const {
   } else {
     if (isUAV()) {
       UAVInfo UAVFlags = getUAV();
-      OS << "  Globally Coherent: " << UAVFlags.GloballyCoherent << "\n"
-         << "  HasCounter: " << UAVFlags.HasCounter << "\n"
-         << "  IsROV: " << UAVFlags.IsROV << "\n";
+      OS << "  IsROV: " << UAVFlags.IsROV << "\n";
     }
     if (isMultiSample())
       OS << "  Sample Count: " << getMultiSampleCount() << "\n";
@@ -577,8 +572,8 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
 
     if (RTI.isUAV()) {
       ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV();
-      MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
-      MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
+      MDVals.push_back(getBoolMD(GloballyCoherent));
+      MDVals.push_back(getBoolMD(HasCounter));
       MDVals.push_back(getBoolMD(UAVFlags.IsROV));
     } else {
       // All SRVs include sample count in the metadata, but it's only meaningful
@@ -619,10 +614,10 @@ ResourceInfo::getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const {
   ResourceTypeInfo::UAVInfo UAVFlags =
       IsUAV ? RTI.getUAV() : ResourceTypeInfo::UAVInfo{};
   bool IsROV = IsUAV && UAVFlags.IsROV;
-  bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
+  bool IsGloballyCoherent = IsUAV && GloballyCoherent;
   uint8_t SamplerCmpOrHasCounter = 0;
   if (IsUAV)
-    SamplerCmpOrHasCounter = UAVFlags.HasCounter;
+    SamplerCmpOrHasCounter = HasCounter;
   else if (RTI.isSampler())
     SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison;
 
@@ -671,6 +666,9 @@ void ResourceInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI,
      << "    Lower Bound: " << Binding.LowerBound << "\n"
      << "    Size: " << Binding.Size << "\n";
 
+  OS << "  Globally Coherent: " << GloballyCoherent << "\n";
+  OS << "  HasCounter: " << HasCounter << "\n";
+
   RTI.print(OS, DL);
 }
 
@@ -767,7 +765,7 @@ void DXILResourceMap::populate(Module &M, DXILResourceTypeMap &DRTM) {
 void DXILResourceMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
                             const DataLayout &DL) const {
   for (unsigned I = 0, E = Infos.size(); I != E; ++I) {
-    OS << "Binding " << I << ":\n";
+    OS << "Resource " << I << ":\n";
     const dxil::ResourceInfo &RI = Infos[I];
     RI.print(OS, DRTM[RI.getHandleTy()], DL);
     OS << "\n";
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 27451074581ee..9576dd4a5e27b 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -229,7 +229,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
 
     dxil::ResourceTypeInfo &TypeInfo = DRTM[RI.getHandleTy()];
     dxbc::PSV::ResourceType ResType;
-    if (TypeInfo.getUAV().HasCounter)
+    if (RI.HasCounter)
       ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
     else if (TypeInfo.isStruct())
       ResType = dxbc::PSV::ResourceType::UAVStructured;
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 88e23479cba2a..095e79832f39f 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -155,8 +155,8 @@ struct FormatResourceDimension
     case dxil::ResourceKind::StructuredBuffer:
       if (!Item.isUAV())
         OS << "r/o";
-      else if (Item.getUAV().HasCounter)
-        OS << "r/w+cnt";
+      //      else if (Item.getUAV().HasCounter)
+      //        OS << "r/w+cnt";
       else
         OS << "r/w";
       break;
diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index 9b4d7722b72ac..b8f092ab4e514 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -7,7 +7,7 @@ define void @test_typedbuffer() {
   %srv0 = call target("dx.RawBuffer", void, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
           i32 1, i32 8, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[SRV0:[0-9]+]]:
+  ; CHECK: Resource [[SRV0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 1
@@ -21,7 +21,7 @@ define void @test_typedbuffer() {
   %srv1 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
           i32 4, i32 2, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[SRV1:[0-9]+]]:
+  ; CHECK: Resource [[SRV1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 4
@@ -36,7 +36,7 @@ define void @test_typedbuffer() {
   %srv2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
       @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_0_0t(
           i32 5, i32 3, i32 24, i32 0, i1 false)
-  ; CHECK: Binding [[SRV2:[0-9]+]]:
+  ; CHECK: Resource [[SRV2:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 2
   ; CHECK:     Space: 5
@@ -51,16 +51,16 @@ define void @test_typedbuffer() {
   %uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
       @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0t(
           i32 2, i32 7, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[UAV0:[0-9]+]]:
+  ; CHECK: Resource [[UAV0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 2
   ; CHECK:     Lower Bound: 7
   ; CHECK:     Size: 1
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: i32
   ; CHECK:   Element Count: 1
@@ -69,16 +69,16 @@ define void @test_typedbuffer() {
   %uav1 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
               @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
                   i32 3, i32 5, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[UAV1:[0-9]+]]:
+  ; CHECK: Resource [[UAV1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 3
   ; CHECK:     Lower Bound: 5
   ; CHECK:     Size: 1
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
@@ -92,23 +92,23 @@ define void @test_typedbuffer() {
   %uav2_2 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
               @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
                   i32 4, i32 0, i32 10, i32 5, i1 false)
-  ; CHECK: Binding [[UAV2:[0-9]+]]:
+  ; CHECK: Resource [[UAV2:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 2
   ; CHECK:     Space: 4
   ; CHECK:     Lower Bound: 0
   ; CHECK:     Size: 10
-  ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   HasCounter: 0
+  ; CHECK:   Class: UAV
+  ; CHECK:   Kind: TypedBuffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
 
   %cb0 = call target("dx.CBuffer", {float})
       @llvm.dx.resource.handlefrombinding(i32 1, i32 0, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[CB0:[0-9]+]]:
+  ; CHECK: Resource [[CB0:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 0
   ; CHECK:     Space: 1
@@ -120,7 +120,7 @@ define void @test_typedbuffer() {
 
   %cb1 = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
       @llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false)
-  ; CHECK: Binding [[CB1:[0-9]+]]:
+  ; CHECK: Resource [[CB1:[0-9]+]]:
   ; CHECK:   Binding:
   ; CHECK:     Record ID: 1
   ; CHECK:     Space: 1
@@ -130,7 +130,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Kind: CBuffer
   ; CHECK:   CBuffer size: 4
 
-  ; CHECK-NOT: Binding {{[0-9]+}}:
+  ; CHECK-NOT: Resource {{[0-9]+}}:
 
   ret void
 }
diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp
index 6f25983801fc3..3a7c7ab6efd92 100644
--- a/llvm/unittests/Analysis/DXILResourceTest.cpp
+++ b/llvm/unittests/Analysis/DXILResourceTest.cpp
@@ -114,8 +114,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     ResourceTypeInfo RTI(llvm::TargetExtType::get(
         Context, "dx.RawBuffer", Int8Ty, {/*IsWriteable=*/1, /*IsROV=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     EXPECT_EQ(RTI.getResourceKind(), ResourceKind::RawBuffer);
 
@@ -128,6 +126,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(1, GV, "BufferOut", 2, 3, 1, 11, false, false, false,
                            nullptr));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // struct BufType0 { int i; float f; double d; };
@@ -268,27 +268,28 @@ TEST(DXILResource, AnnotationsAndMetadata) {
   // globallycoherent RWTexture2D<int2> OutputTexture : register(u0, space2);
   {
     ResourceTypeInfo RTI(llvm::TargetExtType::get(
-                             Context, "dx.Texture", Int32x2Ty,
-                             {/*IsWriteable=*/1,
-                              /*IsROV=*/0, /*IsSigned=*/1,
-                              llvm::to_underlying(ResourceKind::Texture2D)}),
-                         /*GloballyCoherent=*/true, /*HasCounter=*/false);
+        Context, "dx.Texture", Int32x2Ty,
+        {/*IsWriteable=*/1,
+         /*IsROV=*/0, /*IsSigned=*/1,
+         llvm::to_underlying(ResourceKind::Texture2D)}));
 
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, true);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2D);
 
     ResourceInfo RI(
         /*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1,
-        RTI.getHandleTy());
+        RTI.getHandleTy(),
+        /*Symbol=*/nullptr, /*GloballyCoherent=*/true, /*HasCounter=*/false);
     GlobalVariable *GV =
         RI.createSymbol(M, RTI.createElementStruct(), "OutputTexture");
     EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x00005002U, 0x00000204U);
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "OutputTexture", 2, 0, 1, 2, true, false,
                            false, TestMD.get(0, 4)));
+
+    EXPECT_EQ(RI.GloballyCoherent, true);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // RasterizerOrderedBuffer<float4> ROB;
@@ -297,8 +298,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
         Context, "dx.TypedBuffer", Floatx4Ty,
         {/*IsWriteable=*/1, /*IsROV=*/1, /*IsSigned=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, true);
     ASSERT_EQ(RTI.isTyped(), true);
     EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32);
@@ -313,19 +312,17 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "ROB", 0, 0, 1, 10, false, false, true,
                            TestMD.get(0, 9)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // RWStructuredBuffer<ParticleMotion> g_OutputBuffer : register(u2);
   {
     StructType *BufType1 = StructType::create(
         Context, {Floatx3Ty, FloatTy, Int32Ty}, "ParticleMotion");
-    ResourceTypeInfo RTI(
-        llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType1,
-                                 {/*IsWriteable=*/1, /*IsROV=*/0}),
-        /*GloballyCoherent=*/false, /*HasCounter=*/true);
+    ResourceTypeInfo RTI(llvm::TargetExtType::get(
+        Context, "dx.RawBuffer", BufType1, {/*IsWriteable=*/1, /*IsROV=*/0}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, true);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     ASSERT_EQ(RTI.isStruct(), true);
     EXPECT_EQ(RTI.getStruct(DL).Stride, 20u);
@@ -334,13 +331,16 @@ TEST(DXILResource, AnnotationsAndMetadata) {
 
     ResourceInfo RI(
         /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1,
-        RTI.getHandleTy());
+        RTI.getHandleTy(),
+        /*Symbol=*/nullptr, /*GloballyCoherent=*/false, /*HasCounter=*/true);
     GlobalVariable *GV =
         RI.createSymbol(M, RTI.createElementStruct(), "g_OutputBuffer");
     EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x0000920cU, 0x00000014U);
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "g_OutputBuffer", 0, 2, 1, 12, false, true,
                            false, TestMD.get(1, 20)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, true);
   }
 
   // RWTexture2DMSArray<uint, 8> g_rw_t2dmsa;
@@ -350,8 +350,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
         {/*IsWriteable=*/1, /*SampleCount=*/8, /*IsSigned=*/0,
          llvm::to_underlying(ResourceKind::Texture2DMSArray)}));
     EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
-    EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
-    EXPECT_EQ(RTI.getUAV().HasCounter, false);
     EXPECT_EQ(RTI.getUAV().IsROV, false);
     ASSERT_EQ(RTI.isTyped(), true);
     EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::U32);
@@ -369,6 +367,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
     EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
                 TestMD.get(0, GV, "g_rw_t2dmsa", 0, 0, 1, 8, false, false,
                            false, TestMD.get(0, 5)));
+    EXPECT_EQ(RI.GloballyCoherent, false);
+    EXPECT_EQ(RI.HasCounter, false);
   }
 
   // cbuffer cb0 { float4 g_X; float4 g_Y; }

Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just replace HasCounter with the CounterDirection. Or where you planning to do that in the follow-up PR?

@V-FEXrt
Copy link
Contributor Author

V-FEXrt commented Apr 11, 2025

Or where you planning to do that in the follow-up PR?

Yeah but I can do it here!

Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@V-FEXrt V-FEXrt changed the title [HLSL] Move Resouce Instance Properties from TypeInfo [HLSL] Move Resource Instance Properties from TypeInfo Apr 11, 2025
Comment on lines +343 to +344
bool GloballyCoherent = false;
ResourceCounterDirection CounterDirection = ResourceCounterDirection::Unknown;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised to see public member variables as well as setter functions for them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a preference for one vs the other? The members need to be read and written externally so I can make them private and add getters or just delete the setters.

FWIW the previous location for these members (I'm just moving them) had public+setters though I don't think the setters were used

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to defer to @llvm-beanz or @bogner here I think. I have opinions but I'm not sure they're aligned to LLVM's best practices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

picked the one with least churn so we can get the PR in. If someone comes along later to disagree, I'll happily create a new PR to swap them!

@V-FEXrt V-FEXrt merged commit b07fc0f into llvm:main Apr 14, 2025
11 of 12 checks passed
@V-FEXrt V-FEXrt deleted the 134741-move-properties branch April 14, 2025 19:41
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

[HLSL] Move HasCounter and GloballyCoherent from ResourceTypeInfo to ResourceInfo
5 participants