//===- AggressiveAntiDepBreaker.cpp - Anti-dep breaker --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the AggressiveAntiDepBreaker class, which
// implements register anti-dependence breaking during post-RA
// scheduling. It attempts to break all anti-dependencies within a
// block.
//
//===----------------------------------------------------------------------===//

#include "AggressiveAntiDepBreaker.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MachineValueType.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <utility>

using namespace llvm;

#define DEBUG_TYPE "post-RA-sched"

// If DebugDiv > 0 then only break antidep with (ID % DebugDiv) == DebugMod
static cl::opt<int>
DebugDiv("agg-antidep-debugdiv",
         cl::desc("Debug control for aggressive anti-dep breaker"),
         cl::init(0), cl::Hidden);

static cl::opt<int>
DebugMod("agg-antidep-debugmod",
         cl::desc("Debug control for aggressive anti-dep breaker"),
         cl::init(0), cl::Hidden);

AggressiveAntiDepState::AggressiveAntiDepState(const unsigned TargetRegs,
                                               MachineBasicBlock *BB)
    : NumTargetRegs(TargetRegs), GroupNodes(TargetRegs, 0),
      GroupNodeIndices(TargetRegs, 0), KillIndices(TargetRegs, 0),
      DefIndices(TargetRegs, 0) {
  const unsigned BBSize = BB->size();
  for (unsigned i = 0; i < NumTargetRegs; ++i) {
    // Initialize all registers to be in their own group. Initially we
    // assign the register to the same-indexed GroupNode.
    GroupNodeIndices[i] = i;
    // Initialize the indices to indicate that no registers are live.
    KillIndices[i] = ~0u;
    DefIndices[i] = BBSize;
  }
}

unsigned AggressiveAntiDepState::GetGroup(unsigned Reg) {
  unsigned Node = GroupNodeIndices[Reg];
  while (GroupNodes[Node] != Node)
    Node = GroupNodes[Node];

  return Node;
}

void AggressiveAntiDepState::GetGroupRegs(
  unsigned Group,
  std::vector<unsigned> &Regs,
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference> *RegRefs)
{
  for (unsigned Reg = 0; Reg != NumTargetRegs; ++Reg) {
    if ((GetGroup(Reg) == Group) && (RegRefs->count(Reg) > 0))
      Regs.push_back(Reg);
  }
}

unsigned AggressiveAntiDepState::UnionGroups(unsigned Reg1, unsigned Reg2) {
  assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!");
  assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!");

  // find group for each register
  unsigned Group1 = GetGroup(Reg1);
  unsigned Group2 = GetGroup(Reg2);

  // if either group is 0, then that must become the parent
  unsigned Parent = (Group1 == 0) ? Group1 : Group2;
  unsigned Other = (Parent == Group1) ? Group2 : Group1;
  GroupNodes.at(Other) = Parent;
  return Parent;
}

unsigned AggressiveAntiDepState::LeaveGroup(unsigned Reg) {
  // Create a new GroupNode for Reg. Reg's existing GroupNode must
  // stay as is because there could be other GroupNodes referring to
  // it.
  unsigned idx = GroupNodes.size();
  GroupNodes.push_back(idx);
  GroupNodeIndices[Reg] = idx;
  return idx;
}

bool AggressiveAntiDepState::IsLive(unsigned Reg) {
  // KillIndex must be defined and DefIndex not defined for a register
  // to be live.
  return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u));
}

AggressiveAntiDepBreaker::AggressiveAntiDepBreaker(
    MachineFunction &MFi, const RegisterClassInfo &RCI,
    TargetSubtargetInfo::RegClassVector &CriticalPathRCs)
    : AntiDepBreaker(), MF(MFi), MRI(MF.getRegInfo()),
      TII(MF.getSubtarget().getInstrInfo()),
      TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI) {
  /* Collect a bitset of all registers that are only broken if they
     are on the critical path. */
  for (unsigned i = 0, e = CriticalPathRCs.size(); i < e; ++i) {
    BitVector CPSet = TRI->getAllocatableSet(MF, CriticalPathRCs[i]);
    if (CriticalPathSet.none())
      CriticalPathSet = CPSet;
    else
      CriticalPathSet |= CPSet;
   }

   LLVM_DEBUG(dbgs() << "AntiDep Critical-Path Registers:");
   LLVM_DEBUG(for (unsigned r
                   : CriticalPathSet.set_bits()) dbgs()
              << " " << printReg(r, TRI));
   LLVM_DEBUG(dbgs() << '\n');
}

AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() {
  delete State;
}

