//===---------- AArch64CollectLOH.cpp - AArch64 collect LOH pass --*- C++ -*-=//
//
// 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 file contains a pass that collect the Linker Optimization Hint (LOH).
// This pass should be run at the very end of the compilation flow, just before
// assembly printer.
// To be useful for the linker, the LOH must be printed into the assembly file.
//
// A LOH describes a sequence of instructions that may be optimized by the
// linker.
// This same sequence cannot be optimized by the compiler because some of
// the information will be known at link time.
// For instance, consider the following sequence:
//     L1: adrp xA, sym@PAGE
//     L2: add xB, xA, sym@PAGEOFF
//     L3: ldr xC, [xB, #imm]
// This sequence can be turned into:
// A literal load if sym@PAGE + sym@PAGEOFF + #imm - address(L3) is < 1MB:
//     L3: ldr xC, sym+#imm
// It may also be turned into either the following more efficient
// code sequences:
// - If sym@PAGEOFF + #imm fits the encoding space of L3.
//     L1: adrp xA, sym@PAGE
//     L3: ldr xC, [xB, sym@PAGEOFF + #imm]
// - If sym@PAGE + sym@PAGEOFF - address(L1) < 1MB:
//     L1: adr xA, sym
//     L3: ldr xC, [xB, #imm]
//
// To be valid a LOH must meet all the requirements needed by all the related
// possible linker transformations.
// For instance, using the running example, the constraints to emit
// ".loh AdrpAddLdr" are:
// - L1, L2, and L3 instructions are of the expected type, i.e.,
//   respectively ADRP, ADD (immediate), and LD.
// - The result of L1 is used only by L2.
// - The register argument (xA) used in the ADD instruction is defined
//   only by L1.
// - The result of L2 is used only by L3.
// - The base address (xB) in L3 is defined only L2.
// - The ADRP in L1 and the ADD in L2 must reference the same symbol using
//   @PAGE/@PAGEOFF with no additional constants
//
// Currently supported LOHs are:
// * So called non-ADRP-related:
//   - .loh AdrpAddLdr L1, L2, L3:
//     L1: adrp xA, sym@PAGE
//     L2: add xB, xA, sym@PAGEOFF
//     L3: ldr xC, [xB, #imm]
//   - .loh AdrpLdrGotLdr L1, L2, L3:
//     L1: adrp xA, sym@GOTPAGE
//     L2: ldr xB, [xA, sym@GOTPAGEOFF]
//     L3: ldr xC, [xB, #imm]
//   - .loh AdrpLdr L1, L3:
//     L1: adrp xA, sym@PAGE
//     L3: ldr xC, [xA, sym@PAGEOFF]
//   - .loh AdrpAddStr L1, L2, L3:
//     L1: adrp xA, sym@PAGE
//     L2: add xB, xA, sym@PAGEOFF
//     L3: str xC, [xB, #imm]
//   - .loh AdrpLdrGotStr L1, L2, L3:
//     L1: adrp xA, sym@GOTPAGE
//     L2: ldr xB, [xA, sym@GOTPAGEOFF]
//     L3: str xC, [xB, #imm]
//   - .loh AdrpAdd L1, L2:
//     L1: adrp xA, sym@PAGE
//     L2: add xB, xA, sym@PAGEOFF
//   For all these LOHs, L1, L2, L3 form a simple chain:
//   L1 result is used only by L2 and L2 result by L3.
//   L3 LOH-related argument is defined only by L2 and L2 LOH-related argument
//   by L1.
// All these LOHs aim at using more efficient load/store patterns by folding
// some instructions used to compute the address directly into the load/store.
//
// * So called ADRP-related:
//  - .loh AdrpAdrp L2, L1:
//    L2: ADRP xA, sym1@PAGE
//    L1: ADRP xA, sym2@PAGE
//    L2 dominates L1 and xA is not redefined between L2 and L1
// This LOH aims at getting rid of redundant ADRP instructions.
//
// The overall design for emitting the LOHs is:
// 1. AArch64CollectLOH (this pass) records the LOHs in the AArch64FunctionInfo.
// 2. AArch64AsmPrinter reads the LOHs from AArch64FunctionInfo and it:
//     1. Associates them a label.
//     2. Emits them in a MCStreamer (EmitLOHDirective).
//         - The MCMachOStreamer records them into the MCAssembler.
//         - The MCAsmStreamer prints them.
//         - Other MCStreamers ignore them.
//     3. Closes the MCStreamer:
//         - The MachObjectWriter gets them from the MCAssembler and writes
//           them in the object file.
//         - Other ObjectWriters ignore them.
//===----------------------------------------------------------------------===//

