summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/ConstantMerge.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-01-15 18:14:21 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-01-15 18:14:21 +0000
commit2820c25e847c76f241388446f6f3dd86e067403b (patch)
tree75f3a7a0bfe8fd396865147c8e10d2c1428dd159 /lib/Transforms/IPO/ConstantMerge.cpp
parent111fd9ce64726867c634dc8bbe042c6eb8de85fc (diff)
downloadllvm-2820c25e847c76f241388446f6f3dd86e067403b.tar.gz
llvm-2820c25e847c76f241388446f6f3dd86e067403b.tar.bz2
llvm-2820c25e847c76f241388446f6f3dd86e067403b.tar.xz
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/Transforms/IPO/ConstantMerge.cpp')
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index ea01ffeeb5..8efad05855 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();
}