//===- GlobalMerge.cpp - Internal globals merging -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass merges globals with internal linkage into one. This way all the
// globals which were merged into a biggest one can be addressed using offsets
// from the same base pointer (no need for separate base pointer for each of the
// global). Such a transformation can significantly reduce the register pressure
// when many globals are involved.
//
// For example, consider the code which touches several global variables at
// once:
//
// static int foo[N], bar[N], baz[N];
//
// for (i = 0; i < N; ++i) {
//    foo[i] = bar[i] * baz[i];
// }
//
//  On ARM the addresses of 3 arrays should be kept in the registers, thus
//  this code has quite large register pressure (loop body):
//
//  ldr     r1, [r5], #4
//  ldr     r2, [r6], #4
//  mul     r1, r2, r1
//  str     r1, [r0], #4
//
//  Pass converts the code to something like:
//
//  static struct {
//    int foo[N];
//    int bar[N];
//    int baz[N];
//  } merged;
//
//  for (i = 0; i < N; ++i) {
//    merged.foo[i] = merged.bar[i] * merged.baz[i];
//  }
//
//  and in ARM code this becomes:
//
//  ldr     r0, [r5, #40]
//  ldr     r1, [r5, #80]
//  mul     r0, r1, r0
//  str     r0, [r5], #4
//
//  note that we saved 2 registers here almostly "for free".
//
// However, merging globals can have tradeoffs:
// - it confuses debuggers, tools, and users
// - it makes linker optimizations less useful (order files, LOHs, ...)
// - it forces usage of indexed addressing (which isn't necessarily "free")
// - it can increase register pressure when the uses are disparate enough.
//
// We use heuristics to discover the best global grouping we can (cf cl::opts).
//
// ===---------------------------------------------------------------------===//

#include "llvm/CodeGen/GlobalMerge.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "global-merge"

// FIXME: This is only useful as a last-resort way to disable the pass.
static cl::opt<bool>
EnableGlobalMerge("enable-global-merge", cl::Hidden,
                  cl::desc("Enable the global merge pass"),
                  cl::init(true));

static cl::opt<unsigned>
GlobalMergeMaxOffset("global-merge-max-offset", cl::Hidden,
                     cl::desc("Set maximum offset for global merge pass"),
                     cl::init(0));

static cl::opt<bool> GlobalMergeGroupByUse(
    "global-merge-group-by-use", cl::Hidden,
    cl::desc("Improve global merge pass to look at uses"), cl::init(true));

static cl::opt<bool> GlobalMergeAllConst(
    "global-merge-all-const", cl::Hidden,
    cl::desc("Merge all const globals without looking at uses"),
    cl::init(false));

static cl::opt<bool> GlobalMergeIgnoreSingleUse(
    "global-merge-ignore-single-use", cl::Hidden,
    cl::desc("Improve global merge pass to ignore globals only used alone"),
    cl::init(true));

static cl::opt<bool>
EnableGlobalMergeOnConst("global-merge-on-const", cl::Hidden,
                         cl::desc("Enable global merge pass on constants"),
                         cl::init(false));

// FIXME: this could be a transitional option, and we probably need to remove
// it if only we are sure this optimization could always benefit all targets.
static cl::opt<cl::boolOrDefault>
EnableGlobalMergeOnExternal("global-merge-on-external", cl::Hidden,
     cl::desc("Enable global merge pass on external linkage"));

static cl::opt<unsigned>
    GlobalMergeMinDataSize("global-merge-min-data-size",
                           cl::desc("The minimum size in bytes of each global "
                                    "that should considered in merging."),
                           cl::init(0), cl::Hidden);

STATISTIC(NumMerged, "Number of globals merged");

namespace {

class GlobalMergeImpl {
  const TargetMachine *TM = nullptr;
  GlobalMergeOptions Opt;
  bool IsMachO = false;

private:
  bool doMerge(SmallVectorImpl<GlobalVariable *> &Globals, Module &M,
               bool isConst, unsigned AddrSpace) const;

  /// Merge everything in \p Globals for which the corresponding bit
  /// in \p GlobalSet is set.
  bool doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
               const BitVector &GlobalSet, Module &M, bool isConst,
               unsigned AddrSpace) const;

