blob: 498cd7bb1424bec911b87209d2e627f421128930 [file] [log] [blame]
Chris Lattner424132a2003-04-18 04:34:29 +00001//===- ConstantMerge.cpp - Merge duplicate global constants ---------------===//
John Criswell482202a2003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner4816d632001-10-18 20:05:37 +00009//
10// This file defines the interface to a pass that merges duplicate global
11// constants together into a single constant that is shared. This is useful
12// because some passes (ie TraceValues) insert a lot of string constants into
Chris Lattner28d10352002-09-23 23:00:46 +000013// the program, regardless of whether or not an existing string is available.
Chris Lattner4816d632001-10-18 20:05:37 +000014//
15// Algorithm: ConstantMerge is designed to build up a map of available constants
Chris Lattner28d10352002-09-23 23:00:46 +000016// and eliminate duplicates when it is initialized.
Chris Lattner4816d632001-10-18 20:05:37 +000017//
18//===----------------------------------------------------------------------===//
19
Chris Lattnerb0cec702002-07-23 19:57:40 +000020#include "llvm/Transforms/IPO.h"
Chris Lattnerd5d56782002-01-31 00:45:11 +000021#include "llvm/Module.h"
Chris Lattner04805fa2002-02-26 21:46:54 +000022#include "llvm/Pass.h"
Chris Lattnerbf3a0992002-10-01 22:38:41 +000023#include "Support/Statistic.h"
Chris Lattner0b18c1d2002-05-10 15:38:35 +000024
Brian Gaeke960707c2003-11-11 22:41:34 +000025namespace llvm {
26
Chris Lattner2ae9cda2002-06-25 15:55:29 +000027namespace {
Chris Lattnereac4dcd2002-10-09 23:16:04 +000028 Statistic<> NumMerged("constmerge", "Number of global constants merged");
29
Chris Lattner2ae9cda2002-06-25 15:55:29 +000030 struct ConstantMerge : public Pass {
Chris Lattner2ae9cda2002-06-25 15:55:29 +000031 // run - For this pass, process all of the globals in the module,
32 // eliminating duplicate constants.
33 //
34 bool run(Module &M);
Chris Lattner2ae9cda2002-06-25 15:55:29 +000035 };
Chris Lattner6788f252002-07-23 18:06:30 +000036
Chris Lattnera2c09852002-07-26 21:12:44 +000037 RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants");
Chris Lattner2ae9cda2002-06-25 15:55:29 +000038}
39
40Pass *createConstantMergePass() { return new ConstantMerge(); }
41
Chris Lattner2ae9cda2002-06-25 15:55:29 +000042bool ConstantMerge::run(Module &M) {
43 std::map<Constant*, GlobalVariable*> CMap;
Chris Lattner4816d632001-10-18 20:05:37 +000044 bool MadeChanges = false;
45
Chris Lattner2ae9cda2002-06-25 15:55:29 +000046 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
Chris Lattner424132a2003-04-18 04:34:29 +000047 // Only process constants with initializers
48 if (GV->isConstant() && GV->hasInitializer()) {
Chris Lattner3462ae32001-12-03 22:26:30 +000049 Constant *Init = GV->getInitializer();
Chris Lattner4816d632001-10-18 20:05:37 +000050
51 // Check to see if the initializer is already known...
Chris Lattner7f74a562002-01-20 22:54:45 +000052 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
Chris Lattner4816d632001-10-18 20:05:37 +000053
54 if (I == CMap.end()) { // Nope, add it to the map
Chris Lattner2ae9cda2002-06-25 15:55:29 +000055 CMap.insert(I, std::make_pair(Init, GV));
Chris Lattnere5f15cd2003-10-29 06:01:26 +000056 } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate!
Chris Lattner216c7b82003-09-10 05:29:43 +000057 // Make all uses of the duplicate constant use the canonical version...
Chris Lattnereac4dcd2002-10-09 23:16:04 +000058 GV->replaceAllUsesWith(I->second);
Chris Lattnere5f15cd2003-10-29 06:01:26 +000059
Chris Lattner2ae9cda2002-06-25 15:55:29 +000060 // Delete the global value from the module... and back up iterator to
61 // not skip the next global...
62 GV = --M.getGlobalList().erase(GV);
Chris Lattner4816d632001-10-18 20:05:37 +000063
Chris Lattner0b18c1d2002-05-10 15:38:35 +000064 ++NumMerged;
Chris Lattner4816d632001-10-18 20:05:37 +000065 MadeChanges = true;
Chris Lattnere5f15cd2003-10-29 06:01:26 +000066 } else if (I->second->hasInternalLinkage()) {
67 // Make all uses of the duplicate constant use the canonical version...
68 I->second->replaceAllUsesWith(GV);
69
70 // Delete the global value from the module... and back up iterator to
71 // not skip the next global...
72 M.getGlobalList().erase(I->second);
73 I->second = GV;
74
75 ++NumMerged;
76 MadeChanges = true;
Chris Lattner4816d632001-10-18 20:05:37 +000077 }
78 }
Chris Lattner2ae9cda2002-06-25 15:55:29 +000079
Chris Lattner4816d632001-10-18 20:05:37 +000080 return MadeChanges;
81}
Brian Gaeke960707c2003-11-11 22:41:34 +000082
83} // End llvm namespace