void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
  assert(!State);
  State = new AggressiveAntiDepState(TRI->getNumRegs(), BB);

  bool IsReturnBlock = BB->isReturnBlock();
  std::vector<unsigned> &KillIndices = State->GetKillIndices();
  std::vector<unsigned> &DefIndices = State->GetDefIndices();

  // Examine the live-in regs of all successors.
  for (MachineBasicBlock *Succ : BB->successors())
    for (const auto &LI : Succ->liveins()) {
      for (MCRegAliasIterator AI(LI.PhysReg, TRI, true); AI.isValid(); ++AI) {
        unsigned Reg = *AI;
        State->UnionGroups(Reg, 0);
        KillIndices[Reg] = BB->size();
        DefIndices[Reg] = ~0u;
      }
    }

  // Mark live-out callee-saved registers. In a return block this is
  // all callee-saved registers. In non-return this is any
  // callee-saved register that is not saved in the prolog.
  const MachineFrameInfo &MFI = MF.getFrameInfo();
  BitVector Pristine = MFI.getPristineRegs(MF);
  for (const MCPhysReg *I = MF.getRegInfo().getCalleeSavedRegs(); *I;
       ++I) {
    unsigned Reg = *I;
    if (!IsReturnBlock && !Pristine.test(Reg))
      continue;
    for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
      unsigned AliasReg = *AI;
      State->UnionGroups(AliasReg, 0);
      KillIndices[AliasReg] = BB->size();
      DefIndices[AliasReg] = ~0u;
    }
  }
}

void AggressiveAntiDepBreaker::FinishBlock() {
  delete State;
  State = nullptr;
}

void AggressiveAntiDepBreaker::Observe(MachineInstr &MI, unsigned Count,
                                       unsigned InsertPosIndex) {
  assert(Count < InsertPosIndex && "Instruction index out of expected range!");

  std::set<unsigned> PassthruRegs;
  GetPassthruRegs(MI, PassthruRegs);
  PrescanInstruction(MI, Count, PassthruRegs);
  ScanInstruction(MI, Count);

  LLVM_DEBUG(dbgs() << "Observe: ");
  LLVM_DEBUG(MI.dump());
  LLVM_DEBUG(dbgs() << "\tRegs:");

  std::vector<unsigned> &DefIndices = State->GetDefIndices();
  for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg) {
    // If Reg is current live, then mark that it can't be renamed as
    // we don't know the extent of its live-range anymore (now that it
    // has been scheduled). If it is not live but was defined in the
    // previous schedule region, then set its def index to the most
    // conservative location (i.e. the beginning of the previous
    // schedule region).
    if (State->IsLive(Reg)) {
      LLVM_DEBUG(if (State->GetGroup(Reg) != 0) dbgs()
                 << " " << printReg(Reg, TRI) << "=g" << State->GetGroup(Reg)
                 << "->g0(region live-out)");
      State->UnionGroups(Reg, 0);
    } else if ((DefIndices[Reg] < InsertPosIndex)
               && (DefIndices[Reg] >= Count)) {
      DefIndices[Reg] = Count;
    }
  }
  LLVM_DEBUG(dbgs() << '\n');
}

bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr &MI,
                                                MachineOperand &MO) {
  if (!MO.isReg() || !MO.isImplicit())
    return false;

  Register Reg = MO.getReg();
  if (Reg == 0)
    return false;

  MachineOperand *Op = nullptr;
  if (MO.isDef())
    Op = MI.findRegisterUseOperand(Reg, true);
  else
    Op = MI.findRegisterDefOperand(Reg);

  return(Op && Op->isImplicit());
}

void AggressiveAntiDepBreaker::GetPassthruRegs(
    MachineInstr &MI, std::set<unsigned> &PassthruRegs) {
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg()) continue;
    if ((MO.isDef() && MI.isRegTiedToUseOperand(i)) ||
        IsImplicitDefUse(MI, MO)) {
      const Register Reg = MO.getReg();
      for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
           SubRegs.isValid(); ++SubRegs)
        PassthruRegs.insert(*SubRegs);
    }
  }
}

/// AntiDepEdges - Return in Edges the anti- and output- dependencies
/// in SU that we want to consider for breaking.
static void AntiDepEdges(const SUnit *SU, std::vector<const SDep *> &Edges) {
  SmallSet<unsigned, 4> RegSet;
  for (const SDep &Pred : SU->Preds) {
    if ((Pred.getKind() == SDep::Anti) || (Pred.getKind() == SDep::Output)) {
      if (RegSet.insert(Pred.getReg()).second)
        Edges.push_back(&Pred);
    }
  }
}

