[llvm] [CodeGen][NewPM] Port `LiveIntervals` to new pass manager (PR #98118)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 9 01:07:17 PDT 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/98118

>From d524060de3e683ea6604171938707a72f63cf94e Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Tue, 9 Jul 2024 14:32:57 +0800
Subject: [PATCH] [CodeGen][NewPM] Port `LiveIntervals` to new pass manager -
 Add `LiveIntervalsAnalysis`. - Add `LiveIntervalsPrinterPass`. - Use
 `LiveIntervalsWrapperPass` in legacy pass manager. This would be the last
 analysis required by `PHIElimination`.

---
 llvm/include/llvm/CodeGen/LiveIntervals.h     | 922 +++++++++---------
 llvm/include/llvm/InitializePasses.h          |   2 +-
 llvm/include/llvm/Passes/CodeGenPassBuilder.h |   3 +-
 .../llvm/Passes/MachinePassRegistry.def       |   3 +-
 llvm/lib/CodeGen/CodeGen.cpp                  |   2 +-
 llvm/lib/CodeGen/InlineSpiller.cpp            |   4 +-
 llvm/lib/CodeGen/LiveDebugVariables.cpp       |   6 +-
 llvm/lib/CodeGen/LiveIntervals.cpp            |  61 +-
 llvm/lib/CodeGen/LiveRegMatrix.cpp            |   6 +-
 llvm/lib/CodeGen/MachineBasicBlock.cpp        |   3 +-
 llvm/lib/CodeGen/MachinePipeliner.cpp         |  14 +-
 llvm/lib/CodeGen/MachineScheduler.cpp         |   8 +-
 llvm/lib/CodeGen/MachineVerifier.cpp          |   5 +-
 llvm/lib/CodeGen/ModuloSchedule.cpp           |   6 +-
 llvm/lib/CodeGen/PHIElimination.cpp           |   5 +-
 llvm/lib/CodeGen/RegAllocBasic.cpp            |   8 +-
 llvm/lib/CodeGen/RegAllocGreedy.cpp           |   8 +-
 llvm/lib/CodeGen/RegAllocPBQP.cpp             |   8 +-
 llvm/lib/CodeGen/RegisterCoalescer.cpp        |  10 +-
 llvm/lib/CodeGen/RenameIndependentSubregs.cpp |   8 +-
 llvm/lib/CodeGen/StackSlotColoring.cpp        |   2 +-
 .../lib/CodeGen/TwoAddressInstructionPass.cpp |   5 +-
 llvm/lib/CodeGen/VirtRegMap.cpp               |   8 +-
 llvm/lib/Passes/PassBuilder.cpp               |   1 +
 .../AArch64/AArch64PostCoalescerPass.cpp      |   6 +-
 .../AMDGPU/AMDGPUMarkLastScratchLoad.cpp      |   4 +-
 llvm/lib/Target/AMDGPU/GCNNSAReassign.cpp     |   6 +-
 .../Target/AMDGPU/GCNPreRAOptimizations.cpp   |   6 +-
 llvm/lib/Target/AMDGPU/GCNRegPressure.cpp     |   2 +-
 llvm/lib/Target/AMDGPU/GCNRegPressure.h       |   2 +-
 .../AMDGPU/GCNRewritePartialRegUses.cpp       |   5 +-
 .../lib/Target/AMDGPU/SIFormMemoryClauses.cpp |   6 +-
 llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp |   7 +-
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp  |   5 +-
 llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp   |   5 +-
 .../Target/AMDGPU/SIOptimizeExecMasking.cpp   |   2 +-
 .../AMDGPU/SIOptimizeExecMaskingPreRA.cpp     |   6 +-
 .../Target/AMDGPU/SIPreAllocateWWMRegs.cpp    |   6 +-
 llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp     |   2 +-
 llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp    |   8 +-
 .../Target/Hexagon/HexagonCopyHoisting.cpp    |   9 +-
 .../Target/Hexagon/HexagonExpandCondsets.cpp  |  23 +-
 .../LoongArchDeadRegisterDefinitions.cpp      |   8 +-
 llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp |   4 +-
 llvm/lib/Target/PowerPC/PPCVSXFMAMutate.cpp   |   8 +-
 .../RISCV/RISCVDeadRegisterDefinitions.cpp    |   8 +-
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp  |   7 +-
 .../WebAssemblyMemIntrinsicResults.cpp        |   6 +-
 .../WebAssemblyOptimizeLiveIntervals.cpp      |   6 +-
 .../WebAssembly/WebAssemblyRegColoring.cpp    |   4 +-
 .../WebAssembly/WebAssemblyRegStackify.cpp    |   6 +-
 llvm/lib/Target/X86/X86TileConfig.cpp         |   4 +-
 .../AArch64/live-interval-analysis.mir        |   1 +
 llvm/test/CodeGen/AMDGPU/liveness.mir         |   1 +
 .../CodeGen/AMDGPU/phys-partial-liveness.mir  |   1 +
 .../CodeGen/AMDGPU/return-with-successors.mir |   1 +
 llvm/test/CodeGen/AMDGPU/subreg-intervals.mir |   1 +
 llvm/test/CodeGen/X86/invalid-liveness.mir    |   1 +
 llvm/unittests/MI/LiveIntervalTest.cpp        | 394 +++++---
 59 files changed, 918 insertions(+), 761 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/LiveIntervals.h b/llvm/include/llvm/CodeGen/LiveIntervals.h
index baa5476cec94a..f2103375a5e84 100644
--- a/llvm/include/llvm/CodeGen/LiveIntervals.h
+++ b/llvm/include/llvm/CodeGen/LiveIntervals.h
@@ -23,8 +23,10 @@
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/LiveIntervalCalc.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/MC/LaneBitmask.h"
@@ -40,7 +42,6 @@ namespace llvm {
 extern cl::opt<bool> UseSegmentSetForPhysRegs;
 
 class BitVector;
-class LiveIntervalCalc;
 class MachineBlockFrequencyInfo;
 class MachineDominatorTree;
 class MachineFunction;
@@ -50,445 +51,492 @@ class raw_ostream;
 class TargetInstrInfo;
 class VirtRegMap;
 
-  class LiveIntervals : public MachineFunctionPass {
-    MachineFunction *MF = nullptr;
-    MachineRegisterInfo *MRI = nullptr;
-    const TargetRegisterInfo *TRI = nullptr;
-    const TargetInstrInfo *TII = nullptr;
-    SlotIndexes *Indexes = nullptr;
-    MachineDominatorTree *DomTree = nullptr;
-    LiveIntervalCalc *LICalc = nullptr;
-
-    /// Special pool allocator for VNInfo's (LiveInterval val#).
-    VNInfo::Allocator VNInfoAllocator;
-
-    /// Live interval pointers for all the virtual registers.
-    IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
-
-    /// Sorted list of instructions with register mask operands. Always use the
-    /// 'r' slot, RegMasks are normal clobbers, not early clobbers.
-    SmallVector<SlotIndex, 8> RegMaskSlots;
-
-    /// This vector is parallel to RegMaskSlots, it holds a pointer to the
-    /// corresponding register mask.  This pointer can be recomputed as:
-    ///
-    ///   MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
-    ///   unsigned OpNum = findRegMaskOperand(MI);
-    ///   RegMaskBits[N] = MI->getOperand(OpNum).getRegMask();
-    ///
-    /// This is kept in a separate vector partly because some standard
-    /// libraries don't support lower_bound() with mixed objects, partly to
-    /// improve locality when searching in RegMaskSlots.
-    /// Also see the comment in LiveInterval::find().
-    SmallVector<const uint32_t*, 8> RegMaskBits;
-
-    /// For each basic block number, keep (begin, size) pairs indexing into the
-    /// RegMaskSlots and RegMaskBits arrays.
-    /// Note that basic block numbers may not be layout contiguous, that's why
-    /// we can't just keep track of the first register mask in each basic
-    /// block.
-    SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
-
-    /// Keeps a live range set for each register unit to track fixed physreg
-    /// interference.
-    SmallVector<LiveRange*, 0> RegUnitRanges;
-
-  public:
-    static char ID;
-
-    LiveIntervals();
-    ~LiveIntervals() override;
-
-    /// Calculate the spill weight to assign to a single instruction.
-    static float getSpillWeight(bool isDef, bool isUse,
-                                const MachineBlockFrequencyInfo *MBFI,
-                                const MachineInstr &MI);
-
-    /// Calculate the spill weight to assign to a single instruction.
-    static float getSpillWeight(bool isDef, bool isUse,
-                                const MachineBlockFrequencyInfo *MBFI,
-                                const MachineBasicBlock *MBB);
-
-    LiveInterval &getInterval(Register Reg) {
-      if (hasInterval(Reg))
-        return *VirtRegIntervals[Reg.id()];
-
-      return createAndComputeVirtRegInterval(Reg);
-    }
-
-    const LiveInterval &getInterval(Register Reg) const {
-      return const_cast<LiveIntervals*>(this)->getInterval(Reg);
-    }
-
-    bool hasInterval(Register Reg) const {
-      return VirtRegIntervals.inBounds(Reg.id()) &&
-             VirtRegIntervals[Reg.id()];
-    }
-
-    /// Interval creation.
-    LiveInterval &createEmptyInterval(Register Reg) {
-      assert(!hasInterval(Reg) && "Interval already exists!");
-      VirtRegIntervals.grow(Reg.id());
-      VirtRegIntervals[Reg.id()] = createInterval(Reg);
+class LiveIntervals {
+  friend class LiveIntervalsAnalysis;
+  friend class LiveIntervalsWrapperPass;
+
+  MachineFunction *MF = nullptr;
+  MachineRegisterInfo *MRI = nullptr;
+  const TargetRegisterInfo *TRI = nullptr;
+  const TargetInstrInfo *TII = nullptr;
+  SlotIndexes *Indexes = nullptr;
+  MachineDominatorTree *DomTree = nullptr;
+  std::unique_ptr<LiveIntervalCalc> LICalc;
+
+  /// Special pool allocator for VNInfo's (LiveInterval val#).
+  VNInfo::Allocator VNInfoAllocator;
+
+  /// Live interval pointers for all the virtual registers.
+  IndexedMap<LiveInterval *, VirtReg2IndexFunctor> VirtRegIntervals;
+
+  /// Sorted list of instructions with register mask operands. Always use the
+  /// 'r' slot, RegMasks are normal clobbers, not early clobbers.
+  SmallVector<SlotIndex, 8> RegMaskSlots;
+
+  /// This vector is parallel to RegMaskSlots, it holds a pointer to the
+  /// corresponding register mask.  This pointer can be recomputed as:
+  ///
+  ///   MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
+  ///   unsigned OpNum = findRegMaskOperand(MI);
+  ///   RegMaskBits[N] = MI->getOperand(OpNum).getRegMask();
+  ///
+  /// This is kept in a separate vector partly because some standard
+  /// libraries don't support lower_bound() with mixed objects, partly to
+  /// improve locality when searching in RegMaskSlots.
+  /// Also see the comment in LiveInterval::find().
+  SmallVector<const uint32_t *, 8> RegMaskBits;
+
+  /// For each basic block number, keep (begin, size) pairs indexing into the
+  /// RegMaskSlots and RegMaskBits arrays.
+  /// Note that basic block numbers may not be layout contiguous, that's why
+  /// we can't just keep track of the first register mask in each basic
+  /// block.
+  SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
+
+  /// Keeps a live range set for each register unit to track fixed physreg
+  /// interference.
+  SmallVector<LiveRange *, 0> RegUnitRanges;
+
+  // Can only be created from pass manager.
+  LiveIntervals() = default;
+
+  LiveIntervals(MachineFunction &MF, SlotIndexes &SI, MachineDominatorTree &DT)
+      : Indexes(&SI), DomTree(&DT) {
+    analyze(MF);
+  }
+
+  void analyze(MachineFunction &MF);
+
+public:
+  LiveIntervals(LiveIntervals &&) = default;
+  ~LiveIntervals();
+
+  /// Calculate the spill weight to assign to a single instruction.
+  static float getSpillWeight(bool isDef, bool isUse,
+                              const MachineBlockFrequencyInfo *MBFI,
+                              const MachineInstr &MI);
+
+  /// Calculate the spill weight to assign to a single instruction.
+  static float getSpillWeight(bool isDef, bool isUse,
+                              const MachineBlockFrequencyInfo *MBFI,
+                              const MachineBasicBlock *MBB);
+
+  LiveInterval &getInterval(Register Reg) {
+    if (hasInterval(Reg))
       return *VirtRegIntervals[Reg.id()];
-    }
-
-    LiveInterval &createAndComputeVirtRegInterval(Register Reg) {
-      LiveInterval &LI = createEmptyInterval(Reg);
-      computeVirtRegInterval(LI);
-      return LI;
-    }
-
-    /// Return an existing interval for \p Reg.
-    /// If \p Reg has no interval then this creates a new empty one instead.
-    /// Note: does not trigger interval computation.
-    LiveInterval &getOrCreateEmptyInterval(Register Reg) {
-      return hasInterval(Reg) ? getInterval(Reg) : createEmptyInterval(Reg);
-    }
-
-    /// Interval removal.
-    void removeInterval(Register Reg) {
-      delete VirtRegIntervals[Reg];
-      VirtRegIntervals[Reg] = nullptr;
-    }
-
-    /// Given a register and an instruction, adds a live segment from that
-    /// instruction to the end of its MBB.
-    LiveInterval::Segment addSegmentToEndOfBlock(Register Reg,
-                                                 MachineInstr &startInst);
-
-    /// After removing some uses of a register, shrink its live range to just
-    /// the remaining uses. This method does not compute reaching defs for new
-    /// uses, and it doesn't remove dead defs.
-    /// Dead PHIDef values are marked as unused. New dead machine instructions
-    /// are added to the dead vector. Returns true if the interval may have been
-    /// separated into multiple connected components.
-    bool shrinkToUses(LiveInterval *li,
-                      SmallVectorImpl<MachineInstr*> *dead = nullptr);
-
-    /// Specialized version of
-    /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
-    /// that works on a subregister live range and only looks at uses matching
-    /// the lane mask of the subregister range.
-    /// This may leave the subrange empty which needs to be cleaned up with
-    /// LiveInterval::removeEmptySubranges() afterwards.
-    void shrinkToUses(LiveInterval::SubRange &SR, Register Reg);
-
-    /// Extend the live range \p LR to reach all points in \p Indices. The
-    /// points in the \p Indices array must be jointly dominated by the union
-    /// of the existing defs in \p LR and points in \p Undefs.
-    ///
-    /// PHI-defs are added as needed to maintain SSA form.
-    ///
-    /// If a SlotIndex in \p Indices is the end index of a basic block, \p LR
-    /// will be extended to be live out of the basic block.
-    /// If a SlotIndex in \p Indices is jointy dominated only by points in
-    /// \p Undefs, the live range will not be extended to that point.
-    ///
-    /// See also LiveRangeCalc::extend().
-    void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
-                         ArrayRef<SlotIndex> Undefs);
-
-    void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices) {
-      extendToIndices(LR, Indices, /*Undefs=*/{});
-    }
 
-    /// If \p LR has a live value at \p Kill, prune its live range by removing
-    /// any liveness reachable from Kill. Add live range end points to
-    /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
-    /// value's live range.
-    ///
-    /// Calling pruneValue() and extendToIndices() can be used to reconstruct
-    /// SSA form after adding defs to a virtual register.
-    void pruneValue(LiveRange &LR, SlotIndex Kill,
-                    SmallVectorImpl<SlotIndex> *EndPoints);
-
-    /// This function should not be used. Its intent is to tell you that you are
-    /// doing something wrong if you call pruneValue directly on a
-    /// LiveInterval. Indeed, you are supposed to call pruneValue on the main
-    /// LiveRange and all the LiveRanges of the subranges if any.
-    LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
-                                          SmallVectorImpl<SlotIndex> *) {
-      llvm_unreachable(
-          "Use pruneValue on the main LiveRange and on each subrange");
+    return createAndComputeVirtRegInterval(Reg);
+  }
+
+  const LiveInterval &getInterval(Register Reg) const {
+    return const_cast<LiveIntervals *>(this)->getInterval(Reg);
+  }
+
+  bool hasInterval(Register Reg) const {
+    return VirtRegIntervals.inBounds(Reg.id()) && VirtRegIntervals[Reg.id()];
+  }
+
+  /// Interval creation.
+  LiveInterval &createEmptyInterval(Register Reg) {
+    assert(!hasInterval(Reg) && "Interval already exists!");
+    VirtRegIntervals.grow(Reg.id());
+    VirtRegIntervals[Reg.id()] = createInterval(Reg);
+    return *VirtRegIntervals[Reg.id()];
+  }
+
+  LiveInterval &createAndComputeVirtRegInterval(Register Reg) {
+    LiveInterval &LI = createEmptyInterval(Reg);
+    computeVirtRegInterval(LI);
+    return LI;
+  }
+
+  /// Return an existing interval for \p Reg.
+  /// If \p Reg has no interval then this creates a new empty one instead.
+  /// Note: does not trigger interval computation.
+  LiveInterval &getOrCreateEmptyInterval(Register Reg) {
+    return hasInterval(Reg) ? getInterval(Reg) : createEmptyInterval(Reg);
+  }
+
+  /// Interval removal.
+  void removeInterval(Register Reg) {
+    delete VirtRegIntervals[Reg];
+    VirtRegIntervals[Reg] = nullptr;
+  }
+
+  /// Given a register and an instruction, adds a live segment from that
+  /// instruction to the end of its MBB.
+  LiveInterval::Segment addSegmentToEndOfBlock(Register Reg,
+                                               MachineInstr &startInst);
+
+  /// After removing some uses of a register, shrink its live range to just
+  /// the remaining uses. This method does not compute reaching defs for new
+  /// uses, and it doesn't remove dead defs.
+  /// Dead PHIDef values are marked as unused. New dead machine instructions
+  /// are added to the dead vector. Returns true if the interval may have been
+  /// separated into multiple connected components.
+  bool shrinkToUses(LiveInterval *li,
+                    SmallVectorImpl<MachineInstr *> *dead = nullptr);
+
+  /// Specialized version of
+  /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
+  /// that works on a subregister live range and only looks at uses matching
+  /// the lane mask of the subregister range.
+  /// This may leave the subrange empty which needs to be cleaned up with
+  /// LiveInterval::removeEmptySubranges() afterwards.
+  void shrinkToUses(LiveInterval::SubRange &SR, Register Reg);
+
+  /// Extend the live range \p LR to reach all points in \p Indices. The
+  /// points in the \p Indices array must be jointly dominated by the union
+  /// of the existing defs in \p LR and points in \p Undefs.
+  ///
+  /// PHI-defs are added as needed to maintain SSA form.
+  ///
+  /// If a SlotIndex in \p Indices is the end index of a basic block, \p LR
+  /// will be extended to be live out of the basic block.
+  /// If a SlotIndex in \p Indices is jointy dominated only by points in
+  /// \p Undefs, the live range will not be extended to that point.
+  ///
+  /// See also LiveRangeCalc::extend().
+  void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
+                       ArrayRef<SlotIndex> Undefs);
+
+  void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices) {
+    extendToIndices(LR, Indices, /*Undefs=*/{});
+  }
+
+  /// If \p LR has a live value at \p Kill, prune its live range by removing
+  /// any liveness reachable from Kill. Add live range end points to
+  /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
+  /// value's live range.
+  ///
+  /// Calling pruneValue() and extendToIndices() can be used to reconstruct
+  /// SSA form after adding defs to a virtual register.
+  void pruneValue(LiveRange &LR, SlotIndex Kill,
+                  SmallVectorImpl<SlotIndex> *EndPoints);
+
+  /// This function should not be used. Its intent is to tell you that you are
+  /// doing something wrong if you call pruneValue directly on a
+  /// LiveInterval. Indeed, you are supposed to call pruneValue on the main
+  /// LiveRange and all the LiveRanges of the subranges if any.
+  LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
+                                        SmallVectorImpl<SlotIndex> *) {
+    llvm_unreachable(
+        "Use pruneValue on the main LiveRange and on each subrange");
+  }
+
+  SlotIndexes *getSlotIndexes() const { return Indexes; }
+
+  /// Returns true if the specified machine instr has been removed or was
+  /// never entered in the map.
+  bool isNotInMIMap(const MachineInstr &Instr) const {
+    return !Indexes->hasIndex(Instr);
+  }
+
+  /// Returns the base index of the given instruction.
+  SlotIndex getInstructionIndex(const MachineInstr &Instr) const {
+    return Indexes->getInstructionIndex(Instr);
+  }
+
+  /// Returns the instruction associated with the given index.
+  MachineInstr *getInstructionFromIndex(SlotIndex index) const {
+    return Indexes->getInstructionFromIndex(index);
+  }
+
+  /// Return the first index in the given basic block.
+  SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+    return Indexes->getMBBStartIdx(mbb);
+  }
+
+  /// Return the last index in the given basic block.
+  SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+    return Indexes->getMBBEndIdx(mbb);
+  }
+
+  bool isLiveInToMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const {
+    return LR.liveAt(getMBBStartIdx(mbb));
+  }
+
+  bool isLiveOutOfMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const {
+    return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
+  }
+
+  MachineBasicBlock *getMBBFromIndex(SlotIndex index) const {
+    return Indexes->getMBBFromIndex(index);
+  }
+
+  void insertMBBInMaps(MachineBasicBlock *MBB) {
+    Indexes->insertMBBInMaps(MBB);
+    assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
+           "Blocks must be added in order.");
+    RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
+  }
+
+  SlotIndex InsertMachineInstrInMaps(MachineInstr &MI) {
+    return Indexes->insertMachineInstrInMaps(MI);
+  }
+
+  void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
+                                     MachineBasicBlock::iterator E) {
+    for (MachineBasicBlock::iterator I = B; I != E; ++I)
+      Indexes->insertMachineInstrInMaps(*I);
+  }
+
+  void RemoveMachineInstrFromMaps(MachineInstr &MI) {
+    Indexes->removeMachineInstrFromMaps(MI);
+  }
+
+  SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI) {
+    return Indexes->replaceMachineInstrInMaps(MI, NewMI);
+  }
+
+  VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }
+
+  /// Implement the dump method.
+  void print(raw_ostream &O) const;
+  void dump() const;
+
+  void clear();
+
+  void reanalyze(MachineFunction &MF) {
+    clear();
+    analyze(MF);
+  }
+
+  MachineDominatorTree &getDomTree() { return *DomTree; }
+
+  /// If LI is confined to a single basic block, return a pointer to that
+  /// block.  If LI is live in to or out of any block, return NULL.
+  MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
+
+  /// Returns true if VNI is killed by any PHI-def values in LI.
+  /// This may conservatively return true to avoid expensive computations.
+  bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
+
+  /// Add kill flags to any instruction that kills a virtual register.
+  void addKillFlags(const VirtRegMap *);
+
+  /// Call this method to notify LiveIntervals that instruction \p MI has been
+  /// moved within a basic block. This will update the live intervals for all
+  /// operands of \p MI. Moves between basic blocks are not supported.
+  ///
+  /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+  void handleMove(MachineInstr &MI, bool UpdateFlags = false);
+
+  /// Update intervals of operands of all instructions in the newly
+  /// created bundle specified by \p BundleStart.
+  ///
+  /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+  ///
+  /// Assumes existing liveness is accurate.
+  /// \pre BundleStart should be the first instruction in the Bundle.
+  /// \pre BundleStart should not have a have SlotIndex as one will be assigned.
+  void handleMoveIntoNewBundle(MachineInstr &BundleStart,
+                               bool UpdateFlags = false);
+
+  /// Update live intervals for instructions in a range of iterators. It is
+  /// intended for use after target hooks that may insert or remove
+  /// instructions, and is only efficient for a small number of instructions.
+  ///
+  /// OrigRegs is a vector of registers that were originally used by the
+  /// instructions in the range between the two iterators.
+  ///
+  /// Currently, the only changes that are supported are simple removal
+  /// and addition of uses.
+  void repairIntervalsInRange(MachineBasicBlock *MBB,
+                              MachineBasicBlock::iterator Begin,
+                              MachineBasicBlock::iterator End,
+                              ArrayRef<Register> OrigRegs);
+
+  // Register mask functions.
+  //
+  // Machine instructions may use a register mask operand to indicate that a
+  // large number of registers are clobbered by the instruction.  This is
+  // typically used for calls.
+  //
+  // For compile time performance reasons, these clobbers are not recorded in
+  // the live intervals for individual physical registers.  Instead,
+  // LiveIntervalAnalysis maintains a sorted list of instructions with
+  // register mask operands.
+
+  /// Returns a sorted array of slot indices of all instructions with
+  /// register mask operands.
+  ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
+
+  /// Returns a sorted array of slot indices of all instructions with register
+  /// mask operands in the basic block numbered \p MBBNum.
+  ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
+    std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+    return getRegMaskSlots().slice(P.first, P.second);
+  }
+
+  /// Returns an array of register mask pointers corresponding to
+  /// getRegMaskSlots().
+  ArrayRef<const uint32_t *> getRegMaskBits() const { return RegMaskBits; }
+
+  /// Returns an array of mask pointers corresponding to
+  /// getRegMaskSlotsInBlock(MBBNum).
+  ArrayRef<const uint32_t *> getRegMaskBitsInBlock(unsigned MBBNum) const {
+    std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+    return getRegMaskBits().slice(P.first, P.second);
+  }
+
+  /// Test if \p LI is live across any register mask instructions, and
+  /// compute a bit mask of physical registers that are not clobbered by any
+  /// of them.
+  ///
+  /// Returns false if \p LI doesn't cross any register mask instructions. In
+  /// that case, the bit vector is not filled in.
+  bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs);
+
+  // Register unit functions.
+  //
+  // Fixed interference occurs when MachineInstrs use physregs directly
+  // instead of virtual registers. This typically happens when passing
+  // arguments to a function call, or when instructions require operands in
+  // fixed registers.
+  //
+  // Each physreg has one or more register units, see MCRegisterInfo. We
+  // track liveness per register unit to handle aliasing registers more
+  // efficiently.
+
+  /// Return the live range for register unit \p Unit. It will be computed if
+  /// it doesn't exist.
+  LiveRange &getRegUnit(unsigned Unit) {
+    LiveRange *LR = RegUnitRanges[Unit];
+    if (!LR) {
+      // Compute missing ranges on demand.
+      // Use segment set to speed-up initial computation of the live range.
+      RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
+      computeRegUnitRange(*LR, Unit);
     }
-
-    SlotIndexes *getSlotIndexes() const {
-      return Indexes;
-    }
-
-    /// Returns true if the specified machine instr has been removed or was
-    /// never entered in the map.
-    bool isNotInMIMap(const MachineInstr &Instr) const {
-      return !Indexes->hasIndex(Instr);
-    }
-
-    /// Returns the base index of the given instruction.
-    SlotIndex getInstructionIndex(const MachineInstr &Instr) const {
-      return Indexes->getInstructionIndex(Instr);
-    }
-
-    /// Returns the instruction associated with the given index.
-    MachineInstr* getInstructionFromIndex(SlotIndex index) const {
-      return Indexes->getInstructionFromIndex(index);
-    }
-
-    /// Return the first index in the given basic block.
-    SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
-      return Indexes->getMBBStartIdx(mbb);
-    }
-
-    /// Return the last index in the given basic block.
-    SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
-      return Indexes->getMBBEndIdx(mbb);
-    }
-
-    bool isLiveInToMBB(const LiveRange &LR,
-                       const MachineBasicBlock *mbb) const {
-      return LR.liveAt(getMBBStartIdx(mbb));
-    }
-
-    bool isLiveOutOfMBB(const LiveRange &LR,
-                        const MachineBasicBlock *mbb) const {
-      return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
-    }
-
-    MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
-      return Indexes->getMBBFromIndex(index);
-    }
-
-    void insertMBBInMaps(MachineBasicBlock *MBB) {
-      Indexes->insertMBBInMaps(MBB);
-      assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
-             "Blocks must be added in order.");
-      RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
-    }
-
-    SlotIndex InsertMachineInstrInMaps(MachineInstr &MI) {
-      return Indexes->insertMachineInstrInMaps(MI);
-    }
-
-    void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
-                                       MachineBasicBlock::iterator E) {
-      for (MachineBasicBlock::iterator I = B; I != E; ++I)
-        Indexes->insertMachineInstrInMaps(*I);
-    }
-
-    void RemoveMachineInstrFromMaps(MachineInstr &MI) {
-      Indexes->removeMachineInstrFromMaps(MI);
-    }
-
-    SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI) {
-      return Indexes->replaceMachineInstrInMaps(MI, NewMI);
-    }
-
-    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
-
-    void getAnalysisUsage(AnalysisUsage &AU) const override;
-    void releaseMemory() override;
-
-    /// Pass entry point; Calculates LiveIntervals.
-    bool runOnMachineFunction(MachineFunction&) override;
-
-    /// Implement the dump method.
-    void print(raw_ostream &O, const Module* = nullptr) const override;
-
-    /// If LI is confined to a single basic block, return a pointer to that
-    /// block.  If LI is live in to or out of any block, return NULL.
-    MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
-
-    /// Returns true if VNI is killed by any PHI-def values in LI.
-    /// This may conservatively return true to avoid expensive computations.
-    bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
-
-    /// Add kill flags to any instruction that kills a virtual register.
-    void addKillFlags(const VirtRegMap*);
-
-    /// Call this method to notify LiveIntervals that instruction \p MI has been
-    /// moved within a basic block. This will update the live intervals for all
-    /// operands of \p MI. Moves between basic blocks are not supported.
-    ///
-    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
-    void handleMove(MachineInstr &MI, bool UpdateFlags = false);
-
-    /// Update intervals of operands of all instructions in the newly
-    /// created bundle specified by \p BundleStart.
-    ///
-    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
-    ///
-    /// Assumes existing liveness is accurate.
-    /// \pre BundleStart should be the first instruction in the Bundle.
-    /// \pre BundleStart should not have a have SlotIndex as one will be assigned.
-    void handleMoveIntoNewBundle(MachineInstr &BundleStart,
-                                 bool UpdateFlags = false);
-
-    /// Update live intervals for instructions in a range of iterators. It is
-    /// intended for use after target hooks that may insert or remove
-    /// instructions, and is only efficient for a small number of instructions.
-    ///
-    /// OrigRegs is a vector of registers that were originally used by the
-    /// instructions in the range between the two iterators.
-    ///
-    /// Currently, the only changes that are supported are simple removal
-    /// and addition of uses.
-    void repairIntervalsInRange(MachineBasicBlock *MBB,
-                                MachineBasicBlock::iterator Begin,
-                                MachineBasicBlock::iterator End,
-                                ArrayRef<Register> OrigRegs);
-
-    // Register mask functions.
-    //
-    // Machine instructions may use a register mask operand to indicate that a
-    // large number of registers are clobbered by the instruction.  This is
-    // typically used for calls.
-    //
-    // For compile time performance reasons, these clobbers are not recorded in
-    // the live intervals for individual physical registers.  Instead,
-    // LiveIntervalAnalysis maintains a sorted list of instructions with
-    // register mask operands.
-
-    /// Returns a sorted array of slot indices of all instructions with
-    /// register mask operands.
-    ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
-
-    /// Returns a sorted array of slot indices of all instructions with register
-    /// mask operands in the basic block numbered \p MBBNum.
-    ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
-      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
-      return getRegMaskSlots().slice(P.first, P.second);
-    }
-
-    /// Returns an array of register mask pointers corresponding to
-    /// getRegMaskSlots().
-    ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }
-
-    /// Returns an array of mask pointers corresponding to
-    /// getRegMaskSlotsInBlock(MBBNum).
-    ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
-      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
-      return getRegMaskBits().slice(P.first, P.second);
-    }
-
-    /// Test if \p LI is live across any register mask instructions, and
-    /// compute a bit mask of physical registers that are not clobbered by any
-    /// of them.
-    ///
-    /// Returns false if \p LI doesn't cross any register mask instructions. In
-    /// that case, the bit vector is not filled in.
-    bool checkRegMaskInterference(const LiveInterval &LI,
-                                  BitVector &UsableRegs);
-
-    // Register unit functions.
-    //
-    // Fixed interference occurs when MachineInstrs use physregs directly
-    // instead of virtual registers. This typically happens when passing
-    // arguments to a function call, or when instructions require operands in
-    // fixed registers.
-    //
-    // Each physreg has one or more register units, see MCRegisterInfo. We
-    // track liveness per register unit to handle aliasing registers more
-    // efficiently.
-
-    /// Return the live range for register unit \p Unit. It will be computed if
-    /// it doesn't exist.
-    LiveRange &getRegUnit(unsigned Unit) {
-      LiveRange *LR = RegUnitRanges[Unit];
-      if (!LR) {
-        // Compute missing ranges on demand.
-        // Use segment set to speed-up initial computation of the live range.
-        RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
-        computeRegUnitRange(*LR, Unit);
-      }
-      return *LR;
-    }
-
-    /// Return the live range for register unit \p Unit if it has already been
-    /// computed, or nullptr if it hasn't been computed yet.
-    LiveRange *getCachedRegUnit(unsigned Unit) {
-      return RegUnitRanges[Unit];
-    }
-
-    const LiveRange *getCachedRegUnit(unsigned Unit) const {
-      return RegUnitRanges[Unit];
-    }
-
-    /// Remove computed live range for register unit \p Unit. Subsequent uses
-    /// should rely on on-demand recomputation.
-    void removeRegUnit(unsigned Unit) {
-      delete RegUnitRanges[Unit];
-      RegUnitRanges[Unit] = nullptr;
-    }
-
-    /// Remove associated live ranges for the register units associated with \p
-    /// Reg. Subsequent uses should rely on on-demand recomputation.  \note This
-    /// method can result in inconsistent liveness tracking if multiple phyical
-    /// registers share a regunit, and should be used cautiously.
-    void removeAllRegUnitsForPhysReg(MCRegister Reg) {
-      for (MCRegUnit Unit : TRI->regunits(Reg))
-        removeRegUnit(Unit);
-    }
-
-    /// Remove value numbers and related live segments starting at position
-    /// \p Pos that are part of any liverange of physical register \p Reg or one
-    /// of its subregisters.
-    void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos);
-
-    /// Remove value number and related live segments of \p LI and its subranges
-    /// that start at position \p Pos.
-    void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
-
-    /// Split separate components in LiveInterval \p LI into separate intervals.
-    void splitSeparateComponents(LiveInterval &LI,
-                                 SmallVectorImpl<LiveInterval*> &SplitLIs);
-
-    /// For live interval \p LI with correct SubRanges construct matching
-    /// information for the main live range. Expects the main live range to not
-    /// have any segments or value numbers.
-    void constructMainRangeFromSubranges(LiveInterval &LI);
-
-  private:
-    /// Compute live intervals for all virtual registers.
-    void computeVirtRegs();
-
-    /// Compute RegMaskSlots and RegMaskBits.
-    void computeRegMasks();
-
-    /// Walk the values in \p LI and check for dead values:
-    /// - Dead PHIDef values are marked as unused.
-    /// - Dead operands are marked as such.
-    /// - Completely dead machine instructions are added to the \p dead vector
-    ///   if it is not nullptr.
-    /// Returns true if any PHI value numbers have been removed which may
-    /// have separated the interval into multiple connected components.
-    bool computeDeadValues(LiveInterval &LI,
-                           SmallVectorImpl<MachineInstr*> *dead);
-
-    static LiveInterval *createInterval(Register Reg);
-
-    void printInstrs(raw_ostream &O) const;
-    void dumpInstrs() const;
-
-    void computeLiveInRegUnits();
-    void computeRegUnitRange(LiveRange&, unsigned Unit);
-    bool computeVirtRegInterval(LiveInterval&);
-
-    using ShrinkToUsesWorkList = SmallVector<std::pair<SlotIndex, VNInfo*>, 16>;
-    void extendSegmentsToUses(LiveRange &Segments,
-                              ShrinkToUsesWorkList &WorkList, Register Reg,
-                              LaneBitmask LaneMask);
-
-    /// Helper function for repairIntervalsInRange(), walks backwards and
-    /// creates/modifies live segments in \p LR to match the operands found.
-    /// Only full operands or operands with subregisters matching \p LaneMask
-    /// are considered.
-    void repairOldRegInRange(MachineBasicBlock::iterator Begin,
-                             MachineBasicBlock::iterator End,
-                             const SlotIndex endIdx, LiveRange &LR,
-                             Register Reg,
-                             LaneBitmask LaneMask = LaneBitmask::getAll());
-
-    class HMEditor;
-  };
+    return *LR;
+  }
+
+  /// Return the live range for register unit \p Unit if it has already been
+  /// computed, or nullptr if it hasn't been computed yet.
+  LiveRange *getCachedRegUnit(unsigned Unit) { return RegUnitRanges[Unit]; }
+
+  const LiveRange *getCachedRegUnit(unsigned Unit) const {
+    return RegUnitRanges[Unit];
+  }
+
+  /// Remove computed live range for register unit \p Unit. Subsequent uses
+  /// should rely on on-demand recomputation.
+  void removeRegUnit(unsigned Unit) {
+    delete RegUnitRanges[Unit];
+    RegUnitRanges[Unit] = nullptr;
+  }
+
+  /// Remove associated live ranges for the register units associated with \p
+  /// Reg. Subsequent uses should rely on on-demand recomputation.  \note This
+  /// method can result in inconsistent liveness tracking if multiple phyical
+  /// registers share a regunit, and should be used cautiously.
+  void removeAllRegUnitsForPhysReg(MCRegister Reg) {
+    for (MCRegUnit Unit : TRI->regunits(Reg))
+      removeRegUnit(Unit);
+  }
+
+  /// Remove value numbers and related live segments starting at position
+  /// \p Pos that are part of any liverange of physical register \p Reg or one
+  /// of its subregisters.
+  void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos);
+
+  /// Remove value number and related live segments of \p LI and its subranges
+  /// that start at position \p Pos.
+  void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);
+
+  /// Split separate components in LiveInterval \p LI into separate intervals.
+  void splitSeparateComponents(LiveInterval &LI,
+                               SmallVectorImpl<LiveInterval *> &SplitLIs);
+
+  /// For live interval \p LI with correct SubRanges construct matching
+  /// information for the main live range. Expects the main live range to not
+  /// have any segments or value numbers.
+  void constructMainRangeFromSubranges(LiveInterval &LI);
+
+private:
+  /// Compute live intervals for all virtual registers.
+  void computeVirtRegs();
+
+  /// Compute RegMaskSlots and RegMaskBits.
+  void computeRegMasks();
+
+  /// Walk the values in \p LI and check for dead values:
+  /// - Dead PHIDef values are marked as unused.
+  /// - Dead operands are marked as such.
+  /// - Completely dead machine instructions are added to the \p dead vector
+  ///   if it is not nullptr.
+  /// Returns true if any PHI value numbers have been removed which may
+  /// have separated the interval into multiple connected components.
+  bool computeDeadValues(LiveInterval &LI,
+                         SmallVectorImpl<MachineInstr *> *dead);
+
+  static LiveInterval *createInterval(Register Reg);
+
+  void printInstrs(raw_ostream &O) const;
+  void dumpInstrs() const;
+
+  void computeLiveInRegUnits();
+  void computeRegUnitRange(LiveRange &, unsigned Unit);
+  bool computeVirtRegInterval(LiveInterval &);
+
+  using ShrinkToUsesWorkList = SmallVector<std::pair<SlotIndex, VNInfo *>, 16>;
+  void extendSegmentsToUses(LiveRange &Segments, ShrinkToUsesWorkList &WorkList,
+                            Register Reg, LaneBitmask LaneMask);
+
+  /// Helper function for repairIntervalsInRange(), walks backwards and
+  /// creates/modifies live segments in \p LR to match the operands found.
+  /// Only full operands or operands with subregisters matching \p LaneMask
+  /// are considered.
+  void repairOldRegInRange(MachineBasicBlock::iterator Begin,
+                           MachineBasicBlock::iterator End,
+                           const SlotIndex endIdx, LiveRange &LR, Register Reg,
+                           LaneBitmask LaneMask = LaneBitmask::getAll());
+
+  class HMEditor;
+};
+
+class LiveIntervalsAnalysis : public AnalysisInfoMixin<LiveIntervalsAnalysis> {
+  friend AnalysisInfoMixin<LiveIntervalsAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = LiveIntervals;
+  Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
+};
+
+class LiveIntervalsPrinterPass
+    : public PassInfoMixin<LiveIntervalsPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  explicit LiveIntervalsPrinterPass(raw_ostream &OS) : OS(OS) {}
+  PreservedAnalyses run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM);
+  static bool isRequired() { return true; }
+};
+
+class LiveIntervalsWrapperPass : public MachineFunctionPass {
+  LiveIntervals LIS;
+
+public:
+  static char ID;
+
+  LiveIntervalsWrapperPass();
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void releaseMemory() override { LIS.clear(); }
+
+  /// Pass entry point; Calculates LiveIntervals.
+  bool runOnMachineFunction(MachineFunction &) override;
+
+  /// Implement the dump method.
+  void print(raw_ostream &O, const Module * = nullptr) const override {
+    LIS.print(O);
+  }
+
+  LiveIntervals &getLIS() { return LIS; }
+};
 
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 9aa55d0ded79a..a2dfc17ac46fd 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -151,7 +151,7 @@ void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &);
 void initializeGISelKnownBitsAnalysisPass(PassRegistry &);
 void initializeLiveDebugValuesPass(PassRegistry&);
 void initializeLiveDebugVariablesPass(PassRegistry&);
