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 { @@ -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/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/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 @@ -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..c576fbc92f709 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,35 @@ 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 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(); + } + +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/finalize_linkage.ll b/llvm/test/CodeGen/DirectX/finalize_linkage.ll index dc1140f1c9160..f6e54cf907a64 100644 --- a/llvm/test/CodeGen/DirectX/finalize_linkage.ll +++ b/llvm/test/CodeGen/DirectX/finalize_linkage.ll @@ -4,7 +4,8 @@ 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 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 @@ -27,6 +28,27 @@ 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 + %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 }