Split LiveRangeCalc in LiveRangeCalc/LiveIntervalCalc. NFC

Summary:
Refactor LiveRangeCalc such that it is now split into two classes

The objective is to split all the "register specific" logic away
from LiveRangeCalc.
The two new classes created are:

- LiveRangeCalc - is meant as a generic class to compute and modify
  live ranges in a generic way. This class should deal only with
  SlotIndices and VNInfo objects.

- LiveIntervalCals - is meant to be equivalent to the old LiveRangeCalc.
  It computes the liveness virtual registers tracked by a LiveInterval
  object.

With this refactoring LiveRangeCalc can be used to implement tracking of
liveness of LiveRanges that represent other things than just registers.

Subscribers: MatzeB, qcolombet, mgorny, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D76584
diff --git a/llvm/lib/CodeGen/LiveRangeCalc.cpp b/llvm/lib/CodeGen/LiveRangeCalc.cpp
index 24b57be..e9c9b70 100644
--- a/llvm/lib/CodeGen/LiveRangeCalc.cpp
+++ b/llvm/lib/CodeGen/LiveRangeCalc.cpp
@@ -1,4 +1,4 @@
-//===- LiveRangeCalc.cpp - Calculate live ranges --------------------------===//
+//===- LiveRangeCalc.cpp - Calculate live ranges -------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -61,158 +61,6 @@
   LiveIn.clear();
 }
 