#include "AArch64.h"
#include "AArch64MachineFunctionInfo.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "aarch64-collect-loh"

STATISTIC(NumADRPSimpleCandidate,
          "Number of simplifiable ADRP dominate by another");
STATISTIC(NumADDToSTR, "Number of simplifiable STR reachable by ADD");
STATISTIC(NumLDRToSTR, "Number of simplifiable STR reachable by LDR");
STATISTIC(NumADDToLDR, "Number of simplifiable LDR reachable by ADD");
STATISTIC(NumLDRToLDR, "Number of simplifiable LDR reachable by LDR");
STATISTIC(NumADRPToLDR, "Number of simplifiable LDR reachable by ADRP");
STATISTIC(NumADRSimpleCandidate, "Number of simplifiable ADRP + ADD");

#define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"

static bool canAddBePartOfLOH(const MachineInstr &MI) {
  // Check immediate to see if the immediate is an address.
  switch (MI.getOperand(2).getType()) {
  default:
    return false;
  case MachineOperand::MO_GlobalAddress:
  case MachineOperand::MO_JumpTableIndex:
  case MachineOperand::MO_ConstantPoolIndex:
  case MachineOperand::MO_BlockAddress:
    return true;
  }
}

/// Answer the following question: Can Def be one of the definition
/// involved in a part of a LOH?
static bool canDefBePartOfLOH(const MachineInstr &MI) {
  // Accept ADRP, ADDLow and LOADGot.
  switch (MI.getOpcode()) {
  default:
    return false;
  case AArch64::ADRP:
    return true;
  case AArch64::ADDXri:
    return canAddBePartOfLOH(MI);
  case AArch64::LDRXui:
  case AArch64::LDRWui:
    // Check immediate to see if the immediate is an address.
    switch (MI.getOperand(2).getType()) {
    default:
      return false;
    case MachineOperand::MO_GlobalAddress:
      return MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT;
    }
  }
}

/// Check whether the given instruction can the end of a LOH chain involving a
/// store.
static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO) {
  switch (MI.getOpcode()) {
  default:
    return false;
  case AArch64::STRBBui:
  case AArch64::STRHHui:
  case AArch64::STRBui:
  case AArch64::STRHui:
  case AArch64::STRWui:
  case AArch64::STRXui:
  case AArch64::STRSui:
  case AArch64::STRDui:
  case AArch64::STRQui:
    // We can only optimize the index operand.
    // In case we have str xA, [xA, #imm], this is two different uses
    // of xA and we cannot fold, otherwise the xA stored may be wrong,
    // even if #imm == 0.
    return MO.getOperandNo() == 1 &&
           MI.getOperand(0).getReg() != MI.getOperand(1).getReg();
  }
}

/// Check whether the given instruction can be the end of a LOH chain
/// involving a load.
static bool isCandidateLoad(const MachineInstr &MI) {
  switch (MI.getOpcode()) {
  default:
    return false;
  case AArch64::LDRSBWui:
  case AArch64::LDRSBXui:
  case AArch64::LDRSHWui:
  case AArch64::LDRSHXui:
  case AArch64::LDRSWui:
  case AArch64::LDRBui:
  case AArch64::LDRHui:
  case AArch64::LDRWui:
  case AArch64::LDRXui:
  case AArch64::LDRSui:
  case AArch64::LDRDui:
  case AArch64::LDRQui:
    return !(MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT);
  }
}