-void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveIntervalsWrapperPassPass(PassRegistry &);
 void initializeLiveRangeShrinkPass(PassRegistry&);
 void initializeLiveRegMatrixPass(PassRegistry&);
 void initializeLiveStacksPass(PassRegistry&);
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index eef1709bce5df..81900510c9ae7 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -36,6 +36,7 @@
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/InterleavedLoadCombine.h"
 #include "llvm/CodeGen/JMCInstrumenter.h"
+#include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/LocalStackSlotAllocation.h"
 #include "llvm/CodeGen/LowerEmuTLS.h"
 #include "llvm/CodeGen/MIRPrinter.h"
@@ -1106,7 +1107,7 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
 
   // Eventually, we want to run LiveIntervals before PHI elimination.
   if (Opt.EarlyLiveIntervals)
-    addPass(LiveIntervalsPass());
+    addPass(RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>());
 
   addPass(TwoAddressInstructionPass());
   addPass(RegisterCoalescerPass());
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 0e8fde7468707..e8d3810670ef9 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -94,6 +94,7 @@ LOOP_PASS("loop-reduce", LoopStrengthReducePass())
 // LiveVariables can be removed completely, and LiveIntervals can be directly
 // computed. (We still either need to regenerate kill flags after regalloc, or
 // preferably fix the scavenger to not depend on them).
