summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/ConstantMerge.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-10-18 20:05:37 +0000
committerChris Lattner <sabre@nondot.org>2001-10-18 20:05:37 +0000
commit475becb7bc835680c0b6973e8b7be0918f55cffd (patch)
tree935d2c7132f113d32da89dcecaa51e6e230cd703 /lib/Transforms/IPO/ConstantMerge.cpp
parent399376b53b91e52d82cb993ecd4eb895fb8461d2 (diff)
downloadllvm-475becb7bc835680c0b6973e8b7be0918f55cffd.tar.gz
llvm-475becb7bc835680c0b6973e8b7be0918f55cffd.tar.bz2
llvm-475becb7bc835680c0b6973e8b7be0918f55cffd.tar.xz
Initial checkin
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@897 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/ConstantMerge.cpp')
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
new file mode 100644
index 0000000000..3564a814c8
--- /dev/null
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -0,0 +1,80 @@
+//===- ConstantMerge.cpp - Merge duplicate global constants -----------------=//
+//
+// 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.
+//
+// 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 method to see if constants have been added to the
+// constant pool since it was last run... if so, it processes them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/ConstantMerge.h"
+#include "llvm/GlobalVariable.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,
+ map<ConstPoolVal*, GlobalVariable*> &CMap) {
+ Module::GlobalListType &GList = M->getGlobalList();
+ if (GList.size() <= ConstantNo) return false; // No new constants
+ bool MadeChanges = false;
+
+ for (; ConstantNo < GList.size(); ++ConstantNo) {
+ GlobalVariable *GV = GList[ConstantNo];
+ if (GV->isConstant()) { // Only process constants
+ assert(GV->hasInitializer() && "Globals constants must have inits!");
+ ConstPoolVal *Init = GV->getInitializer();
+
+ // Check to see if the initializer is already known...
+ map<ConstPoolVal*, GlobalVariable*>::iterator I = CMap.find(Init);
+
+ if (I == CMap.end()) { // Nope, add it to the map
+ CMap.insert(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);
+
+ --ConstantNo; // Don't skip the next constant.
+ MadeChanges = true;
+ }
+ }
+ }
+ return MadeChanges;
+}
+
+
+// mergeDuplicateConstants - Static accessor for clients that don't want to
+// deal with passes.
+//
+bool ConstantMerge::mergeDuplicateConstants(Module *M) {
+ map<ConstPoolVal*, GlobalVariable*> Constants;
+ unsigned LastConstantSeen = 0;
+ return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
+}
+
+
+// doPassInitialization - For this pass, process all of the globals in the
+// module, eliminating duplicate constants.
+//
+bool ConstantMerge::doPassInitialization(Module *M) {
+ return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
+}
+
+// doPerMethodWork - Check to see if any globals have been added to the
+// global list for the module. If so, eliminate them.
+//
+bool DynamicConstantMerge::doPerMethodWork(Method *M) {
+ return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen, Constants);
+}