  /// Check if the given variable has been identified as must keep
  /// \pre setMustKeepGlobalVariables must have been called on the Module that
  ///      contains GV
  bool isMustKeepGlobalVariable(const GlobalVariable *GV) const {
    return MustKeepGlobalVariables.count(GV);
  }

  /// Collect every variables marked as "used" or used in a landing pad
  /// instruction for this Module.
  void setMustKeepGlobalVariables(Module &M);

  /// Collect every variables marked as "used"
  void collectUsedGlobalVariables(Module &M, StringRef Name);

  /// Keep track of the GlobalVariable that must not be merged away
  SmallSetVector<const GlobalVariable *, 16> MustKeepGlobalVariables;

public:
  GlobalMergeImpl(const TargetMachine *TM, GlobalMergeOptions Opt)
      : TM(TM), Opt(Opt) {}
  bool run(Module &M);
};

class GlobalMerge : public FunctionPass {
  const TargetMachine *TM = nullptr;
  GlobalMergeOptions Opt;

public:
  static char ID; // Pass identification, replacement for typeid.

  explicit GlobalMerge() : FunctionPass(ID) {
    Opt.MaxOffset = GlobalMergeMaxOffset;
    initializeGlobalMergePass(*PassRegistry::getPassRegistry());
  }

  explicit GlobalMerge(const TargetMachine *TM, unsigned MaximalOffset,
                       bool OnlyOptimizeForSize, bool MergeExternalGlobals,
                       bool MergeConstantGlobals, bool MergeConstAggressive)
      : FunctionPass(ID), TM(TM) {
    Opt.MaxOffset = MaximalOffset;
    Opt.SizeOnly = OnlyOptimizeForSize;
    Opt.MergeExternal = MergeExternalGlobals;
    Opt.MergeConstantGlobals = MergeConstantGlobals;
    Opt.MergeConstAggressive = MergeConstAggressive;
    initializeGlobalMergePass(*PassRegistry::getPassRegistry());
  }

  bool doInitialization(Module &M) override {
    auto GetSmallDataLimit = [](Module &M) -> std::optional<uint64_t> {
      Metadata *SDL = M.getModuleFlag("SmallDataLimit");
      if (!SDL)
        return std::nullopt;
      return mdconst::extract<ConstantInt>(SDL)->getZExtValue();
    };
    if (GlobalMergeMinDataSize.getNumOccurrences())
      Opt.MinSize = GlobalMergeMinDataSize;
    else if (auto SDL = GetSmallDataLimit(M); SDL && *SDL > 0)
      Opt.MinSize = *SDL + 1;
    else
      Opt.MinSize = 0;

    GlobalMergeImpl P(TM, Opt);
    return P.run(M);
  }
  bool runOnFunction(Function &F) override { return false; }

  StringRef getPassName() const override { return "Merge internal globals"; }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    FunctionPass::getAnalysisUsage(AU);
  }
};

} // end anonymous namespace

PreservedAnalyses GlobalMergePass::run(Module &M, ModuleAnalysisManager &) {
  GlobalMergeImpl P(TM, Options);
  bool Changed = P.run(M);
  if (!Changed)
    return PreservedAnalyses::all();

  PreservedAnalyses PA;
  PA.preserveSet<CFGAnalyses>();
  return PA;
}

char GlobalMerge::ID = 0;

INITIALIZE_PASS(GlobalMerge, DEBUG_TYPE, "Merge global variables", false, false)

