llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: rj123-nv

<details>
<summary>Changes</summary>

For global, non-static instances of a struct containing resources, we end up 
splitting these recursively into separate global variables for each resource, 
and for numeric members these go into the default $globals cbuffer.

For this change, when there's a instance of a struct (or array of) containing 
only resources, skip emitting a global variable for the struct. Before, it 
would emit external linkage globals of these which would not get removed.

based on 
https://github.com/llvm/wg-hlsl/blob/main/proposals/0038-resources-in-structs.md

improves #<!-- -->194435

assisted by: codex

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


4 Files Affected:

- (modified) clang/include/clang/AST/HLSLResource.h (+5) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+9-2) 
- (modified) clang/lib/Sema/SemaHLSL.cpp (+2-3) 
- (added) clang/test/CodeGenHLSL/resources/resources-in-structs-no-global.hlsl 
(+24) 


``````````diff
diff --git a/clang/include/clang/AST/HLSLResource.h 
b/clang/include/clang/AST/HLSLResource.h
index f3d24de5acadc..f9caa8a2092e4 100644
--- a/clang/include/clang/AST/HLSLResource.h
+++ b/clang/include/clang/AST/HLSLResource.h
@@ -166,6 +166,11 @@ class EmbeddedResourceNameBuilder {
   void pushName(llvm::StringRef N, llvm::StringRef Delim);
 };
 
+inline bool isStructOrArrayOfWithResources(QualType Ty) {
+  return Ty->isHLSLIntangibleType() && !Ty->isHLSLResourceRecord() &&
+         !Ty->isHLSLResourceRecordArray();
+}
+
 } // namespace hlsl
 
 } // namespace clang
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index eec4d9e714abe..7573da8476d03 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -35,6 +35,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/HLSLResource.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
@@ -6537,10 +6538,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const 
VarDecl *D,
 
   // TODO(Reflection): add support for consteval-only types.
 
-  // HLSL default buffer constants will be emitted during HLSLBufferDecl 
codegen
+  // HLSL default buffer constants will be emitted during HLSLBufferDecl 
codegen.
+  // Also skip emitting globals for structs or arrays of structs containing 
only
+  // resource constants, which should have already been flattened into separate
+  // variables.
   if (getLangOpts().HLSL &&
-      D->getType().getAddressSpace() == LangAS::hlsl_constant)
+      (ASTTy.getAddressSpace() == LangAS::hlsl_constant ||
+       (D->getStorageClass() != SC_Static &&
+        hlsl::isStructOrArrayOfWithResources(ASTTy)))) {
     return;
+  }
 
   // If this is OpenMP device, check if it is legal to emit this global
   // normally.
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 87fe8ee53235a..e16ba36d6d652 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -6290,9 +6290,8 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
     }
 
     // Process resources in user-defined structs, or arrays of such structs.
-    const Type *VDTy = VD->getType().getTypePtr();
-    if (VD->getStorageClass() != SC_Static && VDTy->isHLSLIntangibleType() &&
-        !isResourceRecordTypeOrArrayOf(VD))
+    if (VD->getStorageClass() != SC_Static &&
+        isStructOrArrayOfWithResources(VD->getType()))
       handleGlobalStructOrArrayOfWithResources(VD);
 
     // Mark groupshared variables as extern so they will have
diff --git 
a/clang/test/CodeGenHLSL/resources/resources-in-structs-no-global.hlsl 
b/clang/test/CodeGenHLSL/resources/resources-in-structs-no-global.hlsl
new file mode 100644
index 0000000000000..9574d6d7a8e60
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/resources-in-structs-no-global.hlsl
@@ -0,0 +1,24 @@
+// When processing a struct containing resources, we should split members 
recursively into
+// their own global variables, and not emit a global of struct or array of
+// struct type which contains a resource
+
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --implicit-check-not='@g =' 
--implicit-check-not='@array ='
+// RUN: %clang_cc1 -triple spirv1.6-unknown-vulkan1.3-compute -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --implicit-check-not='@g =' 
--implicit-check-not='@array ='
+// RUN: %if spirv-registered-target && spirv-val %{ %clang_cc1 -triple 
spirv1.6-unknown-vulkan1.3-compute -O3 -emit-obj -o %t.spv %s && spirv-val 
--target-env vulkan1.3 %t.spv %}
+
+// CHECK: @_ZL5g.Buf = internal global
+// CHECK: @_ZL11array.0.Buf = internal global
+// CHECK: @_ZL11array.1.Buf = internal global
+
+struct A {
+  RWBuffer<float> Buf;
+};
+A g;
+A array[2];
+
+[numthreads(1, 1, 1)]
+void main() {
+  g.Buf[0] = 1.0f;
+  array[0].Buf[0] = 2.0f;
+  array[1].Buf[0] = 3.0f;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/234797
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to