summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Module.h9
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp22
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h3
-rw-r--r--llvm/lib/Linker/LinkModules.cpp4
4 files changed, 37 insertions, 1 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index b24023b05e4..62f41943be8 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/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/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index aa7242af997..880e1c1bcad 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/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/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 4604d9babb5..3b3be0f9982 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/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/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index 767d465d1be..dc002d8a576 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/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;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud