diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-01-15 18:14:21 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-01-15 18:14:21 +0000 |
commit | 2820c25e847c76f241388446f6f3dd86e067403b (patch) | |
tree | 75f3a7a0bfe8fd396865147c8e10d2c1428dd159 /lib | |
parent | 111fd9ce64726867c634dc8bbe042c6eb8de85fc (diff) | |
download | external_llvm-2820c25e847c76f241388446f6f3dd86e067403b.zip external_llvm-2820c25e847c76f241388446f6f3dd86e067403b.tar.gz external_llvm-2820c25e847c76f241388446f6f3dd86e067403b.tar.bz2 |
Make constmerge a two-pass algorithm so that it won't miss merging
opporuntities. Fixes PR8978.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/IPO/ConstantMerge.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index ea01ffe..8efad05 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -101,15 +101,18 @@ bool ConstantMerge::runOnModule(Module &M) { continue; } - // Only process constants with initializers in the default addres space. + // Only process constants with initializers in the default address space. if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || - GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty() || + GV->getType()->getAddressSpace() != 0 || GV->hasSection() || // Don't touch values marked with attribute(used). UsedGlobals.count(GV)) continue; + // Start by filling slots with only the globals we aren't allowed to + // delete because they're externally visible. + if (GV->hasLocalLinkage()) + continue; - Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. @@ -117,7 +120,32 @@ bool ConstantMerge::runOnModule(Module &M) { if (Slot == 0) { // Nope, add it to the map. Slot = GV; - } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate! + } + } + + for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); + GVI != E; ) { + GlobalVariable *GV = GVI++; + + // Only process constants with initializers in the default address space. + if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || + GV->getType()->getAddressSpace() != 0 || GV->hasSection() || + // Don't touch values marked with attribute(used). + UsedGlobals.count(GV)) + continue; + + // Only look at the remaining globals now. + if (!GV->hasLocalLinkage()) + continue; + + Constant *Init = GV->getInitializer(); + + // Check to see if the initializer is already known. + GlobalVariable *&Slot = CMap[Init]; + + if (Slot == 0) { // Nope, add it to the map. + Slot = GV; + } else { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the canonical version. Replacements.push_back(std::make_pair(GV, Slot)); } @@ -135,6 +163,8 @@ bool ConstantMerge::runOnModule(Module &M) { Replacements[i].first->replaceAllUsesWith(Replacements[i].second); // Delete the global value from the module. + assert(Replacements[i].first->hasLocalLinkage() && + "Refusing to delete an externally visible global variable."); Replacements[i].first->eraseFromParent(); } |