From 65204f17ddca152224d8797ce1241b160a9b4d50 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 28 Mar 2025 10:38:45 -0400 Subject: [PATCH 1/5] [LegacyPM] Restore the GlobalDCE Legacy pass and add it to the DirectX backend --- llvm/include/llvm/InitializePasses.h | 1 + llvm/include/llvm/LinkAllPasses.h | 2 ++ llvm/include/llvm/Transforms/IPO/GlobalDCE.h | 2 ++ llvm/lib/Target/DirectX/CMakeLists.txt | 1 + .../Target/DirectX/DirectXTargetMachine.cpp | 3 ++ llvm/lib/Transforms/IPO/GlobalDCE.cpp | 32 +++++++++++++++++++ llvm/test/CodeGen/DirectX/llc-pipeline.ll | 1 + 7 files changed, 42 insertions(+) diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index e55f94b9022ee..a99b0ff188ea8 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -128,6 +128,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 ea56c83a3b709..630bdf96c18df 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" @@ -84,6 +85,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 { @@ -80,6 +81,7 @@ class GlobalDCEPass : public PassInfoMixin { void ComputeDependencies(Value *V, SmallPtrSetImpl &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/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index 4ca22479f3194..5a3cc8e589077 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/IPO/GlobalDCE.h" #include "llvm/Transforms/Scalar/Scalarizer.h" #include @@ -63,6 +64,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { initializeEmbedDXILPassPass(*PR); initializeWriteDXILPassPass(*PR); initializeDXContainerGlobalsPass(*PR); + initializeGlobalDCELegacyPassPass(*PR); initializeDXILOpLoweringLegacyPass(*PR); initializeDXILResourceAccessLegacyPass(*PR); initializeDXILResourceImplicitBindingLegacyPass(*PR); @@ -105,6 +107,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 ClEnableVFE("enable-vfe", cl::Hidden, cl::init(true), cl::desc("Enable virtual function elimination")); diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index 5c81ba42ffcc8..13c25396ea98f 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 From 7cae2593a43d5f383b10226fd506c9e3562dcd43 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Mon, 28 Jul 2025 16:36:34 -0400 Subject: [PATCH 2/5] Make the dxil-finalize-linkage pass usable using the new pass manager flag syntax --- llvm/lib/Target/DirectX/DirectXPassRegistry.def | 1 + llvm/lib/Target/DirectX/DirectXTargetMachine.cpp | 1 + llvm/test/CodeGen/DirectX/finalize_linkage.ll | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) 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 5a3cc8e589077..74d48430bf640 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" diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll index dc1140f1c9160..ac97a62ef1160 100644 --- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll +++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll @@ -1,4 +1,4 @@ -; 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" From 502dc5a837e87ce0c1cf4ae7f44b6f17662d7cf7 Mon Sep 17 00:00:00 2001 From: kmpeng Date: Wed, 16 Jul 2025 13:33:28 -0700 Subject: [PATCH 3/5] convert external globals with no usage to internal linkage to be removed by globaldce, fix tests --- .../Target/DirectX/DXILFinalizeLinkage.cpp | 8 ++++---- llvm/test/CodeGen/DirectX/finalize_linkage.ll | 20 ++++++++++++++++++- llvm/test/CodeGen/DirectX/scalar-data.ll | 2 +- .../dxil-dis/opaque-value_as_metadata.ll | 1 + 4 files changed, 25 insertions(+), 6 deletions(-) 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 Funcs; diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll index ac97a62ef1160..0e45257ba1824 100644 --- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll +++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll @@ -4,7 +4,14 @@ 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 +@aTile = hidden addrspace(3) global [4 x [1 x i32]] zeroinitializer, align 4 + +; CHECK-NOT: @bTile +@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/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 } From f75de6c826bb2c583a7abd5346fcd3ad420dff32 Mon Sep 17 00:00:00 2001 From: kmpeng Date: Thu, 7 Aug 2025 11:21:38 -0700 Subject: [PATCH 4/5] update finalize_linkage test, update GlobalDCE comment --- llvm/lib/Transforms/IPO/GlobalDCE.cpp | 5 ++--- llvm/test/CodeGen/DirectX/finalize_linkage.ll | 22 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp index 3812032488035..c576fbc92f709 100644 --- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp +++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp @@ -42,9 +42,8 @@ class GlobalDCELegacyPass : public ModulePass { 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. + // Note: GlobalDCEPass does not use any analyses, so we're safe to call the + // new-pm style pass with a default-initialized analysis manager here ModuleAnalysisManager MAM; auto PA = Impl.run(M, MAM); return !PA.areAllPreserved(); diff --git a/llvm/test/CodeGen/DirectX/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll index 0e45257ba1824..f6e54cf907a64 100644 --- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll +++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll @@ -1,17 +1,11 @@ -; RUN: opt -S -passes='dxil-finalize-linkage,globaldce' -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s +; 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" ; DXILFinalizeLinkage changes linkage of all functions that are hidden to -; internal, converts private global variables to internal linkage, and removes -; unused global variables. - -; CHECK-NOT: @aTile -@aTile = hidden addrspace(3) global [4 x [1 x i32]] zeroinitializer, align 4 - -; CHECK-NOT: @bTile -@bTile = hidden addrspace(3) global [1 x <1 x i32>] zeroinitializer, align 4 +; internal, converts private globals to internal linkage, and converts external globals +; with no usage to internal linkage. ; 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 @@ -34,6 +28,16 @@ target triple = "dxilv1.5-pc-shadermodel6.5-compute" ; CHECK: @hidden_var = hidden global i32 @hidden_var = hidden global i32 1, align 4 +; Running the whole pipeline should remove unused global variables + +; CHECK: @aTile = internal addrspace(3) global +; CHECK-LLC-NOT: @aTile +@aTile = hidden addrspace(3) global [4 x [1 x i32]] zeroinitializer, align 4 + +; CHECK: @bTile = internal addrspace(3) global +; CHECK-LLC-NOT: @bTile +@bTile = hidden addrspace(3) global [1 x [1 x i32]] zeroinitializer, align 4 + define void @anchor_function() #0 { entry: %0 = load i32, ptr @switch.table, align 4 From 275e81152cffe234f90e010597adeda761035e71 Mon Sep 17 00:00:00 2001 From: kmpeng Date: Thu, 14 Aug 2025 16:25:05 -0700 Subject: [PATCH 5/5] clang-format --- llvm/lib/Target/DirectX/DirectXTargetMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index 74d48430bf640..f5d5a73c926e9 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -46,8 +46,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO/GlobalDCE.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/Scalarizer.h" #include