[clang] [llvm] [HLSL] Add list of exported functions as named metadata node `dx.exports` (PR #102275)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 7 00:41:27 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Helena Kotas (hekota)

<details>
<summary>Changes</summary>

Adds list of exported functions as named metadata node 'dx.exports`.

During CodeGen each exported functions is marked with an "hlsl.export" attribute. Based on these attributes the DXILTranslateMetadata pass will create a list of all export functions and will add it to the module under `dx.exports`.

This information will be then used by DXILFinalizeLinkage pass (coming soon) to determine which functions should have internal linkage in the final DXIL code. After this pass is completed the `dx.exports` metadata node will be removed.



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


8 Files Affected:

- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+8) 
- (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+1-1) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+7-3) 
- (modified) clang/test/CodeGenHLSL/export.hlsl (+6-4) 
- (modified) llvm/lib/Target/DirectX/DXILMetadata.cpp (+20) 
- (modified) llvm/lib/Target/DirectX/DXILMetadata.h (+1) 
- (modified) llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp (+1) 
- (added) llvm/test/CodeGen/DirectX/Metadata/exports.ll (+19) 


``````````diff
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index a2c3e76f77b7c..5e59b0f00ebd6 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -412,6 +412,14 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
   B.CreateRetVoid();
 }
 
+void CGHLSLRuntime::setHLSLFunctionAttributes(const FunctionDecl *FD,
+                                              llvm::Function *Fn) {
+  if (FD->isInExportDeclContext()) {
+    const StringRef ExportAttrKindStr = "hlsl.export";
+    Fn->addFnAttr(ExportAttrKindStr);
+  }
+}
+
 static void gatherFunctions(SmallVectorImpl<Function *> &Fns, llvm::Module &M,
                             bool CtorOrDtor) {
   const auto *GV =
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 527e73a0e21fc..590d388c456c4 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -124,7 +124,7 @@ class CGHLSLRuntime {
   void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn);
 
   void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
-  void setHLSLFunctionAttributes(llvm::Function *, const FunctionDecl *);
+  void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn);
 
 private:
   void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index af201554898f3..9e9dd6b9c8e17 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1223,9 +1223,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
   if (getLangOpts().OpenMP && CurCodeDecl)
     CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);
 
-  // Handle emitting HLSL entry functions.
-  if (D && D->hasAttr<HLSLShaderAttr>())
-    CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
+  if (FD && getLangOpts().HLSL) {
+    // Handle emitting HLSL entry functions.
+    if (FD->hasAttr<HLSLShaderAttr>()) {
+      CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
+    }
+    CGM.getHLSLRuntime().setHLSLFunctionAttributes(FD, Fn);
+  }
 
   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
 
diff --git a/clang/test/CodeGenHLSL/export.hlsl b/clang/test/CodeGenHLSL/export.hlsl
index 53f603739e329..63f9f9066f927 100644
--- a/clang/test/CodeGenHLSL/export.hlsl
+++ b/clang/test/CodeGenHLSL/export.hlsl
@@ -2,19 +2,21 @@
 // RUN:   dxil-pc-shadermodel6.3-library %s \
 // RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s
 
-// CHECK: define void @"?f1@@YAXXZ"()
+// CHECK: define void @"?f1@@YAXXZ"() [[Attr:\#[0-9]+]]
 export void f1() {
 }
 
-// CHECK: define void @"?f2 at MyNamespace@@YAXXZ"()
+// CHECK: define void @"?f2 at MyNamespace@@YAXXZ"() [[Attr]]
 namespace MyNamespace {
   export void f2() {
   }
 }
 
 export {
-// CHECK: define void @"?f3@@YAXXZ"()
-// CHECK: define void @"?f4@@YAXXZ"()    
+// CHECK: define void @"?f3@@YAXXZ"() [[Attr]]
+// CHECK: define void @"?f4@@YAXXZ"() [[Attr]]
     void f3() {}
     void f4() {}
 }
+
+// CHECK: attributes [[Attr]] = { {{.*}} "hlsl.export" {{.*}} }
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index ed0434ac98a18..5ec56a2852502 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -328,3 +328,23 @@ void dxil::createEntryMD(Module &M, const uint64_t ShaderFlags) {
   for (auto *Entry : Entries)
     EntryPointsNamedMD->addOperand(Entry);
 }
+
+void dxil::createExportsMD(Module &M) {
+  LLVMContext &Ctx = M.getContext();
+  std::vector<MDNode *> ExportsMDList;
+  for (auto &F : M.functions()) {
+    if (!F.hasFnAttribute("hlsl.export"))
+      continue;
+
+    Metadata *MDVals[2];
+    MDVals[0] = ValueAsMetadata::get(&F);
+    MDVals[1] = MDString::get(Ctx, F.getName());
+    ExportsMDList.emplace_back(MDNode::get(Ctx, MDVals));
+  }
+
+  if (ExportsMDList.size() != 0) {
+    NamedMDNode *ExportsNamedMD = M.getOrInsertNamedMetadata("dx.exports");
+    for (auto *ExpMD : ExportsMDList)
+      ExportsNamedMD->addOperand(ExpMD);
+  }
+}
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.h b/llvm/lib/Target/DirectX/DXILMetadata.h
index e05db8d5370db..cee05661c81ca 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.h
+++ b/llvm/lib/Target/DirectX/DXILMetadata.h
@@ -36,6 +36,7 @@ class ValidatorVersionMD {
 void createShaderModelMD(Module &M);
 void createDXILVersionMD(Module &M);
 void createEntryMD(Module &M, const uint64_t ShaderFlags);
+void createExportsMD(Module &M);
 
 } // namespace dxil
 } // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 583bce0f50e70..54eebac6a95d1 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -57,6 +57,7 @@ bool DXILTranslateMetadata::runOnModule(Module &M) {
   const uint64_t Flags = static_cast<uint64_t>(
       getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags());
   dxil::createEntryMD(M, Flags);
+  dxil::createExportsMD(M);
 
   return false;
 }
diff --git a/llvm/test/CodeGen/DirectX/Metadata/exports.ll b/llvm/test/CodeGen/DirectX/Metadata/exports.ll
new file mode 100644
index 0000000000000..4e84ddc4ce90c
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Metadata/exports.ll
@@ -0,0 +1,19 @@
+; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
+
+target triple = "dxilv1.3-unknown-shadermodel6.3-library"
+
+define void @"?f1@@YAXXZ"() #0 {
+entry:
+  ret void
+}
+
+define void @"?f2 at MyNamespace@@YAXXZ"() #0 {
+entry:
+  ret void
+}
+
+attributes #0 = { convergent noinline nounwind optnone "hlsl.export" }
+
+; CHECK: !dx.exports = !{[[Exp1:![0-9]+]], [[Exp2:![0-9]+]]}
+; CHECK: [[Exp1]] = !{ptr @"?f1@@YAXXZ", !"?f1@@YAXXZ"}
+; CHECK: [[Exp2]] = !{ptr @"?f2 at MyNamespace@@YAXXZ", !"?f2 at MyNamespace@@YAXXZ"}

``````````

</details>


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


More information about the llvm-commits mailing list