Make sure to include name information if we have it
[oota-llvm.git] / lib / Transforms / IPO / ConstantMerge.cpp
index ef51105a474c2c9ef526f1d91fbec8848c527dc3..a73fca2b3c5269e9c6831ead3c826374b431c95a 100644 (file)
@@ -3,36 +3,39 @@
 // This file defines the interface to a pass that merges duplicate global
 // constants together into a single constant that is shared.  This is useful
 // because some passes (ie TraceValues) insert a lot of string constants into
-// the program, regardless of whether or not they duplicate an existing string.
+// the program, regardless of whether or not an existing string is available.
 //
 // Algorithm: ConstantMerge is designed to build up a map of available constants
-// and elminate duplicates when it is initialized.
-//
-// The DynamicConstantMerge method is a superset of the ConstantMerge algorithm
-// that checks for each function to see if constants have been added to the
-// constant pool since it was last run... if so, it processes them.
+// and eliminate duplicates when it is initialized.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/ConstantMerge.h"
-#include "llvm/GlobalVariable.h"
+#include "llvm/Transforms/IPO.h"
 #include "llvm/Module.h"
-#include "llvm/Function.h"
 #include "llvm/Pass.h"
+#include "Support/Statistic.h"
 
-// mergeDuplicateConstants - Workhorse for the pass.  This eliminates duplicate
-// constants, starting at global ConstantNo, and adds vars to the map if they
-// are new and unique.
-//
-static inline 
-bool mergeDuplicateConstants(Module *M, unsigned &ConstantNo,
-                             std::map<Constant*, GlobalVariable*> &CMap) {
-  Module::GlobalListType &GList = M->getGlobalList();
-  if (GList.size() <= ConstantNo) return false;   // No new constants
+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);
+  };
+
+  RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants");
+}
+
+Pass *createConstantMergePass() { return new ConstantMerge(); }
+
+
+bool ConstantMerge::run(Module &M) {
+  std::map<Constant*, GlobalVariable*> CMap;
   bool MadeChanges = false;
   
-  for (; ConstantNo < GList.size(); ++ConstantNo) {
-    GlobalVariable *GV = GList[ConstantNo];
+  for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
     if (GV->isConstant()) {  // Only process constants
       assert(GV->hasInitializer() && "Globals constants must have inits!");
       Constant *Init = GV->getInitializer();
@@ -41,59 +44,19 @@ bool mergeDuplicateConstants(Module *M, unsigned &ConstantNo,
       std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
 
       if (I == CMap.end()) {    // Nope, add it to the map
-        CMap.insert(std::make_pair(Init, GV));
+        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...
         GV->replaceAllUsesWith(I->second);
 
-        // Remove and delete the global value from the module...
-        delete GList.remove(GList.begin()+ConstantNo);
+        // Delete the global value from the module... and back up iterator to
+        // not skip the next global...
+        GV = --M.getGlobalList().erase(GV);
 
-        --ConstantNo;  // Don't skip the next constant.
+        ++NumMerged;
         MadeChanges = true;
       }
     }
-  }
-  return MadeChanges;
-}
 
-namespace {
-  // FIXME: ConstantMerge should not be a methodPass!!!
-  class ConstantMerge : public MethodPass {
-  protected:
-    std::map<Constant*, GlobalVariable*> Constants;
-    unsigned LastConstantSeen;
-  public:
-    inline ConstantMerge() : LastConstantSeen(0) {}
-    
-    // doInitialization - For this pass, process all of the globals in the
-    // module, eliminating duplicate constants.
-    //
-    bool doInitialization(Module *M) {
-      return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
-    }
-    
-    bool runOnMethod(Function *) { return false; }
-    
-    // doFinalization - Clean up internal state for this module
-    //
-    bool doFinalization(Module *M) {
-      LastConstantSeen = 0;
-      Constants.clear();
-      return false;
-    }
-  };
-  
-  struct DynamicConstantMerge : public ConstantMerge {
-    // runOnMethod - Check to see if any globals have been added to the 
-    // global list for the module.  If so, eliminate them.
-    //
-    bool runOnMethod(Function *F) {
-      return ::mergeDuplicateConstants(F->getParent(), LastConstantSeen,
-                                       Constants);
-    }
-  };
+  return MadeChanges;
 }
-
-Pass *createConstantMergePass() { return new ConstantMerge(); }
-Pass *createDynamicConstantMergePass() { return new DynamicConstantMerge(); }