LLVM 23.0.0git
ConstantMerge.cpp
Go to the documentation of this file.
1//===- ConstantMerge.cpp - Merge duplicate global constants ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interface to a pass that merges duplicate global
10// constants together into a single constant that is shared. This is useful
11// because some passes (ie TraceValues) insert a lot of string constants into
12// the program, regardless of whether or not an existing string is available.
13//
14// Algorithm: ConstantMerge is designed to build up a map of available constants
15// and eliminate duplicates when it is initialized.
16//
17//===----------------------------------------------------------------------===//
18
20#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/Statistic.h"
24#include "llvm/IR/Constants.h"
25#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/LLVMContext.h"
30#include "llvm/IR/Module.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Transforms/IPO.h"
34#include <algorithm>
35#include <cassert>
36#include <utility>
37
38using namespace llvm;
39
40#define DEBUG_TYPE "constmerge"
41
42STATISTIC(NumIdenticalMerged, "Number of identical global constants merged");
43
44/// Find values that are marked as llvm.used.
45static void FindUsedValues(GlobalVariable *LLVMUsed,
47 if (!LLVMUsed) return;
48 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
49
50 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
51 Value *Operand = Inits->getOperand(i)->stripPointerCasts();
52 GlobalValue *GV = cast<GlobalValue>(Operand);
53 UsedValues.insert(GV);
54 }
55}
56
57// True if A is better than B.
59 const GlobalVariable &B) {
60 if (!A.hasLocalLinkage() && B.hasLocalLinkage())
61 return true;
62
63 if (A.hasLocalLinkage() && !B.hasLocalLinkage())
64 return false;
65
66 return A.hasGlobalUnnamedAddr();
67}
68
69static void copyDebugLocMetadata(const GlobalVariable *From,
70 GlobalVariable *To) {
72 From->getDebugInfo(MDs);
73 for (auto *MD : MDs)
74 To->addDebugInfo(MD);
75}
76
78 return GV->getAlign().value_or(
80}
81
82static bool
84 const SmallPtrSetImpl<const GlobalValue *> &UsedGlobals) {
85 // Only process constants with initializers in the default address space.
86 return !GV->isConstant() || !GV->hasDefinitiveInitializer() ||
87 GV->getType()->getAddressSpace() != 0 || GV->hasSection() ||
88 // Don't touch thread-local variables.
89 GV->isThreadLocal() ||
90 // Don't touch values marked with attribute(used).
91 UsedGlobals.count(GV);
92}
93
94enum class CanMerge { No, Yes };
96 if (!Old->hasGlobalUnnamedAddr() && !New->hasGlobalUnnamedAddr())
97 return CanMerge::No;
99 return CanMerge::No;
100 assert(!New->hasMetadataOtherThanDebugLoc());
101 if (!Old->hasGlobalUnnamedAddr())
102 New->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
103 return CanMerge::Yes;
104}
105
106static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New) {
107 Constant *NewConstant = New;
108
109 LLVM_DEBUG(dbgs() << "Replacing global: @" << Old->getName() << " -> @"
110 << New->getName() << "\n");
111
112 // Bump the alignment if necessary.
113 if (Old->getAlign() || New->getAlign())
114 New->setAlignment(std::max(getAlign(Old), getAlign(New)));
115
116 copyDebugLocMetadata(Old, New);
117 Old->replaceAllUsesWith(NewConstant);
118
119 // Delete the global value from the module.
120 assert(Old->hasLocalLinkage() &&
121 "Refusing to delete an externally visible global variable.");
122 Old->eraseFromParent();
123}
124
125static bool mergeConstants(Module &M) {
126 // Find all the globals that are marked "used". These cannot be merged.
128 FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals);
129 FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals);
130
131 // Map unique constants to globals.
133
135 SameContentReplacements;
136
137 size_t ChangesMade = 0;
138 size_t OldChangesMade = 0;
139
140 // Iterate constant merging while we are still making progress. Merging two
141 // constants together may allow us to merge other constants together if the
142 // second level constants have initializers which point to the globals that
143 // were just merged.
144 while (true) {
145 // Find the canonical constants others will be merged with.
146 for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
147 // If this GV is dead, remove it.
148 GV.removeDeadConstantUsers();
149 if (GV.use_empty() && GV.hasLocalLinkage()) {
150 GV.eraseFromParent();
151 ++ChangesMade;
152 continue;
153 }
154
155 if (isUnmergeableGlobal(&GV, UsedGlobals))
156 continue;
157
158 // This transformation is legal for weak ODR globals in the sense it
159 // doesn't change semantics, but we really don't want to perform it
160 // anyway; it's likely to pessimize code generation, and some tools
161 // (like the Darwin linker in cases involving CFString) don't expect it.
162 if (GV.isWeakForLinker())
163 continue;
164
165 // Don't touch globals with metadata other then !dbg.
166 if (GV.hasMetadataOtherThanDebugLoc())
167 continue;
168
169 Constant *Init = GV.getInitializer();
170
171 // Check to see if the initializer is already known.
172 GlobalVariable *&Slot = CMap[Init];
173
174 // If this is the first constant we find or if the old one is local,
175 // replace with the current one. If the current is externally visible
176 // it cannot be replace, but can be the canonical constant we merge with.
177 bool FirstConstantFound = !Slot;
178 if (FirstConstantFound || IsBetterCanonical(GV, *Slot)) {
179 Slot = &GV;
180 LLVM_DEBUG(dbgs() << "Cmap[" << *Init << "] = " << GV.getName()
181 << (FirstConstantFound ? "\n" : " (updated)\n"));
182 }
183 }
184
185 // Identify all globals that can be merged together, filling in the
186 // SameContentReplacements vector. We cannot do the replacement in this pass
187 // because doing so may cause initializers of other globals to be rewritten,
188 // invalidating the Constant* pointers in CMap.
189 for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
190 if (isUnmergeableGlobal(&GV, UsedGlobals))
191 continue;
192
193 // We can only replace constant with local linkage.
194 if (!GV.hasLocalLinkage())
195 continue;
196
197 Constant *Init = GV.getInitializer();
198
199 // Check to see if the initializer is already known.
200 auto Found = CMap.find(Init);
201 if (Found == CMap.end())
202 continue;
203
204 GlobalVariable *Slot = Found->second;
205 if (Slot == &GV)
206 continue;
207
208 if (makeMergeable(&GV, Slot) == CanMerge::No)
209 continue;
210
211 // Make all uses of the duplicate constant use the canonical version.
212 LLVM_DEBUG(dbgs() << "Will replace: @" << GV.getName() << " -> @"
213 << Slot->getName() << "\n");
214 SameContentReplacements.push_back(std::make_pair(&GV, Slot));
215 }
216
217 // Now that we have figured out which replacements must be made, do them all
218 // now. This avoid invalidating the pointers in CMap, which are unneeded
219 // now.
220 for (const auto &[Old, New] : SameContentReplacements) {
221 replace(M, Old, New);
222 ++ChangesMade;
223 ++NumIdenticalMerged;
224 }
225
226 if (ChangesMade == OldChangesMade)
227 break;
228 OldChangesMade = ChangesMade;
229
230 SameContentReplacements.clear();
231 CMap.clear();
232 }
233
234 return ChangesMade;
235}
236
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool IsBetterCanonical(const GlobalVariable &A, const GlobalVariable &B)
static void copyDebugLocMetadata(const GlobalVariable *From, GlobalVariable *To)
static bool mergeConstants(Module &M)
static bool isUnmergeableGlobal(GlobalVariable *GV, const SmallPtrSetImpl< const GlobalValue * > &UsedGlobals)
static void FindUsedValues(GlobalVariable *LLVMUsed, SmallPtrSetImpl< const GlobalValue * > &UsedValues)
Find values that are marked as llvm.used.
CanMerge
static CanMerge makeMergeable(GlobalVariable *Old, GlobalVariable *New)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
ConstantArray - Constant Array Declarations.
Definition Constants.h:438
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
This is an important base class in LLVM.
Definition Constant.h:43
LLVM_ABI Align getPreferredAlign(const GlobalVariable *GV) const
Returns the preferred alignment of the specified global.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
iterator end()
Definition DenseMap.h:81
LLVM_ABI bool hasMetadataOtherThanDebugLoc() const
Definition Globals.cpp:391
bool hasSection() const
Check if this global has a custom object file section.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasLocalLinkage() const
PointerType * getType() const
Global values are always pointers.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:132
bool hasGlobalUnnamedAddr() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
LLVM_ABI void getDebugInfo(SmallVectorImpl< DIGlobalVariableExpression * > &GVs) const
Fill the vector with all debug info attachements.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Globals.cpp:529
LLVM_ABI void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:708
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
MaybeAlign getAlign(const CallInst &I, unsigned Index)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:632
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1908
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39