//===- 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;
    Opt.MergeConstantGlobals = EnableGlobalMergeOnConst;
    Opt.MergeConstAggressive = GlobalMergeAllConst;
    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());
    MergedGV->setComdat(Globals[i]->getComdat());

    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 = M.getTargetTriple().isOSBinFormatMachO();

  auto &DL = M.getDataLayout();
  MapVector<std::tuple<unsigned, StringRef, Comdat *>,
            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, GV.getComdat()}].push_back(&GV);
      else if (GV.isConstant())
        ConstGlobals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
      else
        Globals[{AddressSpace, Section, GV.getComdat()}].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, std::get<0>(P.first));

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

  if (Opt.MergeConstantGlobals)
    for (auto &P : ConstGlobals)
      if (P.second.size() > 1)
        Changed |= doMerge(P.second, M, true, std::get<0>(P.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;
  unsigned PreferOffset = GlobalMergeMaxOffset.getNumOccurrences() > 0
                              ? GlobalMergeMaxOffset
                              : Offset;
  return new GlobalMerge(TM, PreferOffset, OnlyOptimizeForSize, MergeExternal,
                         MergeConstant, MergeConstAggressive);
}