/// Check whether the given instruction can load a literal.
static bool supportLoadFromLiteral(const MachineInstr &MI) {
  switch (MI.getOpcode()) {
  default:
    return false;
  case AArch64::LDRSWui:
  case AArch64::LDRWui:
  case AArch64::LDRXui:
  case AArch64::LDRSui:
  case AArch64::LDRDui:
  case AArch64::LDRQui:
    return true;
  }
}

/// Returns \p true if there are no non-debug instructions between \p First and
/// \p Second
static bool areInstructionsConsecutive(const MachineInstr *First,
                                       const MachineInstr *Second) {
  auto It = First->getIterator();
  auto EndIt = First->getParent()->instr_end();
  if (It == EndIt)
    return false;
  return next_nodbg(It, EndIt) == Second->getIterator();
}

/// Number of GPR registers tracked by mapRegToGPRIndex()
static const unsigned N_GPR_REGS = 31;
/// Map register number to index from 0-30.
static int mapRegToGPRIndex(MCRegister Reg) {
  static_assert(AArch64::X28 - AArch64::X0 + 3 == N_GPR_REGS, "Number of GPRs");
  static_assert(AArch64::W30 - AArch64::W0 + 1 == N_GPR_REGS, "Number of GPRs");
  if (AArch64::X0 <= Reg && Reg <= AArch64::X28)
    return Reg - AArch64::X0;
  if (AArch64::W0 <= Reg && Reg <= AArch64::W30)
    return Reg - AArch64::W0;
  // TableGen gives "FP" and "LR" an index not adjacent to X28 so we have to
  // handle them as special cases.
  if (Reg == AArch64::FP)
    return 29;
  if (Reg == AArch64::LR)
    return 30;
  return -1;
}

/// State tracked per register.
/// The main algorithm walks backwards over a basic block maintaining this
/// datastructure for each tracked general purpose register.
struct LOHInfo {
  MCLOHType Type : 8;           ///< "Best" type of LOH possible.
  LLVM_PREFERRED_TYPE(bool)
  unsigned IsCandidate : 1;     ///< Possible LOH candidate.
  LLVM_PREFERRED_TYPE(bool)
  unsigned OneUser : 1;         ///< Found exactly one user (yet).
  LLVM_PREFERRED_TYPE(bool)
  unsigned MultiUsers : 1;      ///< Found multiple users.
  const MachineInstr *MI0;      ///< First instruction involved in the LOH.
  const MachineInstr *MI1;      ///< Second instruction involved in the LOH
                                ///  (if any).
  const MachineInstr *LastADRP; ///< Last ADRP in same register.
};

/// Update state \p Info given \p MI uses the tracked register.
static void handleUse(const MachineInstr &MI, const MachineOperand &MO,
                      LOHInfo &Info) {
  // We have multiple uses if we already found one before.
  if (Info.MultiUsers || Info.OneUser) {
    Info.IsCandidate = false;
    Info.MultiUsers = true;
    return;
  }
  Info.OneUser = true;

  // Start new LOHInfo if applicable.
  if (isCandidateLoad(MI)) {
    Info.Type = MCLOH_AdrpLdr;
    Info.IsCandidate = true;
    Info.MI0 = &MI;
    // Note that even this is AdrpLdr now, we can switch to a Ldr variant
    // later.
  } else if (isCandidateStore(MI, MO)) {
    Info.Type = MCLOH_AdrpAddStr;
    Info.IsCandidate = true;
    Info.MI0 = &MI;
    Info.MI1 = nullptr;
  } else if (MI.getOpcode() == AArch64::ADDXri) {
    Info.Type = MCLOH_AdrpAdd;
    Info.IsCandidate = true;
    Info.MI0 = &MI;
  } else if ((MI.getOpcode() == AArch64::LDRXui ||
              MI.getOpcode() == AArch64::LDRWui) &&
             MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT) {
    Info.Type = MCLOH_AdrpLdrGot;
    Info.IsCandidate = true;
    Info.MI0 = &MI;
  }
}