+MACHINE_FUNCTION_ANALYSIS("live-intervals", LiveIntervalsAnalysis())
 MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())
 MACHINE_FUNCTION_ANALYSIS("machine-branch-prob",
                           MachineBranchProbabilityAnalysis())
@@ -132,6 +133,7 @@ MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass())
 MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotAllocationPass())
 MACHINE_FUNCTION_PASS("no-op-machine-function", NoOpMachineFunctionPass())
 MACHINE_FUNCTION_PASS("print", PrintMIRPass())
+MACHINE_FUNCTION_PASS("print<live-intervals>", LiveIntervalsPrinterPass(dbgs()))
 MACHINE_FUNCTION_PASS("print<live-vars>", LiveVariablesPrinterPass(dbgs()))
 MACHINE_FUNCTION_PASS("print<machine-branch-prob>",
                       MachineBranchProbabilityPrinterPass(dbgs()))
@@ -208,7 +210,6 @@ DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass)
 DUMMY_MACHINE_FUNCTION_PASS("kcfi", MachineKCFIPass)
 DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass)
 DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass)
-DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass)
 DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass)
 DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass)
 DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass)
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index 98eebd0d7b5c3..a30eaae90a5fd 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -60,7 +60,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
   initializeJMCInstrumenterPass(Registry);
   initializeLiveDebugValuesPass(Registry);
   initializeLiveDebugVariablesPass(Registry);
