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 they duplicate an existing string. 7 // 8 // Algorithm: ConstantMerge is designed to build up a map of available constants 9 // and elminate duplicates when it is initialized. 10 // 11 // The DynamicConstantMerge method is a superset of the ConstantMerge algorithm 12 // that checks for each function to see if constants have been added to the 13 // constant pool since it was last run... if so, it processes them. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/Transforms/ConstantMerge.h" 18 #include "llvm/Module.h" 19 #include "llvm/Pass.h" 20 #include "Support/StatisticReporter.h" 21 22 static Statistic<> NumMerged("constmerge\t\t- Number of global constants merged"); 23 24 namespace { 25 struct ConstantMerge : public Pass { 26 const char *getPassName() const {return "Merge Duplicate Global Constants";} 27 28 // run - For this pass, process all of the globals in the module, 29 // eliminating duplicate constants. 30 // 31 bool run(Module &M); 32 33 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 34 AU.preservesCFG(); 35 } 36 }; 37 } 38 39 Pass *createConstantMergePass() { return new ConstantMerge(); } 40 41 42 // ConstantMerge::run - Workhorse for the pass. This eliminates duplicate 43 // constants, starting at global ConstantNo, and adds vars to the map if they 44 // are new and unique. 45 // 46 bool ConstantMerge::run(Module &M) { 47 std::map<Constant*, GlobalVariable*> CMap; 48 bool MadeChanges = false; 49 50 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV) 51 if (GV->isConstant()) { // Only process constants 52 assert(GV->hasInitializer() && "Globals constants must have inits!"); 53 Constant *Init = GV->getInitializer(); 54 55 // Check to see if the initializer is already known... 56 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init); 57 58 if (I == CMap.end()) { // Nope, add it to the map 59 CMap.insert(I, std::make_pair(Init, GV)); 60 } else { // Yup, this is a duplicate! 61 // Make all uses of the duplicate constant use the cannonical version... 62 GV->replaceAllUsesWith(I->second); 63 64 // Delete the global value from the module... and back up iterator to 65 // not skip the next global... 66 GV = --M.getGlobalList().erase(GV); 67 68 ++NumMerged; 69 MadeChanges = true; 70 } 71 } 72 73 return MadeChanges; 74 } 75