blob: b979104401c8bb04be1b2242a10f42e1ae5f106e [file] [log] [blame]
Chris Lattner4816d632001-10-18 20:05:37 +00001//===- 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
Chris Lattner62b7fd12002-04-07 20:49:59 +000012// that checks for each function to see if constants have been added to the
Chris Lattner4816d632001-10-18 20:05:37 +000013// constant pool since it was last run... if so, it processes them.
14//
15//===----------------------------------------------------------------------===//
16
Chris Lattnerb0cec702002-07-23 19:57:40 +000017#include "llvm/Transforms/IPO.h"
Chris Lattnerd5d56782002-01-31 00:45:11 +000018#include "llvm/Module.h"
Chris Lattner04805fa2002-02-26 21:46:54 +000019#include "llvm/Pass.h"
Chris Lattner0b18c1d2002-05-10 15:38:35 +000020#include "Support/StatisticReporter.h"
21
Chris Lattner2ae9cda2002-06-25 15:55:29 +000022namespace {
23 struct ConstantMerge : public Pass {
Chris Lattner2ae9cda2002-06-25 15:55:29 +000024 // run - For this pass, process all of the globals in the module,
25 // eliminating duplicate constants.
26 //
27 bool run(Module &M);
28
29 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
30 AU.preservesCFG();
31 }
32 };
Chris Lattner6788f252002-07-23 18:06:30 +000033
Chris Lattnera2c09852002-07-26 21:12:44 +000034 Statistic<> NumMerged("constmerge\t\t- Number of global constants merged");
35 RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants");
Chris Lattner2ae9cda2002-06-25 15:55:29 +000036}
37
38Pass *createConstantMergePass() { return new ConstantMerge(); }
39
40
41// ConstantMerge::run - Workhorse for the pass. This eliminates duplicate
Chris Lattner4816d632001-10-18 20:05:37 +000042// constants, starting at global ConstantNo, and adds vars to the map if they
43// are new and unique.
44//
Chris Lattner2ae9cda2002-06-25 15:55:29 +000045bool ConstantMerge::run(Module &M) {
46 std::map<Constant*, GlobalVariable*> CMap;
Chris Lattner4816d632001-10-18 20:05:37 +000047 bool MadeChanges = false;
48
Chris Lattner2ae9cda2002-06-25 15:55:29 +000049 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
Chris Lattner4816d632001-10-18 20:05:37 +000050 if (GV->isConstant()) { // Only process constants
51 assert(GV->hasInitializer() && "Globals constants must have inits!");
Chris Lattner3462ae32001-12-03 22:26:30 +000052 Constant *Init = GV->getInitializer();
Chris Lattner4816d632001-10-18 20:05:37 +000053
54 // Check to see if the initializer is already known...
Chris Lattner7f74a562002-01-20 22:54:45 +000055 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
Chris Lattner4816d632001-10-18 20:05:37 +000056
57 if (I == CMap.end()) { // Nope, add it to the map
Chris Lattner2ae9cda2002-06-25 15:55:29 +000058 CMap.insert(I, std::make_pair(Init, GV));
Chris Lattner4816d632001-10-18 20:05:37 +000059 } else { // Yup, this is a duplicate!
60 // Make all uses of the duplicate constant use the cannonical version...
61 GV->replaceAllUsesWith(I->second);
62
Chris Lattner2ae9cda2002-06-25 15:55:29 +000063 // Delete the global value from the module... and back up iterator to
64 // not skip the next global...
65 GV = --M.getGlobalList().erase(GV);
Chris Lattner4816d632001-10-18 20:05:37 +000066
Chris Lattner0b18c1d2002-05-10 15:38:35 +000067 ++NumMerged;
Chris Lattner4816d632001-10-18 20:05:37 +000068 MadeChanges = true;
69 }
70 }
Chris Lattner2ae9cda2002-06-25 15:55:29 +000071
Chris Lattner4816d632001-10-18 20:05:37 +000072 return MadeChanges;
73}