summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/ConstantMerge.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-12-28 07:19:08 +0000
committerChris Lattner <sabre@nondot.org>2003-12-28 07:19:08 +0000
commit0898c78a52e04f94de5576d380d73517a9ea1b05 (patch)
treeec996efba5616088a92de1674ed7eba064aca81c /lib/Transforms/IPO/ConstantMerge.cpp
parent6cdc42b3d101b698266421f075fdd8ea47c1a66a (diff)
downloadllvm-0898c78a52e04f94de5576d380d73517a9ea1b05.tar.gz
llvm-0898c78a52e04f94de5576d380d73517a9ea1b05.tar.bz2
llvm-0898c78a52e04f94de5576d380d73517a9ea1b05.tar.xz
Merging constants can cause further room for improvement. Iterate until
we converge git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10618 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/ConstantMerge.cpp')
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp80
1 files changed, 45 insertions, 35 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index 1219b355d2..417cb1de4b 100644
--- a/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -44,44 +44,54 @@ bool ConstantMerge::run(Module &M) {
// Replacements - This vector contains a list of replacements to perform.
std::vector<std::pair<GlobalVariable*, GlobalVariable*> > Replacements;
- // First pass: identify all globals that can be merged together, filling in
- // the Replacements vector. We cannot do the replacement in this pass because
- // doing so may cause initializers of other globals to be rewritten,
- // invalidating the Constant* pointers in CMap.
- //
- for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
- // Only process constants with initializers
- if (GV->isConstant() && GV->hasInitializer()) {
- Constant *Init = GV->getInitializer();
+ bool MadeChange = false;
- // Check to see if the initializer is already known...
- std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
-
- if (I == CMap.end()) { // Nope, add it to the map
- CMap.insert(I, std::make_pair(Init, GV));
- } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate!
- // Make all uses of the duplicate constant use the canonical version...
- Replacements.push_back(std::make_pair(GV, I->second));
- } else if (I->second->hasInternalLinkage()) {
- // Make all uses of the duplicate constant use the canonical version...
- Replacements.push_back(std::make_pair(I->second, GV));
- I->second = GV;
+ // Iterate constant merging while we are still making progress. Merging two
+ // constants together may allow us to merge other constants together if the
+ // second level constants have initializers which point to the globals that
+ // were just merged.
+ while (1) {
+ // First pass: identify all globals that can be merged together, filling in
+ // the Replacements vector. We cannot do the replacement in this pass
+ // because doing so may cause initializers of other globals to be rewritten,
+ // invalidating the Constant* pointers in CMap.
+ //
+ for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
+ // Only process constants with initializers
+ if (GV->isConstant() && GV->hasInitializer()) {
+ Constant *Init = GV->getInitializer();
+
+ // Check to see if the initializer is already known...
+ std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
+
+ if (I == CMap.end()) { // Nope, add it to the map
+ CMap.insert(I, std::make_pair(Init, GV));
+ } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate!
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(GV, I->second));
+ } else if (I->second->hasInternalLinkage()) {
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(I->second, GV));
+ I->second = GV;
+ }
}
+
+ if (Replacements.empty())
+ return MadeChange;
+ CMap.clear();
+
+ // Now that we have figured out which replacements must be made, do them all
+ // now. This avoid invalidating the pointers in CMap, which are unneeded
+ // now.
+ for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
+ // Eliminate any uses of the dead global...
+ Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
+
+ // Delete the global value from the module...
+ M.getGlobalList().erase(Replacements[i].first);
}
-
- if (Replacements.empty()) return false;
- CMap.clear();
-
- // Now that we have figured out which replacements must be made, do them all
- // now. This avoid invalidating the pointers in CMap, which are unneeded now.
- for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
- // Eliminate any uses of the dead global...
- Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
- // Delete the global value from the module...
- M.getGlobalList().erase(Replacements[i].first);
+ NumMerged += Replacements.size();
+ Replacements.clear();
}
-
- NumMerged += Replacements.size();
- return true;
}