12cab237bSDimitry Andric //===- GlobalMerge.cpp - Internal globals merging -------------------------===//
291bc56edSDimitry Andric //
391bc56edSDimitry Andric //                     The LLVM Compiler Infrastructure
491bc56edSDimitry Andric //
591bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source
691bc56edSDimitry Andric // License. See LICENSE.TXT for details.
791bc56edSDimitry Andric //
891bc56edSDimitry Andric //===----------------------------------------------------------------------===//
92cab237bSDimitry Andric //
1091bc56edSDimitry Andric // This pass merges globals with internal linkage into one. This way all the
1191bc56edSDimitry Andric // globals which were merged into a biggest one can be addressed using offsets
1291bc56edSDimitry Andric // from the same base pointer (no need for separate base pointer for each of the
1391bc56edSDimitry Andric // global). Such a transformation can significantly reduce the register pressure
1491bc56edSDimitry Andric // when many globals are involved.
1591bc56edSDimitry Andric //
1691bc56edSDimitry Andric // For example, consider the code which touches several global variables at
1791bc56edSDimitry Andric // once:
1891bc56edSDimitry Andric //
1991bc56edSDimitry Andric // static int foo[N], bar[N], baz[N];
2091bc56edSDimitry Andric //
2191bc56edSDimitry Andric // for (i = 0; i < N; ++i) {
2291bc56edSDimitry Andric //    foo[i] = bar[i] * baz[i];
2391bc56edSDimitry Andric // }
2491bc56edSDimitry Andric //
2591bc56edSDimitry Andric //  On ARM the addresses of 3 arrays should be kept in the registers, thus
2691bc56edSDimitry Andric //  this code has quite large register pressure (loop body):
2791bc56edSDimitry Andric //
2891bc56edSDimitry Andric //  ldr     r1, [r5], #4
2991bc56edSDimitry Andric //  ldr     r2, [r6], #4
3091bc56edSDimitry Andric //  mul     r1, r2, r1
3191bc56edSDimitry Andric //  str     r1, [r0], #4
3291bc56edSDimitry Andric //
3391bc56edSDimitry Andric //  Pass converts the code to something like:
3491bc56edSDimitry Andric //
3591bc56edSDimitry Andric //  static struct {
3691bc56edSDimitry Andric //    int foo[N];
3791bc56edSDimitry Andric //    int bar[N];
3891bc56edSDimitry Andric //    int baz[N];
3991bc56edSDimitry Andric //  } merged;
4091bc56edSDimitry Andric //
4191bc56edSDimitry Andric //  for (i = 0; i < N; ++i) {
4291bc56edSDimitry Andric //    merged.foo[i] = merged.bar[i] * merged.baz[i];
4391bc56edSDimitry Andric //  }
4491bc56edSDimitry Andric //
4591bc56edSDimitry Andric //  and in ARM code this becomes:
4691bc56edSDimitry Andric //
4791bc56edSDimitry Andric //  ldr     r0, [r5, #40]
4891bc56edSDimitry Andric //  ldr     r1, [r5, #80]
4991bc56edSDimitry Andric //  mul     r0, r1, r0
5091bc56edSDimitry Andric //  str     r0, [r5], #4
5191bc56edSDimitry Andric //
5291bc56edSDimitry Andric //  note that we saved 2 registers here almostly "for free".
53ff0cc061SDimitry Andric //
54ff0cc061SDimitry Andric // However, merging globals can have tradeoffs:
55ff0cc061SDimitry Andric // - it confuses debuggers, tools, and users
56ff0cc061SDimitry Andric // - it makes linker optimizations less useful (order files, LOHs, ...)
57ff0cc061SDimitry Andric // - it forces usage of indexed addressing (which isn't necessarily "free")
58ff0cc061SDimitry Andric // - it can increase register pressure when the uses are disparate enough.
59ff0cc061SDimitry Andric //
60ff0cc061SDimitry Andric // We use heuristics to discover the best global grouping we can (cf cl::opts).
612cab237bSDimitry Andric //
6291bc56edSDimitry Andric // ===---------------------------------------------------------------------===//
6391bc56edSDimitry Andric 
642cab237bSDimitry Andric #include "llvm/ADT/BitVector.h"
65ff0cc061SDimitry Andric #include "llvm/ADT/DenseMap.h"
6691bc56edSDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
672cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
6891bc56edSDimitry Andric #include "llvm/ADT/Statistic.h"
692cab237bSDimitry Andric #include "llvm/ADT/StringRef.h"
702cab237bSDimitry Andric #include "llvm/ADT/Triple.h"
712cab237bSDimitry Andric #include "llvm/ADT/Twine.h"
7239d628a0SDimitry Andric #include "llvm/CodeGen/Passes.h"
732cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
7491bc56edSDimitry Andric #include "llvm/IR/Constants.h"
7591bc56edSDimitry Andric #include "llvm/IR/DataLayout.h"
7691bc56edSDimitry Andric #include "llvm/IR/DerivedTypes.h"
7791bc56edSDimitry Andric #include "llvm/IR/Function.h"
782cab237bSDimitry Andric #include "llvm/IR/GlobalAlias.h"
792cab237bSDimitry Andric #include "llvm/IR/GlobalValue.h"
8091bc56edSDimitry Andric #include "llvm/IR/GlobalVariable.h"
812cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
8291bc56edSDimitry Andric #include "llvm/IR/Module.h"
832cab237bSDimitry Andric #include "llvm/IR/Type.h"
842cab237bSDimitry Andric #include "llvm/IR/Use.h"
852cab237bSDimitry Andric #include "llvm/IR/User.h"
8691bc56edSDimitry Andric #include "llvm/Pass.h"
872cab237bSDimitry Andric #include "llvm/Support/Casting.h"
8891bc56edSDimitry Andric #include "llvm/Support/CommandLine.h"
89ff0cc061SDimitry Andric #include "llvm/Support/Debug.h"
90ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
914ba319b5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
922cab237bSDimitry Andric #include "llvm/Target/TargetMachine.h"
93ff0cc061SDimitry Andric #include <algorithm>
942cab237bSDimitry Andric #include <cassert>
952cab237bSDimitry Andric #include <cstddef>
962cab237bSDimitry Andric #include <cstdint>
972cab237bSDimitry Andric #include <string>
982cab237bSDimitry Andric #include <vector>
992cab237bSDimitry Andric 
10091bc56edSDimitry Andric using namespace llvm;
10191bc56edSDimitry Andric 
10291bc56edSDimitry Andric #define DEBUG_TYPE "global-merge"
10391bc56edSDimitry Andric 
104ff0cc061SDimitry Andric // FIXME: This is only useful as a last-resort way to disable the pass.
10591bc56edSDimitry Andric static cl::opt<bool>
10691bc56edSDimitry Andric EnableGlobalMerge("enable-global-merge", cl::Hidden,
107ff0cc061SDimitry Andric                   cl::desc("Enable the global merge pass"),
108ff0cc061SDimitry Andric                   cl::init(true));
109ff0cc061SDimitry Andric 
1103ca95b02SDimitry Andric static cl::opt<unsigned>
1113ca95b02SDimitry Andric GlobalMergeMaxOffset("global-merge-max-offset", cl::Hidden,
1123ca95b02SDimitry Andric                      cl::desc("Set maximum offset for global merge pass"),
1133ca95b02SDimitry Andric                      cl::init(0));
1143ca95b02SDimitry Andric 
115ff0cc061SDimitry Andric static cl::opt<bool> GlobalMergeGroupByUse(
116ff0cc061SDimitry Andric     "global-merge-group-by-use", cl::Hidden,
117ff0cc061SDimitry Andric     cl::desc("Improve global merge pass to look at uses"), cl::init(true));
118ff0cc061SDimitry Andric 
119ff0cc061SDimitry Andric static cl::opt<bool> GlobalMergeIgnoreSingleUse(
120ff0cc061SDimitry Andric     "global-merge-ignore-single-use", cl::Hidden,
121ff0cc061SDimitry Andric     cl::desc("Improve global merge pass to ignore globals only used alone"),
12291bc56edSDimitry Andric     cl::init(true));
12391bc56edSDimitry Andric 
12491bc56edSDimitry Andric static cl::opt<bool>
12591bc56edSDimitry Andric EnableGlobalMergeOnConst("global-merge-on-const", cl::Hidden,
12691bc56edSDimitry Andric                          cl::desc("Enable global merge pass on constants"),
12791bc56edSDimitry Andric                          cl::init(false));
12891bc56edSDimitry Andric 
12991bc56edSDimitry Andric // FIXME: this could be a transitional option, and we probably need to remove
13091bc56edSDimitry Andric // it if only we are sure this optimization could always benefit all targets.
1317d523365SDimitry Andric static cl::opt<cl::boolOrDefault>
13291bc56edSDimitry Andric EnableGlobalMergeOnExternal("global-merge-on-external", cl::Hidden,
1337d523365SDimitry Andric      cl::desc("Enable global merge pass on external linkage"));
13491bc56edSDimitry Andric 
13591bc56edSDimitry Andric STATISTIC(NumMerged, "Number of globals merged");
1362cab237bSDimitry Andric 
13791bc56edSDimitry Andric namespace {
1382cab237bSDimitry Andric 
13991bc56edSDimitry Andric   class GlobalMerge : public FunctionPass {
1402cab237bSDimitry Andric     const TargetMachine *TM = nullptr;
1412cab237bSDimitry Andric 
142ff0cc061SDimitry Andric     // FIXME: Infer the maximum possible offset depending on the actual users
143ff0cc061SDimitry Andric     // (these max offsets are different for the users inside Thumb or ARM
144ff0cc061SDimitry Andric     // functions), see the code that passes in the offset in the ARM backend
145ff0cc061SDimitry Andric     // for more information.
146ff0cc061SDimitry Andric     unsigned MaxOffset;
14791bc56edSDimitry Andric 
14897bc6c73SDimitry Andric     /// Whether we should try to optimize for size only.
14997bc6c73SDimitry Andric     /// Currently, this applies a dead simple heuristic: only consider globals
15097bc6c73SDimitry Andric     /// used in minsize functions for merging.
15197bc6c73SDimitry Andric     /// FIXME: This could learn about optsize, and be used in the cost model.
1522cab237bSDimitry Andric     bool OnlyOptimizeForSize = false;
15397bc6c73SDimitry Andric 
1547d523365SDimitry Andric     /// Whether we should merge global variables that have external linkage.
1552cab237bSDimitry Andric     bool MergeExternalGlobals = false;
1567d523365SDimitry Andric 
1573ca95b02SDimitry Andric     bool IsMachO;
1583ca95b02SDimitry Andric 
15991bc56edSDimitry Andric     bool doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
16091bc56edSDimitry Andric                  Module &M, bool isConst, unsigned AddrSpace) const;
1612cab237bSDimitry Andric 
1624ba319b5SDimitry Andric     /// Merge everything in \p Globals for which the corresponding bit
163ff0cc061SDimitry Andric     /// in \p GlobalSet is set.
1647d523365SDimitry Andric     bool doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
165ff0cc061SDimitry Andric                  const BitVector &GlobalSet, Module &M, bool isConst,
166ff0cc061SDimitry Andric                  unsigned AddrSpace) const;
16791bc56edSDimitry Andric 
1684ba319b5SDimitry Andric     /// Check if the given variable has been identified as must keep
16991bc56edSDimitry Andric     /// \pre setMustKeepGlobalVariables must have been called on the Module that
17091bc56edSDimitry Andric     ///      contains GV
isMustKeepGlobalVariable(const GlobalVariable * GV) const17191bc56edSDimitry Andric     bool isMustKeepGlobalVariable(const GlobalVariable *GV) const {
17291bc56edSDimitry Andric       return MustKeepGlobalVariables.count(GV);
17391bc56edSDimitry Andric     }
17491bc56edSDimitry Andric 
17591bc56edSDimitry Andric     /// Collect every variables marked as "used" or used in a landing pad
17691bc56edSDimitry Andric     /// instruction for this Module.
17791bc56edSDimitry Andric     void setMustKeepGlobalVariables(Module &M);
17891bc56edSDimitry Andric 
17991bc56edSDimitry Andric     /// Collect every variables marked as "used"
1804ba319b5SDimitry Andric     void collectUsedGlobalVariables(Module &M, StringRef Name);
18191bc56edSDimitry Andric 
18291bc56edSDimitry Andric     /// Keep track of the GlobalVariable that must not be merged away
18391bc56edSDimitry Andric     SmallPtrSet<const GlobalVariable *, 16> MustKeepGlobalVariables;
18491bc56edSDimitry Andric 
18591bc56edSDimitry Andric   public:
18691bc56edSDimitry Andric     static char ID;             // Pass identification, replacement for typeid.
1872cab237bSDimitry Andric 
GlobalMerge()1883ca95b02SDimitry Andric     explicit GlobalMerge()
1892cab237bSDimitry Andric         : FunctionPass(ID), MaxOffset(GlobalMergeMaxOffset) {
1903ca95b02SDimitry Andric       initializeGlobalMergePass(*PassRegistry::getPassRegistry());
1913ca95b02SDimitry Andric     }
1923ca95b02SDimitry Andric 
GlobalMerge(const TargetMachine * TM,unsigned MaximalOffset,bool OnlyOptimizeForSize,bool MergeExternalGlobals)1933ca95b02SDimitry Andric     explicit GlobalMerge(const TargetMachine *TM, unsigned MaximalOffset,
1943ca95b02SDimitry Andric                          bool OnlyOptimizeForSize, bool MergeExternalGlobals)
195875ed548SDimitry Andric         : FunctionPass(ID), TM(TM), MaxOffset(MaximalOffset),
1967d523365SDimitry Andric           OnlyOptimizeForSize(OnlyOptimizeForSize),
1977d523365SDimitry Andric           MergeExternalGlobals(MergeExternalGlobals) {
19891bc56edSDimitry Andric       initializeGlobalMergePass(*PassRegistry::getPassRegistry());
19991bc56edSDimitry Andric     }
20091bc56edSDimitry Andric 
20191bc56edSDimitry Andric     bool doInitialization(Module &M) override;
20291bc56edSDimitry Andric     bool runOnFunction(Function &F) override;
20391bc56edSDimitry Andric     bool doFinalization(Module &M) override;
20491bc56edSDimitry Andric 
getPassName() const205d88c1a5aSDimitry Andric     StringRef getPassName() const override { return "Merge internal globals"; }
20691bc56edSDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const20791bc56edSDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
20891bc56edSDimitry Andric       AU.setPreservesCFG();
20991bc56edSDimitry Andric       FunctionPass::getAnalysisUsage(AU);
21091bc56edSDimitry Andric     }
21191bc56edSDimitry Andric   };
2122cab237bSDimitry Andric 
21391bc56edSDimitry Andric } // end anonymous namespace
21491bc56edSDimitry Andric 
21591bc56edSDimitry Andric char GlobalMerge::ID = 0;
2162cab237bSDimitry Andric 
217302affcbSDimitry Andric INITIALIZE_PASS(GlobalMerge, DEBUG_TYPE, "Merge global variables", false, false)
21891bc56edSDimitry Andric 
doMerge(SmallVectorImpl<GlobalVariable * > & Globals,Module & M,bool isConst,unsigned AddrSpace) const21991bc56edSDimitry Andric bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
22091bc56edSDimitry Andric                           Module &M, bool isConst, unsigned AddrSpace) const {
221875ed548SDimitry Andric   auto &DL = M.getDataLayout();
22291bc56edSDimitry Andric   // FIXME: Find better heuristics
2237d523365SDimitry Andric   std::stable_sort(Globals.begin(), Globals.end(),
224875ed548SDimitry Andric                    [&DL](const GlobalVariable *GV1, const GlobalVariable *GV2) {
2257d523365SDimitry Andric                      return DL.getTypeAllocSize(GV1->getValueType()) <
2267d523365SDimitry Andric                             DL.getTypeAllocSize(GV2->getValueType());
22791bc56edSDimitry Andric                    });
22891bc56edSDimitry Andric 
229ff0cc061SDimitry Andric   // If we want to just blindly group all globals together, do so.
230ff0cc061SDimitry Andric   if (!GlobalMergeGroupByUse) {
231ff0cc061SDimitry Andric     BitVector AllGlobals(Globals.size());
232ff0cc061SDimitry Andric     AllGlobals.set();
233ff0cc061SDimitry Andric     return doMerge(Globals, AllGlobals, M, isConst, AddrSpace);
234ff0cc061SDimitry Andric   }
235ff0cc061SDimitry Andric 
236ff0cc061SDimitry Andric   // If we want to be smarter, look at all uses of each global, to try to
237ff0cc061SDimitry Andric   // discover all sets of globals used together, and how many times each of
2387d523365SDimitry Andric   // these sets occurred.
239ff0cc061SDimitry Andric   //
240ff0cc061SDimitry Andric   // Keep this reasonably efficient, by having an append-only list of all sets
241ff0cc061SDimitry Andric   // discovered so far (UsedGlobalSet), and mapping each "together-ness" unit of
242ff0cc061SDimitry Andric   // code (currently, a Function) to the set of globals seen so far that are
243ff0cc061SDimitry Andric   // used together in that unit (GlobalUsesByFunction).
244ff0cc061SDimitry Andric   //
2454ba319b5SDimitry Andric   // When we look at the Nth global, we know that any new set is either:
246ff0cc061SDimitry Andric   // - the singleton set {N}, containing this global only, or
247ff0cc061SDimitry Andric   // - the union of {N} and a previously-discovered set, containing some
248ff0cc061SDimitry Andric   //   combination of the previous N-1 globals.
249ff0cc061SDimitry Andric   // Using that knowledge, when looking at the Nth global, we can keep:
250ff0cc061SDimitry Andric   // - a reference to the singleton set {N} (CurGVOnlySetIdx)
251ff0cc061SDimitry Andric   // - a list mapping each previous set to its union with {N} (EncounteredUGS),
252ff0cc061SDimitry Andric   //   if it actually occurs.
253ff0cc061SDimitry Andric 
254ff0cc061SDimitry Andric   // We keep track of the sets of globals used together "close enough".
255ff0cc061SDimitry Andric   struct UsedGlobalSet {
256ff0cc061SDimitry Andric     BitVector Globals;
2572cab237bSDimitry Andric     unsigned UsageCount = 1;
2582cab237bSDimitry Andric 
2592cab237bSDimitry Andric     UsedGlobalSet(size_t Size) : Globals(Size) {}
260ff0cc061SDimitry Andric   };
261ff0cc061SDimitry Andric 
262ff0cc061SDimitry Andric   // Each set is unique in UsedGlobalSets.
263ff0cc061SDimitry Andric   std::vector<UsedGlobalSet> UsedGlobalSets;
264ff0cc061SDimitry Andric 
265ff0cc061SDimitry Andric   // Avoid repeating the create-global-set pattern.
266ff0cc061SDimitry Andric   auto CreateGlobalSet = [&]() -> UsedGlobalSet & {
267ff0cc061SDimitry Andric     UsedGlobalSets.emplace_back(Globals.size());
268ff0cc061SDimitry Andric     return UsedGlobalSets.back();
269ff0cc061SDimitry Andric   };
270ff0cc061SDimitry Andric 
271ff0cc061SDimitry Andric   // The first set is the empty set.
272ff0cc061SDimitry Andric   CreateGlobalSet().UsageCount = 0;
273ff0cc061SDimitry Andric 
274ff0cc061SDimitry Andric   // We define "close enough" to be "in the same function".
275ff0cc061SDimitry Andric   // FIXME: Grouping uses by function is way too aggressive, so we should have
276ff0cc061SDimitry Andric   // a better metric for distance between uses.
277ff0cc061SDimitry Andric   // The obvious alternative would be to group by BasicBlock, but that's in
278ff0cc061SDimitry Andric   // turn too conservative..
279ff0cc061SDimitry Andric   // Anything in between wouldn't be trivial to compute, so just stick with
280ff0cc061SDimitry Andric   // per-function grouping.
281ff0cc061SDimitry Andric 
282ff0cc061SDimitry Andric   // The value type is an index into UsedGlobalSets.
283ff0cc061SDimitry Andric   // The default (0) conveniently points to the empty set.
284ff0cc061SDimitry Andric   DenseMap<Function *, size_t /*UsedGlobalSetIdx*/> GlobalUsesByFunction;
285ff0cc061SDimitry Andric 
286ff0cc061SDimitry Andric   // Now, look at each merge-eligible global in turn.
287ff0cc061SDimitry Andric 
288ff0cc061SDimitry Andric   // Keep track of the sets we already encountered to which we added the
289ff0cc061SDimitry Andric   // current global.
290ff0cc061SDimitry Andric   // Each element matches the same-index element in UsedGlobalSets.
291ff0cc061SDimitry Andric   // This lets us efficiently tell whether a set has already been expanded to
292ff0cc061SDimitry Andric   // include the current global.
293ff0cc061SDimitry Andric   std::vector<size_t> EncounteredUGS;
294ff0cc061SDimitry Andric 
295ff0cc061SDimitry Andric   for (size_t GI = 0, GE = Globals.size(); GI != GE; ++GI) {
296ff0cc061SDimitry Andric     GlobalVariable *GV = Globals[GI];
297ff0cc061SDimitry Andric 
298ff0cc061SDimitry Andric     // Reset the encountered sets for this global...
299ff0cc061SDimitry Andric     std::fill(EncounteredUGS.begin(), EncounteredUGS.end(), 0);
300ff0cc061SDimitry Andric     // ...and grow it in case we created new sets for the previous global.
301ff0cc061SDimitry Andric     EncounteredUGS.resize(UsedGlobalSets.size());
302ff0cc061SDimitry Andric 
303ff0cc061SDimitry Andric     // We might need to create a set that only consists of the current global.
304ff0cc061SDimitry Andric     // Keep track of its index into UsedGlobalSets.
305ff0cc061SDimitry Andric     size_t CurGVOnlySetIdx = 0;
306ff0cc061SDimitry Andric 
307ff0cc061SDimitry Andric     // For each global, look at all its Uses.
308ff0cc061SDimitry Andric     for (auto &U : GV->uses()) {
309ff0cc061SDimitry Andric       // This Use might be a ConstantExpr.  We're interested in Instruction
310ff0cc061SDimitry Andric       // users, so look through ConstantExpr...
311ff0cc061SDimitry Andric       Use *UI, *UE;
312ff0cc061SDimitry Andric       if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
31397bc6c73SDimitry Andric         if (CE->use_empty())
31497bc6c73SDimitry Andric           continue;
315ff0cc061SDimitry Andric         UI = &*CE->use_begin();
316ff0cc061SDimitry Andric         UE = nullptr;
317ff0cc061SDimitry Andric       } else if (isa<Instruction>(U.getUser())) {
318ff0cc061SDimitry Andric         UI = &U;
319ff0cc061SDimitry Andric         UE = UI->getNext();
320ff0cc061SDimitry Andric       } else {
321ff0cc061SDimitry Andric         continue;
322ff0cc061SDimitry Andric       }
323ff0cc061SDimitry Andric 
324ff0cc061SDimitry Andric       // ...to iterate on all the instruction users of the global.
325ff0cc061SDimitry Andric       // Note that we iterate on Uses and not on Users to be able to getNext().
326ff0cc061SDimitry Andric       for (; UI != UE; UI = UI->getNext()) {
327ff0cc061SDimitry Andric         Instruction *I = dyn_cast<Instruction>(UI->getUser());
328ff0cc061SDimitry Andric         if (!I)
329ff0cc061SDimitry Andric           continue;
330ff0cc061SDimitry Andric 
331ff0cc061SDimitry Andric         Function *ParentFn = I->getParent()->getParent();
33297bc6c73SDimitry Andric 
33397bc6c73SDimitry Andric         // If we're only optimizing for size, ignore non-minsize functions.
3347d523365SDimitry Andric         if (OnlyOptimizeForSize && !ParentFn->optForMinSize())
33597bc6c73SDimitry Andric           continue;
33697bc6c73SDimitry Andric 
337ff0cc061SDimitry Andric         size_t UGSIdx = GlobalUsesByFunction[ParentFn];
338ff0cc061SDimitry Andric 
339ff0cc061SDimitry Andric         // If this is the first global the basic block uses, map it to the set
340ff0cc061SDimitry Andric         // consisting of this global only.
341ff0cc061SDimitry Andric         if (!UGSIdx) {
342ff0cc061SDimitry Andric           // If that set doesn't exist yet, create it.
343ff0cc061SDimitry Andric           if (!CurGVOnlySetIdx) {
344ff0cc061SDimitry Andric             CurGVOnlySetIdx = UsedGlobalSets.size();
345ff0cc061SDimitry Andric             CreateGlobalSet().Globals.set(GI);
346ff0cc061SDimitry Andric           } else {
347ff0cc061SDimitry Andric             ++UsedGlobalSets[CurGVOnlySetIdx].UsageCount;
348ff0cc061SDimitry Andric           }
349ff0cc061SDimitry Andric 
350ff0cc061SDimitry Andric           GlobalUsesByFunction[ParentFn] = CurGVOnlySetIdx;
351ff0cc061SDimitry Andric           continue;
352ff0cc061SDimitry Andric         }
353ff0cc061SDimitry Andric 
354ff0cc061SDimitry Andric         // If we already encountered this BB, just increment the counter.
355ff0cc061SDimitry Andric         if (UsedGlobalSets[UGSIdx].Globals.test(GI)) {
356ff0cc061SDimitry Andric           ++UsedGlobalSets[UGSIdx].UsageCount;
357ff0cc061SDimitry Andric           continue;
358ff0cc061SDimitry Andric         }
359ff0cc061SDimitry Andric 
360ff0cc061SDimitry Andric         // If not, the previous set wasn't actually used in this function.
361ff0cc061SDimitry Andric         --UsedGlobalSets[UGSIdx].UsageCount;
362ff0cc061SDimitry Andric 
363ff0cc061SDimitry Andric         // If we already expanded the previous set to include this global, just
364ff0cc061SDimitry Andric         // reuse that expanded set.
365ff0cc061SDimitry Andric         if (size_t ExpandedIdx = EncounteredUGS[UGSIdx]) {
366ff0cc061SDimitry Andric           ++UsedGlobalSets[ExpandedIdx].UsageCount;
367ff0cc061SDimitry Andric           GlobalUsesByFunction[ParentFn] = ExpandedIdx;
368ff0cc061SDimitry Andric           continue;
369ff0cc061SDimitry Andric         }
370ff0cc061SDimitry Andric 
371ff0cc061SDimitry Andric         // If not, create a new set consisting of the union of the previous set
372ff0cc061SDimitry Andric         // and this global.  Mark it as encountered, so we can reuse it later.
373ff0cc061SDimitry Andric         GlobalUsesByFunction[ParentFn] = EncounteredUGS[UGSIdx] =
374ff0cc061SDimitry Andric             UsedGlobalSets.size();
375ff0cc061SDimitry Andric 
376ff0cc061SDimitry Andric         UsedGlobalSet &NewUGS = CreateGlobalSet();
377ff0cc061SDimitry Andric         NewUGS.Globals.set(GI);
378ff0cc061SDimitry Andric         NewUGS.Globals |= UsedGlobalSets[UGSIdx].Globals;
379ff0cc061SDimitry Andric       }
380ff0cc061SDimitry Andric     }
381ff0cc061SDimitry Andric   }
382ff0cc061SDimitry Andric 
383ff0cc061SDimitry Andric   // Now we found a bunch of sets of globals used together.  We accumulated
384ff0cc061SDimitry Andric   // the number of times we encountered the sets (i.e., the number of blocks
385ff0cc061SDimitry Andric   // that use that exact set of globals).
386ff0cc061SDimitry Andric   //
387ff0cc061SDimitry Andric   // Multiply that by the size of the set to give us a crude profitability
388ff0cc061SDimitry Andric   // metric.
3892cab237bSDimitry Andric   std::stable_sort(UsedGlobalSets.begin(), UsedGlobalSets.end(),
390ff0cc061SDimitry Andric             [](const UsedGlobalSet &UGS1, const UsedGlobalSet &UGS2) {
391ff0cc061SDimitry Andric               return UGS1.Globals.count() * UGS1.UsageCount <
392ff0cc061SDimitry Andric                      UGS2.Globals.count() * UGS2.UsageCount;
393ff0cc061SDimitry Andric             });
394ff0cc061SDimitry Andric 
395ff0cc061SDimitry Andric   // We can choose to merge all globals together, but ignore globals never used
396ff0cc061SDimitry Andric   // with another global.  This catches the obviously non-profitable cases of
397ff0cc061SDimitry Andric   // having a single global, but is aggressive enough for any other case.
398ff0cc061SDimitry Andric   if (GlobalMergeIgnoreSingleUse) {
399ff0cc061SDimitry Andric     BitVector AllGlobals(Globals.size());
400ff0cc061SDimitry Andric     for (size_t i = 0, e = UsedGlobalSets.size(); i != e; ++i) {
401ff0cc061SDimitry Andric       const UsedGlobalSet &UGS = UsedGlobalSets[e - i - 1];
402ff0cc061SDimitry Andric       if (UGS.UsageCount == 0)
403ff0cc061SDimitry Andric         continue;
404ff0cc061SDimitry Andric       if (UGS.Globals.count() > 1)
405ff0cc061SDimitry Andric         AllGlobals |= UGS.Globals;
406ff0cc061SDimitry Andric     }
407ff0cc061SDimitry Andric     return doMerge(Globals, AllGlobals, M, isConst, AddrSpace);
408ff0cc061SDimitry Andric   }
409ff0cc061SDimitry Andric 
410ff0cc061SDimitry Andric   // Starting from the sets with the best (=biggest) profitability, find a
411ff0cc061SDimitry Andric   // good combination.
412ff0cc061SDimitry Andric   // The ideal (and expensive) solution can only be found by trying all
413ff0cc061SDimitry Andric   // combinations, looking for the one with the best profitability.
414ff0cc061SDimitry Andric   // Don't be smart about it, and just pick the first compatible combination,
415ff0cc061SDimitry Andric   // starting with the sets with the best profitability.
416ff0cc061SDimitry Andric   BitVector PickedGlobals(Globals.size());
417ff0cc061SDimitry Andric   bool Changed = false;
418ff0cc061SDimitry Andric 
419ff0cc061SDimitry Andric   for (size_t i = 0, e = UsedGlobalSets.size(); i != e; ++i) {
420ff0cc061SDimitry Andric     const UsedGlobalSet &UGS = UsedGlobalSets[e - i - 1];
421ff0cc061SDimitry Andric     if (UGS.UsageCount == 0)
422ff0cc061SDimitry Andric       continue;
423ff0cc061SDimitry Andric     if (PickedGlobals.anyCommon(UGS.Globals))
424ff0cc061SDimitry Andric       continue;
425ff0cc061SDimitry Andric     PickedGlobals |= UGS.Globals;
426ff0cc061SDimitry Andric     // If the set only contains one global, there's no point in merging.
427ff0cc061SDimitry Andric     // Ignore the global for inclusion in other sets though, so keep it in
428ff0cc061SDimitry Andric     // PickedGlobals.
429ff0cc061SDimitry Andric     if (UGS.Globals.count() < 2)
430ff0cc061SDimitry Andric       continue;
431ff0cc061SDimitry Andric     Changed |= doMerge(Globals, UGS.Globals, M, isConst, AddrSpace);
432ff0cc061SDimitry Andric   }
433ff0cc061SDimitry Andric 
434ff0cc061SDimitry Andric   return Changed;
435ff0cc061SDimitry Andric }
436ff0cc061SDimitry Andric 
doMerge(const SmallVectorImpl<GlobalVariable * > & Globals,const BitVector & GlobalSet,Module & M,bool isConst,unsigned AddrSpace) const4377d523365SDimitry Andric bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
438ff0cc061SDimitry Andric                           const BitVector &GlobalSet, Module &M, bool isConst,
439ff0cc061SDimitry Andric                           unsigned AddrSpace) const {
4407d523365SDimitry Andric   assert(Globals.size() > 1);
441ff0cc061SDimitry Andric 
44291bc56edSDimitry Andric   Type *Int32Ty = Type::getInt32Ty(M.getContext());
4434ba319b5SDimitry Andric   Type *Int8Ty = Type::getInt8Ty(M.getContext());
444875ed548SDimitry Andric   auto &DL = M.getDataLayout();
44591bc56edSDimitry Andric 
4464ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << " Trying to merge set, starts with #"
447ff0cc061SDimitry Andric                     << GlobalSet.find_first() << "\n");
448ff0cc061SDimitry Andric 
4494ba319b5SDimitry Andric   bool Changed = false;
450ff0cc061SDimitry Andric   ssize_t i = GlobalSet.find_first();
451ff0cc061SDimitry Andric   while (i != -1) {
452ff0cc061SDimitry Andric     ssize_t j = 0;
45391bc56edSDimitry Andric     uint64_t MergedSize = 0;
45491bc56edSDimitry Andric     std::vector<Type*> Tys;
45591bc56edSDimitry Andric     std::vector<Constant*> Inits;
4564ba319b5SDimitry Andric     std::vector<unsigned> StructIdxs;
45791bc56edSDimitry Andric 
458d88c1a5aSDimitry Andric     bool HasExternal = false;
459d88c1a5aSDimitry Andric     StringRef FirstExternalName;
4604ba319b5SDimitry Andric     unsigned MaxAlign = 1;
4614ba319b5SDimitry Andric     unsigned CurIdx = 0;
462ff0cc061SDimitry Andric     for (j = i; j != -1; j = GlobalSet.find_next(j)) {
4637d523365SDimitry Andric       Type *Ty = Globals[j]->getValueType();
464*b5893f02SDimitry Andric 
465*b5893f02SDimitry Andric       // Make sure we use the same alignment AsmPrinter would use.
4664ba319b5SDimitry Andric       unsigned Align = DL.getPreferredAlignment(Globals[j]);
4674ba319b5SDimitry Andric       unsigned Padding = alignTo(MergedSize, Align) - MergedSize;
4684ba319b5SDimitry Andric       MergedSize += Padding;
469875ed548SDimitry Andric       MergedSize += DL.getTypeAllocSize(Ty);
47091bc56edSDimitry Andric       if (MergedSize > MaxOffset) {
47191bc56edSDimitry Andric         break;
47291bc56edSDimitry Andric       }
4734ba319b5SDimitry Andric       if (Padding) {
4744ba319b5SDimitry Andric         Tys.push_back(ArrayType::get(Int8Ty, Padding));
4754ba319b5SDimitry Andric         Inits.push_back(ConstantAggregateZero::get(Tys.back()));
4764ba319b5SDimitry Andric         ++CurIdx;
4774ba319b5SDimitry Andric       }
47891bc56edSDimitry Andric       Tys.push_back(Ty);
47991bc56edSDimitry Andric       Inits.push_back(Globals[j]->getInitializer());
4804ba319b5SDimitry Andric       StructIdxs.push_back(CurIdx++);
4814ba319b5SDimitry Andric 
4824ba319b5SDimitry Andric       MaxAlign = std::max(MaxAlign, Align);
483d88c1a5aSDimitry Andric 
484d88c1a5aSDimitry Andric       if (Globals[j]->hasExternalLinkage() && !HasExternal) {
485d88c1a5aSDimitry Andric         HasExternal = true;
486d88c1a5aSDimitry Andric         FirstExternalName = Globals[j]->getName();
487d88c1a5aSDimitry Andric       }
48891bc56edSDimitry Andric     }
48991bc56edSDimitry Andric 
4904ba319b5SDimitry Andric     // Exit early if there is only one global to merge.
4914ba319b5SDimitry Andric     if (Tys.size() < 2) {
4924ba319b5SDimitry Andric       i = j;
4934ba319b5SDimitry Andric       continue;
4944ba319b5SDimitry Andric     }
4954ba319b5SDimitry Andric 
496d88c1a5aSDimitry Andric     // If merged variables doesn't have external linkage, we needn't to expose
497d88c1a5aSDimitry Andric     // the symbol after merging.
498d88c1a5aSDimitry Andric     GlobalValue::LinkageTypes Linkage = HasExternal
499d88c1a5aSDimitry Andric                                             ? GlobalValue::ExternalLinkage
500d88c1a5aSDimitry Andric                                             : GlobalValue::InternalLinkage;
5014ba319b5SDimitry Andric     // Use a packed struct so we can control alignment.
5024ba319b5SDimitry Andric     StructType *MergedTy = StructType::get(M.getContext(), Tys, true);
50391bc56edSDimitry Andric     Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);
50491bc56edSDimitry Andric 
505d88c1a5aSDimitry Andric     // On Darwin external linkage needs to be preserved, otherwise
506d88c1a5aSDimitry Andric     // dsymutil cannot preserve the debug info for the merged
507d88c1a5aSDimitry Andric     // variables.  If they have external linkage, use the symbol name
508d88c1a5aSDimitry Andric     // of the first variable merged as the suffix of global symbol
509d88c1a5aSDimitry Andric     // name.  This avoids a link-time naming conflict for the
510d88c1a5aSDimitry Andric     // _MergedGlobals symbols.
511d88c1a5aSDimitry Andric     Twine MergedName =
512d88c1a5aSDimitry Andric         (IsMachO && HasExternal)
513d88c1a5aSDimitry Andric             ? "_MergedGlobals_" + FirstExternalName
514d88c1a5aSDimitry Andric             : "_MergedGlobals";
515d88c1a5aSDimitry Andric     auto MergedLinkage = IsMachO ? Linkage : GlobalValue::PrivateLinkage;
516d88c1a5aSDimitry Andric     auto *MergedGV = new GlobalVariable(
517d88c1a5aSDimitry Andric         M, MergedTy, isConst, MergedLinkage, MergedInit, MergedName, nullptr,
518d88c1a5aSDimitry Andric         GlobalVariable::NotThreadLocal, AddrSpace);
519d88c1a5aSDimitry Andric 
5204ba319b5SDimitry Andric     MergedGV->setAlignment(MaxAlign);
521*b5893f02SDimitry Andric     MergedGV->setSection(Globals[i]->getSection());
52291bc56edSDimitry Andric 
5234ba319b5SDimitry Andric     const StructLayout *MergedLayout = DL.getStructLayout(MergedTy);
5247d523365SDimitry Andric     for (ssize_t k = i, idx = 0; k != j; k = GlobalSet.find_next(k), ++idx) {
52591bc56edSDimitry Andric       GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
52691bc56edSDimitry Andric       std::string Name = Globals[k]->getName();
5274ba319b5SDimitry Andric       GlobalValue::DLLStorageClassTypes DLLStorage =
5284ba319b5SDimitry Andric           Globals[k]->getDLLStorageClass();
52991bc56edSDimitry Andric 
530d88c1a5aSDimitry Andric       // Copy metadata while adjusting any debug info metadata by the original
531d88c1a5aSDimitry Andric       // global's offset within the merged global.
5324ba319b5SDimitry Andric       MergedGV->copyMetadata(Globals[k],
5334ba319b5SDimitry Andric                              MergedLayout->getElementOffset(StructIdxs[idx]));
534d88c1a5aSDimitry Andric 
53591bc56edSDimitry Andric       Constant *Idx[2] = {
53691bc56edSDimitry Andric           ConstantInt::get(Int32Ty, 0),
5374ba319b5SDimitry Andric           ConstantInt::get(Int32Ty, StructIdxs[idx]),
53891bc56edSDimitry Andric       };
539ff0cc061SDimitry Andric       Constant *GEP =
540ff0cc061SDimitry Andric           ConstantExpr::getInBoundsGetElementPtr(MergedTy, MergedGV, Idx);
54191bc56edSDimitry Andric       Globals[k]->replaceAllUsesWith(GEP);
54291bc56edSDimitry Andric       Globals[k]->eraseFromParent();
54391bc56edSDimitry Andric 
5447d523365SDimitry Andric       // When the linkage is not internal we must emit an alias for the original
5457d523365SDimitry Andric       // variable name as it may be accessed from another object. On non-Mach-O
5467d523365SDimitry Andric       // we can also emit an alias for internal linkage as it's safe to do so.
5477d523365SDimitry Andric       // It's not safe on Mach-O as the alias (and thus the portion of the
5487d523365SDimitry Andric       // MergedGlobals variable) may be dead stripped at link time.
5493ca95b02SDimitry Andric       if (Linkage != GlobalValue::InternalLinkage || !IsMachO) {
5504ba319b5SDimitry Andric         GlobalAlias *GA = GlobalAlias::create(Tys[StructIdxs[idx]], AddrSpace,
5514ba319b5SDimitry Andric                                               Linkage, Name, GEP, &M);
5524ba319b5SDimitry Andric         GA->setDLLStorageClass(DLLStorage);
55391bc56edSDimitry Andric       }
55491bc56edSDimitry Andric 
55591bc56edSDimitry Andric       NumMerged++;
55691bc56edSDimitry Andric     }
5574ba319b5SDimitry Andric     Changed = true;
55891bc56edSDimitry Andric     i = j;
55991bc56edSDimitry Andric   }
56091bc56edSDimitry Andric 
5614ba319b5SDimitry Andric   return Changed;
56291bc56edSDimitry Andric }
56391bc56edSDimitry Andric 
collectUsedGlobalVariables(Module & M,StringRef Name)5644ba319b5SDimitry Andric void GlobalMerge::collectUsedGlobalVariables(Module &M, StringRef Name) {
56591bc56edSDimitry Andric   // Extract global variables from llvm.used array
5664ba319b5SDimitry Andric   const GlobalVariable *GV = M.getGlobalVariable(Name);
56791bc56edSDimitry Andric   if (!GV || !GV->hasInitializer()) return;
56891bc56edSDimitry Andric 
56991bc56edSDimitry Andric   // Should be an array of 'i8*'.
57091bc56edSDimitry Andric   const ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());
57191bc56edSDimitry Andric 
57291bc56edSDimitry Andric   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
57391bc56edSDimitry Andric     if (const GlobalVariable *G =
57491bc56edSDimitry Andric         dyn_cast<GlobalVariable>(InitList->getOperand(i)->stripPointerCasts()))
57591bc56edSDimitry Andric       MustKeepGlobalVariables.insert(G);
57691bc56edSDimitry Andric }
57791bc56edSDimitry Andric 
setMustKeepGlobalVariables(Module & M)57891bc56edSDimitry Andric void GlobalMerge::setMustKeepGlobalVariables(Module &M) {
5794ba319b5SDimitry Andric   collectUsedGlobalVariables(M, "llvm.used");
5804ba319b5SDimitry Andric   collectUsedGlobalVariables(M, "llvm.compiler.used");
58191bc56edSDimitry Andric 
582d88c1a5aSDimitry Andric   for (Function &F : M) {
583d88c1a5aSDimitry Andric     for (BasicBlock &BB : F) {
584d88c1a5aSDimitry Andric       Instruction *Pad = BB.getFirstNonPHI();
585d88c1a5aSDimitry Andric       if (!Pad->isEHPad())
586d88c1a5aSDimitry Andric         continue;
58791bc56edSDimitry Andric 
588d88c1a5aSDimitry Andric       // Keep globals used by landingpads and catchpads.
589d88c1a5aSDimitry Andric       for (const Use &U : Pad->operands()) {
59091bc56edSDimitry Andric         if (const GlobalVariable *GV =
591d88c1a5aSDimitry Andric                 dyn_cast<GlobalVariable>(U->stripPointerCasts()))
59291bc56edSDimitry Andric           MustKeepGlobalVariables.insert(GV);
59391bc56edSDimitry Andric       }
59491bc56edSDimitry Andric     }
59591bc56edSDimitry Andric   }
596d88c1a5aSDimitry Andric }
59791bc56edSDimitry Andric 
doInitialization(Module & M)59891bc56edSDimitry Andric bool GlobalMerge::doInitialization(Module &M) {
59991bc56edSDimitry Andric   if (!EnableGlobalMerge)
60091bc56edSDimitry Andric     return false;
60191bc56edSDimitry Andric 
6023ca95b02SDimitry Andric   IsMachO = Triple(M.getTargetTriple()).isOSBinFormatMachO();
6033ca95b02SDimitry Andric 
604875ed548SDimitry Andric   auto &DL = M.getDataLayout();
605*b5893f02SDimitry Andric   DenseMap<std::pair<unsigned, StringRef>, SmallVector<GlobalVariable *, 16>>
606*b5893f02SDimitry Andric       Globals, ConstGlobals, BSSGlobals;
60791bc56edSDimitry Andric   bool Changed = false;
60891bc56edSDimitry Andric   setMustKeepGlobalVariables(M);
60991bc56edSDimitry Andric 
61091bc56edSDimitry Andric   // Grab all non-const globals.
6117d523365SDimitry Andric   for (auto &GV : M.globals()) {
61291bc56edSDimitry Andric     // Merge is safe for "normal" internal or external globals only
613*b5893f02SDimitry Andric     if (GV.isDeclaration() || GV.isThreadLocal() || GV.hasImplicitSection())
61491bc56edSDimitry Andric       continue;
61591bc56edSDimitry Andric 
6166d97bb29SDimitry Andric     // It's not safe to merge globals that may be preempted
6176d97bb29SDimitry Andric     if (TM && !TM->shouldAssumeDSOLocal(M, &GV))
6186d97bb29SDimitry Andric       continue;
6196d97bb29SDimitry Andric 
6207d523365SDimitry Andric     if (!(MergeExternalGlobals && GV.hasExternalLinkage()) &&
6217d523365SDimitry Andric         !GV.hasInternalLinkage())
62291bc56edSDimitry Andric       continue;
62391bc56edSDimitry Andric 
6247d523365SDimitry Andric     PointerType *PT = dyn_cast<PointerType>(GV.getType());
62591bc56edSDimitry Andric     assert(PT && "Global variable is not a pointer!");
62691bc56edSDimitry Andric 
62791bc56edSDimitry Andric     unsigned AddressSpace = PT->getAddressSpace();
628*b5893f02SDimitry Andric     StringRef Section = GV.getSection();
62991bc56edSDimitry Andric 
63091bc56edSDimitry Andric     // Ignore all 'special' globals.
6317d523365SDimitry Andric     if (GV.getName().startswith("llvm.") ||
6327d523365SDimitry Andric         GV.getName().startswith(".llvm."))
63391bc56edSDimitry Andric       continue;
63491bc56edSDimitry Andric 
63591bc56edSDimitry Andric     // Ignore all "required" globals:
6367d523365SDimitry Andric     if (isMustKeepGlobalVariable(&GV))
63791bc56edSDimitry Andric       continue;
63891bc56edSDimitry Andric 
6394ba319b5SDimitry Andric     Type *Ty = GV.getValueType();
640875ed548SDimitry Andric     if (DL.getTypeAllocSize(Ty) < MaxOffset) {
6413ca95b02SDimitry Andric       if (TM &&
642*b5893f02SDimitry Andric           TargetLoweringObjectFile::getKindForGlobal(&GV, *TM).isBSS())
643*b5893f02SDimitry Andric         BSSGlobals[{AddressSpace, Section}].push_back(&GV);
6447d523365SDimitry Andric       else if (GV.isConstant())
645*b5893f02SDimitry Andric         ConstGlobals[{AddressSpace, Section}].push_back(&GV);
64691bc56edSDimitry Andric       else
647*b5893f02SDimitry Andric         Globals[{AddressSpace, Section}].push_back(&GV);
64891bc56edSDimitry Andric     }
64991bc56edSDimitry Andric   }
65091bc56edSDimitry Andric 
6517d523365SDimitry Andric   for (auto &P : Globals)
6527d523365SDimitry Andric     if (P.second.size() > 1)
653*b5893f02SDimitry Andric       Changed |= doMerge(P.second, M, false, P.first.first);
65491bc56edSDimitry Andric 
6557d523365SDimitry Andric   for (auto &P : BSSGlobals)
6567d523365SDimitry Andric     if (P.second.size() > 1)
657*b5893f02SDimitry Andric       Changed |= doMerge(P.second, M, false, P.first.first);
65891bc56edSDimitry Andric 
65991bc56edSDimitry Andric   if (EnableGlobalMergeOnConst)
6607d523365SDimitry Andric     for (auto &P : ConstGlobals)
6617d523365SDimitry Andric       if (P.second.size() > 1)
662*b5893f02SDimitry Andric         Changed |= doMerge(P.second, M, true, P.first.first);
66391bc56edSDimitry Andric 
66491bc56edSDimitry Andric   return Changed;
66591bc56edSDimitry Andric }
66691bc56edSDimitry Andric 
runOnFunction(Function & F)66791bc56edSDimitry Andric bool GlobalMerge::runOnFunction(Function &F) {
66891bc56edSDimitry Andric   return false;
66991bc56edSDimitry Andric }
67091bc56edSDimitry Andric 
doFinalization(Module & M)67191bc56edSDimitry Andric bool GlobalMerge::doFinalization(Module &M) {
67291bc56edSDimitry Andric   MustKeepGlobalVariables.clear();
67391bc56edSDimitry Andric   return false;
67491bc56edSDimitry Andric }
67591bc56edSDimitry Andric 
createGlobalMergePass(const TargetMachine * TM,unsigned Offset,bool OnlyOptimizeForSize,bool MergeExternalByDefault)67697bc6c73SDimitry Andric Pass *llvm::createGlobalMergePass(const TargetMachine *TM, unsigned Offset,
6777d523365SDimitry Andric                                   bool OnlyOptimizeForSize,
6787d523365SDimitry Andric                                   bool MergeExternalByDefault) {
6797d523365SDimitry Andric   bool MergeExternal = (EnableGlobalMergeOnExternal == cl::BOU_UNSET) ?
6807d523365SDimitry Andric     MergeExternalByDefault : (EnableGlobalMergeOnExternal == cl::BOU_TRUE);
6817d523365SDimitry Andric   return new GlobalMerge(TM, Offset, OnlyOptimizeForSize, MergeExternal);
68291bc56edSDimitry Andric }
683