Chris Lattner | 475becb | 2001-10-18 20:05:37 +0000 | [diff] [blame] | 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 method 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/GlobalVariable.h" |
| 19 | |
| 20 | // mergeDuplicateConstants - Workhorse for the pass. This eliminates duplicate |
| 21 | // constants, starting at global ConstantNo, and adds vars to the map if they |
| 22 | // are new and unique. |
| 23 | // |
| 24 | static inline |
| 25 | bool mergeDuplicateConstants(Module *M, unsigned &ConstantNo, |
| 26 | map<ConstPoolVal*, GlobalVariable*> &CMap) { |
| 27 | Module::GlobalListType &GList = M->getGlobalList(); |
| 28 | if (GList.size() <= ConstantNo) return false; // No new constants |
| 29 | bool MadeChanges = false; |
| 30 | |
| 31 | for (; ConstantNo < GList.size(); ++ConstantNo) { |
| 32 | GlobalVariable *GV = GList[ConstantNo]; |
| 33 | if (GV->isConstant()) { // Only process constants |
| 34 | assert(GV->hasInitializer() && "Globals constants must have inits!"); |
| 35 | ConstPoolVal *Init = GV->getInitializer(); |
| 36 | |
| 37 | // Check to see if the initializer is already known... |
| 38 | map<ConstPoolVal*, GlobalVariable*>::iterator I = CMap.find(Init); |
| 39 | |
| 40 | if (I == CMap.end()) { // Nope, add it to the map |
| 41 | CMap.insert(make_pair(Init, GV)); |
| 42 | } else { // Yup, this is a duplicate! |
| 43 | // Make all uses of the duplicate constant use the cannonical version... |
| 44 | GV->replaceAllUsesWith(I->second); |
| 45 | |
| 46 | // Remove and delete the global value from the module... |
| 47 | delete GList.remove(GList.begin()+ConstantNo); |
| 48 | |
| 49 | --ConstantNo; // Don't skip the next constant. |
| 50 | MadeChanges = true; |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | return MadeChanges; |
| 55 | } |
| 56 | |
| 57 | |
| 58 | // mergeDuplicateConstants - Static accessor for clients that don't want to |
| 59 | // deal with passes. |
| 60 | // |
| 61 | bool ConstantMerge::mergeDuplicateConstants(Module *M) { |
| 62 | map<ConstPoolVal*, GlobalVariable*> Constants; |
| 63 | unsigned LastConstantSeen = 0; |
| 64 | return ::mergeDuplicateConstants(M, LastConstantSeen, Constants); |
| 65 | } |
| 66 | |
| 67 | |
| 68 | // doPassInitialization - For this pass, process all of the globals in the |
| 69 | // module, eliminating duplicate constants. |
| 70 | // |
| 71 | bool ConstantMerge::doPassInitialization(Module *M) { |
| 72 | return ::mergeDuplicateConstants(M, LastConstantSeen, Constants); |
| 73 | } |
| 74 | |
| 75 | // doPerMethodWork - Check to see if any globals have been added to the |
| 76 | // global list for the module. If so, eliminate them. |
| 77 | // |
| 78 | bool DynamicConstantMerge::doPerMethodWork(Method *M) { |
| 79 | return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen, Constants); |
| 80 | } |