From 0d12d4ebc62054cd2ac2164f2a1d5e75789f09e7 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Tue, 20 Jan 2015 19:24:59 +0000 Subject: [PATCH] [llvm link] Destroy ConstantArrays in LLVMContext if they are not used. ConstantArrays constructed during linking can cause quadratic memory explosion. An example is the ConstantArrays constructed when linking in GlobalVariables with appending linkage. Releasing all unused constants can cause a 20% LTO compile-time slowdown for a large application. So this commit releases unused ConstantArrays only. rdar://19040716. It reduces memory footprint from 20+G to 6+G. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226592 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Module.h | 9 +++++++++ lib/IR/LLVMContextImpl.cpp | 22 ++++++++++++++++++++++ lib/IR/LLVMContextImpl.h | 3 +++ lib/Linker/LinkModules.cpp | 4 +++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index b24023b05e4..62f41943be8 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -630,6 +630,15 @@ public: named_metadata_end()); } + /// Destroy ConstantArrays in LLVMContext if they are not used. + /// ConstantArrays constructed during linking can cause quadratic memory + /// explosion. Releasing all unused constants can cause a 20% LTO compile-time + /// slowdown for a large application. + /// + /// NOTE: Constants are currently owned by LLVMContext. This can then only + /// be called where all uses of the LLVMContext are understood. + void dropTriviallyDeadConstantArrays(); + /// @} /// @name Utility functions for printing and dumping Module objects /// @{ diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp index aa7242af997..880e1c1bcad 100644 --- a/lib/IR/LLVMContextImpl.cpp +++ b/lib/IR/LLVMContextImpl.cpp @@ -163,6 +163,28 @@ LLVMContextImpl::~LLVMContextImpl() { MDStringCache.clear(); } +void LLVMContextImpl::dropTriviallyDeadConstantArrays() { + bool Changed; + do { + Changed = false; + + for (auto I = ArrayConstants.map_begin(), E = ArrayConstants.map_end(); + I != E; ) { + auto *C = I->first; + I++; + if (C->use_empty()) { + Changed = true; + C->destroyConstant(); + } + } + + } while (Changed); +} + +void Module::dropTriviallyDeadConstantArrays() { + Context.pImpl->dropTriviallyDeadConstantArrays(); +} + namespace llvm { /// \brief Make MDOperand transparent for hashing. /// diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 4604d9babb5..3b3be0f9982 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -474,6 +474,9 @@ public: LLVMContextImpl(LLVMContext &C); ~LLVMContextImpl(); + + /// Destroy the ConstantArrays if they are not used. + void dropTriviallyDeadConstantArrays(); }; } diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 767d465d1be..dc002d8a576 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -1721,7 +1721,9 @@ void Linker::deleteModule() { bool Linker::linkInModule(Module *Src) { ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, DiagnosticHandler); - return TheLinker.run(); + bool RetCode = TheLinker.run(); + Composite->dropTriviallyDeadConstantArrays(); + return RetCode; } //===----------------------------------------------------------------------===// -- 2.34.1