blob: 71eadbf9829963bdbc92c973c04f970a7318c617 [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
17#include "llvm/Transforms/ConstantMerge.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
22static Statistic<> NumMerged("constmerge\t\t- Number of global constants merged");
Chris Lattner4816d632001-10-18 20:05:37 +000023
Chris Lattner2ae9cda2002-06-25 15:55:29 +000024namespace {
25 struct ConstantMerge : public Pass {
Chris Lattner2ae9cda2002-06-25 15:55:29 +000026 // run - For this pass, process all of the globals in the module,
27 // eliminating duplicate constants.
28 //
29 bool run(Module &M);
30
31 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
32 AU.preservesCFG();
33 }
34 };
Chris Lattner6788f252002-07-23 18:06:30 +000035
36RegisterPass<ConstantMerge> X("constmerge", "Merge Duplicate Global Constants");
Chris Lattner2ae9cda2002-06-25 15:55:29 +000037}
38
39Pass *createConstantMergePass() { return new ConstantMerge(); }
40
41
42// ConstantMerge::run - Workhorse for the pass. This eliminates duplicate
Chris Lattner4816d632001-10-18 20:05:37 +000043// constants, starting at global ConstantNo, and adds vars to the map if they
44// are new and unique.
45//
Chris Lattner2ae9cda2002-06-25 15:55:29 +000046bool ConstantMerge::run(Module &M) {
47 std::map<Constant*, GlobalVariable*> CMap;
Chris Lattner4816d632001-10-18 20:05:37 +000048 bool MadeChanges = false;
49
Chris Lattner2ae9cda2002-06-25 15:55:29 +000050 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
Chris Lattner4816d632001-10-18 20:05:37 +000051 if (GV->isConstant()) { // Only process constants
52 assert(GV->hasInitializer() && "Globals constants must have inits!");
Chris Lattner3462ae32001-12-03 22:26:30 +000053 Constant *Init = GV->getInitializer();
Chris Lattner4816d632001-10-18 20:05:37 +000054
55 // Check to see if the initializer is already known...
Chris Lattner7f74a562002-01-20 22:54:45 +000056 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
Chris Lattner4816d632001-10-18 20:05:37 +000057
58 if (I == CMap.end()) { // Nope, add it to the map
Chris Lattner2ae9cda2002-06-25 15:55:29 +000059 CMap.insert(I, std::make_pair(Init, GV));
Chris Lattner4816d632001-10-18 20:05:37 +000060 } else { // Yup, this is a duplicate!
61 // Make all uses of the duplicate constant use the cannonical version...
62 GV->replaceAllUsesWith(I->second);
63
Chris Lattner2ae9cda2002-06-25 15:55:29 +000064 // Delete the global value from the module... and back up iterator to
65 // not skip the next global...
66 GV = --M.getGlobalList().erase(GV);
Chris Lattner4816d632001-10-18 20:05:37 +000067
Chris Lattner0b18c1d2002-05-10 15:38:35 +000068 ++NumMerged;
Chris Lattner4816d632001-10-18 20:05:37 +000069 MadeChanges = true;
70 }
71 }
Chris Lattner2ae9cda2002-06-25 15:55:29 +000072
Chris Lattner4816d632001-10-18 20:05:37 +000073 return MadeChanges;
74}