/// CriticalPathStep - Return the next SUnit after SU on the bottom-up
/// critical path.
static const SUnit *CriticalPathStep(const SUnit *SU) {
  const SDep *Next = nullptr;
  unsigned NextDepth = 0;
  // Find the predecessor edge with the greatest depth.
  if (SU) {
    for (const SDep &Pred : SU->Preds) {
      const SUnit *PredSU = Pred.getSUnit();
      unsigned PredLatency = Pred.getLatency();
      unsigned PredTotalLatency = PredSU->getDepth() + PredLatency;
      // In the case of a latency tie, prefer an anti-dependency edge over
      // other types of edges.
      if (NextDepth < PredTotalLatency ||
          (NextDepth == PredTotalLatency && Pred.getKind() == SDep::Anti)) {
        NextDepth = PredTotalLatency;
        Next = &Pred;
      }
    }
  }

  return (Next) ? Next->getSUnit() : nullptr;
}

void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
                                             const char *tag,
                                             const char *header,
                                             const char *footer) {
  std::vector<unsigned> &KillIndices = State->GetKillIndices();
  std::vector<unsigned> &DefIndices = State->GetDefIndices();
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
    RegRefs = State->GetRegRefs();

  // FIXME: We must leave subregisters of live super registers as live, so that
  // we don't clear out the register tracking information for subregisters of
  // super registers we're still tracking (and with which we're unioning
  // subregister definitions).
  for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
    if (TRI->isSuperRegister(Reg, *AI) && State->IsLive(*AI)) {
      LLVM_DEBUG(if (!header && footer) dbgs() << footer);
      return;
    }

  if (!State->IsLive(Reg)) {
    KillIndices[Reg] = KillIdx;
    DefIndices[Reg] = ~0u;
    RegRefs.erase(Reg);
    State->LeaveGroup(Reg);
    LLVM_DEBUG(if (header) {
      dbgs() << header << printReg(Reg, TRI);
      header = nullptr;
    });
    LLVM_DEBUG(dbgs() << "->g" << State->GetGroup(Reg) << tag);
    // Repeat for subregisters. Note that we only do this if the superregister
    // was not live because otherwise, regardless whether we have an explicit
    // use of the subregister, the subregister's contents are needed for the
    // uses of the superregister.
    for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
      unsigned SubregReg = *SubRegs;
      if (!State->IsLive(SubregReg)) {
        KillIndices[SubregReg] = KillIdx;
        DefIndices[SubregReg] = ~0u;
        RegRefs.erase(SubregReg);
        State->LeaveGroup(SubregReg);
        LLVM_DEBUG(if (header) {
          dbgs() << header << printReg(Reg, TRI);
          header = nullptr;
        });
        LLVM_DEBUG(dbgs() << " " << printReg(SubregReg, TRI) << "->g"
                          << State->GetGroup(SubregReg) << tag);
      }
    }
  }

  LLVM_DEBUG(if (!header && footer) dbgs() << footer);
}

void AggressiveAntiDepBreaker::PrescanInstruction(
    MachineInstr &MI, unsigned Count, std::set<unsigned> &PassthruRegs) {
  std::vector<unsigned> &DefIndices = State->GetDefIndices();
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
    RegRefs = State->GetRegRefs();

  // Handle dead defs by simulating a last-use of the register just
  // after the def. A dead def can occur because the def is truly
  // dead, or because only a subregister is live at the def. If we
  // don't do this the dead def will be incorrectly merged into the
  // previous def.
  for (const MachineOperand &MO : MI.operands()) {
    if (!MO.isReg() || !MO.isDef()) continue;
    Register Reg = MO.getReg();
    if (Reg == 0) continue;

    HandleLastUse(Reg, Count + 1, "", "\tDead Def: ", "\n");
  }

  LLVM_DEBUG(dbgs() << "\tDef Groups:");
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg() || !MO.isDef()) continue;
    Register Reg = MO.getReg();
    if (Reg == 0) continue;

    LLVM_DEBUG(dbgs() << " " << printReg(Reg, TRI) << "=g"
                      << State->GetGroup(Reg));

    // If MI's defs have a special allocation requirement, don't allow
    // any def registers to be changed. Also assume all registers
    // defined in a call must not be changed (ABI). Inline assembly may
    // reference either system calls or the register directly. Skip it until we
    // can tell user specified registers from compiler-specified.
    if (MI.isCall() || MI.hasExtraDefRegAllocReq() || TII->isPredicated(MI) ||
        MI.isInlineAsm()) {
      LLVM_DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)");
      State->UnionGroups(Reg, 0);
    }

    // Any aliased that are live at this point are completely or
    // partially defined here, so group those aliases with Reg.
    for (MCRegAliasIterator AI(Reg, TRI, false); AI.isValid(); ++AI) {
      unsigned AliasReg = *AI;
      if (State->IsLive(AliasReg)) {
        State->UnionGroups(Reg, AliasReg);
        LLVM_DEBUG(dbgs() << "->g" << State->GetGroup(Reg) << "(via "
                          << printReg(AliasReg, TRI) << ")");
      }
    }

    // Note register reference...
    const TargetRegisterClass *RC = nullptr;
    if (i < MI.getDesc().getNumOperands())
      RC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
    AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
    RegRefs.insert(std::make_pair(Reg, RR));
  }

  LLVM_DEBUG(dbgs() << '\n');

  // Scan the register defs for this instruction and update
  // live-ranges.
  for (const MachineOperand &MO : MI.operands()) {
    if (!MO.isReg() || !MO.isDef()) continue;
    Register Reg = MO.getReg();
    if (Reg == 0) continue;
    // Ignore KILLs and passthru registers for liveness...
    if (MI.isKill() || (PassthruRegs.count(Reg) != 0))
      continue;

    // Update def for Reg and aliases.
    for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
      // We need to be careful here not to define already-live super registers.
      // If the super register is already live, then this definition is not
      // a definition of the whole super register (just a partial insertion
      // into it). Earlier subregister definitions (which we've not yet visited
      // because we're iterating bottom-up) need to be linked to the same group
      // as this definition.
      if (TRI->isSuperRegister(Reg, *AI) && State->IsLive(*AI))
        continue;

      DefIndices[*AI] = Count;
    }
  }
}