-  initializeLiveIntervalsPass(Registry);
+  initializeLiveIntervalsWrapperPassPass(Registry);
   initializeLiveRangeShrinkPass(Registry);
   initializeLiveStacksPass(Registry);
   initializeLiveVariablesWrapperPassPass(Registry);
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index dc03f590ded32..6abbf8b6d7e0a 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -131,7 +131,7 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
 public:
   HoistSpillHelper(MachineFunctionPass &pass, MachineFunction &mf,
                    VirtRegMap &vrm)
-      : MF(mf), LIS(pass.getAnalysis<LiveIntervals>()),
+      : MF(mf), LIS(pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
         LSS(pass.getAnalysis<LiveStacks>()),
         MDT(pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
         VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
@@ -188,7 +188,7 @@ class InlineSpiller : public Spiller {
 public:
   InlineSpiller(MachineFunctionPass &Pass, MachineFunction &MF, VirtRegMap &VRM,
                 VirtRegAuxInfo &VRAI)
-      : MF(MF), LIS(Pass.getAnalysis<LiveIntervals>()),
+      : MF(MF), LIS(Pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
         LSS(Pass.getAnalysis<LiveStacks>()),
         MDT(Pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
         VRM(VRM), MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 3224bedcb58d2..d1341f116a547 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -79,13 +79,13 @@ char LiveDebugVariables::ID = 0;
 INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
                 "Debug Variable Analysis", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
                 "Debug Variable Analysis", false, false)
 
 void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<MachineDominatorTreeWrapperPass>();
-  AU.addRequiredTransitive<LiveIntervals>();
+  AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
   AU.setPreservesAll();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
@@ -1263,7 +1263,7 @@ void LDVImpl::computeIntervals() {
 bool LDVImpl::runOnMachineFunction(MachineFunction &mf, bool InstrRef) {
   clear();
   MF = &mf;
-  LIS = &pass.getAnalysis<LiveIntervals>();
+  LIS = &pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   TRI = mf.getSubtarget().getRegisterInfo();
   LLVM_DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: "
                     << mf.getName() << " **********\n");
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index 9742a48a5c3ad..199fae001ec1e 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -57,14 +57,39 @@ using namespace llvm;
 
 #define DEBUG_TYPE "regalloc"
 
-char LiveIntervals::ID = 0;
-char &llvm::LiveIntervalsID = LiveIntervals::ID;
-INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals", "Live Interval Analysis",
-                      false, false)
+AnalysisKey LiveIntervalsAnalysis::Key;
+
+LiveIntervalsAnalysis::Result
+LiveIntervalsAnalysis::run(MachineFunction &MF,
+                           MachineFunctionAnalysisManager &MFAM) {
+  return Result(MF, MFAM.getResult<SlotIndexesAnalysis>(MF),
+                MFAM.getResult<MachineDominatorTreeAnalysis>(MF));
+}
+
+PreservedAnalyses
+LiveIntervalsPrinterPass::run(MachineFunction &MF,
+                              MachineFunctionAnalysisManager &MFAM) {
+  OS << "Live intervals for machine function: " << MF.getName() << ":\n";
+  MFAM.getResult<LiveIntervalsAnalysis>(MF).print(OS);
+  return PreservedAnalyses::all();
+}
+
+char LiveIntervalsWrapperPass::ID = 0;
+char &llvm::LiveIntervalsID = LiveIntervalsWrapperPass::ID;
+INITIALIZE_PASS_BEGIN(LiveIntervalsWrapperPass, "liveintervals",
+                      "Live Interval Analysis", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
-                "Live Interval Analysis", false, false)
+INITIALIZE_PASS_END(LiveIntervalsWrapperPass, "liveintervals",
+                    "Live Interval Analysis", false, false)
+
+bool LiveIntervalsWrapperPass::runOnMachineFunction(MachineFunction &MF) {
+  LIS.Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
+  LIS.DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  LIS.analyze(MF);
+  LLVM_DEBUG(dump());
+  return false;
+}
 
 #ifndef NDEBUG
 static cl::opt<bool> EnablePrecomputePhysRegs(
@@ -83,7 +108,7 @@ cl::opt<bool> UseSegmentSetForPhysRegs(
 
 } // end namespace llvm
 
-void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
+void LiveIntervalsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
   AU.addPreserved<LiveVariablesWrapperPass>();
   AU.addPreservedID(MachineLoopInfoID);
@@ -94,13 +119,13 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
-LiveIntervals::LiveIntervals() : MachineFunctionPass(ID) {
-  initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
+LiveIntervalsWrapperPass::LiveIntervalsWrapperPass() : MachineFunctionPass(ID) {
+  initializeLiveIntervalsWrapperPassPass(*PassRegistry::getPassRegistry());
 }
 
-LiveIntervals::~LiveIntervals() { delete LICalc; }
+LiveIntervals::~LiveIntervals() { clear(); }
 
-void LiveIntervals::releaseMemory() {
+void LiveIntervals::clear() {
   // Free the live intervals themselves.
   for (unsigned i = 0, e = VirtRegIntervals.size(); i != e; ++i)
     delete VirtRegIntervals[Register::index2VirtReg(i)];
@@ -117,16 +142,14 @@ void LiveIntervals::releaseMemory() {
   VNInfoAllocator.Reset();
 }
 
-bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
+void LiveIntervals::analyze(MachineFunction &fn) {
   MF = &fn;
   MRI = &MF->getRegInfo();
   TRI = MF->getSubtarget().getRegisterInfo();
   TII = MF->getSubtarget().getInstrInfo();
-  Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
-  DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
 
   if (!LICalc)
-    LICalc = new LiveIntervalCalc();
+    LICalc = std::make_unique<LiveIntervalCalc>();
 
   // Allocate space for all virtual registers.
   VirtRegIntervals.resize(MRI->getNumVirtRegs());
@@ -141,11 +164,9 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
     for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
       getRegUnit(i);
   }
-  LLVM_DEBUG(dump());
-  return false;
 }
 
-void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
+void LiveIntervals::print(raw_ostream &OS) const {
   OS << "********** INTERVALS **********\n";
 
   // Dump the regunits.
@@ -179,6 +200,10 @@ LLVM_DUMP_METHOD void LiveIntervals::dumpInstrs() const {
 }
 #endif
 
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD void LiveIntervals::dump() const { print(dbgs()); }
+#endif
+
 LiveInterval *LiveIntervals::createInterval(Register reg) {
   float Weight = reg.isPhysical() ? huge_valf : 0.0F;
   return new LiveInterval(reg, Weight);
diff --git a/llvm/lib/CodeGen/LiveRegMatrix.cpp b/llvm/lib/CodeGen/LiveRegMatrix.cpp
index 6df7e5c108628..c8c722359a4c4 100644
--- a/llvm/lib/CodeGen/LiveRegMatrix.cpp
+++ b/llvm/lib/CodeGen/LiveRegMatrix.cpp
@@ -38,7 +38,7 @@ STATISTIC(NumUnassigned , "Number of registers unassigned");
 char LiveRegMatrix::ID = 0;
 INITIALIZE_PASS_BEGIN(LiveRegMatrix, "liveregmatrix",
                       "Live Register Matrix", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_PASS_END(LiveRegMatrix, "liveregmatrix",
                     "Live Register Matrix", false, false)
@@ -47,14 +47,14 @@ LiveRegMatrix::LiveRegMatrix() : MachineFunctionPass(ID) {}
 
 void LiveRegMatrix::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addRequiredTransitive<LiveIntervals>();
+  AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
   AU.addRequiredTransitive<VirtRegMap>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
 bool LiveRegMatrix::runOnMachineFunction(MachineFunction &MF) {
   TRI = MF.getSubtarget().getRegisterInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   VRM = &getAnalysis<VirtRegMap>();
 
   unsigned NumRegUnits = TRI->getNumRegUnits();
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 292bfa6c85edc..5fe7a9d35dc9a 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1161,7 +1161,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
                     << " -- " << printMBBReference(*NMBB) << " -- "
                     << printMBBReference(*Succ) << '\n');
 
-  LiveIntervals *LIS = P.getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = P.getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   auto *SIWrapper = P.getAnalysisIfAvailable<SlotIndexesWrapperPass>();
   SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
   if (LIS)
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 4460f1f666b08..2488f81fee228 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -236,7 +236,7 @@ INITIALIZE_PASS_BEGIN(MachinePipeliner, DEBUG_TYPE,
 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(MachinePipeliner, DEBUG_TYPE,
                     "Modulo Software Pipelining", false, false)
 
@@ -437,7 +437,8 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
 
 void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
   MachineRegisterInfo &MRI = MF->getRegInfo();
-  SlotIndexes &Slots = *getAnalysis<LiveIntervals>().getSlotIndexes();
+  SlotIndexes &Slots =
+      *getAnalysis<LiveIntervalsWrapperPass>().getLIS().getSlotIndexes();
 
   for (MachineInstr &PI : B.phis()) {
     MachineOperand &DefOp = PI.getOperand(0);
@@ -472,8 +473,9 @@ void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
 bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
   assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
 
-  SwingSchedulerDAG SMS(*this, L, getAnalysis<LiveIntervals>(), RegClassInfo,
-                        II_setByPragma, LI.LoopPipelinerInfo.get());
+  SwingSchedulerDAG SMS(
+      *this, L, getAnalysis<LiveIntervalsWrapperPass>().getLIS(), RegClassInfo,
+      II_setByPragma, LI.LoopPipelinerInfo.get());
 
   MachineBasicBlock *MBB = L.getHeader();
   // The kernel should not include any terminator instructions.  These
@@ -501,7 +503,7 @@ void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addPreserved<AAResultsWrapperPass>();
   AU.addRequired<MachineLoopInfoWrapperPass>();
   AU.addRequired<MachineDominatorTreeWrapperPass>();
-  AU.addRequired<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   AU.addRequired<TargetPassConfig>();
   MachineFunctionPass::getAnalysisUsage(AU);
@@ -514,7 +516,7 @@ bool MachinePipeliner::runWindowScheduler(MachineLoop &L) {
   Context.MDT = MDT;
   Context.PassConfig = &getAnalysis<TargetPassConfig>();
   Context.AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
-  Context.LIS = &getAnalysis<LiveIntervals>();
+  Context.LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   Context.RegClassInfo->runOnMachineFunction(*MF);
   WindowScheduler WS(&Context, L);
   return WS.run();
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 50eac1a570344..a8a17101b9c92 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -269,7 +269,7 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(MachineScheduler, DEBUG_TYPE,
                     "Machine Instruction Scheduler", false, false)
 
@@ -285,8 +285,8 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<SlotIndexesWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
-  AU.addRequired<LiveIntervals>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
@@ -449,7 +449,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
   PassConfig = &getAnalysis<TargetPassConfig>();
   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
 
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   if (VerifyScheduling) {
     LLVM_DEBUG(LIS->dump());
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 395f5de34b582..d0d3af0e5e4fc 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -316,7 +316,7 @@ namespace {
       AU.addUsedIfAvailable<LiveStacks>();
       AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
       AU.addUsedIfAvailable<SlotIndexesWrapperPass>();
-      AU.addUsedIfAvailable<LiveIntervals>();
+      AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
       AU.setPreservesAll();
       MachineFunctionPass::getAnalysisUsage(AU);
     }
@@ -428,7 +428,8 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
       MachineFunctionProperties::Property::TracksDebugUserValues);
 
   if (PASS) {
-    LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>();
+    auto *LISWrapper = PASS->getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+    LiveInts = LISWrapper ? &LISWrapper->getLIS() : nullptr;
     // We don't want to verify LiveVariables if LiveIntervals is available.
     auto *LVWrapper = PASS->getAnalysisIfAvailable<LiveVariablesWrapperPass>();
     if (!LiveInts)
diff --git a/llvm/lib/CodeGen/ModuloSchedule.cpp b/llvm/lib/CodeGen/ModuloSchedule.cpp
index 8b4a6fe1d4cec..0f29ebe3ee798 100644
--- a/llvm/lib/CodeGen/ModuloSchedule.cpp
+++ b/llvm/lib/CodeGen/ModuloSchedule.cpp
@@ -2764,7 +2764,7 @@ class ModuloScheduleTest : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<MachineLoopInfoWrapperPass>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 };
@@ -2775,7 +2775,7 @@ char ModuloScheduleTest::ID = 0;
 INITIALIZE_PASS_BEGIN(ModuloScheduleTest, "modulo-schedule-test",
                       "Modulo Schedule test pass", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(ModuloScheduleTest, "modulo-schedule-test",
                     "Modulo Schedule test pass", false, false)
 
@@ -2810,7 +2810,7 @@ static void parseSymbolString(StringRef S, int &Cycle, int &Stage) {
 }
 
 void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) {
-  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   MachineBasicBlock *BB = L.getTopBlock();
   dbgs() << "--- ModuloScheduleTest running on BB#" << BB->getNumber() << "\n";
 
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
index cddbb5b4ed719..ec78a3d4b6269 100644
--- a/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/llvm/lib/CodeGen/PHIElimination.cpp
@@ -139,7 +139,7 @@ void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
   AU.addPreserved<LiveVariablesWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   AU.addPreserved<MachineDominatorTreeWrapperPass>();
   AU.addPreserved<MachineLoopInfoWrapperPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
@@ -149,7 +149,8 @@ bool PHIElimination::runOnMachineFunction(MachineFunction &MF) {
   MRI = &MF.getRegInfo();
   auto *LVWrapper = getAnalysisIfAvailable<LiveVariablesWrapperPass>();
   LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
 
   bool Changed = false;
 
diff --git a/llvm/lib/CodeGen/RegAllocBasic.cpp b/llvm/lib/CodeGen/RegAllocBasic.cpp
index 133904cdbcf44..544bc98d770f2 100644
--- a/llvm/lib/CodeGen/RegAllocBasic.cpp
+++ b/llvm/lib/CodeGen/RegAllocBasic.cpp
@@ -131,7 +131,7 @@ INITIALIZE_PASS_BEGIN(RABasic, "regallocbasic", "Basic Register Allocator",
                       false, false)
 INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
 INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
 INITIALIZE_PASS_DEPENDENCY(LiveStacks)
@@ -177,8 +177,8 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
   AU.addRequired<AAResultsWrapperPass>();
   AU.addPreserved<AAResultsWrapperPass>();
-  AU.addRequired<LiveIntervals>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
   AU.addRequired<LiveDebugVariables>();
   AU.addPreserved<LiveDebugVariables>();
@@ -310,7 +310,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
 
   MF = &mf;
   RegAllocBase::init(getAnalysis<VirtRegMap>(),
-                     getAnalysis<LiveIntervals>(),
+                     getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
                      getAnalysis<LiveRegMatrix>());
   VirtRegAuxInfo VRAI(*MF, *LIS, *VRM,
                       getAnalysis<MachineLoopInfoWrapperPass>().getLI(),
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 2fdf63e32fb7c..2006cdaed51f7 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -156,7 +156,7 @@ INITIALIZE_PASS_BEGIN(RAGreedy, "greedy",
                 "Greedy Register Allocator", false, false)
 INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
 INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
 INITIALIZE_PASS_DEPENDENCY(LiveStacks)
@@ -205,8 +205,8 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
   AU.addRequired<MachineBlockFrequencyInfo>();
   AU.addPreserved<MachineBlockFrequencyInfo>();
-  AU.addRequired<LiveIntervals>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   AU.addRequired<SlotIndexesWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
   AU.addRequired<LiveDebugVariables>();
@@ -2716,7 +2716,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
     MF->verify(this, "Before greedy register allocator");
 
   RegAllocBase::init(getAnalysis<VirtRegMap>(),
-                     getAnalysis<LiveIntervals>(),
+                     getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
                      getAnalysis<LiveRegMatrix>());
 
   // Early return if there is no virtual register to be allocated to a
diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index dd7bd38060572..88e91390a4c59 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -121,7 +121,7 @@ class RegAllocPBQP : public MachineFunctionPass {
   RegAllocPBQP(char *cPassID = nullptr)
       : MachineFunctionPass(ID), customPassID(cPassID) {
     initializeSlotIndexesWrapperPassPass(*PassRegistry::getPassRegistry());
-    initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
+    initializeLiveIntervalsWrapperPassPass(*PassRegistry::getPassRegistry());
     initializeLiveStacksPass(*PassRegistry::getPassRegistry());
     initializeVirtRegMapPass(*PassRegistry::getPassRegistry());
   }
@@ -546,8 +546,8 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
   au.addPreserved<AAResultsWrapperPass>();
   au.addRequired<SlotIndexesWrapperPass>();
   au.addPreserved<SlotIndexesWrapperPass>();
-  au.addRequired<LiveIntervals>();
-  au.addPreserved<LiveIntervals>();
+  au.addRequired<LiveIntervalsWrapperPass>();
+  au.addPreserved<LiveIntervalsWrapperPass>();
   //au.addRequiredID(SplitCriticalEdgesID);
   if (customPassID)
     au.addRequiredID(*customPassID);
@@ -791,7 +791,7 @@ void RegAllocPBQP::postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS) {
 }
 
 bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
-  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   MachineBlockFrequencyInfo &MBFI =
     getAnalysis<MachineBlockFrequencyInfo>();
 
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index c84650b730816..1c35a88b4dc4a 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -406,7 +406,7 @@ char &llvm::RegisterCoalescerID = RegisterCoalescer::ID;
 
 INITIALIZE_PASS_BEGIN(RegisterCoalescer, "register-coalescer",
                       "Register Coalescer", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
@@ -588,8 +588,8 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
 void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
   AU.addRequired<AAResultsWrapperPass>();
-  AU.addRequired<LiveIntervals>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
   AU.addRequired<MachineLoopInfoWrapperPass>();
   AU.addPreserved<MachineLoopInfoWrapperPass>();
@@ -4206,7 +4206,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
   const TargetSubtargetInfo &STI = fn.getSubtarget();
   TRI = STI.getRegisterInfo();
   TII = STI.getInstrInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
   Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
   if (EnableGlobalCopies == cl::BOU_UNSET)
@@ -4298,5 +4298,5 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
 }
 
 void RegisterCoalescer::print(raw_ostream &O, const Module* m) const {
-   LIS->print(O, m);
+  LIS->print(O);
 }
diff --git a/llvm/lib/CodeGen/RenameIndependentSubregs.cpp b/llvm/lib/CodeGen/RenameIndependentSubregs.cpp
index 2c4a0270172e6..0128f87748a77 100644
--- a/llvm/lib/CodeGen/RenameIndependentSubregs.cpp
+++ b/llvm/lib/CodeGen/RenameIndependentSubregs.cpp
@@ -54,8 +54,8 @@ class RenameIndependentSubregs : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addRequired<LiveIntervals>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addRequired<SlotIndexesWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -115,7 +115,7 @@ char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID;
 INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE,
                       "Rename Independent Subregisters", false, false)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE,
                     "Rename Independent Subregisters", false, false)
 
@@ -390,7 +390,7 @@ bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
   LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
                     << MF.getName() << '\n');
 
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   TII = MF.getSubtarget().getInstrInfo();
 
   // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
diff --git a/llvm/lib/CodeGen/StackSlotColoring.cpp b/llvm/lib/CodeGen/StackSlotColoring.cpp
index 928ec39ad25a8..1118287352d3d 100644
--- a/llvm/lib/CodeGen/StackSlotColoring.cpp
+++ b/llvm/lib/CodeGen/StackSlotColoring.cpp
@@ -159,7 +159,7 @@ namespace {
       // split into multiple phases based on register class. So, this pass
       // may be invoked multiple times requiring it to save these analyses to be
       // used by RA later.
-      AU.addPreserved<LiveIntervals>();
+      AU.addPreserved<LiveIntervalsWrapperPass>();
       AU.addPreserved<LiveDebugVariables>();
 
       MachineFunctionPass::getAnalysisUsage(AU);
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index eb6f36892d8e7..73385fee019b0 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -198,7 +198,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
     AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
     AU.addPreserved<LiveVariablesWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreservedID(MachineLoopInfoID);
     AU.addPreservedID(MachineDominatorsID);
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -1764,7 +1764,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
   InstrItins = MF->getSubtarget().getInstrItineraryData();
   auto *LVWrapper = getAnalysisIfAvailable<LiveVariablesWrapperPass>();
   LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   if (auto *AAPass = getAnalysisIfAvailable<AAResultsWrapperPass>())
     AA = &AAPass->getAAResults();
   else
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp
index c2c13ea3a3e7c..4acc4f845291d 100644
--- a/llvm/lib/CodeGen/VirtRegMap.cpp
+++ b/llvm/lib/CodeGen/VirtRegMap.cpp
@@ -229,7 +229,7 @@ char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
 INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
                       "Virtual Register Rewriter", false, false)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
 INITIALIZE_PASS_DEPENDENCY(LiveStacks)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
@@ -238,8 +238,8 @@ INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
 
 void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
-  AU.addRequired<LiveIntervals>();
-  AU.addPreserved<LiveIntervals>();
+  AU.addRequired<LiveIntervalsWrapperPass>();
+  AU.addPreserved<LiveIntervalsWrapperPass>();
   AU.addRequired<SlotIndexesWrapperPass>();
   AU.addPreserved<SlotIndexesWrapperPass>();
   AU.addRequired<LiveDebugVariables>();
@@ -259,7 +259,7 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
   TII = MF->getSubtarget().getInstrInfo();
   MRI = &MF->getRegInfo();
   Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   VRM = &getAnalysis<VirtRegMap>();
   DebugVars = &getAnalysis<LiveDebugVariables>();
   LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 4f3867826bfa0..219e8b75450e2 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -90,6 +90,7 @@
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/InterleavedLoadCombine.h"
 #include "llvm/CodeGen/JMCInstrumenter.h"
+#include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/LocalStackSlotAllocation.h"
 #include "llvm/CodeGen/LowerEmuTLS.h"
diff --git a/llvm/lib/Target/AArch64/AArch64PostCoalescerPass.cpp b/llvm/lib/Target/AArch64/AArch64PostCoalescerPass.cpp
index dd5234c4504d3..f702147476dc8 100644
--- a/llvm/lib/Target/AArch64/AArch64PostCoalescerPass.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PostCoalescerPass.cpp
@@ -37,7 +37,7 @@ struct AArch64PostCoalescer : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 };
@@ -48,7 +48,7 @@ char AArch64PostCoalescer::ID = 0;
 
 INITIALIZE_PASS_BEGIN(AArch64PostCoalescer, "aarch64-post-coalescer-pass",
                       "AArch64 Post Coalescer Pass", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(AArch64PostCoalescer, "aarch64-post-coalescer-pass",
                     "AArch64 Post Coalescer Pass", false, false)
 
@@ -61,7 +61,7 @@ bool AArch64PostCoalescer::runOnMachineFunction(MachineFunction &MF) {
     return false;
 
   MRI = &MF.getRegInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   bool Changed = false;
 
   for (MachineBasicBlock &MBB : MF) {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
index be809fc120637..359cd7ad6a714 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
@@ -43,7 +43,7 @@ class AMDGPUMarkLastScratchLoad : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<SlotIndexesWrapperPass>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addRequired<LiveStacks>();
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -65,7 +65,7 @@ bool AMDGPUMarkLastScratchLoad::runOnMachineFunction(MachineFunction &MF) {
     return false;
 
   LS = &getAnalysis<LiveStacks>();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   SI = &getAnalysis<SlotIndexesWrapperPass>().getSI();
   SII = ST.getInstrInfo();
   SlotIndexes &Slots = *LIS->getSlotIndexes();
diff --git a/llvm/lib/Target/AMDGPU/GCNNSAReassign.cpp b/llvm/lib/Target/AMDGPU/GCNNSAReassign.cpp
index 272cc7fa6bc66..90dbbf407d3dd 100644
--- a/llvm/lib/Target/AMDGPU/GCNNSAReassign.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNNSAReassign.cpp
@@ -48,7 +48,7 @@ class GCNNSAReassign : public MachineFunctionPass {
   StringRef getPassName() const override { return "GCN NSA Reassign"; }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addRequired<VirtRegMap>();
     AU.addRequired<LiveRegMatrix>();
     AU.setPreservesAll();
@@ -94,7 +94,7 @@ class GCNNSAReassign : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(GCNNSAReassign, DEBUG_TYPE, "GCN NSA Reassign",
                       false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
 INITIALIZE_PASS_END(GCNNSAReassign, DEBUG_TYPE, "GCN NSA Reassign",
@@ -244,7 +244,7 @@ bool GCNNSAReassign::runOnMachineFunction(MachineFunction &MF) {
   TRI = ST->getRegisterInfo();
   VRM = &getAnalysis<VirtRegMap>();
   LRM = &getAnalysis<LiveRegMatrix>();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
   MaxNumVGPRs = ST->getMaxNumVGPRs(MF);
diff --git a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
index a906a4207758f..4467836cffc56 100644
--- a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
@@ -60,7 +60,7 @@ class GCNPreRAOptimizations : public MachineFunctionPass {
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -70,7 +70,7 @@ class GCNPreRAOptimizations : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(GCNPreRAOptimizations, DEBUG_TYPE,
                       "AMDGPU Pre-RA optimizations", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(GCNPreRAOptimizations, DEBUG_TYPE, "Pre-RA optimizations",
                     false, false)
 
@@ -219,7 +219,7 @@ bool GCNPreRAOptimizations::runOnMachineFunction(MachineFunction &MF) {
   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
   TII = ST.getInstrInfo();
   MRI = &MF.getRegInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   TRI = ST.getRegisterInfo();
 
   bool Changed = false;
diff --git a/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp b/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
index 5c394e6d6296d..c83af729f501f 100644
--- a/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
@@ -628,7 +628,7 @@ getRegLiveThroughMask(const MachineRegisterInfo &MRI, const LiveIntervals &LIS,
 bool GCNRegPressurePrinter::runOnMachineFunction(MachineFunction &MF) {
   const MachineRegisterInfo &MRI = MF.getRegInfo();
   const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
-  const LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  const LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   auto &OS = dbgs();
 
diff --git a/llvm/lib/Target/AMDGPU/GCNRegPressure.h b/llvm/lib/Target/AMDGPU/GCNRegPressure.h
index 752f53752fa68..98f9b3bc6aada 100644
--- a/llvm/lib/Target/AMDGPU/GCNRegPressure.h
+++ b/llvm/lib/Target/AMDGPU/GCNRegPressure.h
@@ -356,7 +356,7 @@ struct GCNRegPressurePrinter : public MachineFunctionPass {
   bool runOnMachineFunction(MachineFunction &MF) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
diff --git a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
index e6dd3042887b9..6f83804f0a6f4 100644
--- a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
@@ -57,7 +57,7 @@ class GCNRewritePartialRegUses : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -482,7 +482,8 @@ bool GCNRewritePartialRegUses::runOnMachineFunction(MachineFunction &MF) {
   MRI = &MF.getRegInfo();
   TRI = static_cast<const SIRegisterInfo *>(MRI->getTargetRegisterInfo());
   TII = MF.getSubtarget().getInstrInfo();
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   bool Changed = false;
   for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
     Changed |= rewriteReg(Register::index2VirtReg(I));
diff --git a/llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp b/llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp
index edcfd994033e7..70ea5b8916155 100644
--- a/llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp
@@ -49,7 +49,7 @@ class SIFormMemoryClauses : public MachineFunctionPass {
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -81,7 +81,7 @@ class SIFormMemoryClauses : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(SIFormMemoryClauses, DEBUG_TYPE,
                       "SI Form memory clauses", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(SIFormMemoryClauses, DEBUG_TYPE,
                     "SI Form memory clauses", false, false)
 
@@ -266,7 +266,7 @@ bool SIFormMemoryClauses::runOnMachineFunction(MachineFunction &MF) {
   TRI = ST->getRegisterInfo();
   MRI = &MF.getRegInfo();
   MFI = MF.getInfo<SIMachineFunctionInfo>();
-  LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
+  LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   SlotIndexes *Ind = LIS->getSlotIndexes();
   bool Changed = false;
 
diff --git a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
index 4bccf2b1ff671..99c7d2b306789 100644
--- a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
@@ -147,11 +147,11 @@ class SILowerControlFlow : public MachineFunctionPass {
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addUsedIfAvailable<LiveIntervals>();
+    AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
     // Should preserve the same set that TwoAddressInstructions does.
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreservedID(LiveVariablesID);
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -761,7 +761,8 @@ bool SILowerControlFlow::runOnMachineFunction(MachineFunction &MF) {
                         MF.getTarget().getOptLevel() > CodeGenOptLevel::None;
 
   // This doesn't actually need LiveIntervals, but we can preserve them.
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   // This doesn't actually need LiveVariables, but we can preserve them.
   auto *LVWrapper = getAnalysisIfAvailable<LiveVariablesWrapperPass>();
   LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index 1ca419b93c9f5..3e0baede919cc 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -75,7 +75,7 @@ char SILowerSGPRSpills::ID = 0;
 
 INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE,
                       "SI lower SGPR spill instructions", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_PASS_END(SILowerSGPRSpills, DEBUG_TYPE,
                     "SI lower SGPR spill instructions", false, false)
@@ -311,7 +311,8 @@ bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) {
   TII = ST.getInstrInfo();
   TRI = &TII->getRegisterInfo();
 
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
   Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
 
diff --git a/llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp b/llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp
index c05406b21a45c..c6779659ff97f 100644
--- a/llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerWWMCopies.cpp
@@ -63,7 +63,7 @@ class SILowerWWMCopies : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(SILowerWWMCopies, DEBUG_TYPE, "SI Lower WWM Copies",
                       false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_PASS_END(SILowerWWMCopies, DEBUG_TYPE, "SI Lower WWM Copies", false,
                     false)
@@ -102,7 +102,8 @@ bool SILowerWWMCopies::runOnMachineFunction(MachineFunction &MF) {
   const SIInstrInfo *TII = ST.getInstrInfo();
 
   MFI = MF.getInfo<SIMachineFunctionInfo>();
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
   Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
   VRM = getAnalysisIfAvailable<VirtRegMap>();
diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp
index 3c60459e54e8f..1f6f45e9630ce 100644
--- a/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp
+++ b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp
@@ -84,7 +84,7 @@ class SIOptimizeExecMasking : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(SIOptimizeExecMasking, DEBUG_TYPE,
                       "SI optimize exec mask operations", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(SIOptimizeExecMasking, DEBUG_TYPE,
                     "SI optimize exec mask operations", false, false)
 
diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeExecMaskingPreRA.cpp b/llvm/lib/Target/AMDGPU/SIOptimizeExecMaskingPreRA.cpp
index c91d241f81abc..494b2341f0e0e 100644
--- a/llvm/lib/Target/AMDGPU/SIOptimizeExecMaskingPreRA.cpp
+++ b/llvm/lib/Target/AMDGPU/SIOptimizeExecMaskingPreRA.cpp
@@ -56,7 +56,7 @@ class SIOptimizeExecMaskingPreRA : public MachineFunctionPass {
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -66,7 +66,7 @@ class SIOptimizeExecMaskingPreRA : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(SIOptimizeExecMaskingPreRA, DEBUG_TYPE,
                       "SI optimize exec mask operations pre-RA", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(SIOptimizeExecMaskingPreRA, DEBUG_TYPE,
                     "SI optimize exec mask operations pre-RA", false, false)
 
@@ -348,7 +348,7 @@ bool SIOptimizeExecMaskingPreRA::runOnMachineFunction(MachineFunction &MF) {
   TRI = ST.getRegisterInfo();
   TII = ST.getInstrInfo();
   MRI = &MF.getRegInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   const bool Wave32 = ST.isWave32();
   AndOpc = Wave32 ? AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64;
diff --git a/llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp b/llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp
index 5837dbeb3f986..29fef49ee7095 100644
--- a/llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp
+++ b/llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp
@@ -59,7 +59,7 @@ class SIPreAllocateWWMRegs : public MachineFunctionPass {
   bool runOnMachineFunction(MachineFunction &MF) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addRequired<VirtRegMap>();
     AU.addRequired<LiveRegMatrix>();
     AU.setPreservesAll();
@@ -75,7 +75,7 @@ class SIPreAllocateWWMRegs : public MachineFunctionPass {
 
 INITIALIZE_PASS_BEGIN(SIPreAllocateWWMRegs, DEBUG_TYPE,
                 "SI Pre-allocate WWM Registers", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
 INITIALIZE_PASS_END(SIPreAllocateWWMRegs, DEBUG_TYPE,
@@ -193,7 +193,7 @@ bool SIPreAllocateWWMRegs::runOnMachineFunction(MachineFunction &MF) {
   TRI = &TII->getRegisterInfo();
   MRI = &MF.getRegInfo();
 
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   Matrix = &getAnalysis<LiveRegMatrix>();
   VRM = &getAnalysis<VirtRegMap>();
 
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 4c5e60c873bb9..8a315aa822786 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -3157,7 +3157,7 @@ MachineInstr *SIRegisterInfo::findReachingDef(Register Reg, unsigned SubReg,
                                               MachineInstr &Use,
                                               MachineRegisterInfo &MRI,
                                               LiveIntervals *LIS) const {
-  auto &MDT = LIS->getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+  auto &MDT = LIS->getDomTree();
   SlotIndex UseIdx = LIS->getInstructionIndex(Use);
   SlotIndex DefIdx;
 
diff --git a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
index b39f3ba970600..9f064493f5047 100644
--- a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
+++ b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
@@ -236,9 +236,9 @@ class SIWholeQuadMode : public MachineFunctionPass {
   StringRef getPassName() const override { return "SI Whole Quad Mode"; }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
     AU.addPreserved<MachinePostDominatorTreeWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -256,7 +256,7 @@ char SIWholeQuadMode::ID = 0;
 
 INITIALIZE_PASS_BEGIN(SIWholeQuadMode, DEBUG_TYPE, "SI Whole Quad Mode", false,
                       false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
 INITIALIZE_PASS_END(SIWholeQuadMode, DEBUG_TYPE, "SI Whole Quad Mode", false,
@@ -1637,7 +1637,7 @@ bool SIWholeQuadMode::runOnMachineFunction(MachineFunction &MF) {
   TII = ST->getInstrInfo();
   TRI = &TII->getRegisterInfo();
   MRI = &MF.getRegInfo();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   auto *MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
   MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
   auto *PDTWrapper =
diff --git a/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp b/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp
index 9cfbaf9452587..e9d95c6e89db4 100644
--- a/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp
@@ -47,9 +47,9 @@ class HexagonCopyHoisting : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<SlotIndexesWrapperPass>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addRequired<MachineDominatorTreeWrapperPass>();
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -107,11 +107,10 @@ bool HexagonCopyHoisting::runOnMachineFunction(MachineFunction &Fn) {
   }
   // Re-compute liveness
   if (Changed) {
-    LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+    LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
     SlotIndexes *SI = LIS.getSlotIndexes();
     SI->reanalyze(Fn);
-    LIS.releaseMemory();
-    LIS.runOnMachineFunction(Fn);
+    LIS.reanalyze(Fn);
   }
   return Changed;
 }
diff --git a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
index 65093e054dc4e..88b4defc754ab 100644
--- a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
@@ -152,8 +152,8 @@ namespace {
     StringRef getPassName() const override { return "Hexagon Expand Condsets"; }
 
     void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.addRequired<LiveIntervals>();
-      AU.addPreserved<LiveIntervals>();
+      AU.addRequired<LiveIntervalsWrapperPass>();
+      AU.addPreserved<LiveIntervalsWrapperPass>();
       AU.addPreserved<SlotIndexesWrapperPass>();
       AU.addRequired<MachineDominatorTreeWrapperPass>();
       AU.addPreserved<MachineDominatorTreeWrapperPass>();
@@ -256,7 +256,7 @@ INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets",
   "Hexagon Expand Condsets", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_END(HexagonExpandCondsets, "expand-condsets",
   "Hexagon Expand Condsets", false, false)
 
@@ -1278,11 +1278,10 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
   HII = static_cast<const HexagonInstrInfo*>(MF.getSubtarget().getInstrInfo());
   TRI = MF.getSubtarget().getRegisterInfo();
   MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  LIS = &getAnalysis<LiveIntervals>();
+  LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   MRI = &MF.getRegInfo();
 
-  LLVM_DEBUG(LIS->print(dbgs() << "Before expand-condsets\n",
-                        MF.getFunction().getParent()));
+  LLVM_DEBUG(LIS->print(dbgs() << "Before expand-condsets\n"));
 
   bool Changed = false;
   std::set<Register> CoalUpd, PredUpd;
@@ -1314,8 +1313,7 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
     }
   }
   updateLiveness(KillUpd, false, true, false);
-  LLVM_DEBUG(
-      LIS->print(dbgs() << "After coalescing\n", MF.getFunction().getParent()));
+  LLVM_DEBUG(LIS->print(dbgs() << "After coalescing\n"));
 
   // First, simply split all muxes into a pair of conditional transfers
   // and update the live intervals to reflect the new arrangement. The
@@ -1331,8 +1329,7 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
   // predication, and after splitting they are difficult to recalculate
   // (because of predicated defs), so make sure they are left untouched.
   // Predication does not use live intervals.
-  LLVM_DEBUG(
-      LIS->print(dbgs() << "After splitting\n", MF.getFunction().getParent()));
+  LLVM_DEBUG(LIS->print(dbgs() << "After splitting\n"));
 
   // Traverse all blocks and collapse predicable instructions feeding
   // conditional transfers into predicated instructions.
@@ -1340,8 +1337,7 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
   // cases that were not created in the previous step.
   for (auto &B : MF)
     Changed |= predicateInBlock(B, PredUpd);
-  LLVM_DEBUG(LIS->print(dbgs() << "After predicating\n",
-                        MF.getFunction().getParent()));
+  LLVM_DEBUG(LIS->print(dbgs() << "After predicating\n"));
 
   PredUpd.insert(CoalUpd.begin(), CoalUpd.end());
   updateLiveness(PredUpd, true, true, true);
@@ -1351,8 +1347,7 @@ bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
 
   LLVM_DEBUG({
     if (Changed)
-      LIS->print(dbgs() << "After expand-condsets\n",
-                 MF.getFunction().getParent());
+      LIS->print(dbgs() << "After expand-condsets\n");
   });
 
   return Changed;
diff --git a/llvm/lib/Target/LoongArch/LoongArchDeadRegisterDefinitions.cpp b/llvm/lib/Target/LoongArch/LoongArchDeadRegisterDefinitions.cpp
index eb589dafd4e3f..3b289ce391dd4 100644
--- a/llvm/lib/Target/LoongArch/LoongArchDeadRegisterDefinitions.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchDeadRegisterDefinitions.cpp
@@ -35,9 +35,9 @@ class LoongArchDeadRegisterDefinitions : public MachineFunctionPass {
   bool runOnMachineFunction(MachineFunction &MF) override;
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addRequired<LiveIntervals>();
-    AU.addPreserved<LiveIntervals>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveDebugVariables>();
     AU.addPreserved<LiveStacks>();
@@ -63,7 +63,7 @@ bool LoongArchDeadRegisterDefinitions::runOnMachineFunction(
 
   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
-  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   LLVM_DEBUG(dbgs() << "***** LoongArchDeadRegisterDefinitions *****\n");
 
   bool MadeChange = false;
diff --git a/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp b/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
index 3ad89641d21cc..e0202ba6797db 100644
--- a/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
+++ b/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
@@ -325,7 +325,7 @@ namespace {
     }
 
     void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.addRequired<LiveIntervals>();
+      AU.addRequired<LiveIntervalsWrapperPass>();
       AU.addRequired<SlotIndexesWrapperPass>();
       MachineFunctionPass::getAnalysisUsage(AU);
     }
@@ -334,7 +334,7 @@ namespace {
 
 INITIALIZE_PASS_BEGIN(PPCTLSDynamicCall, DEBUG_TYPE,
                       "PowerPC TLS Dynamic Call Fixup", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
 INITIALIZE_PASS_END(PPCTLSDynamicCall, DEBUG_TYPE,
                     "PowerPC TLS Dynamic Call Fixup", false, false)
diff --git a/llvm/lib/Target/PowerPC/PPCVSXFMAMutate.cpp b/llvm/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
index b1a1f44dc9fe8..4b4e47e9532a8 100644
--- a/llvm/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
+++ b/llvm/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
@@ -347,7 +347,7 @@ namespace {
       if (!STI.hasVSX())
         return false;
 
-      LIS = &getAnalysis<LiveIntervals>();
+      LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
       TII = STI.getInstrInfo();
 
@@ -364,8 +364,8 @@ namespace {
     }
 
     void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.addRequired<LiveIntervals>();
-      AU.addPreserved<LiveIntervals>();
+      AU.addRequired<LiveIntervalsWrapperPass>();
+      AU.addPreserved<LiveIntervalsWrapperPass>();
       AU.addRequired<SlotIndexesWrapperPass>();
       AU.addPreserved<SlotIndexesWrapperPass>();
       AU.addRequired<MachineDominatorTreeWrapperPass>();
@@ -377,7 +377,7 @@ namespace {
 
 INITIALIZE_PASS_BEGIN(PPCVSXFMAMutate, DEBUG_TYPE,
                       "PowerPC VSX FMA Mutation", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
 INITIALIZE_PASS_END(PPCVSXFMAMutate, DEBUG_TYPE,
diff --git a/llvm/lib/Target/RISCV/RISCVDeadRegisterDefinitions.cpp b/llvm/lib/Target/RISCV/RISCVDeadRegisterDefinitions.cpp
index d2c42f98dd893..cce0ffe16e5fe 100644
--- a/llvm/lib/Target/RISCV/RISCVDeadRegisterDefinitions.cpp
+++ b/llvm/lib/Target/RISCV/RISCVDeadRegisterDefinitions.cpp
@@ -35,9 +35,9 @@ class RISCVDeadRegisterDefinitions : public MachineFunctionPass {
   bool runOnMachineFunction(MachineFunction &MF) override;
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addRequired<LiveIntervals>();
-    AU.addPreserved<LiveIntervals>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveDebugVariables>();
     AU.addPreserved<LiveStacks>();
@@ -62,7 +62,7 @@ bool RISCVDeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
 
   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
-  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   LLVM_DEBUG(dbgs() << "***** RISCVDeadRegisterDefinitions *****\n");
 
   bool MadeChange = false;
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index a92118b1444b8..0ae7d57678272 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -891,8 +891,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
 
-    AU.addUsedIfAvailable<LiveIntervals>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveDebugVariables>();
     AU.addPreserved<LiveStacks>();
@@ -1772,7 +1772,8 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
 
   TII = ST->getInstrInfo();
   MRI = &MF.getRegInfo();
-  LIS = getAnalysisIfAvailable<LiveIntervals>();
+  auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
+  LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
 
   assert(BlockInfo.empty() && "Expect empty block infos");
   BlockInfo.resize(MF.getNumBlockIDs());
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
index f2aebacebddf3..120e350ab272a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMemIntrinsicResults.cpp
@@ -58,9 +58,9 @@ class WebAssemblyMemIntrinsicResults final : public MachineFunctionPass {
     AU.addPreserved<MachineBlockFrequencyInfo>();
     AU.addRequired<MachineDominatorTreeWrapperPass>();
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addRequired<TargetLibraryInfoWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -185,7 +185,7 @@ bool WebAssemblyMemIntrinsicResults::runOnMachineFunction(MachineFunction &MF) {
       *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
   const auto &LibInfo =
       getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
-  auto &LIS = getAnalysis<LiveIntervals>();
+  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   bool Changed = false;
 
   // We don't preserve SSA form.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
index affaa454b734f..22213ccc58991 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyOptimizeLiveIntervals.cpp
@@ -40,10 +40,10 @@ class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<MachineBlockFrequencyInfo>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreservedID(LiveVariablesID);
     AU.addPreservedID(MachineDominatorsID);
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -77,7 +77,7 @@ bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(
                     << MF.getName() << '\n');
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  auto &LIS = getAnalysis<LiveIntervals>();
+  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   // We don't preserve SSA form.
   MRI.leaveSSA();
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
index acd984f2f8f88..34aa679e53081 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp
@@ -40,7 +40,7 @@ class WebAssemblyRegColoring final : public MachineFunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addRequired<MachineBlockFrequencyInfo>();
     AU.addPreserved<MachineBlockFrequencyInfo>();
     AU.addPreservedID(MachineDominatorsID);
@@ -232,7 +232,7 @@ bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
     return false;
 
   MachineRegisterInfo *MRI = &MF.getRegInfo();
-  LiveIntervals *Liveness = &getAnalysis<LiveIntervals>();
+  LiveIntervals *Liveness = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   const MachineBlockFrequencyInfo *MBFI =
       &getAnalysis<MachineBlockFrequencyInfo>();
   WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
index a53b4d478a20f..17e166c3e32b5 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -50,10 +50,10 @@ class WebAssemblyRegStackify final : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesCFG();
     AU.addRequired<MachineDominatorTreeWrapperPass>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     AU.addPreserved<MachineBlockFrequencyInfo>();
     AU.addPreserved<SlotIndexesWrapperPass>();
-    AU.addPreserved<LiveIntervals>();
+    AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreservedID(LiveVariablesID);
     AU.addPreserved<MachineDominatorTreeWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -815,7 +815,7 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
   const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
   const auto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
   auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-  auto &LIS = getAnalysis<LiveIntervals>();
+  auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
 
   // Walk the instructions from the bottom up. Currently we don't look past
   // block boundaries, and the blocks aren't ordered so the block visitation
diff --git a/llvm/lib/Target/X86/X86TileConfig.cpp b/llvm/lib/Target/X86/X86TileConfig.cpp
index ebe48910225f9..4552820f0f624 100644
--- a/llvm/lib/Target/X86/X86TileConfig.cpp
+++ b/llvm/lib/Target/X86/X86TileConfig.cpp
@@ -51,7 +51,7 @@ struct X86TileConfig : public MachineFunctionPass {
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
     AU.addRequired<VirtRegMap>();
-    AU.addRequired<LiveIntervals>();
+    AU.addRequired<LiveIntervalsWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
@@ -86,7 +86,7 @@ bool X86TileConfig::runOnMachineFunction(MachineFunction &MF) {
   const TargetRegisterInfo *TRI = ST.getRegisterInfo();
   const TargetInstrInfo *TII = ST.getInstrInfo();
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+  LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   VirtRegMap &VRM = getAnalysis<VirtRegMap>();
 
   if (VRM.isShapeMapEmpty())
diff --git a/llvm/test/CodeGen/AArch64/live-interval-analysis.mir b/llvm/test/CodeGen/AArch64/live-interval-analysis.mir
index 8e705b9e77190..5f33ea6ca15fb 100644
--- a/llvm/test/CodeGen/AArch64/live-interval-analysis.mir
+++ b/llvm/test/CodeGen/AArch64/live-interval-analysis.mir
@@ -1,4 +1,5 @@
 # RUN: llc -o /dev/null %s -mtriple=aarch64-darwin-ios -run-pass=liveintervals -debug-only=regalloc -precompute-phys-liveness 2>&1 | FileCheck %s
+# RUN: llc -o /dev/null %s -mtriple=aarch64-darwin-ios --passes='print<live-intervals>' -debug-only=regalloc -precompute-phys-liveness 2>&1 | FileCheck %s
 # REQUIRES: asserts
 --- |
   define void @reserved_reg_liveness() { ret void }
diff --git a/llvm/test/CodeGen/AMDGPU/liveness.mir b/llvm/test/CodeGen/AMDGPU/liveness.mir
index 3f28f51f49329..0805596673fda 100644
--- a/llvm/test/CodeGen/AMDGPU/liveness.mir
+++ b/llvm/test/CodeGen/AMDGPU/liveness.mir
@@ -1,4 +1,5 @@
 # RUN: llc -mtriple=amdgcn -run-pass liveintervals -verify-machineinstrs -o /dev/null -debug-only=regalloc %s 2>&1 | FileCheck %s
+# RUN: llc -mtriple=amdgcn -passes='print<live-intervals>' -o /dev/null -debug-only=regalloc %s 2>&1 | FileCheck %s
 # REQUIRES: asserts
 # We currently maintain a main liveness range which operates like a superset of
 # all subregister liveranges. We may need to create additional SSA values at
diff --git a/llvm/test/CodeGen/AMDGPU/phys-partial-liveness.mir b/llvm/test/CodeGen/AMDGPU/phys-partial-liveness.mir
index 91d0e7c3b4b35..d1cc5659f5ab5 100644
--- a/llvm/test/CodeGen/AMDGPU/phys-partial-liveness.mir
+++ b/llvm/test/CodeGen/AMDGPU/phys-partial-liveness.mir
@@ -1,4 +1,5 @@
 # RUN: llc -mtriple=amdgcn--amdpal -mcpu=gfx1100 -debug-only=regalloc -verify-machineinstrs -run-pass=liveintervals -o - %s 2>&1 | FileCheck %s
+# RUN: llc -mtriple=amdgcn--amdpal -mcpu=gfx1100 -debug-only=regalloc --passes='print<live-intervals>' -o - %s 2>&1 | FileCheck %s
 # REQUIRES: asserts
 
 # CHECK: Computing live-in reg-units in ABI blocks.
diff --git a/llvm/test/CodeGen/AMDGPU/return-with-successors.mir b/llvm/test/CodeGen/AMDGPU/return-with-successors.mir
index 29f084f87f066..8d529f27399fd 100644
--- a/llvm/test/CodeGen/AMDGPU/return-with-successors.mir
+++ b/llvm/test/CodeGen/AMDGPU/return-with-successors.mir
@@ -1,5 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs -run-pass=liveintervals -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs --passes='print<live-intervals>' -o - %s | FileCheck %s
 # Test that getNoPreservedMask is implemented, which is called when
 # return blocks have successors.
 
diff --git a/llvm/test/CodeGen/AMDGPU/subreg-intervals.mir b/llvm/test/CodeGen/AMDGPU/subreg-intervals.mir
index 2fd874ddfdfe5..1da41678af79a 100644
--- a/llvm/test/CodeGen/AMDGPU/subreg-intervals.mir
+++ b/llvm/test/CodeGen/AMDGPU/subreg-intervals.mir
@@ -1,4 +1,5 @@
 # RUN: llc -mtriple=amdgcn -run-pass liveintervals -debug-only=regalloc -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: llc -mtriple=amdgcn --passes='print<live-intervals>' -debug-only=regalloc -o /dev/null %s 2>&1 | FileCheck %s
 # REQUIRES: asserts
 
 # CHECK: INTERVALS
diff --git a/llvm/test/CodeGen/X86/invalid-liveness.mir b/llvm/test/CodeGen/X86/invalid-liveness.mir
index 039bb6bc79c75..107c903911871 100644
--- a/llvm/test/CodeGen/X86/invalid-liveness.mir
+++ b/llvm/test/CodeGen/X86/invalid-liveness.mir
@@ -1,4 +1,5 @@
 # RUN: not --crash llc -mtriple=i686-- -run-pass liveintervals -o - %s 2>&1 | FileCheck %s
+# RUN: not --crash llc -mtriple=i686-- --passes='print<live-intervals>' -o - %s 2>&1 | FileCheck %s
 # REQUIRES: asserts
 
 --- |
diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp
index 2ed25ec479601..bba5cb84d1152 100644
--- a/llvm/unittests/MI/LiveIntervalTest.cpp
+++ b/llvm/unittests/MI/LiveIntervalTest.cpp
@@ -218,7 +218,7 @@ static void doTest(StringRef MIRFunc,
 }
 
 static void liveIntervalTest(StringRef MIRFunc,
-                             TestPassT<LiveIntervals>::TestFx T,
+                             TestPassT<LiveIntervalsWrapperPass>::TestFx T,
                              bool ShouldPass = true) {
   SmallString<160> S;
   StringRef MIRString = (Twine(R"MIR(
@@ -231,7 +231,7 @@ body: |
   bb.0:
 )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
 
-  doTest<LiveIntervals>(MIRString, T, ShouldPass);
+  doTest<LiveIntervalsWrapperPass>(MIRString, T, ShouldPass);
 }
 
 static void liveVariablesTest(StringRef MIRFunc,
@@ -258,14 +258,16 @@ INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
 
 TEST(LiveIntervalTest, MoveUpDef) {
   // Value defined.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     S_NOP 0
     S_NOP 0
     early-clobber %0 = IMPLICIT_DEF
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUpRedef) {
@@ -274,52 +276,61 @@ TEST(LiveIntervalTest, MoveUpRedef) {
     S_NOP 0
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+                   [](MachineFunction &MF, LiveIntervalsWrapperPass &LIS) {
+                     testHandleMove(MF, LIS.getLIS(), 2, 1);
+                   });
 }
 
 TEST(LiveIntervalTest, MoveUpEarlyDef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     S_NOP 0
     S_NOP 0
     early-clobber %0 = IMPLICIT_DEF
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUpEarlyRedef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUpKill) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUpKillFollowing) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
+      });
 }
 
 // TODO: Construct a situation where we have intervals following a hole
@@ -327,86 +338,101 @@ TEST(LiveIntervalTest, MoveUpKillFollowing) {
 
 TEST(LiveIntervalTest, MoveDownDef) {
   // Value defined.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     S_NOP 0
     early-clobber %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveDownRedef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_NOP 0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveDownEarlyDef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     S_NOP 0
     early-clobber %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveDownEarlyRedef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_NOP 0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveDownKill) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0, implicit %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveDownKillFollowing) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUndefUse) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0, implicit undef %0
     S_NOP 0, implicit %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 3);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 3);
+      });
 }
 
 TEST(LiveIntervalTest, MoveUpValNos) {
   // handleMoveUp() had a bug where it would reuse the value number of the
   // destination segment, even though we have no guarantee that this valno
   // wasn't used in other segments.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1, %bb.2
     %0 = IMPLICIT_DEF
     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
@@ -419,39 +445,45 @@ TEST(LiveIntervalTest, MoveUpValNos) {
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_BRANCH %bb.2
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 2, 0, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 2, 0, 2);
+      });
 }
 
 TEST(LiveIntervalTest, MoveOverUndefUse0) {
   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit undef %0
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 3, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 3, 1);
+      });
 }
 
 TEST(LiveIntervalTest, MoveOverUndefUse1) {
   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     $sgpr0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit undef $sgpr0
     $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 3, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 3, 1);
+      });
 }
 
 TEST(LiveIntervalTest, SubRegMoveDown) {
   // Subregister ranges can have holes inside a basic block. Check for a
   // movement of the form 32->150 in a liverange [16, 32) [100,200).
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1, %bb.2
     %0 = IMPLICIT_DEF
     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
@@ -465,18 +497,20 @@ TEST(LiveIntervalTest, SubRegMoveDown) {
     %0.sub1 = IMPLICIT_DEF
   bb.1:
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    // Scheduler behaviour: Clear def,read-undef flag and move.
-    MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
-    MI.getOperand(0).setIsUndef(false);
-    testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        // Scheduler behaviour: Clear def,read-undef flag and move.
+        MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
+        MI.getOperand(0).setIsUndef(false);
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 4, /*BlockNum=*/1);
+      });
 }
 
 TEST(LiveIntervalTest, SubRegMoveUp) {
   // handleMoveUp had a bug not updating valno of segment incoming to bb.2
   // after swapping subreg definitions.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1, %bb.2
     undef %0.sub0 = IMPLICIT_DEF
     %0.sub1 = IMPLICIT_DEF
@@ -486,15 +520,17 @@ TEST(LiveIntervalTest, SubRegMoveUp) {
     S_NOP 0, implicit %0.sub1
   bb.2:
     S_NOP 0, implicit %0.sub1
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 0);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 0);
+      });
 }
 
 TEST(LiveIntervalTest, DeadSubRegMoveUp) {
   // handleMoveUp had a bug where moving a dead subreg def into the middle of
   // an earlier segment resulted in an invalid live range.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
     %125.sub1:vreg_128 = COPY %125.sub0
     %125.sub2:vreg_128 = COPY %125.sub0
@@ -511,28 +547,32 @@ TEST(LiveIntervalTest, DeadSubRegMoveUp) {
     undef %124.sub1:vreg_128 = nofpexcept V_MAD_F32_e64 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $mode, implicit $exec
     %124.sub0:vreg_128 = nofpexcept V_MAD_F32_e64 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $mode, implicit $exec
     dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 15, 12);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 15, 12);
+      });
 }
 
 TEST(LiveIntervalTest, EarlyClobberSubRegMoveUp) {
   // handleMoveUp had a bug where moving an early-clobber subreg def into the
   // middle of an earlier segment resulted in an invalid live range.
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %4:sreg_32 = IMPLICIT_DEF
     %6:sreg_32 = IMPLICIT_DEF
     undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec
     %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
     early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec
     %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 4, 3);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 4, 3);
+      });
 }
 
 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %1:vreg_64 = IMPLICIT_DEF
 
   bb.1:
@@ -543,16 +583,18 @@ TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {
     S_NOP 0, implicit %1.sub1
     S_BRANCH %bb.1
 
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-     MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
-     // The scheduler clears undef from subregister defs before moving
-     UndefSubregDef.getOperand(0).setIsUndef(false);
-     testHandleMove(MF, LIS, 3, 1, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
+        // The scheduler clears undef from subregister defs before moving
+        UndefSubregDef.getOperand(0).setIsUndef(false);
+        testHandleMove(MF, LISWrapper.getLIS(), 3, 1, 1);
+      });
 }
 
 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %1:vreg_96 = IMPLICIT_DEF
 
   bb.1:
@@ -564,16 +606,18 @@ TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {
     S_NOP 0, implicit %1.sub1, implicit %1.sub2
     S_BRANCH %bb.1
 
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-     MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
-     // The scheduler clears undef from subregister defs before moving
-     UndefSubregDef.getOperand(0).setIsUndef(false);
-     testHandleMove(MF, LIS, 4, 1, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
+        // The scheduler clears undef from subregister defs before moving
+        UndefSubregDef.getOperand(0).setIsUndef(false);
+        testHandleMove(MF, LISWrapper.getLIS(), 4, 1, 1);
+      });
 }
 
 TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %1:sgpr_128 = IMPLICIT_DEF
   bb.1:
     %2:sgpr_32 = COPY %1.sub2
@@ -584,84 +628,98 @@ TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) {
     S_CBRANCH_SCC1 %bb.1, implicit undef $scc
     S_BRANCH %bb.2
   bb.2:
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
-    MI.getOperand(0).setIsUndef(false);
-    testHandleMove(MF, LIS, 4, 3, 1);
-    testHandleMove(MF, LIS, 1, 4, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
+        MI.getOperand(0).setIsUndef(false);
+        testHandleMove(MF, LISWrapper.getLIS(), 4, 3, 1);
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 4, 1);
+      });
 }
 
 TEST(LiveIntervalTest, TestMoveSubRegsOfOneReg) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
     %1:vreg_64 = COPY %4
     undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
     %2.sub1:vreg_64 = COPY %2.sub0
     %3:vreg_64 = COPY %2
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMove(MF, LIS, 1, 4);
-    testHandleMove(MF, LIS, 0, 3);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMove(MF, LISWrapper.getLIS(), 1, 4);
+        testHandleMove(MF, LISWrapper.getLIS(), 0, 3);
+      });
 }
 
 TEST(LiveIntervalTest, BundleUse) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, BundleDef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 0, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1);
+      });
 }
 
 TEST(LiveIntervalTest, BundleRedef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
     S_NOP 0, implicit %0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, BundleInternalUse) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 0, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 2);
+      });
 }
 
 TEST(LiveIntervalTest, BundleUndefUse) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     %0 = IMPLICIT_DEF
     S_NOP 0
     S_NOP 0, implicit undef %0
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
+      });
 }
 
 TEST(LiveIntervalTest, BundleSubRegUse) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1, %bb.2
     undef %0.sub0 = IMPLICIT_DEF
     %0.sub1 = IMPLICIT_DEF
@@ -672,13 +730,15 @@ TEST(LiveIntervalTest, BundleSubRegUse) {
     S_NOP 0, implicit %0.sub1
   bb.2:
     S_NOP 0, implicit %0.sub1
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 1);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 1);
+      });
 }
 
 TEST(LiveIntervalTest, BundleSubRegDef) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1, %bb.2
     undef %0.sub0 = IMPLICIT_DEF
     %0.sub1 = IMPLICIT_DEF
@@ -689,25 +749,29 @@ TEST(LiveIntervalTest, BundleSubRegDef) {
     S_NOP 0, implicit %0.sub1
   bb.2:
     S_NOP 0, implicit %0.sub1
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 0);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 0);
+      });
 }
 
 TEST(LiveIntervalTest, SplitAtOneInstruction) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1
     %0 = IMPLICIT_DEF
     S_BRANCH %bb.1
   bb.1:
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testSplitAt(MF, LIS, 1, 0);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testSplitAt(MF, LISWrapper.getLIS(), 1, 0);
+      });
 }
 
 TEST(LiveIntervalTest, SplitAtMultiInstruction) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
     successors: %bb.1
     %0 = IMPLICIT_DEF
     S_NOP 0
