diff options
author | Chris Lattner <sabre@nondot.org> | 2002-10-09 23:16:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-10-09 23:16:04 +0000 |
commit | c67ebfa78810f518c54381ed38c09d3a0afd77e4 (patch) | |
tree | 42e5e5b1d97346eb13fca45d42b998fd8de6e131 /lib/Transforms/IPO/ConstantMerge.cpp | |
parent | 28eca8bb5692dced9f51a99c96078cbd67e230c6 (diff) |
- Dramatically simplify the ConstantMerge code now that
Value::replaceAllUsesWith works with constants correctly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4104 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/ConstantMerge.cpp')
-rw-r--r-- | lib/Transforms/IPO/ConstantMerge.cpp | 105 |
1 files changed, 3 insertions, 102 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index 02a9100a2e..a73fca2b3c 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -12,23 +12,19 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Module.h" -#include "llvm/Constants.h" #include "llvm/Pass.h" #include "Support/Statistic.h" namespace { + Statistic<> NumMerged("constmerge", "Number of global constants merged"); + struct ConstantMerge : public Pass { // run - For this pass, process all of the globals in the module, // eliminating duplicate constants. // bool run(Module &M); - - private: - void replaceUsesOfWith(GlobalVariable *Old, GlobalVariable *New); - void replaceConstantWith(Constant *Old, Constant *New); }; - Statistic<> NumMerged("constmerge", "Number of global constants merged"); RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants"); } @@ -51,7 +47,7 @@ bool ConstantMerge::run(Module &M) { CMap.insert(I, std::make_pair(Init, GV)); } else { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the cannonical version... - replaceUsesOfWith(GV, I->second); + GV->replaceAllUsesWith(I->second); // Delete the global value from the module... and back up iterator to // not skip the next global... @@ -64,98 +60,3 @@ bool ConstantMerge::run(Module &M) { return MadeChanges; } - -/// replaceUsesOfWith - Replace all uses of Old with New. For instructions, -/// this is a really simple matter of replacing the reference to Old with a -/// reference to New. For constants references, however, we must carefully -/// build replacement constants to substitute in. -/// -void ConstantMerge::replaceUsesOfWith(GlobalVariable *Old, GlobalVariable *New){ - while (!Old->use_empty()) { - User *U = Old->use_back(); - if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(U)) - replaceConstantWith(CPR, ConstantPointerRef::get(New)); - else - U->replaceUsesOfWith(Old, New); - } -} - -/// replaceWith - Ok, so we have a constant 'Old' and we want to replace it with -/// 'New'. To do this, we have to recursively go through the uses of Old, -/// replacing them with new things. The problem is that if a constant uses Old, -/// then we need to replace the uses of the constant with uses of the equivalent -/// constant that uses New instead. -/// -void ConstantMerge::replaceConstantWith(Constant *Old, Constant *New) { - while (!Old->use_empty()) { - User *U = Old->use_back(); - - if (Constant *C = dyn_cast<Constant>(U)) { - Constant *Replacement = 0; - - // Depending on the type of constant, build a suitable replacement... - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - std::vector<Constant*> Indices; - Constant *Pointer = cast<Constant>(CE->getOperand(0)); - Indices.reserve(CE->getNumOperands()-1); - if (Pointer == Old) Pointer = New; - - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) { - Constant *Val = cast<Constant>(CE->getOperand(i)); - if (Val == Old) Val = New; - Indices.push_back(Val); - } - Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices); - } else if (CE->getOpcode() == Instruction::Cast) { - assert(CE->getOperand(0) == Old && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(New, CE->getType()); - } else if (CE->getNumOperands() == 2) { - Constant *C1 = cast<Constant>(CE->getOperand(0)); - Constant *C2 = cast<Constant>(CE->getOperand(1)); - if (C1 == Old) C1 = New; - if (C2 == Old) C2 = New; - Replacement = ConstantExpr::get(CE->getOpcode(), C1, C2); - } else { - assert(0 && "Unknown ConstantExpr type!"); - } - - - } else if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) { - std::vector<Constant*> Values; - Values.reserve(CA->getValues().size()); - for (unsigned i = 0, e = CA->getValues().size(); i != e; ++i) { - Constant *Val = cast<Constant>(CA->getValues()[i]); - if (Val == Old) Val = New; - Values.push_back(Val); - } - - Replacement = ConstantArray::get(CA->getType(), Values); - } else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) { - std::vector<Constant*> Values; - Values.reserve(CS->getValues().size()); - - for (unsigned i = 0, e = CS->getValues().size(); i != e; ++i) { - Constant *Val = cast<Constant>(CS->getValues()[i]); - if (Val == Old) Val = New; - Values.push_back(Val); - } - - Replacement = ConstantStruct::get(CS->getType(), Values); - } else { - assert(0 && "Unexpected/unknown constant type!"); - } - - // Now that we have a suitable replacement, recursively eliminate C. - replaceConstantWith(C, Replacement); - - } else { - // If it is not a constant, we can simply replace uses of Old with New. - U->replaceUsesOfWith(Old, New); - } - - } - - // No-one refers to this old dead constant now, destroy it! - Old->destroyConstant(); -} |