[llvm] [HLSL] Change default linkage of HLSL functions to internal (PR #95331)
Helena Kotas via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 15:13:40 PDT 2024
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/95331
>From 0c5f982f065b3d880b9897e015c8b0782f46b653 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 7 Aug 2024 14:04:38 -0700
Subject: [PATCH 1/4] Adds `DXILFinalizeLinkage` pass that updates functions
linkage to make sure only shader entry points and exported functions are
visible from the module (have program linkage). Linkage of all other
functions will be changed to internal.
Related spec update: microsoft/hlsl-specs#295
---
llvm/lib/Target/DirectX/CMakeLists.txt | 1 +
.../Target/DirectX/DXILFinalizeLinkage.cpp | 63 +++++++++++++++++++
llvm/lib/Target/DirectX/DXILFinalizeLinkage.h | 34 ++++++++++
llvm/lib/Target/DirectX/DirectX.h | 7 +++
.../Target/DirectX/DirectXTargetMachine.cpp | 2 +
.../DirectX/conflicting-bitcast-insert.ll | 4 +-
.../CodeGen/DirectX/omit-bitcast-insert.ll | 6 +-
7 files changed, 112 insertions(+), 5 deletions(-)
create mode 100644 llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
create mode 100644 llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index 4c70b3f9230edb..f7ae09957996b5 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_target(DirectXCodeGen
DirectXSubtarget.cpp
DirectXTargetMachine.cpp
DXContainerGlobals.cpp
+ DXILFinalizeLinkage.cpp
DXILIntrinsicExpansion.cpp
DXILMetadata.cpp
DXILOpBuilder.cpp
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
new file mode 100644
index 00000000000000..6850d9fa50e3eb
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -0,0 +1,63 @@
+//===- DXILFinalizeLinkage.cpp - Finalize linkage of functions ------------===//
+//
+// 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 ......TODO HEKOTA
+//===----------------------------------------------------------------------===//
+
+#include "DXILFinalizeLinkage.h"
+#include "DirectX.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+
+#define DEBUG_TYPE "dxil-finalize-linkage"
+
+using namespace llvm;
+
+static bool finalizeLinkage(Module &M) {
+ SmallPtrSet<Function *, 8> EntriesAndExports;
+
+ // Find all entry points and export functions
+ for (Function &EF : M.functions()) {
+ if (!EF.hasFnAttribute("hlsl.shader") && !EF.hasFnAttribute("hlsl.export"))
+ continue;
+ EntriesAndExports.insert(&EF);
+ }
+
+ for (Function &F : M.functions()) {
+ if (F.getLinkage() == GlobalValue::ExternalLinkage &&
+ !EntriesAndExports.contains(&F)) {
+ F.setLinkage(GlobalValue::InternalLinkage);
+ }
+ }
+
+ return false;
+}
+
+PreservedAnalyses DXILFinalizeLinkage::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ if (finalizeLinkage(M))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+}
+
+bool DXILFinalizeLinkageLegacy::runOnModule(Module &M) {
+ return finalizeLinkage(M);
+}
+
+char DXILFinalizeLinkageLegacy::ID = 0;
+
+INITIALIZE_PASS_BEGIN(DXILFinalizeLinkageLegacy, DEBUG_TYPE,
+ "DXIL Finalize Linkage", false, false)
+INITIALIZE_PASS_END(DXILFinalizeLinkageLegacy, DEBUG_TYPE,
+ "DXIL Finalize Linkage", false, false)
+
+ModulePass *llvm::createDXILFinalizeLinkageLegacyPass() {
+ return new DXILFinalizeLinkageLegacy();
+}
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
new file mode 100644
index 00000000000000..9019ee667bf41e
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
@@ -0,0 +1,34 @@
+//===- DXILFinalizeLinkage.h - Finalize linkage of functions --------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
+#define LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class DXILFinalizeLinkage : public PassInfoMixin<DXILFinalizeLinkage> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+
+ static bool isRequired() { return true; }
+};
+
+class DXILFinalizeLinkageLegacy : public ModulePass {
+
+public:
+ DXILFinalizeLinkageLegacy() : ModulePass(ID) {}
+
+ static char ID; // Pass identification.
+
+ bool runOnModule(Module &M) override;
+};
+} // namespace llvm
+
+#endif // LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index d056ae2bc488e7..de6c6f2db5b244 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -63,6 +63,13 @@ void initializeDXContainerGlobalsPass(PassRegistry &);
/// Pass for generating DXContainer part globals.
ModulePass *createDXContainerGlobalsPass();
+
+/// Initializer for DXILFinalizeLinkage pass.
+void initializeDXILFinalizeLinkageLegacyPass(PassRegistry &);
+
+/// Pass to finalize linkage of functions.
+ModulePass *createDXILFinalizeLinkageLegacyPass();
+
} // namespace llvm
#endif // LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 92bd69b69684f0..2c2b86e7193382 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -48,6 +48,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
initializeDXILTranslateMetadataPass(*PR);
initializeDXILResourceMDWrapperPass(*PR);
initializeShaderFlagsAnalysisWrapperPass(*PR);
+ initializeDXILFinalizeLinkageLegacyPass(*PR);
}
class DXILTargetObjectFile : public TargetLoweringObjectFile {
@@ -79,6 +80,7 @@ class DirectXPassConfig : public TargetPassConfig {
void addCodeGenPrepare() override {
addPass(createDXILIntrinsicExpansionLegacyPass());
addPass(createDXILOpLoweringLegacyPass());
+ addPass(createDXILFinalizeLinkageLegacyPass());
addPass(createDXILTranslateMetadataPass());
addPass(createDXILPrepareModulePass());
}
diff --git a/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll b/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
index 01084f285cd72a..8f5d3ae8641717 100644
--- a/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
+++ b/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
@@ -7,7 +7,7 @@ define i64 @test(ptr %p) {
ret i64 %v
}
-; CHECK: define i64 @test(ptr %p) {
+; CHECK: define internal i64 @test(ptr %p) {
; CHECK-NEXT: %1 = bitcast ptr %p to ptr
; CHECK-NEXT: store i32 0, ptr %1, align 4
; CHECK-NEXT: %2 = bitcast ptr %p to ptr
@@ -19,7 +19,7 @@ define i64 @testGEP(ptr %p) {
ret i64 %val
}
-; CHECK: define i64 @testGEP(ptr %p) {
+; CHECK: define internal i64 @testGEP(ptr %p) {
; CHECK-NEXT: %1 = bitcast ptr %p to ptr
; CHECK-NEXT: %ptr = getelementptr i32, ptr %1, i32 4
; CHECK-NEXT: %2 = bitcast ptr %p to ptr
diff --git a/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll b/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll
index 73c33e8cfdd864..6066a0033e45de 100644
--- a/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll
+++ b/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll
@@ -6,7 +6,7 @@ define i64 @test(ptr %p) {
ret i64 %v
}
-; CHECK: define i64 @test(ptr %p) {
+; CHECK: define internal i64 @test(ptr %p) {
; CHECK-NEXT: %v = load i64, ptr %p, align 8
; CHECK-NEXT: ret i64 %v
@@ -16,7 +16,7 @@ define i64 @test2(ptr %p) {
ret i64 %v
}
-; CHECK: define i64 @test2(ptr %p) {
+; CHECK: define internal i64 @test2(ptr %p) {
; CHECK-NEXT: store i64 0, ptr %p
; CHECK-NEXT: %v = load i64, ptr %p, align 8
; CHECK-NEXT: ret i64 %v
@@ -27,6 +27,6 @@ define i32 @test3(ptr %0) {
ret i32 %3
}
-; CHECK: define i32 @test3(ptr %0) {
+; CHECK: define internal i32 @test3(ptr %0) {
; CHECK-NEXT: %2 = getelementptr i32, ptr %0, i32 4
; CHECK-NEXT: %3 = load i32, ptr %2
>From b396a1c46135b1868cf098a1bc57432e424edb12 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 7 Aug 2024 14:15:33 -0700
Subject: [PATCH 2/4] Add test, update comments
---
.../Target/DirectX/DXILFinalizeLinkage.cpp | 3 -
llvm/lib/Target/DirectX/DXILFinalizeLinkage.h | 8 +++
llvm/test/CodeGen/DirectX/finalize_linkage.ll | 60 +++++++++++++++++++
3 files changed, 68 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/finalize_linkage.ll
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index 6850d9fa50e3eb..c02eb768cdf49b 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -5,9 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-///
-/// \file This file contains ......TODO HEKOTA
-//===----------------------------------------------------------------------===//
#include "DXILFinalizeLinkage.h"
#include "DirectX.h"
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
index 9019ee667bf41e..f8dddf2136d57f 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
@@ -5,6 +5,14 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// DXILFinalizeLinkage pass updates the linkage of functions to make sure only
+/// shader entry points and exported functions are visible from the module (have
+/// program linkage). All other functions will be updated to have internal
+/// linkage.
+///
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
#define LLVM_TARGET_DIRECTX_DXILFINALIZELINKAGE_H
diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
new file mode 100644
index 00000000000000..e10cc4aaf81dff
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
@@ -0,0 +1,60 @@
+; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+
+target triple = "dxilv1.5-pc-shadermodel6.5-compute"
+
+; DXILFinalizeLinkage changes linkage of all functions that are not
+; entry points or exported function to internal.
+
+; CHECK: define internal void @"?f1@@YAXXZ"()
+define void @"?f1@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; CHECK: define internal void @"?f2@@YAXXZ"()
+define void @"?f2@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; CHECK: define internal void @"?f3@@YAXXZ"()
+define void @"?f3@@YAXXZ"() #0 {
+entry:
+ ret void
+}
+
+; CHECK: define internal void @"?foo@@YAXXZ"()
+define void @"?foo@@YAXXZ"() #0 {
+entry:
+ call void @"?f2@@YAXXZ"() #3
+ ret void
+}
+
+; Exported function - do not change linkage
+; CHECK: define void @"?bar@@YAXXZ"()
+define void @"?bar@@YAXXZ"() #1 {
+entry:
+ call void @"?f3@@YAXXZ"() #3
+ ret void
+}
+
+; CHECK: define internal void @"?main@@YAXXZ"() #0
+define internal void @"?main@@YAXXZ"() #0 {
+entry:
+ call void @"?foo@@YAXXZ"() #3
+ call void @"?bar@@YAXXZ"() #3
+ ret void
+}
+
+; Entry point function - do not change linkage
+; CHECK: define void @main() #2
+define void @main() #2 {
+entry:
+ call void @"?main@@YAXXZ"()
+ ret void
+}
+
+attributes #0 = { convergent noinline nounwind optnone}
+attributes #1 = { convergent noinline nounwind optnone "hlsl.export"}
+attributes #2 = { convergent "hlsl.numthreads"="4,1,1" "hlsl.shader"="compute"}
+attributes #3 = { convergent }
>From 299600111e45329c6bd16b1cc13891b9957d88ec Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 7 Aug 2024 14:23:00 -0700
Subject: [PATCH 3/4] Remove empty lines, this is too sparse.
---
llvm/lib/Target/DirectX/DXILFinalizeLinkage.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
index f8dddf2136d57f..aab1bc3f7a28e2 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h
@@ -24,18 +24,15 @@ namespace llvm {
class DXILFinalizeLinkage : public PassInfoMixin<DXILFinalizeLinkage> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
-
static bool isRequired() { return true; }
};
class DXILFinalizeLinkageLegacy : public ModulePass {
-
public:
DXILFinalizeLinkageLegacy() : ModulePass(ID) {}
+ bool runOnModule(Module &M) override;
static char ID; // Pass identification.
-
- bool runOnModule(Module &M) override;
};
} // namespace llvm
>From e1ae67af89f1d73a8231dad30b31e1ee9bdad623 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 14 Aug 2024 15:13:23 -0700
Subject: [PATCH 4/4] Add llc test to make sure "hlsl.export" attribute is
stripped
---
llvm/test/CodeGen/DirectX/finalize_linkage.ll | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
index e10cc4aaf81dff..0ee8a5f44593ba 100644
--- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll
+++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
@@ -1,4 +1,5 @@
; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+; RUN: llc %s --filetype=asm -o - | FileCheck %s --check-prefixes=CHECK-LLC
target triple = "dxilv1.5-pc-shadermodel6.5-compute"
@@ -58,3 +59,6 @@ attributes #0 = { convergent noinline nounwind optnone}
attributes #1 = { convergent noinline nounwind optnone "hlsl.export"}
attributes #2 = { convergent "hlsl.numthreads"="4,1,1" "hlsl.shader"="compute"}
attributes #3 = { convergent }
+
+; Make sure "hlsl.export" attribute is stripped by llc
+; CHECK-LLC-NOT: "hlsl.export"
More information about the llvm-commits
mailing list