[llvm] [DirectX] Add GlobalDCE pass after finalize linkage pass in DirectX backend (PR #151071)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 28 19:07:39 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Kaitlin Peng (kmpeng)
<details>
<summary>Changes</summary>
Fixes #<!-- -->139023.
This PR essentially removes unused global variables:
- Restores the `GlobalDCE` Legacy pass and adds it to the DirectX backend after the finalize linkage pass
- Converts external global variables with no usage to internal linkage in the finalize linkage pass
- (so they can be removed by GlobalDCE)
- Makes the `dxil-finalize-linkage` pass usable using the new pass manager flag syntax
- Adds tests to `finalize_linkage.ll` that make sure unused global variables are removed
- Adds a use for variable `@<!-- -->CBV` in `opaque-value_as_metadata.ll` so it isn't removed
- Changes the `scalar-data.ll` run command to avoid removing its global variables
---
Full diff: https://github.com/llvm/llvm-project/pull/151071.diff
12 Files Affected:
- (modified) llvm/include/llvm/InitializePasses.h (+1)
- (modified) llvm/include/llvm/LinkAllPasses.h (+2)
- (modified) llvm/include/llvm/Transforms/IPO/GlobalDCE.h (+2)
- (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1)
- (modified) llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp (+4-4)
- (modified) llvm/lib/Target/DirectX/DirectXPassRegistry.def (+1)
- (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+4)
- (modified) llvm/lib/Transforms/IPO/GlobalDCE.cpp (+32)
- (modified) llvm/test/CodeGen/DirectX/finalize_linkage.ll (+20-2)
- (modified) llvm/test/CodeGen/DirectX/llc-pipeline.ll (+1)
- (modified) llvm/test/CodeGen/DirectX/scalar-data.ll (+1-1)
- (modified) llvm/test/tools/dxil-dis/opaque-value_as_metadata.ll (+1)
``````````diff
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 31801daa126ad..0e48d80936270 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -127,6 +127,7 @@ LLVM_ABI void initializeGCEmptyBasicBlocksPass(PassRegistry &);
LLVM_ABI void initializeGCMachineCodeAnalysisPass(PassRegistry &);
LLVM_ABI void initializeGCModuleInfoPass(PassRegistry &);
LLVM_ABI void initializeGVNLegacyPassPass(PassRegistry &);
+LLVM_ABI void initializeGlobalDCELegacyPassPass(PassRegistry &);
LLVM_ABI void initializeGlobalMergeFuncPassWrapperPass(PassRegistry &);
LLVM_ABI void initializeGlobalMergePass(PassRegistry &);
LLVM_ABI void initializeGlobalsAAWrapperPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index f82a43967e67a..7b33ec7f09124 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -38,6 +38,7 @@
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
+#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
@@ -83,6 +84,7 @@ struct ForcePassLinking {
(void)llvm::createDomOnlyViewerWrapperPassPass();
(void)llvm::createDomViewerWrapperPassPass();
(void)llvm::createAlwaysInlinerLegacyPass();
+ (void)llvm::createGlobalDCEPass();
(void)llvm::createGlobalMergeFuncPass();
(void)llvm::createGlobalsAAWrapperPass();
(void)llvm::createInstSimplifyLegacyPass();
diff --git a/llvm/include/llvm/Transforms/IPO/GlobalDCE.h b/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
index f8f775b8ea96e..55dff64889270 100644
--- a/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
+++ b/llvm/include/llvm/Transforms/IPO/GlobalDCE.h
@@ -32,6 +32,7 @@ class GlobalVariable;
class Metadata;
class Module;
class Value;
+class ModulePass;
/// Pass to remove unused function declarations.
class GlobalDCEPass : public PassInfoMixin<GlobalDCEPass> {
@@ -80,6 +81,7 @@ class GlobalDCEPass : public PassInfoMixin<GlobalDCEPass> {
void ComputeDependencies(Value *V, SmallPtrSetImpl<GlobalValue *> &U);
};
+ModulePass *createGlobalDCEPass();
}
#endif // LLVM_TRANSFORMS_IPO_GLOBALDCE_H
diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index c7c09caf43667..8100f941c8d94 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -49,6 +49,7 @@ add_llvm_target(DirectXCodeGen
DirectXInfo
DirectXPointerTypeAnalysis
FrontendHLSL
+ IPO
MC
ScalarOpts
SelectionDAG
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index 5f331dbd2d826..13e3408815bba 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -20,13 +20,13 @@ using namespace llvm;
static bool finalizeLinkage(Module &M) {
bool MadeChange = false;
- // Convert private global variables to internal linkage.
- for (GlobalVariable &GV : M.globals()) {
- if (GV.hasPrivateLinkage()) {
+ // Convert private globals and external globals with no usage to internal
+ // linkage.
+ for (GlobalVariable &GV : M.globals())
+ if (GV.hasPrivateLinkage() || (GV.hasExternalLinkage() && GV.use_empty())) {
GV.setLinkage(GlobalValue::InternalLinkage);
MadeChange = true;
}
- }
SmallVector<Function *> Funcs;
diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
index d5069541642b5..b4b48a166800e 100644
--- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def
+++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
@@ -24,6 +24,7 @@ MODULE_ANALYSIS("dxil-root-signature-analysis", dxil::RootSignatureAnalysis())
#define MODULE_PASS(NAME, CREATE_PASS)
#endif
MODULE_PASS("dxil-cbuffer-access", DXILCBufferAccess())
+MODULE_PASS("dxil-finalize-linkage", DXILFinalizeLinkage())
MODULE_PASS("dxil-data-scalarization", DXILDataScalarization())
MODULE_PASS("dxil-flatten-arrays", DXILFlattenArrays())
MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion())
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 84751d2db2266..d7609d596e444 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -14,6 +14,7 @@
#include "DirectXTargetMachine.h"
#include "DXILCBufferAccess.h"
#include "DXILDataScalarization.h"
+#include "DXILFinalizeLinkage.h"
#include "DXILFlattenArrays.h"
#include "DXILForwardHandleAccesses.h"
#include "DXILIntrinsicExpansion.h"
@@ -45,6 +46,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/Scalar/Scalarizer.h"
#include <optional>
@@ -62,6 +64,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
initializeEmbedDXILPassPass(*PR);
initializeWriteDXILPassPass(*PR);
initializeDXContainerGlobalsPass(*PR);
+ initializeGlobalDCELegacyPassPass(*PR);
initializeDXILOpLoweringLegacyPass(*PR);
initializeDXILResourceAccessLegacyPass(*PR);
initializeDXILResourceImplicitBindingLegacyPass(*PR);
@@ -103,6 +106,7 @@ class DirectXPassConfig : public TargetPassConfig {
FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
void addCodeGenPrepare() override {
addPass(createDXILFinalizeLinkageLegacyPass());
+ addPass(createGlobalDCEPass());
addPass(createDXILResourceAccessLegacyPass());
addPass(createDXILIntrinsicExpansionLegacyPass());
addPass(createDXILCBufferAccessLegacyPass());
diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp
index 45fb1f5212b70..3812032488035 100644
--- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp
@@ -21,6 +21,8 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/CtorUtils.h"
@@ -30,6 +32,36 @@ using namespace llvm;
#define DEBUG_TYPE "globaldce"
+namespace {
+class GlobalDCELegacyPass : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ GlobalDCELegacyPass() : ModulePass(ID) {
+ initializeGlobalDCELegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+ bool runOnModule(Module &M) override {
+ if (skipModule(M))
+ return false;
+ // Note: GlobalDCEPass does not use MAM. That
+ // means we can get away with init and pass
+ // as arg.
+ ModuleAnalysisManager MAM;
+ auto PA = Impl.run(M, MAM);
+ return !PA.areAllPreserved();
+ }
+
+private:
+ GlobalDCEPass Impl;
+};
+} // namespace
+
+char GlobalDCELegacyPass::ID = 0;
+INITIALIZE_PASS(GlobalDCELegacyPass, "globaldce", "Dead Global Elimination",
+ false, false)
+
+// Public interface to the GlobalDCEPass.
+ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCELegacyPass(); }
+
static cl::opt<bool>
ClEnableVFE("enable-vfe", cl::Hidden, cl::init(true),
cl::desc("Enable virtual function elimination"));
diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
index dc1140f1c9160..0e45257ba1824 100644
--- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll
+++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll
@@ -1,10 +1,17 @@
-; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
+; RUN: opt -S -passes='dxil-finalize-linkage,globaldce' -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"
; DXILFinalizeLinkage changes linkage of all functions that are hidden to
-; internal, and converts private global variables to internal linkage.
+; internal, converts private global variables to internal linkage, and removes
+; unused global variables.
+
+; CHECK-NOT: @aTile
+ at aTile = hidden addrspace(3) global [4 x [1 x i32]] zeroinitializer, align 4
+
+; CHECK-NOT: @bTile
+ at bTile = hidden addrspace(3) global [1 x <1 x i32>] zeroinitializer, align 4
; CHECK: @switch.table = internal unnamed_addr constant [4 x i32]
@switch.table = private unnamed_addr constant [4 x i32] [i32 1, i32 257, i32 65793, i32 16843009], align 4
@@ -27,6 +34,17 @@ target triple = "dxilv1.5-pc-shadermodel6.5-compute"
; CHECK: @hidden_var = hidden global i32
@hidden_var = hidden global i32 1, align 4
+define void @anchor_function() #0 {
+entry:
+ %0 = load i32, ptr @switch.table, align 4
+ %1 = load [3 x float], ptr @private_array, align 4
+ %2 = load i32, ptr @private_var, align 4
+ %3 = load i32, ptr @internal_var, align 4
+ %4 = load i32, ptr @external_var, align 4
+ %5 = load i32, ptr @hidden_var, align 4
+ ret void
+}
+
; CHECK-NOT: define internal void @"?f1@@YAXXZ"()
define void @"?f1@@YAXXZ"() #0 {
entry:
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 151603a7161c5..a3a214338536f 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -14,6 +14,7 @@
; CHECK-NEXT: ModulePass Manager
; CHECK-NEXT: DXIL Finalize Linkage
+; CHECK-NEXT: Dead Global Elimination
; CHECK-NEXT: FunctionPass Manager
; CHECK-NEXT: DXIL Resource Access
; CHECK-NEXT: DXIL Intrinsic Expansion
diff --git a/llvm/test/CodeGen/DirectX/scalar-data.ll b/llvm/test/CodeGen/DirectX/scalar-data.ll
index 4861a0890f136..d9c8df9bc169c 100644
--- a/llvm/test/CodeGen/DirectX/scalar-data.ll
+++ b/llvm/test/CodeGen/DirectX/scalar-data.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -mtriple=dxil-pc-shadermodel6.3-library --filetype=asm -o - | FileCheck %s
+; RUN: opt -S -passes='dxil-data-scalarization,dxil-flatten-arrays' -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
; Make sure we don't touch arrays without vectors and that can recurse and flatten multiple-dimension arrays of vectors
diff --git a/llvm/test/tools/dxil-dis/opaque-value_as_metadata.ll b/llvm/test/tools/dxil-dis/opaque-value_as_metadata.ll
index 165d5d2e520df..c53bb2127ebcc 100644
--- a/llvm/test/tools/dxil-dis/opaque-value_as_metadata.ll
+++ b/llvm/test/tools/dxil-dis/opaque-value_as_metadata.ll
@@ -7,6 +7,7 @@ target triple = "dxil-unknown-shadermodel6.7-library"
@CBV = external constant %"$Globals"
define void @main() #0 {
+ %1 = load float, ptr @CBV, align 4
ret void
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/151071
More information about the llvm-commits
mailing list