bool GlobalMergeImpl::doMerge(SmallVectorImpl<GlobalVariable *> &Globals,
                              Module &M, bool isConst,
                              unsigned AddrSpace) const {
  auto &DL = M.getDataLayout();
  // FIXME: Find better heuristics
  llvm::stable_sort(
      Globals, [&DL](const GlobalVariable *GV1, const GlobalVariable *GV2) {
        // We don't support scalable global variables.
        return DL.getTypeAllocSize(GV1->getValueType()).getFixedValue() <
               DL.getTypeAllocSize(GV2->getValueType()).getFixedValue();
      });

  // If we want to just blindly group all globals together, do so.
  if (!GlobalMergeGroupByUse || (Opt.MergeConstAggressive && isConst)) {
    BitVector AllGlobals(Globals.size(), true);
    return doMerge(Globals, AllGlobals, M, isConst, AddrSpace);
  }

  // If we want to be smarter, look at all uses of each global, to try to
  // discover all sets of globals used together, and how many times each of
  // these sets occurred.
  //
  // Keep this reasonably efficient, by having an append-only list of all sets
  // discovered so far (UsedGlobalSet), and mapping each "together-ness" unit of
  // code (currently, a Function) to the set of globals seen so far that are
  // used together in that unit (GlobalUsesByFunction).
  //
  // When we look at the Nth global, we know that any new set is either:
  // - the singleton set {N}, containing this global only, or
  // - the union of {N} and a previously-discovered set, containing some
  //   combination of the previous N-1 globals.
  // Using that knowledge, when looking at the Nth global, we can keep:
  // - a reference to the singleton set {N} (CurGVOnlySetIdx)
  // - a list mapping each previous set to its union with {N} (EncounteredUGS),
  //   if it actually occurs.

  // We keep track of the sets of globals used together "close enough".
  struct UsedGlobalSet {
    BitVector Globals;
    unsigned UsageCount = 1;

    UsedGlobalSet(size_t Size) : Globals(Size) {}
  };

  // Each set is unique in UsedGlobalSets.
  std::vector<UsedGlobalSet> UsedGlobalSets;

  // Avoid repeating the create-global-set pattern.
  auto CreateGlobalSet = [&]() -> UsedGlobalSet & {
    UsedGlobalSets.emplace_back(Globals.size());
    return UsedGlobalSets.back();
  };

  // The first set is the empty set.
  CreateGlobalSet().UsageCount = 0;

  // We define "close enough" to be "in the same function".
  // FIXME: Grouping uses by function is way too aggressive, so we should have
  // a better metric for distance between uses.
  // The obvious alternative would be to group by BasicBlock, but that's in
  // turn too conservative..
  // Anything in between wouldn't be trivial to compute, so just stick with
  // per-function grouping.

  // The value type is an index into UsedGlobalSets.
  // The default (0) conveniently points to the empty set.
  DenseMap<Function *, size_t /*UsedGlobalSetIdx*/> GlobalUsesByFunction;

  // Now, look at each merge-eligible global in turn.

  // Keep track of the sets we already encountered to which we added the
  // current global.
  // Each element matches the same-index element in UsedGlobalSets.
  // This lets us efficiently tell whether a set has already been expanded to
  // include the current global.
  std::vector<size_t> EncounteredUGS;

  for (size_t GI = 0, GE = Globals.size(); GI != GE; ++GI) {
    GlobalVariable *GV = Globals[GI];

    // Reset the encountered sets for this global and grow it in case we created
    // new sets for the previous global.
    EncounteredUGS.assign(UsedGlobalSets.size(), 0);

    // We might need to create a set that only consists of the current global.
    // Keep track of its index into UsedGlobalSets.
    size_t CurGVOnlySetIdx = 0;

    // For each global, look at all its Uses.
    for (auto &U : GV->uses()) {
      // This Use might be a ConstantExpr.  We're interested in Instruction
      // users, so look through ConstantExpr...
      Use *UI, *UE;
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
        if (CE->use_empty())
          continue;
        UI = &*CE->use_begin();
        UE = nullptr;
      } else if (isa<Instruction>(U.getUser())) {
        UI = &U;
        UE = UI->getNext();
      } else {
        continue;
      }

      // ...to iterate on all the instruction users of the global.
      // Note that we iterate on Uses and not on Users to be able to getNext().
      for (; UI != UE; UI = UI->getNext()) {
        Instruction *I = dyn_cast<Instruction>(UI->getUser());
        if (!I)
          continue;

        Function *ParentFn = I->getParent()->getParent();

        // If we're only optimizing for size, ignore non-minsize functions.
        if (Opt.SizeOnly && !ParentFn->hasMinSize())
          continue;

        size_t UGSIdx = GlobalUsesByFunction[ParentFn];

        // If this is the first global the function uses, map it to the set
        // consisting of this global only.
        if (!UGSIdx) {
          // If that set doesn't exist yet, create it.
          if (!CurGVOnlySetIdx) {
            CurGVOnlySetIdx = UsedGlobalSets.size();
            CreateGlobalSet().Globals.set(GI);
          } else {
            ++UsedGlobalSets[CurGVOnlySetIdx].UsageCount;
          }

          GlobalUsesByFunction[ParentFn] = CurGVOnlySetIdx;
          continue;
        }

        // If we already encountered a use of this global in this function, just
        // increment the counter.
        if (UsedGlobalSets[UGSIdx].Globals.test(GI)) {
          ++UsedGlobalSets[UGSIdx].UsageCount;
          continue;
        }

        // If not, the previous set wasn't actually used in this function.
        --UsedGlobalSets[UGSIdx].UsageCount;

        // If we already expanded the previous set to include this global, just
        // reuse that expanded set.
        if (size_t ExpandedIdx = EncounteredUGS[UGSIdx]) {
          ++UsedGlobalSets[ExpandedIdx].UsageCount;
          GlobalUsesByFunction[ParentFn] = ExpandedIdx;
          continue;
        }

        // If not, create a new set consisting of the union of the previous set
        // and this global.  Mark it as encountered, so we can reuse it later.
        GlobalUsesByFunction[ParentFn] = EncounteredUGS[UGSIdx] =
            UsedGlobalSets.size();

        UsedGlobalSet &NewUGS = CreateGlobalSet();
        NewUGS.Globals.set(GI);
        NewUGS.Globals |= UsedGlobalSets[UGSIdx].Globals;
      }
    }
  }

  // We can choose to merge all globals together, but ignore globals never used
  // with another global.  This catches the obviously non-profitable cases of
  // having a single global, but is aggressive enough for any other case.
  if (GlobalMergeIgnoreSingleUse) {
    BitVector AllGlobals(Globals.size());
    for (const UsedGlobalSet &UGS : UsedGlobalSets) {
      if (UGS.UsageCount == 0)
        continue;
      if (UGS.Globals.count() > 1)
        AllGlobals |= UGS.Globals;
    }
    return doMerge(Globals, AllGlobals, M, isConst, AddrSpace);
  }

  // Now we found a bunch of sets of globals used together.  We accumulated
  // the number of times we encountered the sets (i.e., the number of functions
  // that use that exact set of globals).
  //
  // Multiply that by the size of the set to give us a crude profitability
  // metric.
  llvm::stable_sort(UsedGlobalSets,
                    [](const UsedGlobalSet &UGS1, const UsedGlobalSet &UGS2) {
                      return UGS1.Globals.count() * UGS1.UsageCount <
                             UGS2.Globals.count() * UGS2.UsageCount;
                    });

  // Starting from the sets with the best (=biggest) profitability, find a
  // good combination.
  // The ideal (and expensive) solution can only be found by trying all
  // combinations, looking for the one with the best profitability.
  // Don't be smart about it, and just pick the first compatible combination,
  // starting with the sets with the best profitability.
  BitVector PickedGlobals(Globals.size());
  bool Changed = false;

  for (const UsedGlobalSet &UGS : llvm::reverse(UsedGlobalSets)) {
    if (UGS.UsageCount == 0)
      continue;
    if (PickedGlobals.anyCommon(UGS.Globals))
      continue;
    PickedGlobals |= UGS.Globals;
    // If the set only contains one global, there's no point in merging.
    // Ignore the global for inclusion in other sets though, so keep it in
    // PickedGlobals.
    if (UGS.Globals.count() < 2)
      continue;
    Changed |= doMerge(Globals, UGS.Globals, M, isConst, AddrSpace);
  }

  return Changed;
}