-static void createDeadDef(SlotIndexes &Indexes, VNInfo::Allocator &Alloc,
-                          LiveRange &LR, const MachineOperand &MO) {
-  const MachineInstr &MI = *MO.getParent();
-  SlotIndex DefIdx =
-      Indexes.getInstructionIndex(MI).getRegSlot(MO.isEarlyClobber());
-
-  // Create the def in LR. This may find an existing def.
-  LR.createDeadDef(DefIdx, Alloc);
-}
-
-void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
-  assert(MRI && Indexes && "call reset() first");
-
-  // Step 1: Create minimal live segments for every definition of Reg.
-  // Visit all def operands. If the same instruction has multiple defs of Reg,
-  // createDeadDef() will deduplicate.
-  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
-  unsigned Reg = LI.reg;
-  for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
-    if (!MO.isDef() && !MO.readsReg())
-      continue;
-
-    unsigned SubReg = MO.getSubReg();
-    if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) {
-      LaneBitmask SubMask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg)
-                                        : MRI->getMaxLaneMaskForVReg(Reg);
-      // If this is the first time we see a subregister def, initialize
-      // subranges by creating a copy of the main range.
-      if (!LI.hasSubRanges() && !LI.empty()) {
-        LaneBitmask ClassMask = MRI->getMaxLaneMaskForVReg(Reg);
-        LI.createSubRangeFrom(*Alloc, ClassMask, LI);
-      }
-
-      LI.refineSubRanges(*Alloc, SubMask,
-                         [&MO, this](LiveInterval::SubRange &SR) {
-                           if (MO.isDef())
-                             createDeadDef(*Indexes, *Alloc, SR, MO);
-                         },
-                         *Indexes, TRI);
-    }
-
-    // Create the def in the main liverange. We do not have to do this if
-    // subranges are tracked as we recreate the main range later in this case.
-    if (MO.isDef() && !LI.hasSubRanges())
-      createDeadDef(*Indexes, *Alloc, LI, MO);
-  }
-
-  // We may have created empty live ranges for partially undefined uses, we
-  // can't keep them because we won't find defs in them later.
-  LI.removeEmptySubRanges();
-
-  // Step 2: Extend live segments to all uses, constructing SSA form as
-  // necessary.
-  if (LI.hasSubRanges()) {
-    for (LiveInterval::SubRange &S : LI.subranges()) {
-      LiveRangeCalc SubLRC;
-      SubLRC.reset(MF, Indexes, DomTree, Alloc);
-      SubLRC.extendToUses(S, Reg, S.LaneMask, &LI);
-    }
-    LI.clear();
-    constructMainRangeFromSubranges(LI);
-  } else {
-    resetLiveOutMap();
-    extendToUses(LI, Reg, LaneBitmask::getAll());
-  }
-}
-
-void LiveRangeCalc::constructMainRangeFromSubranges(LiveInterval &LI) {
-  // First create dead defs at all defs found in subranges.
-  LiveRange &MainRange = LI;
-  assert(MainRange.segments.empty() && MainRange.valnos.empty() &&
-         "Expect empty main liverange");
-
-  for (const LiveInterval::SubRange &SR : LI.subranges()) {
-    for (const VNInfo *VNI : SR.valnos) {
-      if (!VNI->isUnused() && !VNI->isPHIDef())
-        MainRange.createDeadDef(VNI->def, *Alloc);
-    }
-  }
-  resetLiveOutMap();
-  extendToUses(MainRange, LI.reg, LaneBitmask::getAll(), &LI);
-}
-
-void LiveRangeCalc::createDeadDefs(LiveRange &LR, unsigned Reg) {
-  assert(MRI && Indexes && "call reset() first");
-
-  // Visit all def operands. If the same instruction has multiple defs of Reg,
-  // LR.createDeadDef() will deduplicate.
-  for (MachineOperand &MO : MRI->def_operands(Reg))
-    createDeadDef(*Indexes, *Alloc, LR, MO);
-}
-
-void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask,
-                                 LiveInterval *LI) {
-  SmallVector<SlotIndex, 4> Undefs;
-  if (LI != nullptr)
-    LI->computeSubRangeUndefs(Undefs, Mask, *MRI, *Indexes);
-
-  // Visit all operands that read Reg. This may include partial defs.
-  bool IsSubRange = !Mask.all();
-  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
-  for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
-    // Clear all kill flags. They will be reinserted after register allocation
-    // by LiveIntervals::addKillFlags().
-    if (MO.isUse())
-      MO.setIsKill(false);
-    // MO::readsReg returns "true" for subregister defs. This is for keeping
-    // liveness of the entire register (i.e. for the main range of the live
-    // interval). For subranges, definitions of non-overlapping subregisters
-    // do not count as uses.
-    if (!MO.readsReg() || (IsSubRange && MO.isDef()))
-      continue;
-
-    unsigned SubReg = MO.getSubReg();
-    if (SubReg != 0) {
-      LaneBitmask SLM = TRI.getSubRegIndexLaneMask(SubReg);
-      if (MO.isDef())
-        SLM = ~SLM;
-      // Ignore uses not reading the current (sub)range.
-      if ((SLM & Mask).none())
-        continue;
-    }
-
-    // Determine the actual place of the use.
-    const MachineInstr *MI = MO.getParent();
-    unsigned OpNo = (&MO - &MI->getOperand(0));
-    SlotIndex UseIdx;
-    if (MI->isPHI()) {
-      assert(!MO.isDef() && "Cannot handle PHI def of partial register.");
-      // The actual place where a phi operand is used is the end of the pred
-      // MBB. PHI operands are paired: (Reg, PredMBB).
-      UseIdx = Indexes->getMBBEndIdx(MI->getOperand(OpNo+1).getMBB());
-    } else {
-      // Check for early-clobber redefs.
-      bool isEarlyClobber = false;
-      unsigned DefIdx;
-      if (MO.isDef())
-        isEarlyClobber = MO.isEarlyClobber();
-      else if (MI->isRegTiedToDefOperand(OpNo, &DefIdx)) {
-        // FIXME: This would be a lot easier if tied early-clobber uses also
-        // had an early-clobber flag.
-        isEarlyClobber = MI->getOperand(DefIdx).isEarlyClobber();
-      }
-      UseIdx = Indexes->getInstructionIndex(*MI).getRegSlot(isEarlyClobber);
-    }
-
-    // MI is reading Reg. We may have visited MI before if it happens to be
-    // reading Reg multiple times. That is OK, extend() is idempotent.
-    extend(LR, UseIdx, Reg, Undefs);
-  }
-}
-
 void LiveRangeCalc::updateFromLiveIns() {
   LiveRangeUpdater Updater;
   for (const LiveInBlock &I : LiveIn) {