@@ -717,30 +781,34 @@ TEST(LiveIntervalTest, SplitAtMultiInstruction) {
     S_BRANCH %bb.1
   bb.1:
     S_NOP 0
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    testSplitAt(MF, LIS, 0, 0);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        testSplitAt(MF, LISWrapper.getLIS(), 0, 0);
+      });
 }
 
 TEST(LiveIntervalTest, RepairIntervals) {
-  liveIntervalTest(R"MIR(
+  liveIntervalTest(
+      R"MIR(
   %1:sgpr_32 = IMPLICIT_DEF
   dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128
   undef %4.sub2:sgpr_128 = COPY %1:sgpr_32
   %5:sgpr_32 = COPY %4.sub2:sgpr_128
-)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
-    MachineInstr &Instr1 = getMI(MF, 1, 0);
-    MachineInstr &Instr2 = getMI(MF, 2, 0);
-    MachineInstr &Instr3 = getMI(MF, 3, 0);
-    LIS.RemoveMachineInstrFromMaps(Instr2);
-    MachineBasicBlock *MBB = Instr1.getParent();
-    SmallVector<Register> OrigRegs{
-      Instr1.getOperand(0).getReg(),
-      Instr2.getOperand(0).getReg(),
-      Instr2.getOperand(1).getReg(),
-    };
-    LIS.repairIntervalsInRange(MBB, Instr2, Instr3, OrigRegs);
-  });
+)MIR",
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        auto &LIS = LISWrapper.getLIS();
+        MachineInstr &Instr1 = getMI(MF, 1, 0);
+        MachineInstr &Instr2 = getMI(MF, 2, 0);
+        MachineInstr &Instr3 = getMI(MF, 3, 0);
+        LIS.RemoveMachineInstrFromMaps(Instr2);
+        MachineBasicBlock *MBB = Instr1.getParent();
+        SmallVector<Register> OrigRegs{
+            Instr1.getOperand(0).getReg(),
+            Instr2.getOperand(0).getReg(),
+            Instr2.getOperand(1).getReg(),
+        };
+        LIS.repairIntervalsInRange(MBB, Instr2, Instr3, OrigRegs);
+      });
 }
 
 TEST(LiveIntervalTest, AdjacentIntervals) {
@@ -765,7 +833,8 @@ TEST(LiveIntervalTest, AdjacentIntervals) {
     S_BRANCH %bb.3
   bb.3:
 )MIR",
-      [](MachineFunction &MF, LiveIntervals &LIS) {
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        auto &LIS = LISWrapper.getLIS();
         const auto &R1 =
             LIS.getInterval(getMI(MF, 2, 0).getOperand(0).getReg());
         const auto &R2 =
@@ -790,7 +859,8 @@ TEST(LiveIntervalTest, LiveThroughSegments) {
   bb.2:
     S_BRANCH %bb.1
 )MIR",
-      [](MachineFunction &MF, LiveIntervals &LIS) {
+      [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
+        auto &LIS = LISWrapper.getLIS();
         MachineInstr &ImpDef = getMI(MF, 0, 0);
         MachineInstr &Nop = getMI(MF, 0, 1);
         LiveInterval &LI = LIS.getInterval(ImpDef.getOperand(0).getReg());



More information about the llvm-commits mailing list