bool GlobalMergeImpl::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
                              const BitVector &GlobalSet, Module &M,
                              bool isConst, unsigned AddrSpace) const {
  assert(Globals.size() > 1);

  Type *Int32Ty = Type::getInt32Ty(M.getContext());
  Type *Int8Ty = Type::getInt8Ty(M.getContext());
  auto &DL = M.getDataLayout();

  LLVM_DEBUG(dbgs() << " Trying to merge set, starts with #"
                    << GlobalSet.find_first() << ", total of " << Globals.size()
                    << "\n");

  bool Changed = false;
  ssize_t i = GlobalSet.find_first();
  while (i != -1) {
    ssize_t j = 0;
    uint64_t MergedSize = 0;
    std::vector<Type*> Tys;
    std::vector<Constant*> Inits;
    std::vector<unsigned> StructIdxs;

    bool HasExternal = false;
    StringRef FirstExternalName;
    Align MaxAlign;
    unsigned CurIdx = 0;
    for (j = i; j != -1; j = GlobalSet.find_next(j)) {
      Type *Ty = Globals[j]->getValueType();

      // Make sure we use the same alignment AsmPrinter would use.
      Align Alignment = DL.getPreferredAlign(Globals[j]);
      unsigned Padding = alignTo(MergedSize, Alignment) - MergedSize;
      MergedSize += Padding;
      MergedSize += DL.getTypeAllocSize(Ty);
      if (MergedSize > Opt.MaxOffset) {
        break;
      }
      if (Padding) {
        Tys.push_back(ArrayType::get(Int8Ty, Padding));
        Inits.push_back(ConstantAggregateZero::get(Tys.back()));
        ++CurIdx;
      }
      Tys.push_back(Ty);
      Inits.push_back(Globals[j]->getInitializer());
      StructIdxs.push_back(CurIdx++);

      MaxAlign = std::max(MaxAlign, Alignment);

      if (Globals[j]->hasExternalLinkage() && !HasExternal) {
        HasExternal = true;
        FirstExternalName = Globals[j]->getName();
      }
    }

    // Exit early if there is only one global to merge.
    if (Tys.size() < 2) {
      i = j;
      continue;
    }

    // If merged variables doesn't have external linkage, we needn't to expose
    // the symbol after merging.
    GlobalValue::LinkageTypes Linkage = HasExternal
                                            ? GlobalValue::ExternalLinkage
                                            : GlobalValue::InternalLinkage;
    // Use a packed struct so we can control alignment.
    StructType *MergedTy = StructType::get(M.getContext(), Tys, true);
    Constant *MergedInit = ConstantStruct::get(MergedTy, Inits);

    // On Darwin external linkage needs to be preserved, otherwise
    // dsymutil cannot preserve the debug info for the merged
    // variables.  If they have external linkage, use the symbol name
    // of the first variable merged as the suffix of global symbol
    // name.  This avoids a link-time naming conflict for the
    // _MergedGlobals symbols.
    Twine MergedName =
        (IsMachO && HasExternal)
            ? "_MergedGlobals_" + FirstExternalName
            : "_MergedGlobals";
    auto MergedLinkage = IsMachO ? Linkage : GlobalValue::PrivateLinkage;
    auto *MergedGV = new GlobalVariable(
        M, MergedTy, isConst, MergedLinkage, MergedInit, MergedName, nullptr,
        GlobalVariable::NotThreadLocal, AddrSpace);

    MergedGV->setAlignment(MaxAlign);
    MergedGV->setSection(Globals[i]->getSection());

    LLVM_DEBUG(dbgs() << "MergedGV:  " << *MergedGV << "\n");

    const StructLayout *MergedLayout = DL.getStructLayout(MergedTy);
    for (ssize_t k = i, idx = 0; k != j; k = GlobalSet.find_next(k), ++idx) {
      GlobalValue::LinkageTypes Linkage = Globals[k]->getLinkage();
      std::string Name(Globals[k]->getName());
      GlobalValue::VisibilityTypes Visibility = Globals[k]->getVisibility();
      GlobalValue::DLLStorageClassTypes DLLStorage =
          Globals[k]->getDLLStorageClass();

      // Copy metadata while adjusting any debug info metadata by the original
      // global's offset within the merged global.
      MergedGV->copyMetadata(Globals[k],
                             MergedLayout->getElementOffset(StructIdxs[idx]));

      Constant *Idx[2] = {
          ConstantInt::get(Int32Ty, 0),
          ConstantInt::get(Int32Ty, StructIdxs[idx]),
      };
      Constant *GEP =
          ConstantExpr::getInBoundsGetElementPtr(MergedTy, MergedGV, Idx);
      Globals[k]->replaceAllUsesWith(GEP);
      Globals[k]->eraseFromParent();

      // Emit an alias for the original variable name. This is necessary for an
      // external symbol, as it may be accessed from another object. For
      // internal symbols, it's not strictly required, but it's useful.
      //
      // This _should_ also work on Mach-O ever since '.alt_entry' support was
      // added in 2016. Unfortunately, there's a bug in ld-prime (present at
      // least from Xcode 15.0 through Xcode 16.0), in which -dead_strip doesn't
      // always honor alt_entry. To workaround this issue, we don't emit aliases
      // on Mach-O. Except, we _must_ do so for external symbols. That means
      // MergeExternal is broken with that linker. (That option is currently off
      // by default on MachO).
      if (!IsMachO || Linkage == GlobalValue::ExternalLinkage) {
        GlobalAlias *GA = GlobalAlias::create(Tys[StructIdxs[idx]], AddrSpace,
                                              Linkage, Name, GEP, &M);
        GA->setVisibility(Visibility);
        GA->setDLLStorageClass(DLLStorage);
      }

      NumMerged++;
    }
    Changed = true;
    i = j;
  }

  return Changed;
}

