[llvm] [HLSL] Change default linkage of HLSL functions and groupshared variables (v2) (PR #95331)
Helena Kotas via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 7 14:06:50 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] 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 4c70b3f9230ed..f7ae09957996b 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 0000000000000..6850d9fa50e3e
--- /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 0000000000000..9019ee667bf41
--- /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 d056ae2bc488e..de6c6f2db5b24 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 92bd69b69684f..2c2b86e719338 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 01084f285cd72..8f5d3ae864171 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 73c33e8cfdd86..6066a0033e45d 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
More information about the llvm-commits
mailing list