/// Update state \p Info given the tracked register is clobbered.
static void handleClobber(LOHInfo &Info) {
  Info.IsCandidate = false;
  Info.OneUser = false;
  Info.MultiUsers = false;
  Info.LastADRP = nullptr;
}

/// Update state \p Info given that \p MI is possibly the middle instruction
/// of an LOH involving 3 instructions.
static bool handleMiddleInst(const MachineInstr &MI, LOHInfo &DefInfo,
                             LOHInfo &OpInfo) {
  if (!DefInfo.IsCandidate || (&DefInfo != &OpInfo && OpInfo.OneUser))
    return false;
  // Copy LOHInfo for dest register to LOHInfo for source register.
  if (&DefInfo != &OpInfo) {
    OpInfo = DefInfo;
    // Invalidate \p DefInfo because we track it in \p OpInfo now.
    handleClobber(DefInfo);
  } else
    DefInfo.LastADRP = nullptr;

  // Advance state machine.
  assert(OpInfo.IsCandidate && "Expect valid state");
  if (MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(MI)) {
    if (OpInfo.Type == MCLOH_AdrpLdr) {
      OpInfo.Type = MCLOH_AdrpAddLdr;
      OpInfo.IsCandidate = true;
      OpInfo.MI1 = &MI;
      return true;
    } else if (OpInfo.Type == MCLOH_AdrpAddStr && OpInfo.MI1 == nullptr) {
      OpInfo.Type = MCLOH_AdrpAddStr;
      OpInfo.IsCandidate = true;
      OpInfo.MI1 = &MI;
      return true;
    }
  } else {
    assert((MI.getOpcode() == AArch64::LDRXui ||
            MI.getOpcode() == AArch64::LDRWui) &&
           "Expect LDRXui or LDRWui");
    assert((MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT) &&
           "Expected GOT relocation");
    if (OpInfo.Type == MCLOH_AdrpAddStr && OpInfo.MI1 == nullptr) {
      OpInfo.Type = MCLOH_AdrpLdrGotStr;
      OpInfo.IsCandidate = true;
      OpInfo.MI1 = &MI;
      return true;
    } else if (OpInfo.Type == MCLOH_AdrpLdr) {
      OpInfo.Type = MCLOH_AdrpLdrGotLdr;
      OpInfo.IsCandidate = true;
      OpInfo.MI1 = &MI;
      return true;
    }
  }
  return false;
}