void GlobalMergeImpl::collectUsedGlobalVariables(Module &M, StringRef Name) {
  // Extract global variables from llvm.used array
  const GlobalVariable *GV = M.getGlobalVariable(Name);
  if (!GV || !GV->hasInitializer()) return;

  // Should be an array of 'i8*'.
  const ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());

  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
    if (const GlobalVariable *G =
        dyn_cast<GlobalVariable>(InitList->getOperand(i)->stripPointerCasts()))
      MustKeepGlobalVariables.insert(G);
}

void GlobalMergeImpl::setMustKeepGlobalVariables(Module &M) {
  collectUsedGlobalVariables(M, "llvm.used");
  collectUsedGlobalVariables(M, "llvm.compiler.used");

  for (Function &F : M) {
    for (BasicBlock &BB : F) {
      BasicBlock::iterator Pad = BB.getFirstNonPHIIt();
      auto *II = dyn_cast<IntrinsicInst>(Pad);
      if (!Pad->isEHPad() &&
          !(II && II->getIntrinsicID() == Intrinsic::eh_typeid_for))
        continue;

      // Keep globals used by landingpads, catchpads,
      // or intrinsics that require a plain global.
      for (const Use &U : Pad->operands()) {
        if (const GlobalVariable *GV =
                dyn_cast<GlobalVariable>(U->stripPointerCasts()))
          MustKeepGlobalVariables.insert(GV);
        else if (const ConstantArray *CA = dyn_cast<ConstantArray>(U->stripPointerCasts())) {
          for (const Use &Elt : CA->operands()) {
            if (const GlobalVariable *GV =
                    dyn_cast<GlobalVariable>(Elt->stripPointerCasts()))
              MustKeepGlobalVariables.insert(GV);
          }
        }
      }
    }
  }
}

