[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