39#define DEBUG_TYPE "post-RA-sched" 
   43    : MF(MFi), MRI(MF.getRegInfo()), TII(MF.getSubtarget().getInstrInfo()),
 
   44      TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI),
 
   45      Classes(TRI->getNumRegs(), nullptr), KillIndices(TRI->getNumRegs(), 0),
 
   46      DefIndices(TRI->getNumRegs(), 0), KeepRegs(TRI->getNumRegs(), 
false) {}
 
 
   51  const unsigned BBSize = BB->
size();
 
   52  for (
unsigned i = 1, e = TRI->getNumRegs(); i != e; ++i) {
 
   58    DefIndices[i] = BBSize;
 
   68    for (
const auto &LI : Succ->liveins()) {
 
   72        KillIndices[Reg.id()] = BBSize;
 
   73        DefIndices[Reg.id()] = ~0u;
 
   82  for (
const MCPhysReg *
I = MF.getRegInfo().getCalleeSavedRegs(); *
I;
 
   85    if (!IsReturnBlock && !Pristine.
test(Reg))
 
   90      KillIndices[Reg.id()] = BBSize;
 
   91      DefIndices[Reg.id()] = ~0u;
 
 
  102                                     unsigned InsertPosIndex) {
 
  110  if (
MI.isDebugInstr() || 
MI.isKill())
 
  112  assert(
Count < InsertPosIndex && 
"Instruction index out of expected range!");
 
  114  for (
unsigned Reg = 1; Reg != TRI->getNumRegs(); ++Reg) {
 
  115    if (KillIndices[Reg] != ~0u) {
 
  120      KillIndices[Reg] = 
Count;
 
  121    } 
else if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= 
Count) {
 
  130      DefIndices[Reg] = InsertPosIndex;
 
  134  PrescanInstruction(
MI);
 
 
  142  unsigned NextDepth = 0;
 
  145    const SUnit *PredSU = 
P.getSUnit();
 
  146    unsigned PredLatency = 
P.getLatency();
 
  147    unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
 
  150    if (NextDepth < PredTotalLatency ||
 
  151        (NextDepth == PredTotalLatency && 
P.getKind() == 
SDep::Anti)) {
 
  152      NextDepth = PredTotalLatency;
 
 
  159void CriticalAntiDepBreaker::PrescanInstruction(
MachineInstr &
MI) {
 
  177      MI.isCall() || 
MI.hasExtraSrcRegAllocReq() || TII->isPredicated(
MI);
 
  181  for (
unsigned i = 0, e = 
MI.getNumOperands(); i != e; ++i) {
 
  182    MachineOperand &MO = 
MI.getOperand(i);
 
  183    if (!MO.
isReg()) 
continue;
 
  187    const TargetRegisterClass *NewRC = 
nullptr;
 
  189    if (i < 
MI.getDesc().getNumOperands())
 
  190      NewRC = TII->getRegClass(
MI.getDesc(), i, TRI);
 
  194    if (!Classes[
Reg.
id()] && NewRC)
 
  195      Classes[
Reg.
id()] = NewRC;
 
  196    else if (!NewRC || Classes[
Reg.
id()] != NewRC)
 
  197      Classes[
Reg.
id()] = 
reinterpret_cast<TargetRegisterClass *
>(-1);
 
  200    for (MCRegAliasIterator AI(
Reg, TRI, 
false); AI.isValid(); ++AI) {
 
  204      unsigned AliasReg = (*AI).id();
 
  205      if (Classes[AliasReg]) {
 
  206        Classes[AliasReg] = 
reinterpret_cast<TargetRegisterClass *
>(-1);
 
  207        Classes[
Reg.
id()] = 
reinterpret_cast<TargetRegisterClass *
>(-1);
 
  212    if (Classes[
Reg.
id()] != 
reinterpret_cast<TargetRegisterClass *
>(-1))
 
  213      RegRefs.emplace(
Reg, &MO);
 
  215    if (MO.
isUse() && Special) {
 
  216      if (!KeepRegs.test(
Reg.
id())) {
 
  223  for (
unsigned I = 0, 
E = 
MI.getNumOperands(); 
I != 
E; ++
I) {
 
  224    const MachineOperand &MO = 
MI.getOperand(
I);
 
  225    if (!MO.
isReg()) 
continue;
 
  239    if (
MI.isRegTiedToUseOperand(
I) &&
 
  240        Classes[
Reg.
id()] == 
reinterpret_cast<TargetRegisterClass *
>(-1)) {
 
  245        KeepRegs.set(SuperReg);
 
  255  assert(!
MI.isKill() && 
"Attempting to scan a kill instruction");
 
  257  if (!TII->isPredicated(
MI)) {
 
  260    for (
unsigned i = 0, e = 
MI.getNumOperands(); i != e; ++i) {
 
  261      MachineOperand &MO = 
MI.getOperand(i);
 
  264        auto ClobbersPhysRegAndSubRegs = [&](
unsigned PhysReg) {
 
  265          return all_of(TRI->subregs_inclusive(PhysReg),
 
  266                        [&](
MCPhysReg SR) { return MO.clobbersPhysReg(SR); });
 
  269        for (
unsigned i = 1, e = TRI->getNumRegs(); i != e; ++i) {
 
  270          if (ClobbersPhysRegAndSubRegs(i)) {
 
  271            DefIndices[i] = 
Count;
 
  272            KillIndices[i] = ~0
u;
 
  274            Classes[i] = 
nullptr;
 
  280      if (!MO.
isReg()) 
continue;
 
  284      if (!MO.
isDef()) 
continue;
 
  287      if (
MI.isRegTiedToUseOperand(i))
 
  296      for (
MCPhysReg SubregReg : TRI->subregs_inclusive(
Reg)) {
 
  297        DefIndices[SubregReg] = 
Count;
 
  298        KillIndices[SubregReg] = ~0
u;
 
  299        Classes[SubregReg] = 
nullptr;
 
  300        RegRefs.erase(SubregReg);
 
  302          KeepRegs.reset(SubregReg);
 
  306        Classes[SR] = 
reinterpret_cast<TargetRegisterClass *
>(-1);
 
  309  for (
unsigned i = 0, e = 
MI.getNumOperands(); i != e; ++i) {
 
  310    MachineOperand &MO = 
MI.getOperand(i);
 
  311    if (!MO.
isReg()) 
continue;
 
  315    if (!MO.
isUse()) 
continue;
 
  317    const TargetRegisterClass *NewRC = 
nullptr;
 
  318    if (i < 
MI.getDesc().getNumOperands())
 
  319      NewRC = TII->getRegClass(
MI.getDesc(), i, TRI);
 
  323    if (!Classes[
Reg.
id()] && NewRC)
 
  324      Classes[
Reg.
id()] = NewRC;
 
  325    else if (!NewRC || Classes[
Reg.
id()] != NewRC)
 
  326      Classes[
Reg.
id()] = 
reinterpret_cast<TargetRegisterClass *
>(-1);
 
  328    RegRefs.emplace(
Reg, &MO);
 
  332    for (MCRegAliasIterator AI(
Reg, TRI, 
true); AI.isValid(); ++AI) {
 
  333      MCRegister AliasReg = *AI;
 
  334      if (KillIndices[AliasReg.
id()] == ~0u) {
 
  335        KillIndices[AliasReg.
id()] = 
Count;
 
  336        DefIndices[AliasReg.
id()] = ~0
u;
 
  353bool CriticalAntiDepBreaker::isNewRegClobberedByRefs(RegRefIter RegRefBegin,
 
  354                                                     RegRefIter RegRefEnd,
 
  356  for (RegRefIter 
I = RegRefBegin; 
I != RegRefEnd; ++
I ) {
 
  357    MachineOperand *RefOper = 
I->second;
 
  367    for (
const MachineOperand &CheckOper : 
MI->operands()) {
 
  368      if (CheckOper.isRegMask() && CheckOper.clobbersPhysReg(NewReg))
 
  371      if (!CheckOper.isReg() || !CheckOper.isDef() ||
 
  372          CheckOper.getReg() != NewReg)
 
  377      if (RefOper->
isDef())
 
  382      if (CheckOper.isEarlyClobber())
 
  387      if (
MI->isInlineAsm())
 
  394MCRegister CriticalAntiDepBreaker::findSuitableFreeRegister(
 
  395    RegRefIter RegRefBegin, RegRefIter RegRefEnd, 
MCRegister AntiDepReg,
 
  399  for (MCRegister NewReg : Order) {
 
  401    if (NewReg == AntiDepReg) 
continue;
 
  405    if (NewReg == LastNewReg) 
continue;
 
  409    if (isNewRegClobberedByRefs(RegRefBegin, RegRefEnd, NewReg)) 
continue;
 
  412    assert(((KillIndices[AntiDepReg.
id()] == ~0u) !=
 
  413            (DefIndices[AntiDepReg.
id()] == ~0u)) &&
 
  414           "Kill and Def maps aren't consistent for AntiDepReg!");
 
  415    assert(((KillIndices[NewReg.
id()] == ~0u) !=
 
  416            (DefIndices[NewReg.
id()] == ~0u)) &&
 
  417           "Kill and Def maps aren't consistent for NewReg!");
 
  418    if (KillIndices[NewReg.
id()] != ~0u ||
 
  419        Classes[NewReg.
id()] == 
reinterpret_cast<TargetRegisterClass *
>(-1) ||
 
  420        KillIndices[AntiDepReg.
id()] > DefIndices[NewReg.
id()])
 
  423    bool Forbidden = 
false;
 
  425      if (TRI->regsOverlap(NewReg, R)) {
 
  429    if (Forbidden) 
continue;
 
  441                      unsigned InsertPosIndex,
 
  445  if (SUnits.empty()) 
return 0;
 
  454  const SUnit *Max = 
nullptr;
 
  455  for (
const SUnit &SU : SUnits) {
 
  456    MISUnitMap[SU.getInstr()] = &SU;
 
  457    if (!Max || SU.getDepth() + SU.Latency > Max->getDepth() + Max->Latency)
 
  460  assert(Max && 
"Failed to find bottom of the critical path");
 
  465                      << (Max->getDepth() + Max->Latency) << 
"\n");
 
  467    for (
unsigned Reg = 1; Reg < TRI->getNumRegs(); ++Reg) {
 
  468      if (KillIndices[Reg] == ~0u)
 
  477  const SUnit *CriticalPathSU = Max;
 
  521  std::vector<MCRegister> LastNewReg(TRI->getNumRegs(), 
MCRegister());
 
  527  unsigned Count = InsertPosIndex - 1;
 
  537    if (
MI.isDebugInstr() || 
MI.isKill())
 
  554    if (&
MI == CriticalPathMI) {
 
  556        const SUnit *NextSU = Edge->getSUnit();
 
  560          AntiDepReg = Edge->getReg().asMCReg();
 
  561          assert(AntiDepReg && 
"Anti-dependence on reg0?");
 
  562          if (!MRI.isAllocatable(AntiDepReg))
 
  565          else if (KeepRegs.test(AntiDepReg.
id()))
 
  579              if (
P.getSUnit() == NextSU
 
  580                      ? (
P.getKind() != 
SDep::Anti || 
P.getReg() != AntiDepReg)
 
  582                         P.getReg() == AntiDepReg)) {
 
  588        CriticalPathSU = NextSU;
 
  589        CriticalPathMI = CriticalPathSU->
getInstr();
 
  592        CriticalPathSU = 
nullptr;
 
  593        CriticalPathMI = 
nullptr;
 
  597    PrescanInstruction(
MI);
 
  604    if (
MI.isCall() || 
MI.hasExtraDefRegAllocReq() || TII->isPredicated(
MI))
 
  608    else if (AntiDepReg) {
 
  614        if (!MO.
isReg()) 
continue;
 
  618        if (MO.
isUse() && TRI->regsOverlap(AntiDepReg, Reg)) {
 
  622        if (MO.
isDef() && Reg != AntiDepReg)
 
  630        AntiDepReg ? Classes[AntiDepReg.
id()] : 
nullptr;
 
  631    assert((!AntiDepReg || RC != 
nullptr) &&
 
  632           "Register should be live if it's causing an anti-dependence!");
 
  641      std::pair<std::multimap<MCRegister, MachineOperand *>::iterator,
 
  642                std::multimap<MCRegister, MachineOperand *>::iterator>
 
  643          Range = RegRefs.equal_range(AntiDepReg);
 
  644      if (
MCRegister NewReg = findSuitableFreeRegister(
 
  646              LastNewReg[AntiDepReg.
id()], RC, ForbidRegs)) {
 
  648                          << 
printReg(AntiDepReg, TRI) << 
" with " 
  649                          << RegRefs.count(AntiDepReg) << 
" references" 
  650                          << 
" using " << 
printReg(NewReg, TRI) << 
"!\n");
 
  654        for (std::multimap<MCRegister, MachineOperand *>::iterator
 
  658          Q->second->setReg(NewReg);
 
  662          const SUnit *SU = MISUnitMap[Q->second->getParent()];
 
  671        Classes[NewReg.
id()] = Classes[AntiDepReg.
id()];
 
  672        DefIndices[NewReg.
id()] = DefIndices[AntiDepReg.
id()];
 
  673        KillIndices[NewReg.
id()] = KillIndices[AntiDepReg.
id()];
 
  674        assert(((KillIndices[NewReg.
id()] == ~0u) !=
 
  675                (DefIndices[NewReg.
id()] == ~0u)) &&
 
  676               "Kill and Def maps aren't consistent for NewReg!");
 
  678        Classes[AntiDepReg.
id()] = 
nullptr;
 
  679        DefIndices[AntiDepReg.
id()] = KillIndices[AntiDepReg.
id()];
 
  680        KillIndices[AntiDepReg.
id()] = ~0u;
 
  681        assert(((KillIndices[AntiDepReg.
id()] == ~0u) !=
 
  682                (DefIndices[AntiDepReg.
id()] == ~0u)) &&
 
  683               "Kill and Def maps aren't consistent for AntiDepReg!");
 
  685        RegRefs.erase(AntiDepReg);
 
  686        LastNewReg[AntiDepReg.
id()] = NewReg;
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static const SUnit * CriticalPathStep(const SUnit *SU)
CriticalPathStep - Return the next SUnit after SU on the bottom-up critical path.
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
This file defines the DenseMap class.
 
Promote Memory to Register
 
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
 
This file defines the SmallVector class.
 
This class works in conjunction with the post-RA scheduler to rename registers to break register anti...
 
void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI, MCRegister OldReg, MCRegister NewReg)
Update all DBG_VALUE instructions that may be affected by the dependency breaker's update of ParentMI...
 
std::vector< std::pair< MachineInstr *, MachineInstr * > > DbgValueVector
 
bool test(unsigned Idx) const
 
void clear()
clear - Removes all bits from the bitvector.
 
~CriticalAntiDepBreaker() override
 
unsigned BreakAntiDependencies(const std::vector< SUnit > &SUnits, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned InsertPosIndex, DbgValueVector &DbgValues) override
Identifiy anti-dependencies along the critical path of the ScheduleDAG and break them by renaming reg...
 
void FinishBlock() override
Finish anti-dep breaking for a basic block.
 
void Observe(MachineInstr &MI, unsigned Count, unsigned InsertPosIndex) override
Update liveness information to account for the current instruction, which will not be scheduled.
 
void StartBlock(MachineBasicBlock *BB) override
Initialize anti-dep breaking for a new basic block.
 
CriticalAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI)
 
MCRegAliasIterator enumerates all registers aliasing Reg.
 
Wrapper class representing physical registers. Should be passed by value.
 
constexpr unsigned id() const
 
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
 
iterator_range< succ_iterator > successors()
 
MachineInstrBundleIterator< MachineInstr > iterator
 
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
 
LLVM_ABI BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
 
Representation of each machine instruction.
 
MachineOperand class - Representation of each machine instruction operand.
 
bool isReg() const
isReg - Tests if this is a MO_Register operand.
 
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
 
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
 
bool isEarlyClobber() const
 
Register getReg() const
getReg - Returns the register number.
 
Wrapper class representing virtual and physical registers.
 
constexpr bool isValid() const
 
constexpr unsigned id() const
 
@ Anti
A register anti-dependence (aka WAR).
 
@ Data
Regular data dependence (aka true-dependence).
 
Scheduling unit. This is a node in the scheduling DAG.
 
unsigned getDepth() const
Returns the depth of this node, which is the length of the maximum path up to any node which has no p...
 
SmallVector< SDep, 4 > Preds
All sunit predecessors.
 
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
 
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
This is an optimization pass for GlobalISel generic memory operations.
 
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
FunctionAddr VTableAddr Count
 
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
 
FunctionAddr VTableAddr Next
 
ArrayRef(const T &OneElt) -> ArrayRef< T >
 
AntiDepBreaker * createCriticalAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI)
 
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
 
@ Keep
No function return thunk.