// This function returns true if the given data Section name has custom
// subsection-splitting semantics in Mach-O (such as splitting by a fixed size)
//
// See also ObjFile::parseSections and getRecordSize in lld/MachO/InputFiles.cpp
static bool isSpecialMachOSection(StringRef Section) {
  // Uses starts_with, since section attributes can appear at the end of the
  // name.
  return Section.starts_with("__DATA,__cfstring") ||
         Section.starts_with("__DATA,__objc_classrefs") ||
         Section.starts_with("__DATA,__objc_selrefs");
}

bool GlobalMergeImpl::run(Module &M) {
  if (!EnableGlobalMerge)
    return false;

  IsMachO = Triple(M.getTargetTriple()).isOSBinFormatMachO();

  auto &DL = M.getDataLayout();
  MapVector<std::pair<unsigned, StringRef>, SmallVector<GlobalVariable *, 0>>
      Globals, ConstGlobals, BSSGlobals;
  bool Changed = false;
  setMustKeepGlobalVariables(M);

  LLVM_DEBUG({
      dbgs() << "Number of GV that must be kept:  " <<
                MustKeepGlobalVariables.size() << "\n";
      for (const GlobalVariable *KeptGV : MustKeepGlobalVariables)
        dbgs() << "Kept: " << *KeptGV << "\n";
  });
  // Grab all non-const globals.
  for (auto &GV : M.globals()) {
    // Merge is safe for "normal" internal or external globals only
    if (GV.isDeclaration() || GV.isThreadLocal() || GV.hasImplicitSection())
      continue;

    // It's not safe to merge globals that may be preempted
    if (TM && !TM->shouldAssumeDSOLocal(&GV))
      continue;

    if (!(Opt.MergeExternal && GV.hasExternalLinkage()) &&
        !GV.hasLocalLinkage())
      continue;

    PointerType *PT = dyn_cast<PointerType>(GV.getType());
    assert(PT && "Global variable is not a pointer!");

    unsigned AddressSpace = PT->getAddressSpace();
    StringRef Section = GV.getSection();

    // On Mach-O, some section names have special semantics. Don't merge these.
    if (IsMachO && isSpecialMachOSection(Section))
      continue;

    // Ignore all 'special' globals.
    if (GV.getName().starts_with("llvm.") ||
        GV.getName().starts_with(".llvm.") || Section == "llvm.metadata")
      continue;

    // Ignore all "required" globals:
    if (isMustKeepGlobalVariable(&GV))
      continue;

    // Don't merge tagged globals, as each global should have its own unique
    // memory tag at runtime. TODO(hctim): This can be relaxed: constant globals
    // with compatible alignment and the same contents may be merged as long as
    // the globals occupy the same number of tag granules (i.e. `size_a / 16 ==
    // size_b / 16`).
    if (GV.isTagged())
      continue;

    Type *Ty = GV.getValueType();
    TypeSize AllocSize = DL.getTypeAllocSize(Ty);
    bool CanMerge = AllocSize < Opt.MaxOffset && AllocSize >= Opt.MinSize;
    if (CanMerge) {
      if (TM &&
          TargetLoweringObjectFile::getKindForGlobal(&GV, *TM).isBSS())
        BSSGlobals[{AddressSpace, Section}].push_back(&GV);
      else if (GV.isConstant())
        ConstGlobals[{AddressSpace, Section}].push_back(&GV);
      else
        Globals[{AddressSpace, Section}].push_back(&GV);
    }
    LLVM_DEBUG(dbgs() << "GV " << (CanMerge ? "" : "not ") << "to merge: " << GV
                      << "\n");
  }

  for (auto &P : Globals)
    if (P.second.size() > 1)
      Changed |= doMerge(P.second, M, false, P.first.first);

  for (auto &P : BSSGlobals)
    if (P.second.size() > 1)
      Changed |= doMerge(P.second, M, false, P.first.first);

  if (Opt.MergeConstantGlobals)
    for (auto &P : ConstGlobals)
      if (P.second.size() > 1)
        Changed |= doMerge(P.second, M, true, P.first.first);

  return Changed;
}

Pass *llvm::createGlobalMergePass(const TargetMachine *TM, unsigned Offset,
                                  bool OnlyOptimizeForSize,
                                  bool MergeExternalByDefault,
                                  bool MergeConstantByDefault,
                                  bool MergeConstAggressiveByDefault) {
  bool MergeExternal = (EnableGlobalMergeOnExternal == cl::BOU_UNSET) ?
    MergeExternalByDefault : (EnableGlobalMergeOnExternal == cl::BOU_TRUE);
  bool MergeConstant = EnableGlobalMergeOnConst || MergeConstantByDefault;
  bool MergeConstAggressive = GlobalMergeAllConst.getNumOccurrences() > 0
                                  ? GlobalMergeAllConst
                                  : MergeConstAggressiveByDefault;
  return new GlobalMerge(TM, Offset, OnlyOptimizeForSize, MergeExternal,
                         MergeConstant, MergeConstAggressive);
}