/// Update state when seeing and ADRP instruction.
static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI,
                       LOHInfo &Info, LOHInfo *LOHInfos) {
  if (Info.LastADRP != nullptr) {
    LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAdrp:\n"
                      << '\t' << MI << '\t' << *Info.LastADRP);
    AFI.addLOHDirective(MCLOH_AdrpAdrp, {&MI, Info.LastADRP});
    ++NumADRPSimpleCandidate;
  }

  // Produce LOH directive if possible.
  if (Info.IsCandidate) {
    switch (Info.Type) {
    case MCLOH_AdrpAdd: {
      // ADRPs and ADDs for this candidate may be split apart if using
      // GlobalISel instead of pseudo-expanded. If that happens, the
      // def register of the ADD may have a use in between. Adding an LOH in
      // this case can cause the linker to rewrite the ADRP to write to that
      // register, clobbering the use.
      const MachineInstr *AddMI = Info.MI0;
      int DefIdx = mapRegToGPRIndex(MI.getOperand(0).getReg());
      int OpIdx = mapRegToGPRIndex(AddMI->getOperand(0).getReg());
      LOHInfo DefInfo = LOHInfos[OpIdx];
      if (DefIdx != OpIdx && (DefInfo.OneUser || DefInfo.MultiUsers))
        break;
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAdd:\n"
                        << '\t' << MI << '\t' << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpAdd, {&MI, Info.MI0});
      ++NumADRSimpleCandidate;
      break;
    }
    case MCLOH_AdrpLdr:
      if (supportLoadFromLiteral(*Info.MI0)) {
        LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpLdr:\n"
                          << '\t' << MI << '\t' << *Info.MI0);
        AFI.addLOHDirective(MCLOH_AdrpLdr, {&MI, Info.MI0});
        ++NumADRPToLDR;
      }
      break;
    case MCLOH_AdrpAddLdr:
      // There is a possibility that the linker may try to rewrite:
      // adrp x0, @sym@PAGE
      // add x1, x0, @sym@PAGEOFF
      // [x0 = some other def]
      // ldr x2, [x1]
      //    ...into...
      // adrp x0, @sym
      // nop
      // [x0 = some other def]
      // ldr x2, [x0]
      // ...if the offset to the symbol won't fit within a literal load.
      // This causes the load to use the result of the adrp, which in this
      // case has already been clobbered.
      // FIXME: Implement proper liveness tracking for all registers. For now,
      // don't emit the LOH if there are any instructions between the add and
      // the ldr.
      if (!areInstructionsConsecutive(Info.MI1, Info.MI0))
        break;
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddLdr:\n"
                        << '\t' << MI << '\t' << *Info.MI1 << '\t'
                        << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpAddLdr, {&MI, Info.MI1, Info.MI0});
      ++NumADDToLDR;
      break;
    case MCLOH_AdrpAddStr:
      if (!Info.MI1)
        break;
      if (!areInstructionsConsecutive(Info.MI1, Info.MI0))
        break;
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpAddStr:\n"
                        << '\t' << MI << '\t' << *Info.MI1 << '\t'
                        << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpAddStr, {&MI, Info.MI1, Info.MI0});
      ++NumADDToSTR;
      break;
    case MCLOH_AdrpLdrGotLdr:
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGotLdr:\n"
                        << '\t' << MI << '\t' << *Info.MI1 << '\t'
                        << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpLdrGotLdr, {&MI, Info.MI1, Info.MI0});
      ++NumLDRToLDR;
      break;
    case MCLOH_AdrpLdrGotStr:
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGotStr:\n"
                        << '\t' << MI << '\t' << *Info.MI1 << '\t'
                        << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpLdrGotStr, {&MI, Info.MI1, Info.MI0});
      ++NumLDRToSTR;
      break;
    case MCLOH_AdrpLdrGot:
      LLVM_DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGot:\n"
                        << '\t' << MI << '\t' << *Info.MI0);
      AFI.addLOHDirective(MCLOH_AdrpLdrGot, {&MI, Info.MI0});
      break;
    case MCLOH_AdrpAdrp:
      llvm_unreachable("MCLOH_AdrpAdrp not used in state machine");
    }
  }

  handleClobber(Info);
  Info.LastADRP = &MI;
}

static void handleRegMaskClobber(const uint32_t *RegMask, MCPhysReg Reg,
                                 LOHInfo *LOHInfos) {
  if (!MachineOperand::clobbersPhysReg(RegMask, Reg))
    return;
  int Idx = mapRegToGPRIndex(Reg);
  if (Idx >= 0)
    handleClobber(LOHInfos[Idx]);
}

static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos) {
  // Handle defs and regmasks.
  for (const MachineOperand &MO : MI.operands()) {
    if (MO.isRegMask()) {
      const uint32_t *RegMask = MO.getRegMask();
      for (MCPhysReg Reg : AArch64::GPR32RegClass)
        handleRegMaskClobber(RegMask, Reg, LOHInfos);
      for (MCPhysReg Reg : AArch64::GPR64RegClass)
        handleRegMaskClobber(RegMask, Reg, LOHInfos);
      continue;
    }
    if (!MO.isReg() || !MO.isDef())
      continue;
    int Idx = mapRegToGPRIndex(MO.getReg());
    if (Idx < 0)
      continue;
    handleClobber(LOHInfos[Idx]);
  }
  // Handle uses.

  SmallSet<int, 4> UsesSeen;
  for (const MachineOperand &MO : MI.uses()) {
    if (!MO.isReg() || !MO.readsReg())
      continue;
    int Idx = mapRegToGPRIndex(MO.getReg());
    if (Idx < 0)
      continue;

    // Multiple uses of the same register within a single instruction don't
    // count as MultiUser or block optimization. This is especially important on
    // arm64_32, where any memory operation is likely to be an explicit use of
    // xN and an implicit use of wN (the base address register).
    if (UsesSeen.insert(Idx).second)
      handleUse(MI, MO, LOHInfos[Idx]);
  }
}

