1 //===- ConstantMerge.cpp - Merge duplicate global constants ---------------===// 2 // 3 // This file defines the interface to a pass that merges duplicate global 4 // constants together into a single constant that is shared. This is useful 5 // because some passes (ie TraceValues) insert a lot of string constants into 6 // the program, regardless of whether or not an existing string is available. 7 // 8 // Algorithm: ConstantMerge is designed to build up a map of available constants 9 // and eliminate duplicates when it is initialized. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Transforms/IPO.h" 14 #include "llvm/Module.h" 15 #include "llvm/Pass.h" 16 #include "Support/Statistic.h" 17 18 namespace { 19 Statistic<> NumMerged("constmerge", "Number of global constants merged"); 20 21 struct ConstantMerge : public Pass { 22 // run - For this pass, process all of the globals in the module, 23 // eliminating duplicate constants. 24 // 25 bool run(Module &M); 26 }; 27 28 RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants"); 29 } 30 31 Pass *createConstantMergePass() { return new ConstantMerge(); } 32 33 34 bool ConstantMerge::run(Module &M) { 35 std::map<Constant*, GlobalVariable*> CMap; 36 bool MadeChanges = false; 37 38 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV) 39 // Only process constants with initializers 40 if (GV->isConstant() && GV->hasInitializer()) { 41 Constant *Init = GV->getInitializer(); 42 43 // Check to see if the initializer is already known... 44 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init); 45 46 if (I == CMap.end()) { // Nope, add it to the map 47 CMap.insert(I, std::make_pair(Init, GV)); 48 } else { // Yup, this is a duplicate! 49 // Make all uses of the duplicate constant use the cannonical version... 50 GV->replaceAllUsesWith(I->second); 51 52 // Delete the global value from the module... and back up iterator to 53 // not skip the next global... 54 GV = --M.getGlobalList().erase(GV); 55 56 ++NumMerged; 57 MadeChanges = true; 58 } 59 } 60 61 return MadeChanges; 62 } 63