void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr &MI,
                                               unsigned Count) {
  LLVM_DEBUG(dbgs() << "\tUse Groups:");
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
    RegRefs = State->GetRegRefs();

  // If MI's uses have special allocation requirement, don't allow
  // any use registers to be changed. Also assume all registers
  // used in a call must not be changed (ABI).
  // Inline Assembly register uses also cannot be safely changed.
  // FIXME: The issue with predicated instruction is more complex. We are being
  // conservatively here because the kill markers cannot be trusted after
  // if-conversion:
  // %r6 = LDR %sp, %reg0, 92, 14, %reg0; mem:LD4[FixedStack14]
  // ...
  // STR %r0, killed %r6, %reg0, 0, 0, %cpsr; mem:ST4[%395]
  // %r6 = LDR %sp, %reg0, 100, 0, %cpsr; mem:LD4[FixedStack12]
  // STR %r0, killed %r6, %reg0, 0, 14, %reg0; mem:ST4[%396](align=8)
  //
  // The first R6 kill is not really a kill since it's killed by a predicated
  // instruction which may not be executed. The second R6 def may or may not
  // re-define R6 so it's not safe to change it since the last R6 use cannot be
  // changed.
  bool Special = MI.isCall() || MI.hasExtraSrcRegAllocReq() ||
                 TII->isPredicated(MI) || MI.isInlineAsm();

  // Scan the register uses for this instruction and update
  // live-ranges, groups and RegRefs.
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg() || !MO.isUse()) continue;
    Register Reg = MO.getReg();
    if (Reg == 0) continue;

    LLVM_DEBUG(dbgs() << " " << printReg(Reg, TRI) << "=g"
                      << State->GetGroup(Reg));

    // It wasn't previously live but now it is, this is a kill. Forget
    // the previous live-range information and start a new live-range
    // for the register.
    HandleLastUse(Reg, Count, "(last-use)");

    if (Special) {
      LLVM_DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)");
      State->UnionGroups(Reg, 0);
    }

    // Note register reference...
    const TargetRegisterClass *RC = nullptr;
    if (i < MI.getDesc().getNumOperands())
      RC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
    AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
    RegRefs.insert(std::make_pair(Reg, RR));
  }

  LLVM_DEBUG(dbgs() << '\n');

  // Form a group of all defs and uses of a KILL instruction to ensure
  // that all registers are renamed as a group.
  if (MI.isKill()) {
    LLVM_DEBUG(dbgs() << "\tKill Group:");

    unsigned FirstReg = 0;
    for (const MachineOperand &MO : MI.operands()) {
      if (!MO.isReg()) continue;
      Register Reg = MO.getReg();
      if (Reg == 0) continue;

      if (FirstReg != 0) {
        LLVM_DEBUG(dbgs() << "=" << printReg(Reg, TRI));
        State->UnionGroups(FirstReg, Reg);
      } else {
        LLVM_DEBUG(dbgs() << " " << printReg(Reg, TRI));
        FirstReg = Reg;
      }
    }

    LLVM_DEBUG(dbgs() << "->g" << State->GetGroup(FirstReg) << '\n');
  }
}

BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
  BitVector BV(TRI->getNumRegs(), false);
  bool first = true;

  // Check all references that need rewriting for Reg. For each, use
  // the corresponding register class to narrow the set of registers
  // that are appropriate for renaming.
  for (const auto &Q : make_range(State->GetRegRefs().equal_range(Reg))) {
    const TargetRegisterClass *RC = Q.second.RC;
    if (!RC) continue;

    BitVector RCBV = TRI->getAllocatableSet(MF, RC);
    if (first) {
      BV |= RCBV;
      first = false;
    } else {
      BV &= RCBV;
    }

    LLVM_DEBUG(dbgs() << " " << TRI->getRegClassName(RC));
  }

  return BV;
}

bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
                                unsigned AntiDepGroupIndex,
                                RenameOrderType& RenameOrder,
                                std::map<unsigned, unsigned> &RenameMap) {
  std::vector<unsigned> &KillIndices = State->GetKillIndices();
  std::vector<unsigned> &DefIndices = State->GetDefIndices();
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
    RegRefs = State->GetRegRefs();

  // Collect all referenced registers in the same group as
  // AntiDepReg. These all need to be renamed together if we are to
  // break the anti-dependence.
  std::vector<unsigned> Regs;
  State->GetGroupRegs(AntiDepGroupIndex, Regs, &RegRefs);
  assert(!Regs.empty() && "Empty register group!");
  if (Regs.empty())
    return false;

  // Find the "superest" register in the group. At the same time,
  // collect the BitVector of registers that can be used to rename
  // each register.
  LLVM_DEBUG(dbgs() << "\tRename Candidates for Group g" << AntiDepGroupIndex
                    << ":\n");
  std::map<unsigned, BitVector> RenameRegisterMap;
  unsigned SuperReg = 0;
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    unsigned Reg = Regs[i];
    if ((SuperReg == 0) || TRI->isSuperRegister(SuperReg, Reg))
      SuperReg = Reg;

    // If Reg has any references, then collect possible rename regs
    if (RegRefs.count(Reg) > 0) {
      LLVM_DEBUG(dbgs() << "\t\t" << printReg(Reg, TRI) << ":");

      BitVector &BV = RenameRegisterMap[Reg];
      assert(BV.empty());
      BV = GetRenameRegisters(Reg);

      LLVM_DEBUG({
        dbgs() << " ::";
        for (unsigned r : BV.set_bits())
          dbgs() << " " << printReg(r, TRI);
        dbgs() << "\n";
      });
    }
  }

  // All group registers should be a subreg of SuperReg.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    unsigned Reg = Regs[i];
    if (Reg == SuperReg) continue;
    bool IsSub = TRI->isSubRegister(SuperReg, Reg);
    // FIXME: remove this once PR18663 has been properly fixed. For now,
    // return a conservative answer:
    // assert(IsSub && "Expecting group subregister");
    if (!IsSub)
      return false;
  }

#ifndef NDEBUG
  // If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod
  if (DebugDiv > 0) {
    static int renamecnt = 0;
    if (renamecnt++ % DebugDiv != DebugMod)
      return false;

    dbgs() << "*** Performing rename " << printReg(SuperReg, TRI)
           << " for debug ***\n";
  }