namespace {

void runAArch64CollectLOH(MachineFunction &MF) {
  LLVM_DEBUG(dbgs() << "********** AArch64 Collect LOH **********\n"
                    << "Looking in function " << MF.getName() << '\n');

  LOHInfo LOHInfos[N_GPR_REGS];
  AArch64FunctionInfo &AFI = *MF.getInfo<AArch64FunctionInfo>();
  for (const MachineBasicBlock &MBB : MF) {
    // Reset register tracking state.
    memset(LOHInfos, 0, sizeof(LOHInfos));
    // Live-out registers are used.
    for (const MachineBasicBlock *Succ : MBB.successors()) {
      for (const auto &LI : Succ->liveins()) {
        int RegIdx = mapRegToGPRIndex(LI.PhysReg);
        if (RegIdx >= 0)
          LOHInfos[RegIdx].OneUser = true;
      }
    }

    // Walk the basic block backwards and update the per register state machine
    // in the process.
    for (const MachineInstr &MI :
         instructionsWithoutDebug(MBB.instr_rbegin(), MBB.instr_rend())) {
      unsigned Opcode = MI.getOpcode();
      switch (Opcode) {
      case AArch64::ADDXri:
      case AArch64::LDRXui:
      case AArch64::LDRWui:
        if (canDefBePartOfLOH(MI)) {
          const MachineOperand &Def = MI.getOperand(0);
          const MachineOperand &Op = MI.getOperand(1);
          assert(Def.isReg() && Def.isDef() && "Expected reg def");
          assert(Op.isReg() && Op.isUse() && "Expected reg use");
          int DefIdx = mapRegToGPRIndex(Def.getReg());
          int OpIdx = mapRegToGPRIndex(Op.getReg());
          if (DefIdx >= 0 && OpIdx >= 0 &&
              handleMiddleInst(MI, LOHInfos[DefIdx], LOHInfos[OpIdx]))
            continue;
        }
        break;
      case AArch64::ADRP:
        const MachineOperand &Op0 = MI.getOperand(0);
        int Idx = mapRegToGPRIndex(Op0.getReg());
        if (Idx >= 0) {
          handleADRP(MI, AFI, LOHInfos[Idx], LOHInfos);
          continue;
        }
        break;
      }
      handleNormalInst(MI, LOHInfos);
    }
  }
}

struct AArch64CollectLOHLegacy : public MachineFunctionPass {
  static char ID;
  AArch64CollectLOHLegacy() : MachineFunctionPass(ID) {}

  bool runOnMachineFunction(MachineFunction &MF) override {
    if (skipFunction(MF.getFunction()))
      return false;
    runAArch64CollectLOH(MF);

    // Return "no change": The pass only collects information.
    return false;
  }

  MachineFunctionProperties getRequiredProperties() const override {
    return MachineFunctionProperties().setNoVRegs();
  }

  StringRef getPassName() const override { return AARCH64_COLLECT_LOH_NAME; }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    MachineFunctionPass::getAnalysisUsage(AU);
    AU.setPreservesAll();
  }
};

char AArch64CollectLOHLegacy::ID = 0;

} // end anonymous namespace.

INITIALIZE_PASS(AArch64CollectLOHLegacy, "aarch64-collect-loh",
                AARCH64_COLLECT_LOH_NAME, false, false)

PreservedAnalyses
AArch64CollectLOHPass::run(MachineFunction &MF,
                           MachineFunctionAnalysisManager &MFAM) {
  runAArch64CollectLOH(MF);

  // This pass only collects information.
  return PreservedAnalyses::all();
}

FunctionPass *llvm::createAArch64CollectLOHPass() {
  return new AArch64CollectLOHLegacy();
}
