blob: 2ae61fac6e05cbc34e431705241ad867e12ba311 [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 Lattnerf52e03c2003-11-21 21:54:22 +000024using namespace llvm;
Brian Gaeke960707c2003-11-11 22:41:34 +000025
Chris Lattner2ae9cda2002-06-25 15:55:29 +000026namespace {
Chris Lattnereac4dcd2002-10-09 23:16:04 +000027 Statistic<> NumMerged("constmerge", "Number of global constants merged");
28
Chris Lattner2ae9cda2002-06-25 15:55:29 +000029 struct ConstantMerge : public Pass {
Chris Lattner2ae9cda2002-06-25 15:55:29 +000030 // run - For this pass, process all of the globals in the module,
31 // eliminating duplicate constants.
32 //
33 bool run(Module &M);
Chris Lattner2ae9cda2002-06-25 15:55:29 +000034 };
Chris Lattner6788f252002-07-23 18:06:30 +000035
Chris Lattnera2c09852002-07-26 21:12:44 +000036 RegisterOpt<ConstantMerge> X("constmerge","Merge Duplicate Global Constants");
Chris Lattner2ae9cda2002-06-25 15:55:29 +000037}
38
Chris Lattnerf52e03c2003-11-21 21:54:22 +000039Pass *llvm::createConstantMergePass() { return new ConstantMerge(); }
Chris Lattner2ae9cda2002-06-25 15:55:29 +000040
Chris Lattner2ae9cda2002-06-25 15:55:29 +000041bool ConstantMerge::run(Module &M) {
42 std::map<Constant*, GlobalVariable*> CMap;
Chris Lattner4816d632001-10-18 20:05:37 +000043 bool MadeChanges = false;
44
Chris Lattner2ae9cda2002-06-25 15:55:29 +000045 for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
Chris Lattner424132a2003-04-18 04:34:29 +000046 // Only process constants with initializers
47 if (GV->isConstant() && GV->hasInitializer()) {
Chris Lattner3462ae32001-12-03 22:26:30 +000048 Constant *Init = GV->getInitializer();
Chris Lattner4816d632001-10-18 20:05:37 +000049
50 // Check to see if the initializer is already known...
Chris Lattner7f74a562002-01-20 22:54:45 +000051 std::map<Constant*, GlobalVariable*>::iterator I = CMap.find(Init);
Chris Lattner4816d632001-10-18 20:05:37 +000052
53 if (I == CMap.end()) { // Nope, add it to the map
Chris Lattner2ae9cda2002-06-25 15:55:29 +000054 CMap.insert(I, std::make_pair(Init, GV));
Chris Lattnere5f15cd2003-10-29 06:01:26 +000055 } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate!
Chris Lattner216c7b82003-09-10 05:29:43 +000056 // Make all uses of the duplicate constant use the canonical version...
Chris Lattnereac4dcd2002-10-09 23:16:04 +000057 GV->replaceAllUsesWith(I->second);
Chris Lattnere5f15cd2003-10-29 06:01:26 +000058
Chris Lattner2ae9cda2002-06-25 15:55:29 +000059 // Delete the global value from the module... and back up iterator to
60 // not skip the next global...
61 GV = --M.getGlobalList().erase(GV);
Chris Lattner4816d632001-10-18 20:05:37 +000062
Chris Lattner0b18c1d2002-05-10 15:38:35 +000063 ++NumMerged;
Chris Lattner4816d632001-10-18 20:05:37 +000064 MadeChanges = true;
Chris Lattnere5f15cd2003-10-29 06:01:26 +000065 } else if (I->second->hasInternalLinkage()) {
66 // Make all uses of the duplicate constant use the canonical version...
67 I->second->replaceAllUsesWith(GV);
68
69 // Delete the global value from the module... and back up iterator to
70 // not skip the next global...
71 M.getGlobalList().erase(I->second);
72 I->second = GV;
73
74 ++NumMerged;
75 MadeChanges = true;
Chris Lattner4816d632001-10-18 20:05:37 +000076 }
77 }
Chris Lattner2ae9cda2002-06-25 15:55:29 +000078
Chris Lattner4816d632001-10-18 20:05:37 +000079 return MadeChanges;
80}
Brian Gaeke960707c2003-11-11 22:41:34 +000081