#endif

  // Check each possible rename register for SuperReg in round-robin
  // order. If that register is available, and the corresponding
  // registers are available for the other group subregisters, then we
  // can use those registers to rename.

  // FIXME: Using getMinimalPhysRegClass is very conservative. We should
  // check every use of the register and find the largest register class
  // that can be used in all of them.
  const TargetRegisterClass *SuperRC =
    TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);

  ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
  if (Order.empty()) {
    LLVM_DEBUG(dbgs() << "\tEmpty Super Regclass!!\n");
    return false;
  }

  LLVM_DEBUG(dbgs() << "\tFind Registers:");

  RenameOrder.insert(RenameOrderType::value_type(SuperRC, Order.size()));

  unsigned OrigR = RenameOrder[SuperRC];
  unsigned EndR = ((OrigR == Order.size()) ? 0 : OrigR);
  unsigned R = OrigR;
  do {
    if (R == 0) R = Order.size();
    --R;
    const unsigned NewSuperReg = Order[R];
    // Don't consider non-allocatable registers
    if (!MRI.isAllocatable(NewSuperReg)) continue;
    // Don't replace a register with itself.
    if (NewSuperReg == SuperReg) continue;

    LLVM_DEBUG(dbgs() << " [" << printReg(NewSuperReg, TRI) << ':');
    RenameMap.clear();

    // For each referenced group register (which must be a SuperReg or
    // a subregister of SuperReg), find the corresponding subregister
    // of NewSuperReg and make sure it is free to be renamed.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
      unsigned Reg = Regs[i];
      unsigned NewReg = 0;
      if (Reg == SuperReg) {
        NewReg = NewSuperReg;
      } else {
        unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg);
        if (NewSubRegIdx != 0)
          NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx);
      }

      LLVM_DEBUG(dbgs() << " " << printReg(NewReg, TRI));

      // Check if Reg can be renamed to NewReg.
      if (!RenameRegisterMap[Reg].test(NewReg)) {
        LLVM_DEBUG(dbgs() << "(no rename)");
        goto next_super_reg;
      }

      // If NewReg is dead and NewReg's most recent def is not before
      // Regs's kill, it's safe to replace Reg with NewReg. We
      // must also check all aliases of NewReg, because we can't define a
      // register when any sub or super is already live.
      if (State->IsLive(NewReg) || (KillIndices[Reg] > DefIndices[NewReg])) {
        LLVM_DEBUG(dbgs() << "(live)");
        goto next_super_reg;
      } else {
        bool found = false;
        for (MCRegAliasIterator AI(NewReg, TRI, false); AI.isValid(); ++AI) {
          unsigned AliasReg = *AI;
          if (State->IsLive(AliasReg) ||
              (KillIndices[Reg] > DefIndices[AliasReg])) {
            LLVM_DEBUG(dbgs()
                       << "(alias " << printReg(AliasReg, TRI) << " live)");
            found = true;
            break;
          }
        }
        if (found)
          goto next_super_reg;
      }

      // We cannot rename 'Reg' to 'NewReg' if one of the uses of 'Reg' also
      // defines 'NewReg' via an early-clobber operand.
      for (const auto &Q : make_range(RegRefs.equal_range(Reg))) {
        MachineInstr *UseMI = Q.second.Operand->getParent();
        int Idx = UseMI->findRegisterDefOperandIdx(NewReg, false, true, TRI);
        if (Idx == -1)
          continue;

        if (UseMI->getOperand(Idx).isEarlyClobber()) {
          LLVM_DEBUG(dbgs() << "(ec)");
          goto next_super_reg;
        }
      }

      // Also, we cannot rename 'Reg' to 'NewReg' if the instruction defining
      // 'Reg' is an early-clobber define and that instruction also uses
      // 'NewReg'.
      for (const auto &Q : make_range(RegRefs.equal_range(Reg))) {
        if (!Q.second.Operand->isDef() || !Q.second.Operand->isEarlyClobber())
          continue;

        MachineInstr *DefMI = Q.second.Operand->getParent();
        if (DefMI->readsRegister(NewReg, TRI)) {
          LLVM_DEBUG(dbgs() << "(ec)");
          goto next_super_reg;
        }
      }

      // Record that 'Reg' can be renamed to 'NewReg'.
      RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));
    }

    // If we fall-out here, then every register in the group can be
    // renamed, as recorded in RenameMap.
    RenameOrder.erase(SuperRC);
    RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
    LLVM_DEBUG(dbgs() << "]\n");
    return true;

  next_super_reg:
    LLVM_DEBUG(dbgs() << ']');
  } while (R != EndR);

  LLVM_DEBUG(dbgs() << '\n');

  // No registers are free and available!
  return false;
}

/// BreakAntiDependencies - Identifiy anti-dependencies within the
/// ScheduleDAG and break them by renaming registers.
unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
                              const std::vector<SUnit> &SUnits,
                              MachineBasicBlock::iterator Begin,
                              MachineBasicBlock::iterator End,
                              unsigned InsertPosIndex,
                              DbgValueVector &DbgValues) {
  std::vector<unsigned> &KillIndices = State->GetKillIndices();
  std::vector<unsigned> &DefIndices = State->GetDefIndices();
  std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
    RegRefs = State->GetRegRefs();

  // The code below assumes that there is at least one instruction,
  // so just duck out immediately if the block is empty.
  if (SUnits.empty()) return 0;

  // For each regclass the next register to use for renaming.
  RenameOrderType RenameOrder;

  // ...need a map from MI to SUnit.
  std::map<MachineInstr *, const SUnit *> MISUnitMap;
  for (const SUnit &SU : SUnits)
    MISUnitMap.insert(std::make_pair(SU.getInstr(), &SU));

  // Track progress along the critical path through the SUnit graph as
  // we walk the instructions. This is needed for regclasses that only
  // break critical-path anti-dependencies.
  const SUnit *CriticalPathSU = nullptr;
  MachineInstr *CriticalPathMI = nullptr;
  if (CriticalPathSet.any()) {
    for (const SUnit &SU : SUnits) {
      if (!CriticalPathSU ||
          ((SU.getDepth() + SU.Latency) >
           (CriticalPathSU->getDepth() + CriticalPathSU->Latency))) {
        CriticalPathSU = &SU;
      }
    }
    assert(CriticalPathSU && "Failed to find SUnit critical path");
    CriticalPathMI = CriticalPathSU->getInstr();
  }

#ifndef NDEBUG
  LLVM_DEBUG(dbgs() << "\n===== Aggressive anti-dependency breaking\n");
  LLVM_DEBUG(dbgs() << "Available regs:");
  for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {
    if (!State->IsLive(Reg))
      LLVM_DEBUG(dbgs() << " " << printReg(Reg, TRI));
  }
  LLVM_DEBUG(dbgs() << '\n');
#endif

  BitVector RegAliases(TRI->getNumRegs());

  // Attempt to break anti-dependence edges. Walk the instructions
  // from the bottom up, tracking information about liveness as we go
  // to help determine which registers are available.
  unsigned Broken = 0;
  unsigned Count = InsertPosIndex - 1;
  for (MachineBasicBlock::iterator I = End, E = Begin;
       I != E; --Count) {
    MachineInstr &MI = *--I;

    if (MI.isDebugInstr())
      continue;

    LLVM_DEBUG(dbgs() << "Anti: ");
    LLVM_DEBUG(MI.dump());

    std::set<unsigned> PassthruRegs;
    GetPassthruRegs(MI, PassthruRegs);

    // Process the defs in MI...
    PrescanInstruction(MI, Count, PassthruRegs);

    // The dependence edges that represent anti- and output-
    // dependencies that are candidates for breaking.
    std::vector<const SDep *> Edges;
    const SUnit *PathSU = MISUnitMap[&MI];
    AntiDepEdges(PathSU, Edges);

    // If MI is not on the critical path, then we don't rename
    // registers in the CriticalPathSet.
    BitVector *ExcludeRegs = nullptr;
    if (&MI == CriticalPathMI) {
      CriticalPathSU = CriticalPathStep(CriticalPathSU);
      CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->getInstr() : nullptr;
    } else if (CriticalPathSet.any()) {
      ExcludeRegs = &CriticalPathSet;
    }

    // Ignore KILL instructions (they form a group in ScanInstruction
    // but don't cause any anti-dependence breaking themselves)
    if (!MI.isKill()) {
      // Attempt to break each anti-dependency...
      for (const SDep *Edge : Edges) {
        SUnit *NextSU = Edge->getSUnit();

        if ((Edge->getKind() != SDep::Anti) &&
            (Edge->getKind() != SDep::Output)) continue;

        unsigned AntiDepReg = Edge->getReg();
        LLVM_DEBUG(dbgs() << "\tAntidep reg: " << printReg(AntiDepReg, TRI));
        assert(AntiDepReg != 0 && "Anti-dependence on reg0?");

        if (!MRI.isAllocatable(AntiDepReg)) {
          // Don't break anti-dependencies on non-allocatable registers.
          LLVM_DEBUG(dbgs() << " (non-allocatable)\n");
          continue;
        } else if (ExcludeRegs && ExcludeRegs->test(AntiDepReg)) {
          // Don't break anti-dependencies for critical path registers
          // if not on the critical path
          LLVM_DEBUG(dbgs() << " (not critical-path)\n");
          continue;
        } else if (PassthruRegs.count(AntiDepReg) != 0) {
          // If the anti-dep register liveness "passes-thru", then
          // don't try to change it. It will be changed along with
          // the use if required to break an earlier antidep.
          LLVM_DEBUG(dbgs() << " (passthru)\n");
          continue;
        } else {
          // No anti-dep breaking for implicit deps
          MachineOperand *AntiDepOp = MI.findRegisterDefOperand(AntiDepReg);
          assert(AntiDepOp && "Can't find index for defined register operand");
          if (!AntiDepOp || AntiDepOp->isImplicit()) {
            LLVM_DEBUG(dbgs() << " (implicit)\n");
            continue;
          }

          // If the SUnit has other dependencies on the SUnit that
          // it anti-depends on, don't bother breaking the
          // anti-dependency since those edges would prevent such
          // units from being scheduled past each other
          // regardless.
          //
          // Also, if there are dependencies on other SUnits with the
          // same register as the anti-dependency, don't attempt to
          // break it.
          for (const SDep &Pred : PathSU->Preds) {
            if (Pred.getSUnit() == NextSU ? (Pred.getKind() != SDep::Anti ||
                                             Pred.getReg() != AntiDepReg)
                                          : (Pred.getKind() == SDep::Data &&
                                             Pred.getReg() == AntiDepReg)) {
              AntiDepReg = 0;
              break;
            }
          }
          for (const SDep &Pred : PathSU->Preds) {
            if ((Pred.getSUnit() == NextSU) && (Pred.getKind() != SDep::Anti) &&
                (Pred.getKind() != SDep::Output)) {
              LLVM_DEBUG(dbgs() << " (real dependency)\n");
              AntiDepReg = 0;
              break;
            } else if ((Pred.getSUnit() != NextSU) &&
                       (Pred.getKind() == SDep::Data) &&
                       (Pred.getReg() == AntiDepReg)) {
              LLVM_DEBUG(dbgs() << " (other dependency)\n");
              AntiDepReg = 0;
              break;
            }
          }

          if (AntiDepReg == 0) continue;

          // If the definition of the anti-dependency register does not start
          // a new live range, bail out. This can happen if the anti-dep
          // register is a sub-register of another register whose live range
          // spans over PathSU. In such case, PathSU defines only a part of
          // the larger register.
          RegAliases.reset();
          for (MCRegAliasIterator AI(AntiDepReg, TRI, true); AI.isValid(); ++AI)
            RegAliases.set(*AI);
          for (SDep S : PathSU->Succs) {
            SDep::Kind K = S.getKind();
            if (K != SDep::Data && K != SDep::Output && K != SDep::Anti)
              continue;
            unsigned R = S.getReg();
            if (!RegAliases[R])
              continue;
            if (R == AntiDepReg || TRI->isSubRegister(AntiDepReg, R))
              continue;
            AntiDepReg = 0;
            break;
          }

          if (AntiDepReg == 0) continue;
        }

        assert(AntiDepReg != 0);
        if (AntiDepReg == 0) continue;

        // Determine AntiDepReg's register group.
        const unsigned GroupIndex = State->GetGroup(AntiDepReg);
        if (GroupIndex == 0) {
          LLVM_DEBUG(dbgs() << " (zero group)\n");
          continue;
        }

        LLVM_DEBUG(dbgs() << '\n');

        // Look for a suitable register to use to break the anti-dependence.
        std::map<unsigned, unsigned> RenameMap;
        if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) {
          LLVM_DEBUG(dbgs() << "\tBreaking anti-dependence edge on "
                            << printReg(AntiDepReg, TRI) << ":");

          // Handle each group register...
          for (const auto &P : RenameMap) {
            unsigned CurrReg = P.first;
            unsigned NewReg = P.second;

            LLVM_DEBUG(dbgs() << " " << printReg(CurrReg, TRI) << "->"
                              << printReg(NewReg, TRI) << "("
                              << RegRefs.count(CurrReg) << " refs)");

            // Update the references to the old register CurrReg to
            // refer to the new register NewReg.
            for (const auto &Q : make_range(RegRefs.equal_range(CurrReg))) {
              Q.second.Operand->setReg(NewReg);
              // If the SU for the instruction being updated has debug
              // information related to the anti-dependency register, make
              // sure to update that as well.
              const SUnit *SU = MISUnitMap[Q.second.Operand->getParent()];
              if (!SU) continue;
              UpdateDbgValues(DbgValues, Q.second.Operand->getParent(),
                              AntiDepReg, NewReg);
            }

            // We just went back in time and modified history; the
            // liveness information for CurrReg is now inconsistent. Set
            // the state as if it were dead.
            State->UnionGroups(NewReg, 0);
            RegRefs.erase(NewReg);
            DefIndices[NewReg] = DefIndices[CurrReg];
            KillIndices[NewReg] = KillIndices[CurrReg];

            State->UnionGroups(CurrReg, 0);
            RegRefs.erase(CurrReg);
            DefIndices[CurrReg] = KillIndices[CurrReg];
            KillIndices[CurrReg] = ~0u;
            assert(((KillIndices[CurrReg] == ~0u) !=
                    (DefIndices[CurrReg] == ~0u)) &&
                   "Kill and Def maps aren't consistent for AntiDepReg!");
          }

          ++Broken;
          LLVM_DEBUG(dbgs() << '\n');
        }
      }
    }

    ScanInstruction(MI, Count);
  }

  return Broken;
}

AntiDepBreaker *llvm::createAggressiveAntiDepBreaker(
    MachineFunction &MFi, const RegisterClassInfo &RCI,
    TargetSubtargetInfo::RegClassVector &CriticalPathRCs) {
  return new AggressiveAntiDepBreaker(MFi, RCI, CriticalPathRCs);
}
