xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/RegisterPressure.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- RegisterPressure.cpp - Dynamic Register Pressure -------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements the RegisterPressure class which can be used to track
1009467b48Spatrick // MachineInstr level register pressure.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "llvm/CodeGen/RegisterPressure.h"
1509467b48Spatrick #include "llvm/ADT/ArrayRef.h"
1609467b48Spatrick #include "llvm/ADT/STLExtras.h"
1709467b48Spatrick #include "llvm/ADT/SmallVector.h"
1809467b48Spatrick #include "llvm/CodeGen/LiveInterval.h"
1909467b48Spatrick #include "llvm/CodeGen/LiveIntervals.h"
2009467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2209467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
2309467b48Spatrick #include "llvm/CodeGen/MachineInstrBundle.h"
2409467b48Spatrick #include "llvm/CodeGen/MachineOperand.h"
2509467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
2609467b48Spatrick #include "llvm/CodeGen/RegisterClassInfo.h"
2709467b48Spatrick #include "llvm/CodeGen/SlotIndexes.h"
2809467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h"
2909467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
3009467b48Spatrick #include "llvm/Config/llvm-config.h"
3109467b48Spatrick #include "llvm/MC/LaneBitmask.h"
3209467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
3309467b48Spatrick #include "llvm/Support/Compiler.h"
3409467b48Spatrick #include "llvm/Support/Debug.h"
3509467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3609467b48Spatrick #include "llvm/Support/raw_ostream.h"
3709467b48Spatrick #include <algorithm>
3809467b48Spatrick #include <cassert>
3909467b48Spatrick #include <cstdint>
4009467b48Spatrick #include <cstdlib>
4109467b48Spatrick #include <cstring>
4209467b48Spatrick #include <iterator>
4309467b48Spatrick #include <limits>
4409467b48Spatrick #include <utility>
4509467b48Spatrick #include <vector>
4609467b48Spatrick 
4709467b48Spatrick using namespace llvm;
4809467b48Spatrick 
4909467b48Spatrick /// Increase pressure for each pressure set provided by TargetRegisterInfo.
increaseSetPressure(std::vector<unsigned> & CurrSetPressure,const MachineRegisterInfo & MRI,unsigned Reg,LaneBitmask PrevMask,LaneBitmask NewMask)5009467b48Spatrick static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
5109467b48Spatrick                                 const MachineRegisterInfo &MRI, unsigned Reg,
5209467b48Spatrick                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
5309467b48Spatrick   assert((PrevMask & ~NewMask).none() && "Must not remove bits");
5409467b48Spatrick   if (PrevMask.any() || NewMask.none())
5509467b48Spatrick     return;
5609467b48Spatrick 
5709467b48Spatrick   PSetIterator PSetI = MRI.getPressureSets(Reg);
5809467b48Spatrick   unsigned Weight = PSetI.getWeight();
5909467b48Spatrick   for (; PSetI.isValid(); ++PSetI)
6009467b48Spatrick     CurrSetPressure[*PSetI] += Weight;
6109467b48Spatrick }
6209467b48Spatrick 
6309467b48Spatrick /// Decrease pressure for each pressure set provided by TargetRegisterInfo.
decreaseSetPressure(std::vector<unsigned> & CurrSetPressure,const MachineRegisterInfo & MRI,Register Reg,LaneBitmask PrevMask,LaneBitmask NewMask)6409467b48Spatrick static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
6573471bf0Spatrick                                 const MachineRegisterInfo &MRI, Register Reg,
6609467b48Spatrick                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
6709467b48Spatrick   //assert((NewMask & !PrevMask) == 0 && "Must not add bits");
6809467b48Spatrick   if (NewMask.any() || PrevMask.none())
6909467b48Spatrick     return;
7009467b48Spatrick 
7109467b48Spatrick   PSetIterator PSetI = MRI.getPressureSets(Reg);
7209467b48Spatrick   unsigned Weight = PSetI.getWeight();
7309467b48Spatrick   for (; PSetI.isValid(); ++PSetI) {
7409467b48Spatrick     assert(CurrSetPressure[*PSetI] >= Weight && "register pressure underflow");
7509467b48Spatrick     CurrSetPressure[*PSetI] -= Weight;
7609467b48Spatrick   }
7709467b48Spatrick }
7809467b48Spatrick 
7909467b48Spatrick #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
8009467b48Spatrick LLVM_DUMP_METHOD
dumpRegSetPressure(ArrayRef<unsigned> SetPressure,const TargetRegisterInfo * TRI)8109467b48Spatrick void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
8209467b48Spatrick                               const TargetRegisterInfo *TRI) {
8309467b48Spatrick   bool Empty = true;
8409467b48Spatrick   for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) {
8509467b48Spatrick     if (SetPressure[i] != 0) {
8609467b48Spatrick       dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n';
8709467b48Spatrick       Empty = false;
8809467b48Spatrick     }
8909467b48Spatrick   }
9009467b48Spatrick   if (Empty)
9109467b48Spatrick     dbgs() << "\n";
9209467b48Spatrick }
9309467b48Spatrick 
9409467b48Spatrick LLVM_DUMP_METHOD
dump(const TargetRegisterInfo * TRI) const9509467b48Spatrick void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
9609467b48Spatrick   dbgs() << "Max Pressure: ";
9709467b48Spatrick   dumpRegSetPressure(MaxSetPressure, TRI);
9809467b48Spatrick   dbgs() << "Live In: ";
9909467b48Spatrick   for (const RegisterMaskPair &P : LiveInRegs) {
10009467b48Spatrick     dbgs() << printVRegOrUnit(P.RegUnit, TRI);
10109467b48Spatrick     if (!P.LaneMask.all())
10209467b48Spatrick       dbgs() << ':' << PrintLaneMask(P.LaneMask);
10309467b48Spatrick     dbgs() << ' ';
10409467b48Spatrick   }
10509467b48Spatrick   dbgs() << '\n';
10609467b48Spatrick   dbgs() << "Live Out: ";
10709467b48Spatrick   for (const RegisterMaskPair &P : LiveOutRegs) {
10809467b48Spatrick     dbgs() << printVRegOrUnit(P.RegUnit, TRI);
10909467b48Spatrick     if (!P.LaneMask.all())
11009467b48Spatrick       dbgs() << ':' << PrintLaneMask(P.LaneMask);
11109467b48Spatrick     dbgs() << ' ';
11209467b48Spatrick   }
11309467b48Spatrick   dbgs() << '\n';
11409467b48Spatrick }
11509467b48Spatrick 
11609467b48Spatrick LLVM_DUMP_METHOD
dump() const11709467b48Spatrick void RegPressureTracker::dump() const {
11809467b48Spatrick   if (!isTopClosed() || !isBottomClosed()) {
11909467b48Spatrick     dbgs() << "Curr Pressure: ";
12009467b48Spatrick     dumpRegSetPressure(CurrSetPressure, TRI);
12109467b48Spatrick   }
12209467b48Spatrick   P.dump(TRI);
12309467b48Spatrick }
12409467b48Spatrick 
12509467b48Spatrick LLVM_DUMP_METHOD
dump(const TargetRegisterInfo & TRI) const12609467b48Spatrick void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
12709467b48Spatrick   const char *sep = "";
12809467b48Spatrick   for (const PressureChange &Change : *this) {
12909467b48Spatrick     if (!Change.isValid())
13009467b48Spatrick       break;
13109467b48Spatrick     dbgs() << sep << TRI.getRegPressureSetName(Change.getPSet())
13209467b48Spatrick            << " " << Change.getUnitInc();
13309467b48Spatrick     sep = "    ";
13409467b48Spatrick   }
13509467b48Spatrick   dbgs() << '\n';
13609467b48Spatrick }
13709467b48Spatrick 
13809467b48Spatrick LLVM_DUMP_METHOD
dump() const13909467b48Spatrick void PressureChange::dump() const {
14009467b48Spatrick   dbgs() << "[" << getPSetOrMax() << ", " << getUnitInc() << "]\n";
14109467b48Spatrick }
14209467b48Spatrick 
dump() const14309467b48Spatrick void RegPressureDelta::dump() const {
14409467b48Spatrick   dbgs() << "[Excess=";
14509467b48Spatrick   Excess.dump();
14609467b48Spatrick   dbgs() << ", CriticalMax=";
14709467b48Spatrick   CriticalMax.dump();
14809467b48Spatrick   dbgs() << ", CurrentMax=";
14909467b48Spatrick   CurrentMax.dump();
15009467b48Spatrick   dbgs() << "]\n";
15109467b48Spatrick }
15209467b48Spatrick 
15309467b48Spatrick #endif
15409467b48Spatrick 
increaseRegPressure(Register RegUnit,LaneBitmask PreviousMask,LaneBitmask NewMask)15573471bf0Spatrick void RegPressureTracker::increaseRegPressure(Register RegUnit,
15609467b48Spatrick                                              LaneBitmask PreviousMask,
15709467b48Spatrick                                              LaneBitmask NewMask) {
15809467b48Spatrick   if (PreviousMask.any() || NewMask.none())
15909467b48Spatrick     return;
16009467b48Spatrick 
16109467b48Spatrick   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
16209467b48Spatrick   unsigned Weight = PSetI.getWeight();
16309467b48Spatrick   for (; PSetI.isValid(); ++PSetI) {
16409467b48Spatrick     CurrSetPressure[*PSetI] += Weight;
16509467b48Spatrick     P.MaxSetPressure[*PSetI] =
16609467b48Spatrick         std::max(P.MaxSetPressure[*PSetI], CurrSetPressure[*PSetI]);
16709467b48Spatrick   }
16809467b48Spatrick }
16909467b48Spatrick 
decreaseRegPressure(Register RegUnit,LaneBitmask PreviousMask,LaneBitmask NewMask)17073471bf0Spatrick void RegPressureTracker::decreaseRegPressure(Register RegUnit,
17109467b48Spatrick                                              LaneBitmask PreviousMask,
17209467b48Spatrick                                              LaneBitmask NewMask) {
17309467b48Spatrick   decreaseSetPressure(CurrSetPressure, *MRI, RegUnit, PreviousMask, NewMask);
17409467b48Spatrick }
17509467b48Spatrick 
17609467b48Spatrick /// Clear the result so it can be used for another round of pressure tracking.
reset()17709467b48Spatrick void IntervalPressure::reset() {
17809467b48Spatrick   TopIdx = BottomIdx = SlotIndex();
17909467b48Spatrick   MaxSetPressure.clear();
18009467b48Spatrick   LiveInRegs.clear();
18109467b48Spatrick   LiveOutRegs.clear();
18209467b48Spatrick }
18309467b48Spatrick 
18409467b48Spatrick /// Clear the result so it can be used for another round of pressure tracking.
reset()18509467b48Spatrick void RegionPressure::reset() {
18609467b48Spatrick   TopPos = BottomPos = MachineBasicBlock::const_iterator();
18709467b48Spatrick   MaxSetPressure.clear();
18809467b48Spatrick   LiveInRegs.clear();
18909467b48Spatrick   LiveOutRegs.clear();
19009467b48Spatrick }
19109467b48Spatrick 
19209467b48Spatrick /// If the current top is not less than or equal to the next index, open it.
19309467b48Spatrick /// We happen to need the SlotIndex for the next top for pressure update.
openTop(SlotIndex NextTop)19409467b48Spatrick void IntervalPressure::openTop(SlotIndex NextTop) {
19509467b48Spatrick   if (TopIdx <= NextTop)
19609467b48Spatrick     return;
19709467b48Spatrick   TopIdx = SlotIndex();
19809467b48Spatrick   LiveInRegs.clear();
19909467b48Spatrick }
20009467b48Spatrick 
20109467b48Spatrick /// If the current top is the previous instruction (before receding), open it.
openTop(MachineBasicBlock::const_iterator PrevTop)20209467b48Spatrick void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
20309467b48Spatrick   if (TopPos != PrevTop)
20409467b48Spatrick     return;
20509467b48Spatrick   TopPos = MachineBasicBlock::const_iterator();
20609467b48Spatrick   LiveInRegs.clear();
20709467b48Spatrick }
20809467b48Spatrick 
20909467b48Spatrick /// If the current bottom is not greater than the previous index, open it.
openBottom(SlotIndex PrevBottom)21009467b48Spatrick void IntervalPressure::openBottom(SlotIndex PrevBottom) {
21109467b48Spatrick   if (BottomIdx > PrevBottom)
21209467b48Spatrick     return;
21309467b48Spatrick   BottomIdx = SlotIndex();
21409467b48Spatrick   LiveInRegs.clear();
21509467b48Spatrick }
21609467b48Spatrick 
21709467b48Spatrick /// If the current bottom is the previous instr (before advancing), open it.
openBottom(MachineBasicBlock::const_iterator PrevBottom)21809467b48Spatrick void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
21909467b48Spatrick   if (BottomPos != PrevBottom)
22009467b48Spatrick     return;
22109467b48Spatrick   BottomPos = MachineBasicBlock::const_iterator();
22209467b48Spatrick   LiveInRegs.clear();
22309467b48Spatrick }
22409467b48Spatrick 
init(const MachineRegisterInfo & MRI)22509467b48Spatrick void LiveRegSet::init(const MachineRegisterInfo &MRI) {
22609467b48Spatrick   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
22709467b48Spatrick   unsigned NumRegUnits = TRI.getNumRegs();
22809467b48Spatrick   unsigned NumVirtRegs = MRI.getNumVirtRegs();
22909467b48Spatrick   Regs.setUniverse(NumRegUnits + NumVirtRegs);
23009467b48Spatrick   this->NumRegUnits = NumRegUnits;
23109467b48Spatrick }
23209467b48Spatrick 
clear()23309467b48Spatrick void LiveRegSet::clear() {
23409467b48Spatrick   Regs.clear();
23509467b48Spatrick }
23609467b48Spatrick 
getLiveRange(const LiveIntervals & LIS,unsigned Reg)23709467b48Spatrick static const LiveRange *getLiveRange(const LiveIntervals &LIS, unsigned Reg) {
23809467b48Spatrick   if (Register::isVirtualRegister(Reg))
23909467b48Spatrick     return &LIS.getInterval(Reg);
24009467b48Spatrick   return LIS.getCachedRegUnit(Reg);
24109467b48Spatrick }
24209467b48Spatrick 
reset()24309467b48Spatrick void RegPressureTracker::reset() {
24409467b48Spatrick   MBB = nullptr;
24509467b48Spatrick   LIS = nullptr;
24609467b48Spatrick 
24709467b48Spatrick   CurrSetPressure.clear();
24809467b48Spatrick   LiveThruPressure.clear();
24909467b48Spatrick   P.MaxSetPressure.clear();
25009467b48Spatrick 
25109467b48Spatrick   if (RequireIntervals)
25209467b48Spatrick     static_cast<IntervalPressure&>(P).reset();
25309467b48Spatrick   else
25409467b48Spatrick     static_cast<RegionPressure&>(P).reset();
25509467b48Spatrick 
25609467b48Spatrick   LiveRegs.clear();
25709467b48Spatrick   UntiedDefs.clear();
25809467b48Spatrick }
25909467b48Spatrick 
26009467b48Spatrick /// Setup the RegPressureTracker.
26109467b48Spatrick ///
26209467b48Spatrick /// TODO: Add support for pressure without LiveIntervals.
init(const MachineFunction * mf,const RegisterClassInfo * rci,const LiveIntervals * lis,const MachineBasicBlock * mbb,MachineBasicBlock::const_iterator pos,bool TrackLaneMasks,bool TrackUntiedDefs)26309467b48Spatrick void RegPressureTracker::init(const MachineFunction *mf,
26409467b48Spatrick                               const RegisterClassInfo *rci,
26509467b48Spatrick                               const LiveIntervals *lis,
26609467b48Spatrick                               const MachineBasicBlock *mbb,
26709467b48Spatrick                               MachineBasicBlock::const_iterator pos,
26809467b48Spatrick                               bool TrackLaneMasks, bool TrackUntiedDefs) {
26909467b48Spatrick   reset();
27009467b48Spatrick 
27109467b48Spatrick   MF = mf;
27209467b48Spatrick   TRI = MF->getSubtarget().getRegisterInfo();
27309467b48Spatrick   RCI = rci;
27409467b48Spatrick   MRI = &MF->getRegInfo();
27509467b48Spatrick   MBB = mbb;
27609467b48Spatrick   this->TrackUntiedDefs = TrackUntiedDefs;
27709467b48Spatrick   this->TrackLaneMasks = TrackLaneMasks;
27809467b48Spatrick 
27909467b48Spatrick   if (RequireIntervals) {
28009467b48Spatrick     assert(lis && "IntervalPressure requires LiveIntervals");
28109467b48Spatrick     LIS = lis;
28209467b48Spatrick   }
28309467b48Spatrick 
28409467b48Spatrick   CurrPos = pos;
28509467b48Spatrick   CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
28609467b48Spatrick 
28709467b48Spatrick   P.MaxSetPressure = CurrSetPressure;
28809467b48Spatrick 
28909467b48Spatrick   LiveRegs.init(*MRI);
29009467b48Spatrick   if (TrackUntiedDefs)
29109467b48Spatrick     UntiedDefs.setUniverse(MRI->getNumVirtRegs());
29209467b48Spatrick }
29309467b48Spatrick 
29409467b48Spatrick /// Does this pressure result have a valid top position and live ins.
isTopClosed() const29509467b48Spatrick bool RegPressureTracker::isTopClosed() const {
29609467b48Spatrick   if (RequireIntervals)
29709467b48Spatrick     return static_cast<IntervalPressure&>(P).TopIdx.isValid();
29809467b48Spatrick   return (static_cast<RegionPressure&>(P).TopPos ==
29909467b48Spatrick           MachineBasicBlock::const_iterator());
30009467b48Spatrick }
30109467b48Spatrick 
30209467b48Spatrick /// Does this pressure result have a valid bottom position and live outs.
isBottomClosed() const30309467b48Spatrick bool RegPressureTracker::isBottomClosed() const {
30409467b48Spatrick   if (RequireIntervals)
30509467b48Spatrick     return static_cast<IntervalPressure&>(P).BottomIdx.isValid();
30609467b48Spatrick   return (static_cast<RegionPressure&>(P).BottomPos ==
30709467b48Spatrick           MachineBasicBlock::const_iterator());
30809467b48Spatrick }
30909467b48Spatrick 
getCurrSlot() const31009467b48Spatrick SlotIndex RegPressureTracker::getCurrSlot() const {
31109467b48Spatrick   MachineBasicBlock::const_iterator IdxPos =
31209467b48Spatrick     skipDebugInstructionsForward(CurrPos, MBB->end());
31309467b48Spatrick   if (IdxPos == MBB->end())
31409467b48Spatrick     return LIS->getMBBEndIdx(MBB);
31509467b48Spatrick   return LIS->getInstructionIndex(*IdxPos).getRegSlot();
31609467b48Spatrick }
31709467b48Spatrick 
31809467b48Spatrick /// Set the boundary for the top of the region and summarize live ins.
closeTop()31909467b48Spatrick void RegPressureTracker::closeTop() {
32009467b48Spatrick   if (RequireIntervals)
32109467b48Spatrick     static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot();
32209467b48Spatrick   else
32309467b48Spatrick     static_cast<RegionPressure&>(P).TopPos = CurrPos;
32409467b48Spatrick 
32509467b48Spatrick   assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
32609467b48Spatrick   P.LiveInRegs.reserve(LiveRegs.size());
32709467b48Spatrick   LiveRegs.appendTo(P.LiveInRegs);
32809467b48Spatrick }
32909467b48Spatrick 
33009467b48Spatrick /// Set the boundary for the bottom of the region and summarize live outs.
closeBottom()33109467b48Spatrick void RegPressureTracker::closeBottom() {
33209467b48Spatrick   if (RequireIntervals)
33309467b48Spatrick     static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot();
33409467b48Spatrick   else
33509467b48Spatrick     static_cast<RegionPressure&>(P).BottomPos = CurrPos;
33609467b48Spatrick 
33709467b48Spatrick   assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
33809467b48Spatrick   P.LiveOutRegs.reserve(LiveRegs.size());
33909467b48Spatrick   LiveRegs.appendTo(P.LiveOutRegs);
34009467b48Spatrick }
34109467b48Spatrick 
34209467b48Spatrick /// Finalize the region boundaries and record live ins and live outs.
closeRegion()34309467b48Spatrick void RegPressureTracker::closeRegion() {
34409467b48Spatrick   if (!isTopClosed() && !isBottomClosed()) {
34509467b48Spatrick     assert(LiveRegs.size() == 0 && "no region boundary");
34609467b48Spatrick     return;
34709467b48Spatrick   }
34809467b48Spatrick   if (!isBottomClosed())
34909467b48Spatrick     closeBottom();
35009467b48Spatrick   else if (!isTopClosed())
35109467b48Spatrick     closeTop();
35209467b48Spatrick   // If both top and bottom are closed, do nothing.
35309467b48Spatrick }
35409467b48Spatrick 
35509467b48Spatrick /// The register tracker is unaware of global liveness so ignores normal
35609467b48Spatrick /// live-thru ranges. However, two-address or coalesced chains can also lead
35709467b48Spatrick /// to live ranges with no holes. Count these to inform heuristics that we
35809467b48Spatrick /// can never drop below this pressure.
initLiveThru(const RegPressureTracker & RPTracker)35909467b48Spatrick void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
36009467b48Spatrick   LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
36109467b48Spatrick   assert(isBottomClosed() && "need bottom-up tracking to intialize.");
36209467b48Spatrick   for (const RegisterMaskPair &Pair : P.LiveOutRegs) {
36373471bf0Spatrick     Register RegUnit = Pair.RegUnit;
364*d415bd75Srobert     if (RegUnit.isVirtual() && !RPTracker.hasUntiedDef(RegUnit))
36509467b48Spatrick       increaseSetPressure(LiveThruPressure, *MRI, RegUnit,
36609467b48Spatrick                           LaneBitmask::getNone(), Pair.LaneMask);
36709467b48Spatrick   }
36809467b48Spatrick }
36909467b48Spatrick 
getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,Register RegUnit)37009467b48Spatrick static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
37173471bf0Spatrick                                Register RegUnit) {
37209467b48Spatrick   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
37309467b48Spatrick     return Other.RegUnit == RegUnit;
37409467b48Spatrick   });
37509467b48Spatrick   if (I == RegUnits.end())
37609467b48Spatrick     return LaneBitmask::getNone();
37709467b48Spatrick   return I->LaneMask;
37809467b48Spatrick }
37909467b48Spatrick 
addRegLanes(SmallVectorImpl<RegisterMaskPair> & RegUnits,RegisterMaskPair Pair)38009467b48Spatrick static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
38109467b48Spatrick                         RegisterMaskPair Pair) {
38273471bf0Spatrick   Register RegUnit = Pair.RegUnit;
38309467b48Spatrick   assert(Pair.LaneMask.any());
38409467b48Spatrick   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
38509467b48Spatrick     return Other.RegUnit == RegUnit;
38609467b48Spatrick   });
38709467b48Spatrick   if (I == RegUnits.end()) {
38809467b48Spatrick     RegUnits.push_back(Pair);
38909467b48Spatrick   } else {
39009467b48Spatrick     I->LaneMask |= Pair.LaneMask;
39109467b48Spatrick   }
39209467b48Spatrick }
39309467b48Spatrick 
setRegZero(SmallVectorImpl<RegisterMaskPair> & RegUnits,Register RegUnit)39409467b48Spatrick static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
39573471bf0Spatrick                        Register RegUnit) {
39609467b48Spatrick   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
39709467b48Spatrick     return Other.RegUnit == RegUnit;
39809467b48Spatrick   });
39909467b48Spatrick   if (I == RegUnits.end()) {
40009467b48Spatrick     RegUnits.push_back(RegisterMaskPair(RegUnit, LaneBitmask::getNone()));
40109467b48Spatrick   } else {
40209467b48Spatrick     I->LaneMask = LaneBitmask::getNone();
40309467b48Spatrick   }
40409467b48Spatrick }
40509467b48Spatrick 
removeRegLanes(SmallVectorImpl<RegisterMaskPair> & RegUnits,RegisterMaskPair Pair)40609467b48Spatrick static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
40709467b48Spatrick                            RegisterMaskPair Pair) {
40873471bf0Spatrick   Register RegUnit = Pair.RegUnit;
40909467b48Spatrick   assert(Pair.LaneMask.any());
41009467b48Spatrick   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
41109467b48Spatrick     return Other.RegUnit == RegUnit;
41209467b48Spatrick   });
41309467b48Spatrick   if (I != RegUnits.end()) {
41409467b48Spatrick     I->LaneMask &= ~Pair.LaneMask;
41509467b48Spatrick     if (I->LaneMask.none())
41609467b48Spatrick       RegUnits.erase(I);
41709467b48Spatrick   }
41809467b48Spatrick }
41909467b48Spatrick 
42073471bf0Spatrick static LaneBitmask
getLanesWithProperty(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,bool TrackLaneMasks,Register RegUnit,SlotIndex Pos,LaneBitmask SafeDefault,bool (* Property)(const LiveRange & LR,SlotIndex Pos))42173471bf0Spatrick getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
42273471bf0Spatrick                      bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
42373471bf0Spatrick                      LaneBitmask SafeDefault,
42409467b48Spatrick                      bool (*Property)(const LiveRange &LR, SlotIndex Pos)) {
42573471bf0Spatrick   if (RegUnit.isVirtual()) {
42609467b48Spatrick     const LiveInterval &LI = LIS.getInterval(RegUnit);
42709467b48Spatrick     LaneBitmask Result;
42809467b48Spatrick     if (TrackLaneMasks && LI.hasSubRanges()) {
42909467b48Spatrick         for (const LiveInterval::SubRange &SR : LI.subranges()) {
43009467b48Spatrick           if (Property(SR, Pos))
43109467b48Spatrick             Result |= SR.LaneMask;
43209467b48Spatrick         }
43309467b48Spatrick     } else if (Property(LI, Pos)) {
43409467b48Spatrick       Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit)
43509467b48Spatrick                               : LaneBitmask::getAll();
43609467b48Spatrick     }
43709467b48Spatrick 
43809467b48Spatrick     return Result;
43909467b48Spatrick   } else {
44009467b48Spatrick     const LiveRange *LR = LIS.getCachedRegUnit(RegUnit);
44109467b48Spatrick     // Be prepared for missing liveranges: We usually do not compute liveranges
44209467b48Spatrick     // for physical registers on targets with many registers (GPUs).
44309467b48Spatrick     if (LR == nullptr)
44409467b48Spatrick       return SafeDefault;
44509467b48Spatrick     return Property(*LR, Pos) ? LaneBitmask::getAll() : LaneBitmask::getNone();
44609467b48Spatrick   }
44709467b48Spatrick }
44809467b48Spatrick 
getLiveLanesAt(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,bool TrackLaneMasks,Register RegUnit,SlotIndex Pos)44909467b48Spatrick static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
45009467b48Spatrick                                   const MachineRegisterInfo &MRI,
45173471bf0Spatrick                                   bool TrackLaneMasks, Register RegUnit,
45209467b48Spatrick                                   SlotIndex Pos) {
45309467b48Spatrick   return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos,
45409467b48Spatrick                               LaneBitmask::getAll(),
45509467b48Spatrick                               [](const LiveRange &LR, SlotIndex Pos) {
45609467b48Spatrick                                 return LR.liveAt(Pos);
45709467b48Spatrick                               });
45809467b48Spatrick }
45909467b48Spatrick 
46009467b48Spatrick namespace {
46109467b48Spatrick 
46209467b48Spatrick /// Collect this instruction's unique uses and defs into SmallVectors for
46309467b48Spatrick /// processing defs and uses in order.
46409467b48Spatrick ///
46509467b48Spatrick /// FIXME: always ignore tied opers
46609467b48Spatrick class RegisterOperandsCollector {
46709467b48Spatrick   friend class llvm::RegisterOperands;
46809467b48Spatrick 
46909467b48Spatrick   RegisterOperands &RegOpers;
47009467b48Spatrick   const TargetRegisterInfo &TRI;
47109467b48Spatrick   const MachineRegisterInfo &MRI;
47209467b48Spatrick   bool IgnoreDead;
47309467b48Spatrick 
RegisterOperandsCollector(RegisterOperands & RegOpers,const TargetRegisterInfo & TRI,const MachineRegisterInfo & MRI,bool IgnoreDead)47409467b48Spatrick   RegisterOperandsCollector(RegisterOperands &RegOpers,
47509467b48Spatrick                             const TargetRegisterInfo &TRI,
47609467b48Spatrick                             const MachineRegisterInfo &MRI, bool IgnoreDead)
47709467b48Spatrick     : RegOpers(RegOpers), TRI(TRI), MRI(MRI), IgnoreDead(IgnoreDead) {}
47809467b48Spatrick 
collectInstr(const MachineInstr & MI) const47909467b48Spatrick   void collectInstr(const MachineInstr &MI) const {
48009467b48Spatrick     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
48109467b48Spatrick       collectOperand(*OperI);
48209467b48Spatrick 
48309467b48Spatrick     // Remove redundant physreg dead defs.
48409467b48Spatrick     for (const RegisterMaskPair &P : RegOpers.Defs)
48509467b48Spatrick       removeRegLanes(RegOpers.DeadDefs, P);
48609467b48Spatrick   }
48709467b48Spatrick 
collectInstrLanes(const MachineInstr & MI) const48809467b48Spatrick   void collectInstrLanes(const MachineInstr &MI) const {
48909467b48Spatrick     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
49009467b48Spatrick       collectOperandLanes(*OperI);
49109467b48Spatrick 
49209467b48Spatrick     // Remove redundant physreg dead defs.
49309467b48Spatrick     for (const RegisterMaskPair &P : RegOpers.Defs)
49409467b48Spatrick       removeRegLanes(RegOpers.DeadDefs, P);
49509467b48Spatrick   }
49609467b48Spatrick 
49709467b48Spatrick   /// Push this operand's register onto the correct vectors.
collectOperand(const MachineOperand & MO) const49809467b48Spatrick   void collectOperand(const MachineOperand &MO) const {
49909467b48Spatrick     if (!MO.isReg() || !MO.getReg())
50009467b48Spatrick       return;
50109467b48Spatrick     Register Reg = MO.getReg();
50209467b48Spatrick     if (MO.isUse()) {
50309467b48Spatrick       if (!MO.isUndef() && !MO.isInternalRead())
50409467b48Spatrick         pushReg(Reg, RegOpers.Uses);
50509467b48Spatrick     } else {
50609467b48Spatrick       assert(MO.isDef());
50709467b48Spatrick       // Subregister definitions may imply a register read.
50809467b48Spatrick       if (MO.readsReg())
50909467b48Spatrick         pushReg(Reg, RegOpers.Uses);
51009467b48Spatrick 
51109467b48Spatrick       if (MO.isDead()) {
51209467b48Spatrick         if (!IgnoreDead)
51309467b48Spatrick           pushReg(Reg, RegOpers.DeadDefs);
51409467b48Spatrick       } else
51509467b48Spatrick         pushReg(Reg, RegOpers.Defs);
51609467b48Spatrick     }
51709467b48Spatrick   }
51809467b48Spatrick 
pushReg(Register Reg,SmallVectorImpl<RegisterMaskPair> & RegUnits) const51973471bf0Spatrick   void pushReg(Register Reg,
52009467b48Spatrick                SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
52173471bf0Spatrick     if (Reg.isVirtual()) {
52209467b48Spatrick       addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneBitmask::getAll()));
52309467b48Spatrick     } else if (MRI.isAllocatable(Reg)) {
52473471bf0Spatrick       for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
52573471bf0Spatrick            ++Units)
52609467b48Spatrick         addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
52709467b48Spatrick     }
52809467b48Spatrick   }
52909467b48Spatrick 
collectOperandLanes(const MachineOperand & MO) const53009467b48Spatrick   void collectOperandLanes(const MachineOperand &MO) const {
53109467b48Spatrick     if (!MO.isReg() || !MO.getReg())
53209467b48Spatrick       return;
53309467b48Spatrick     Register Reg = MO.getReg();
53409467b48Spatrick     unsigned SubRegIdx = MO.getSubReg();
53509467b48Spatrick     if (MO.isUse()) {
53609467b48Spatrick       if (!MO.isUndef() && !MO.isInternalRead())
53709467b48Spatrick         pushRegLanes(Reg, SubRegIdx, RegOpers.Uses);
53809467b48Spatrick     } else {
53909467b48Spatrick       assert(MO.isDef());
54009467b48Spatrick       // Treat read-undef subreg defs as definitions of the whole register.
54109467b48Spatrick       if (MO.isUndef())
54209467b48Spatrick         SubRegIdx = 0;
54309467b48Spatrick 
54409467b48Spatrick       if (MO.isDead()) {
54509467b48Spatrick         if (!IgnoreDead)
54609467b48Spatrick           pushRegLanes(Reg, SubRegIdx, RegOpers.DeadDefs);
54709467b48Spatrick       } else
54809467b48Spatrick         pushRegLanes(Reg, SubRegIdx, RegOpers.Defs);
54909467b48Spatrick     }
55009467b48Spatrick   }
55109467b48Spatrick 
pushRegLanes(Register Reg,unsigned SubRegIdx,SmallVectorImpl<RegisterMaskPair> & RegUnits) const55273471bf0Spatrick   void pushRegLanes(Register Reg, unsigned SubRegIdx,
55309467b48Spatrick                     SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
55473471bf0Spatrick     if (Reg.isVirtual()) {
55509467b48Spatrick       LaneBitmask LaneMask = SubRegIdx != 0
55609467b48Spatrick                              ? TRI.getSubRegIndexLaneMask(SubRegIdx)
55709467b48Spatrick                              : MRI.getMaxLaneMaskForVReg(Reg);
55809467b48Spatrick       addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneMask));
55909467b48Spatrick     } else if (MRI.isAllocatable(Reg)) {
56073471bf0Spatrick       for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
56173471bf0Spatrick            ++Units)
56209467b48Spatrick         addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
56309467b48Spatrick     }
56409467b48Spatrick   }
56509467b48Spatrick };
56609467b48Spatrick 
56709467b48Spatrick } // end anonymous namespace
56809467b48Spatrick 
collect(const MachineInstr & MI,const TargetRegisterInfo & TRI,const MachineRegisterInfo & MRI,bool TrackLaneMasks,bool IgnoreDead)56909467b48Spatrick void RegisterOperands::collect(const MachineInstr &MI,
57009467b48Spatrick                                const TargetRegisterInfo &TRI,
57109467b48Spatrick                                const MachineRegisterInfo &MRI,
57209467b48Spatrick                                bool TrackLaneMasks, bool IgnoreDead) {
57309467b48Spatrick   RegisterOperandsCollector Collector(*this, TRI, MRI, IgnoreDead);
57409467b48Spatrick   if (TrackLaneMasks)
57509467b48Spatrick     Collector.collectInstrLanes(MI);
57609467b48Spatrick   else
57709467b48Spatrick     Collector.collectInstr(MI);
57809467b48Spatrick }
57909467b48Spatrick 
detectDeadDefs(const MachineInstr & MI,const LiveIntervals & LIS)58009467b48Spatrick void RegisterOperands::detectDeadDefs(const MachineInstr &MI,
58109467b48Spatrick                                       const LiveIntervals &LIS) {
58209467b48Spatrick   SlotIndex SlotIdx = LIS.getInstructionIndex(MI);
583*d415bd75Srobert   for (auto *RI = Defs.begin(); RI != Defs.end(); /*empty*/) {
58473471bf0Spatrick     Register Reg = RI->RegUnit;
58509467b48Spatrick     const LiveRange *LR = getLiveRange(LIS, Reg);
58609467b48Spatrick     if (LR != nullptr) {
58709467b48Spatrick       LiveQueryResult LRQ = LR->Query(SlotIdx);
58809467b48Spatrick       if (LRQ.isDeadDef()) {
58909467b48Spatrick         // LiveIntervals knows this is a dead even though it's MachineOperand is
59009467b48Spatrick         // not flagged as such.
59109467b48Spatrick         DeadDefs.push_back(*RI);
59209467b48Spatrick         RI = Defs.erase(RI);
59309467b48Spatrick         continue;
59409467b48Spatrick       }
59509467b48Spatrick     }
59609467b48Spatrick     ++RI;
59709467b48Spatrick   }
59809467b48Spatrick }
59909467b48Spatrick 
adjustLaneLiveness(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,SlotIndex Pos,MachineInstr * AddFlagsMI)60009467b48Spatrick void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
60109467b48Spatrick                                           const MachineRegisterInfo &MRI,
60209467b48Spatrick                                           SlotIndex Pos,
60309467b48Spatrick                                           MachineInstr *AddFlagsMI) {
604*d415bd75Srobert   for (auto *I = Defs.begin(); I != Defs.end();) {
60509467b48Spatrick     LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
60609467b48Spatrick                                            Pos.getDeadSlot());
60709467b48Spatrick     // If the def is all that is live after the instruction, then in case
60809467b48Spatrick     // of a subregister def we need a read-undef flag.
60973471bf0Spatrick     Register RegUnit = I->RegUnit;
610*d415bd75Srobert     if (RegUnit.isVirtual() && AddFlagsMI != nullptr &&
611*d415bd75Srobert         (LiveAfter & ~I->LaneMask).none())
61209467b48Spatrick       AddFlagsMI->setRegisterDefReadUndef(RegUnit);
61309467b48Spatrick 
61409467b48Spatrick     LaneBitmask ActualDef = I->LaneMask & LiveAfter;
61509467b48Spatrick     if (ActualDef.none()) {
61609467b48Spatrick       I = Defs.erase(I);
61709467b48Spatrick     } else {
61809467b48Spatrick       I->LaneMask = ActualDef;
61909467b48Spatrick       ++I;
62009467b48Spatrick     }
62109467b48Spatrick   }
622*d415bd75Srobert   for (auto *I = Uses.begin(); I != Uses.end();) {
62309467b48Spatrick     LaneBitmask LiveBefore = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
62409467b48Spatrick                                             Pos.getBaseIndex());
62509467b48Spatrick     LaneBitmask LaneMask = I->LaneMask & LiveBefore;
62609467b48Spatrick     if (LaneMask.none()) {
62709467b48Spatrick       I = Uses.erase(I);
62809467b48Spatrick     } else {
62909467b48Spatrick       I->LaneMask = LaneMask;
63009467b48Spatrick       ++I;
63109467b48Spatrick     }
63209467b48Spatrick   }
63309467b48Spatrick   if (AddFlagsMI != nullptr) {
63409467b48Spatrick     for (const RegisterMaskPair &P : DeadDefs) {
63573471bf0Spatrick       Register RegUnit = P.RegUnit;
636*d415bd75Srobert       if (!RegUnit.isVirtual())
63709467b48Spatrick         continue;
63809467b48Spatrick       LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
63909467b48Spatrick                                              Pos.getDeadSlot());
64009467b48Spatrick       if (LiveAfter.none())
64109467b48Spatrick         AddFlagsMI->setRegisterDefReadUndef(RegUnit);
64209467b48Spatrick     }
64309467b48Spatrick   }
64409467b48Spatrick }
64509467b48Spatrick 
64609467b48Spatrick /// Initialize an array of N PressureDiffs.
init(unsigned N)64709467b48Spatrick void PressureDiffs::init(unsigned N) {
64809467b48Spatrick   Size = N;
64909467b48Spatrick   if (N <= Max) {
65009467b48Spatrick     memset(PDiffArray, 0, N * sizeof(PressureDiff));
65109467b48Spatrick     return;
65209467b48Spatrick   }
65309467b48Spatrick   Max = Size;
65409467b48Spatrick   free(PDiffArray);
65509467b48Spatrick   PDiffArray = static_cast<PressureDiff*>(safe_calloc(N, sizeof(PressureDiff)));
65609467b48Spatrick }
65709467b48Spatrick 
addInstruction(unsigned Idx,const RegisterOperands & RegOpers,const MachineRegisterInfo & MRI)65809467b48Spatrick void PressureDiffs::addInstruction(unsigned Idx,
65909467b48Spatrick                                    const RegisterOperands &RegOpers,
66009467b48Spatrick                                    const MachineRegisterInfo &MRI) {
66109467b48Spatrick   PressureDiff &PDiff = (*this)[Idx];
66209467b48Spatrick   assert(!PDiff.begin()->isValid() && "stale PDiff");
66309467b48Spatrick   for (const RegisterMaskPair &P : RegOpers.Defs)
66409467b48Spatrick     PDiff.addPressureChange(P.RegUnit, true, &MRI);
66509467b48Spatrick 
66609467b48Spatrick   for (const RegisterMaskPair &P : RegOpers.Uses)
66709467b48Spatrick     PDiff.addPressureChange(P.RegUnit, false, &MRI);
66809467b48Spatrick }
66909467b48Spatrick 
67009467b48Spatrick /// Add a change in pressure to the pressure diff of a given instruction.
addPressureChange(Register RegUnit,bool IsDec,const MachineRegisterInfo * MRI)67173471bf0Spatrick void PressureDiff::addPressureChange(Register RegUnit, bool IsDec,
67209467b48Spatrick                                      const MachineRegisterInfo *MRI) {
67309467b48Spatrick   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
67409467b48Spatrick   int Weight = IsDec ? -PSetI.getWeight() : PSetI.getWeight();
67509467b48Spatrick   for (; PSetI.isValid(); ++PSetI) {
67609467b48Spatrick     // Find an existing entry in the pressure diff for this PSet.
67709467b48Spatrick     PressureDiff::iterator I = nonconst_begin(), E = nonconst_end();
67809467b48Spatrick     for (; I != E && I->isValid(); ++I) {
67909467b48Spatrick       if (I->getPSet() >= *PSetI)
68009467b48Spatrick         break;
68109467b48Spatrick     }
68209467b48Spatrick     // If all pressure sets are more constrained, skip the remaining PSets.
68309467b48Spatrick     if (I == E)
68409467b48Spatrick       break;
68509467b48Spatrick     // Insert this PressureChange.
68609467b48Spatrick     if (!I->isValid() || I->getPSet() != *PSetI) {
68709467b48Spatrick       PressureChange PTmp = PressureChange(*PSetI);
68809467b48Spatrick       for (PressureDiff::iterator J = I; J != E && PTmp.isValid(); ++J)
68909467b48Spatrick         std::swap(*J, PTmp);
69009467b48Spatrick     }
69109467b48Spatrick     // Update the units for this pressure set.
69209467b48Spatrick     unsigned NewUnitInc = I->getUnitInc() + Weight;
69309467b48Spatrick     if (NewUnitInc != 0) {
69409467b48Spatrick       I->setUnitInc(NewUnitInc);
69509467b48Spatrick     } else {
69609467b48Spatrick       // Remove entry
69709467b48Spatrick       PressureDiff::iterator J;
69809467b48Spatrick       for (J = std::next(I); J != E && J->isValid(); ++J, ++I)
69909467b48Spatrick         *I = *J;
70009467b48Spatrick       *I = PressureChange();
70109467b48Spatrick     }
70209467b48Spatrick   }
70309467b48Spatrick }
70409467b48Spatrick 
70509467b48Spatrick /// Force liveness of registers.
addLiveRegs(ArrayRef<RegisterMaskPair> Regs)70609467b48Spatrick void RegPressureTracker::addLiveRegs(ArrayRef<RegisterMaskPair> Regs) {
70709467b48Spatrick   for (const RegisterMaskPair &P : Regs) {
70809467b48Spatrick     LaneBitmask PrevMask = LiveRegs.insert(P);
70909467b48Spatrick     LaneBitmask NewMask = PrevMask | P.LaneMask;
71009467b48Spatrick     increaseRegPressure(P.RegUnit, PrevMask, NewMask);
71109467b48Spatrick   }
71209467b48Spatrick }
71309467b48Spatrick 
discoverLiveInOrOut(RegisterMaskPair Pair,SmallVectorImpl<RegisterMaskPair> & LiveInOrOut)71409467b48Spatrick void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
71509467b48Spatrick     SmallVectorImpl<RegisterMaskPair> &LiveInOrOut) {
71609467b48Spatrick   assert(Pair.LaneMask.any());
71709467b48Spatrick 
71873471bf0Spatrick   Register RegUnit = Pair.RegUnit;
71909467b48Spatrick   auto I = llvm::find_if(LiveInOrOut, [RegUnit](const RegisterMaskPair &Other) {
72009467b48Spatrick     return Other.RegUnit == RegUnit;
72109467b48Spatrick   });
72209467b48Spatrick   LaneBitmask PrevMask;
72309467b48Spatrick   LaneBitmask NewMask;
72409467b48Spatrick   if (I == LiveInOrOut.end()) {
72509467b48Spatrick     PrevMask = LaneBitmask::getNone();
72609467b48Spatrick     NewMask = Pair.LaneMask;
72709467b48Spatrick     LiveInOrOut.push_back(Pair);
72809467b48Spatrick   } else {
72909467b48Spatrick     PrevMask = I->LaneMask;
73009467b48Spatrick     NewMask = PrevMask | Pair.LaneMask;
73109467b48Spatrick     I->LaneMask = NewMask;
73209467b48Spatrick   }
73309467b48Spatrick   increaseSetPressure(P.MaxSetPressure, *MRI, RegUnit, PrevMask, NewMask);
73409467b48Spatrick }
73509467b48Spatrick 
discoverLiveIn(RegisterMaskPair Pair)73609467b48Spatrick void RegPressureTracker::discoverLiveIn(RegisterMaskPair Pair) {
73709467b48Spatrick   discoverLiveInOrOut(Pair, P.LiveInRegs);
73809467b48Spatrick }
73909467b48Spatrick 
discoverLiveOut(RegisterMaskPair Pair)74009467b48Spatrick void RegPressureTracker::discoverLiveOut(RegisterMaskPair Pair) {
74109467b48Spatrick   discoverLiveInOrOut(Pair, P.LiveOutRegs);
74209467b48Spatrick }
74309467b48Spatrick 
bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs)74409467b48Spatrick void RegPressureTracker::bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs) {
74509467b48Spatrick   for (const RegisterMaskPair &P : DeadDefs) {
74673471bf0Spatrick     Register Reg = P.RegUnit;
74709467b48Spatrick     LaneBitmask LiveMask = LiveRegs.contains(Reg);
74809467b48Spatrick     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
74909467b48Spatrick     increaseRegPressure(Reg, LiveMask, BumpedMask);
75009467b48Spatrick   }
75109467b48Spatrick   for (const RegisterMaskPair &P : DeadDefs) {
75273471bf0Spatrick     Register Reg = P.RegUnit;
75309467b48Spatrick     LaneBitmask LiveMask = LiveRegs.contains(Reg);
75409467b48Spatrick     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
75509467b48Spatrick     decreaseRegPressure(Reg, BumpedMask, LiveMask);
75609467b48Spatrick   }
75709467b48Spatrick }
75809467b48Spatrick 
75909467b48Spatrick /// Recede across the previous instruction. If LiveUses is provided, record any
76009467b48Spatrick /// RegUnits that are made live by the current instruction's uses. This includes
76109467b48Spatrick /// registers that are both defined and used by the instruction.  If a pressure
76209467b48Spatrick /// difference pointer is provided record the changes is pressure caused by this
76309467b48Spatrick /// instruction independent of liveness.
recede(const RegisterOperands & RegOpers,SmallVectorImpl<RegisterMaskPair> * LiveUses)76409467b48Spatrick void RegPressureTracker::recede(const RegisterOperands &RegOpers,
76509467b48Spatrick                                 SmallVectorImpl<RegisterMaskPair> *LiveUses) {
76673471bf0Spatrick   assert(!CurrPos->isDebugOrPseudoInstr());
76709467b48Spatrick 
76809467b48Spatrick   // Boost pressure for all dead defs together.
76909467b48Spatrick   bumpDeadDefs(RegOpers.DeadDefs);
77009467b48Spatrick 
77109467b48Spatrick   // Kill liveness at live defs.
77209467b48Spatrick   // TODO: consider earlyclobbers?
77309467b48Spatrick   for (const RegisterMaskPair &Def : RegOpers.Defs) {
77473471bf0Spatrick     Register Reg = Def.RegUnit;
77509467b48Spatrick 
77609467b48Spatrick     LaneBitmask PreviousMask = LiveRegs.erase(Def);
77709467b48Spatrick     LaneBitmask NewMask = PreviousMask & ~Def.LaneMask;
77809467b48Spatrick 
77909467b48Spatrick     LaneBitmask LiveOut = Def.LaneMask & ~PreviousMask;
78009467b48Spatrick     if (LiveOut.any()) {
78109467b48Spatrick       discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
78209467b48Spatrick       // Retroactively model effects on pressure of the live out lanes.
78309467b48Spatrick       increaseSetPressure(CurrSetPressure, *MRI, Reg, LaneBitmask::getNone(),
78409467b48Spatrick                           LiveOut);
78509467b48Spatrick       PreviousMask = LiveOut;
78609467b48Spatrick     }
78709467b48Spatrick 
78809467b48Spatrick     if (NewMask.none()) {
78909467b48Spatrick       // Add a 0 entry to LiveUses as a marker that the complete vreg has become
79009467b48Spatrick       // dead.
79109467b48Spatrick       if (TrackLaneMasks && LiveUses != nullptr)
79209467b48Spatrick         setRegZero(*LiveUses, Reg);
79309467b48Spatrick     }
79409467b48Spatrick 
79509467b48Spatrick     decreaseRegPressure(Reg, PreviousMask, NewMask);
79609467b48Spatrick   }
79709467b48Spatrick 
79809467b48Spatrick   SlotIndex SlotIdx;
79909467b48Spatrick   if (RequireIntervals)
80009467b48Spatrick     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
80109467b48Spatrick 
80209467b48Spatrick   // Generate liveness for uses.
80309467b48Spatrick   for (const RegisterMaskPair &Use : RegOpers.Uses) {
80473471bf0Spatrick     Register Reg = Use.RegUnit;
80509467b48Spatrick     assert(Use.LaneMask.any());
80609467b48Spatrick     LaneBitmask PreviousMask = LiveRegs.insert(Use);
80709467b48Spatrick     LaneBitmask NewMask = PreviousMask | Use.LaneMask;
80809467b48Spatrick     if (NewMask == PreviousMask)
80909467b48Spatrick       continue;
81009467b48Spatrick 
81109467b48Spatrick     // Did the register just become live?
81209467b48Spatrick     if (PreviousMask.none()) {
81309467b48Spatrick       if (LiveUses != nullptr) {
81409467b48Spatrick         if (!TrackLaneMasks) {
81509467b48Spatrick           addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
81609467b48Spatrick         } else {
81709467b48Spatrick           auto I =
81809467b48Spatrick               llvm::find_if(*LiveUses, [Reg](const RegisterMaskPair Other) {
81909467b48Spatrick                 return Other.RegUnit == Reg;
82009467b48Spatrick               });
82109467b48Spatrick           bool IsRedef = I != LiveUses->end();
82209467b48Spatrick           if (IsRedef) {
82309467b48Spatrick             // ignore re-defs here...
82409467b48Spatrick             assert(I->LaneMask.none());
82509467b48Spatrick             removeRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
82609467b48Spatrick           } else {
82709467b48Spatrick             addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
82809467b48Spatrick           }
82909467b48Spatrick         }
83009467b48Spatrick       }
83109467b48Spatrick 
83209467b48Spatrick       // Discover live outs if this may be the first occurance of this register.
83309467b48Spatrick       if (RequireIntervals) {
83409467b48Spatrick         LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
83509467b48Spatrick         if (LiveOut.any())
83609467b48Spatrick           discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
83709467b48Spatrick       }
83809467b48Spatrick     }
83909467b48Spatrick 
84009467b48Spatrick     increaseRegPressure(Reg, PreviousMask, NewMask);
84109467b48Spatrick   }
84209467b48Spatrick   if (TrackUntiedDefs) {
84309467b48Spatrick     for (const RegisterMaskPair &Def : RegOpers.Defs) {
84473471bf0Spatrick       Register RegUnit = Def.RegUnit;
845*d415bd75Srobert       if (RegUnit.isVirtual() &&
84609467b48Spatrick           (LiveRegs.contains(RegUnit) & Def.LaneMask).none())
84709467b48Spatrick         UntiedDefs.insert(RegUnit);
84809467b48Spatrick     }
84909467b48Spatrick   }
85009467b48Spatrick }
85109467b48Spatrick 
recedeSkipDebugValues()85209467b48Spatrick void RegPressureTracker::recedeSkipDebugValues() {
85309467b48Spatrick   assert(CurrPos != MBB->begin());
85409467b48Spatrick   if (!isBottomClosed())
85509467b48Spatrick     closeBottom();
85609467b48Spatrick 
85709467b48Spatrick   // Open the top of the region using block iterators.
85809467b48Spatrick   if (!RequireIntervals && isTopClosed())
85909467b48Spatrick     static_cast<RegionPressure&>(P).openTop(CurrPos);
86009467b48Spatrick 
86109467b48Spatrick   // Find the previous instruction.
862097a140dSpatrick   CurrPos = prev_nodbg(CurrPos, MBB->begin());
86309467b48Spatrick 
86409467b48Spatrick   SlotIndex SlotIdx;
86573471bf0Spatrick   if (RequireIntervals && !CurrPos->isDebugOrPseudoInstr())
86609467b48Spatrick     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
86709467b48Spatrick 
86809467b48Spatrick   // Open the top of the region using slot indexes.
86909467b48Spatrick   if (RequireIntervals && isTopClosed())
87009467b48Spatrick     static_cast<IntervalPressure&>(P).openTop(SlotIdx);
87109467b48Spatrick }
87209467b48Spatrick 
recede(SmallVectorImpl<RegisterMaskPair> * LiveUses)87309467b48Spatrick void RegPressureTracker::recede(SmallVectorImpl<RegisterMaskPair> *LiveUses) {
87409467b48Spatrick   recedeSkipDebugValues();
87573471bf0Spatrick   if (CurrPos->isDebugInstr() || CurrPos->isPseudoProbe()) {
87673471bf0Spatrick     // It's possible to only have debug_value and pseudo probe instructions and
87773471bf0Spatrick     // hit the start of the block.
87809467b48Spatrick     assert(CurrPos == MBB->begin());
87909467b48Spatrick     return;
88009467b48Spatrick   }
88109467b48Spatrick 
88209467b48Spatrick   const MachineInstr &MI = *CurrPos;
88309467b48Spatrick   RegisterOperands RegOpers;
88409467b48Spatrick   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
88509467b48Spatrick   if (TrackLaneMasks) {
88609467b48Spatrick     SlotIndex SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
88709467b48Spatrick     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
88809467b48Spatrick   } else if (RequireIntervals) {
88909467b48Spatrick     RegOpers.detectDeadDefs(MI, *LIS);
89009467b48Spatrick   }
89109467b48Spatrick 
89209467b48Spatrick   recede(RegOpers, LiveUses);
89309467b48Spatrick }
89409467b48Spatrick 
89509467b48Spatrick /// Advance across the current instruction.
advance(const RegisterOperands & RegOpers)89609467b48Spatrick void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
89709467b48Spatrick   assert(!TrackUntiedDefs && "unsupported mode");
89809467b48Spatrick   assert(CurrPos != MBB->end());
89909467b48Spatrick   if (!isTopClosed())
90009467b48Spatrick     closeTop();
90109467b48Spatrick 
90209467b48Spatrick   SlotIndex SlotIdx;
90309467b48Spatrick   if (RequireIntervals)
90409467b48Spatrick     SlotIdx = getCurrSlot();
90509467b48Spatrick 
90609467b48Spatrick   // Open the bottom of the region using slot indexes.
90709467b48Spatrick   if (isBottomClosed()) {
90809467b48Spatrick     if (RequireIntervals)
90909467b48Spatrick       static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
91009467b48Spatrick     else
91109467b48Spatrick       static_cast<RegionPressure&>(P).openBottom(CurrPos);
91209467b48Spatrick   }
91309467b48Spatrick 
91409467b48Spatrick   for (const RegisterMaskPair &Use : RegOpers.Uses) {
91573471bf0Spatrick     Register Reg = Use.RegUnit;
91609467b48Spatrick     LaneBitmask LiveMask = LiveRegs.contains(Reg);
91709467b48Spatrick     LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
91809467b48Spatrick     if (LiveIn.any()) {
91909467b48Spatrick       discoverLiveIn(RegisterMaskPair(Reg, LiveIn));
92009467b48Spatrick       increaseRegPressure(Reg, LiveMask, LiveMask | LiveIn);
92109467b48Spatrick       LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
92209467b48Spatrick     }
92309467b48Spatrick     // Kill liveness at last uses.
92409467b48Spatrick     if (RequireIntervals) {
92509467b48Spatrick       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
92609467b48Spatrick       if (LastUseMask.any()) {
92709467b48Spatrick         LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
92809467b48Spatrick         decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
92909467b48Spatrick       }
93009467b48Spatrick     }
93109467b48Spatrick   }
93209467b48Spatrick 
93309467b48Spatrick   // Generate liveness for defs.
93409467b48Spatrick   for (const RegisterMaskPair &Def : RegOpers.Defs) {
93509467b48Spatrick     LaneBitmask PreviousMask = LiveRegs.insert(Def);
93609467b48Spatrick     LaneBitmask NewMask = PreviousMask | Def.LaneMask;
93709467b48Spatrick     increaseRegPressure(Def.RegUnit, PreviousMask, NewMask);
93809467b48Spatrick   }
93909467b48Spatrick 
94009467b48Spatrick   // Boost pressure for all dead defs together.
94109467b48Spatrick   bumpDeadDefs(RegOpers.DeadDefs);
94209467b48Spatrick 
94309467b48Spatrick   // Find the next instruction.
944097a140dSpatrick   CurrPos = next_nodbg(CurrPos, MBB->end());
94509467b48Spatrick }
94609467b48Spatrick 
advance()94709467b48Spatrick void RegPressureTracker::advance() {
94809467b48Spatrick   const MachineInstr &MI = *CurrPos;
94909467b48Spatrick   RegisterOperands RegOpers;
95009467b48Spatrick   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
95109467b48Spatrick   if (TrackLaneMasks) {
95209467b48Spatrick     SlotIndex SlotIdx = getCurrSlot();
95309467b48Spatrick     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
95409467b48Spatrick   }
95509467b48Spatrick   advance(RegOpers);
95609467b48Spatrick }
95709467b48Spatrick 
95809467b48Spatrick /// Find the max change in excess pressure across all sets.
computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,ArrayRef<unsigned> NewPressureVec,RegPressureDelta & Delta,const RegisterClassInfo * RCI,ArrayRef<unsigned> LiveThruPressureVec)95909467b48Spatrick static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
96009467b48Spatrick                                        ArrayRef<unsigned> NewPressureVec,
96109467b48Spatrick                                        RegPressureDelta &Delta,
96209467b48Spatrick                                        const RegisterClassInfo *RCI,
96309467b48Spatrick                                        ArrayRef<unsigned> LiveThruPressureVec) {
96409467b48Spatrick   Delta.Excess = PressureChange();
96509467b48Spatrick   for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
96609467b48Spatrick     unsigned POld = OldPressureVec[i];
96709467b48Spatrick     unsigned PNew = NewPressureVec[i];
96809467b48Spatrick     int PDiff = (int)PNew - (int)POld;
96909467b48Spatrick     if (!PDiff) // No change in this set in the common case.
97009467b48Spatrick       continue;
97109467b48Spatrick     // Only consider change beyond the limit.
97209467b48Spatrick     unsigned Limit = RCI->getRegPressureSetLimit(i);
97309467b48Spatrick     if (!LiveThruPressureVec.empty())
97409467b48Spatrick       Limit += LiveThruPressureVec[i];
97509467b48Spatrick 
97609467b48Spatrick     if (Limit > POld) {
97709467b48Spatrick       if (Limit > PNew)
97809467b48Spatrick         PDiff = 0;            // Under the limit
97909467b48Spatrick       else
98009467b48Spatrick         PDiff = PNew - Limit; // Just exceeded limit.
98109467b48Spatrick     } else if (Limit > PNew)
98209467b48Spatrick       PDiff = Limit - POld;   // Just obeyed limit.
98309467b48Spatrick 
98409467b48Spatrick     if (PDiff) {
98509467b48Spatrick       Delta.Excess = PressureChange(i);
98609467b48Spatrick       Delta.Excess.setUnitInc(PDiff);
98709467b48Spatrick       break;
98809467b48Spatrick     }
98909467b48Spatrick   }
99009467b48Spatrick }
99109467b48Spatrick 
99209467b48Spatrick /// Find the max change in max pressure that either surpasses a critical PSet
99309467b48Spatrick /// limit or exceeds the current MaxPressureLimit.
99409467b48Spatrick ///
99509467b48Spatrick /// FIXME: comparing each element of the old and new MaxPressure vectors here is
99609467b48Spatrick /// silly. It's done now to demonstrate the concept but will go away with a
99709467b48Spatrick /// RegPressureTracker API change to work with pressure differences.
computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,ArrayRef<unsigned> NewMaxPressureVec,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit,RegPressureDelta & Delta)99809467b48Spatrick static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
99909467b48Spatrick                                     ArrayRef<unsigned> NewMaxPressureVec,
100009467b48Spatrick                                     ArrayRef<PressureChange> CriticalPSets,
100109467b48Spatrick                                     ArrayRef<unsigned> MaxPressureLimit,
100209467b48Spatrick                                     RegPressureDelta &Delta) {
100309467b48Spatrick   Delta.CriticalMax = PressureChange();
100409467b48Spatrick   Delta.CurrentMax = PressureChange();
100509467b48Spatrick 
100609467b48Spatrick   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
100709467b48Spatrick   for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
100809467b48Spatrick     unsigned POld = OldMaxPressureVec[i];
100909467b48Spatrick     unsigned PNew = NewMaxPressureVec[i];
101009467b48Spatrick     if (PNew == POld) // No change in this set in the common case.
101109467b48Spatrick       continue;
101209467b48Spatrick 
101309467b48Spatrick     if (!Delta.CriticalMax.isValid()) {
101409467b48Spatrick       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < i)
101509467b48Spatrick         ++CritIdx;
101609467b48Spatrick 
101709467b48Spatrick       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == i) {
101809467b48Spatrick         int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].getUnitInc();
101909467b48Spatrick         if (PDiff > 0) {
102009467b48Spatrick           Delta.CriticalMax = PressureChange(i);
102109467b48Spatrick           Delta.CriticalMax.setUnitInc(PDiff);
102209467b48Spatrick         }
102309467b48Spatrick       }
102409467b48Spatrick     }
102509467b48Spatrick     // Find the first increase above MaxPressureLimit.
102609467b48Spatrick     // (Ignores negative MDiff).
102709467b48Spatrick     if (!Delta.CurrentMax.isValid() && PNew > MaxPressureLimit[i]) {
102809467b48Spatrick       Delta.CurrentMax = PressureChange(i);
102909467b48Spatrick       Delta.CurrentMax.setUnitInc(PNew - POld);
103009467b48Spatrick       if (CritIdx == CritEnd || Delta.CriticalMax.isValid())
103109467b48Spatrick         break;
103209467b48Spatrick     }
103309467b48Spatrick   }
103409467b48Spatrick }
103509467b48Spatrick 
103609467b48Spatrick /// Record the upward impact of a single instruction on current register
103709467b48Spatrick /// pressure. Unlike the advance/recede pressure tracking interface, this does
103809467b48Spatrick /// not discover live in/outs.
103909467b48Spatrick ///
104009467b48Spatrick /// This is intended for speculative queries. It leaves pressure inconsistent
104109467b48Spatrick /// with the current position, so must be restored by the caller.
bumpUpwardPressure(const MachineInstr * MI)104209467b48Spatrick void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
104373471bf0Spatrick   assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
104409467b48Spatrick 
104509467b48Spatrick   SlotIndex SlotIdx;
104609467b48Spatrick   if (RequireIntervals)
104709467b48Spatrick     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
104809467b48Spatrick 
104909467b48Spatrick   // Account for register pressure similar to RegPressureTracker::recede().
105009467b48Spatrick   RegisterOperands RegOpers;
105109467b48Spatrick   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/true);
105209467b48Spatrick   assert(RegOpers.DeadDefs.size() == 0);
105309467b48Spatrick   if (TrackLaneMasks)
105409467b48Spatrick     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
105509467b48Spatrick   else if (RequireIntervals)
105609467b48Spatrick     RegOpers.detectDeadDefs(*MI, *LIS);
105709467b48Spatrick 
105809467b48Spatrick   // Boost max pressure for all dead defs together.
105909467b48Spatrick   // Since CurrSetPressure and MaxSetPressure
106009467b48Spatrick   bumpDeadDefs(RegOpers.DeadDefs);
106109467b48Spatrick 
106209467b48Spatrick   // Kill liveness at live defs.
106309467b48Spatrick   for (const RegisterMaskPair &P : RegOpers.Defs) {
106473471bf0Spatrick     Register Reg = P.RegUnit;
106509467b48Spatrick     LaneBitmask LiveLanes = LiveRegs.contains(Reg);
106609467b48Spatrick     LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg);
106709467b48Spatrick     LaneBitmask DefLanes = P.LaneMask;
106809467b48Spatrick     LaneBitmask LiveAfter = (LiveLanes & ~DefLanes) | UseLanes;
106909467b48Spatrick     decreaseRegPressure(Reg, LiveLanes, LiveAfter);
107009467b48Spatrick   }
107109467b48Spatrick   // Generate liveness for uses.
107209467b48Spatrick   for (const RegisterMaskPair &P : RegOpers.Uses) {
107373471bf0Spatrick     Register Reg = P.RegUnit;
107409467b48Spatrick     LaneBitmask LiveLanes = LiveRegs.contains(Reg);
107509467b48Spatrick     LaneBitmask LiveAfter = LiveLanes | P.LaneMask;
107609467b48Spatrick     increaseRegPressure(Reg, LiveLanes, LiveAfter);
107709467b48Spatrick   }
107809467b48Spatrick }
107909467b48Spatrick 
108009467b48Spatrick /// Consider the pressure increase caused by traversing this instruction
108109467b48Spatrick /// bottom-up. Find the pressure set with the most change beyond its pressure
108209467b48Spatrick /// limit based on the tracker's current pressure, and return the change in
108309467b48Spatrick /// number of register units of that pressure set introduced by this
108409467b48Spatrick /// instruction.
108509467b48Spatrick ///
108609467b48Spatrick /// This assumes that the current LiveOut set is sufficient.
108709467b48Spatrick ///
108809467b48Spatrick /// This is expensive for an on-the-fly query because it calls
108909467b48Spatrick /// bumpUpwardPressure to recompute the pressure sets based on current
109009467b48Spatrick /// liveness. This mainly exists to verify correctness, e.g. with
109109467b48Spatrick /// -verify-misched. getUpwardPressureDelta is the fast version of this query
109209467b48Spatrick /// that uses the per-SUnit cache of the PressureDiff.
109309467b48Spatrick void RegPressureTracker::
getMaxUpwardPressureDelta(const MachineInstr * MI,PressureDiff * PDiff,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit)109409467b48Spatrick getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
109509467b48Spatrick                           RegPressureDelta &Delta,
109609467b48Spatrick                           ArrayRef<PressureChange> CriticalPSets,
109709467b48Spatrick                           ArrayRef<unsigned> MaxPressureLimit) {
109809467b48Spatrick   // Snapshot Pressure.
109909467b48Spatrick   // FIXME: The snapshot heap space should persist. But I'm planning to
110009467b48Spatrick   // summarize the pressure effect so we don't need to snapshot at all.
110109467b48Spatrick   std::vector<unsigned> SavedPressure = CurrSetPressure;
110209467b48Spatrick   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
110309467b48Spatrick 
110409467b48Spatrick   bumpUpwardPressure(MI);
110509467b48Spatrick 
110609467b48Spatrick   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
110709467b48Spatrick                              LiveThruPressure);
110809467b48Spatrick   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
110909467b48Spatrick                           MaxPressureLimit, Delta);
111009467b48Spatrick   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
111109467b48Spatrick          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
111209467b48Spatrick 
111309467b48Spatrick   // Restore the tracker's state.
111409467b48Spatrick   P.MaxSetPressure.swap(SavedMaxPressure);
111509467b48Spatrick   CurrSetPressure.swap(SavedPressure);
111609467b48Spatrick 
111709467b48Spatrick #ifndef NDEBUG
111809467b48Spatrick   if (!PDiff)
111909467b48Spatrick     return;
112009467b48Spatrick 
112109467b48Spatrick   // Check if the alternate algorithm yields the same result.
112209467b48Spatrick   RegPressureDelta Delta2;
112309467b48Spatrick   getUpwardPressureDelta(MI, *PDiff, Delta2, CriticalPSets, MaxPressureLimit);
112409467b48Spatrick   if (Delta != Delta2) {
112509467b48Spatrick     dbgs() << "PDiff: ";
112609467b48Spatrick     PDiff->dump(*TRI);
112709467b48Spatrick     dbgs() << "DELTA: " << *MI;
112809467b48Spatrick     if (Delta.Excess.isValid())
112909467b48Spatrick       dbgs() << "Excess1 " << TRI->getRegPressureSetName(Delta.Excess.getPSet())
113009467b48Spatrick              << " " << Delta.Excess.getUnitInc() << "\n";
113109467b48Spatrick     if (Delta.CriticalMax.isValid())
113209467b48Spatrick       dbgs() << "Critic1 " << TRI->getRegPressureSetName(Delta.CriticalMax.getPSet())
113309467b48Spatrick              << " " << Delta.CriticalMax.getUnitInc() << "\n";
113409467b48Spatrick     if (Delta.CurrentMax.isValid())
113509467b48Spatrick       dbgs() << "CurrMx1 " << TRI->getRegPressureSetName(Delta.CurrentMax.getPSet())
113609467b48Spatrick              << " " << Delta.CurrentMax.getUnitInc() << "\n";
113709467b48Spatrick     if (Delta2.Excess.isValid())
113809467b48Spatrick       dbgs() << "Excess2 " << TRI->getRegPressureSetName(Delta2.Excess.getPSet())
113909467b48Spatrick              << " " << Delta2.Excess.getUnitInc() << "\n";
114009467b48Spatrick     if (Delta2.CriticalMax.isValid())
114109467b48Spatrick       dbgs() << "Critic2 " << TRI->getRegPressureSetName(Delta2.CriticalMax.getPSet())
114209467b48Spatrick              << " " << Delta2.CriticalMax.getUnitInc() << "\n";
114309467b48Spatrick     if (Delta2.CurrentMax.isValid())
114409467b48Spatrick       dbgs() << "CurrMx2 " << TRI->getRegPressureSetName(Delta2.CurrentMax.getPSet())
114509467b48Spatrick              << " " << Delta2.CurrentMax.getUnitInc() << "\n";
114609467b48Spatrick     llvm_unreachable("RegP Delta Mismatch");
114709467b48Spatrick   }
114809467b48Spatrick #endif
114909467b48Spatrick }
115009467b48Spatrick 
115109467b48Spatrick /// This is the fast version of querying register pressure that does not
115209467b48Spatrick /// directly depend on current liveness.
115309467b48Spatrick ///
115409467b48Spatrick /// @param Delta captures information needed for heuristics.
115509467b48Spatrick ///
115609467b48Spatrick /// @param CriticalPSets Are the pressure sets that are known to exceed some
115709467b48Spatrick /// limit within the region, not necessarily at the current position.
115809467b48Spatrick ///
115909467b48Spatrick /// @param MaxPressureLimit Is the max pressure within the region, not
116009467b48Spatrick /// necessarily at the current position.
116109467b48Spatrick void RegPressureTracker::
getUpwardPressureDelta(const MachineInstr * MI,PressureDiff & PDiff,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit) const116209467b48Spatrick getUpwardPressureDelta(const MachineInstr *MI, /*const*/ PressureDiff &PDiff,
116309467b48Spatrick                        RegPressureDelta &Delta,
116409467b48Spatrick                        ArrayRef<PressureChange> CriticalPSets,
116509467b48Spatrick                        ArrayRef<unsigned> MaxPressureLimit) const {
116609467b48Spatrick   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
116709467b48Spatrick   for (PressureDiff::const_iterator
116809467b48Spatrick          PDiffI = PDiff.begin(), PDiffE = PDiff.end();
116909467b48Spatrick        PDiffI != PDiffE && PDiffI->isValid(); ++PDiffI) {
117009467b48Spatrick 
117109467b48Spatrick     unsigned PSetID = PDiffI->getPSet();
117209467b48Spatrick     unsigned Limit = RCI->getRegPressureSetLimit(PSetID);
117309467b48Spatrick     if (!LiveThruPressure.empty())
117409467b48Spatrick       Limit += LiveThruPressure[PSetID];
117509467b48Spatrick 
117609467b48Spatrick     unsigned POld = CurrSetPressure[PSetID];
117709467b48Spatrick     unsigned MOld = P.MaxSetPressure[PSetID];
117809467b48Spatrick     unsigned MNew = MOld;
117909467b48Spatrick     // Ignore DeadDefs here because they aren't captured by PressureChange.
118009467b48Spatrick     unsigned PNew = POld + PDiffI->getUnitInc();
118109467b48Spatrick     assert((PDiffI->getUnitInc() >= 0) == (PNew >= POld)
118209467b48Spatrick            && "PSet overflow/underflow");
118309467b48Spatrick     if (PNew > MOld)
118409467b48Spatrick       MNew = PNew;
118509467b48Spatrick     // Check if current pressure has exceeded the limit.
118609467b48Spatrick     if (!Delta.Excess.isValid()) {
118709467b48Spatrick       unsigned ExcessInc = 0;
118809467b48Spatrick       if (PNew > Limit)
118909467b48Spatrick         ExcessInc = POld > Limit ? PNew - POld : PNew - Limit;
119009467b48Spatrick       else if (POld > Limit)
119109467b48Spatrick         ExcessInc = Limit - POld;
119209467b48Spatrick       if (ExcessInc) {
119309467b48Spatrick         Delta.Excess = PressureChange(PSetID);
119409467b48Spatrick         Delta.Excess.setUnitInc(ExcessInc);
119509467b48Spatrick       }
119609467b48Spatrick     }
119709467b48Spatrick     // Check if max pressure has exceeded a critical pressure set max.
119809467b48Spatrick     if (MNew == MOld)
119909467b48Spatrick       continue;
120009467b48Spatrick     if (!Delta.CriticalMax.isValid()) {
120109467b48Spatrick       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < PSetID)
120209467b48Spatrick         ++CritIdx;
120309467b48Spatrick 
120409467b48Spatrick       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == PSetID) {
120509467b48Spatrick         int CritInc = (int)MNew - (int)CriticalPSets[CritIdx].getUnitInc();
120609467b48Spatrick         if (CritInc > 0 && CritInc <= std::numeric_limits<int16_t>::max()) {
120709467b48Spatrick           Delta.CriticalMax = PressureChange(PSetID);
120809467b48Spatrick           Delta.CriticalMax.setUnitInc(CritInc);
120909467b48Spatrick         }
121009467b48Spatrick       }
121109467b48Spatrick     }
121209467b48Spatrick     // Check if max pressure has exceeded the current max.
121309467b48Spatrick     if (!Delta.CurrentMax.isValid() && MNew > MaxPressureLimit[PSetID]) {
121409467b48Spatrick       Delta.CurrentMax = PressureChange(PSetID);
121509467b48Spatrick       Delta.CurrentMax.setUnitInc(MNew - MOld);
121609467b48Spatrick     }
121709467b48Spatrick   }
121809467b48Spatrick }
121909467b48Spatrick 
122009467b48Spatrick /// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
122109467b48Spatrick /// The query starts with a lane bitmask which gets lanes/bits removed for every
122209467b48Spatrick /// use we find.
findUseBetween(unsigned Reg,LaneBitmask LastUseMask,SlotIndex PriorUseIdx,SlotIndex NextUseIdx,const MachineRegisterInfo & MRI,const LiveIntervals * LIS)122309467b48Spatrick static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
122409467b48Spatrick                                   SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
122509467b48Spatrick                                   const MachineRegisterInfo &MRI,
122609467b48Spatrick                                   const LiveIntervals *LIS) {
122709467b48Spatrick   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
122809467b48Spatrick   for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
122909467b48Spatrick     if (MO.isUndef())
123009467b48Spatrick       continue;
123109467b48Spatrick     const MachineInstr *MI = MO.getParent();
123209467b48Spatrick     SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
123309467b48Spatrick     if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx) {
123409467b48Spatrick       unsigned SubRegIdx = MO.getSubReg();
123509467b48Spatrick       LaneBitmask UseMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
123609467b48Spatrick       LastUseMask &= ~UseMask;
123709467b48Spatrick       if (LastUseMask.none())
123809467b48Spatrick         return LaneBitmask::getNone();
123909467b48Spatrick     }
124009467b48Spatrick   }
124109467b48Spatrick   return LastUseMask;
124209467b48Spatrick }
124309467b48Spatrick 
getLiveLanesAt(Register RegUnit,SlotIndex Pos) const124473471bf0Spatrick LaneBitmask RegPressureTracker::getLiveLanesAt(Register RegUnit,
124509467b48Spatrick                                                SlotIndex Pos) const {
124609467b48Spatrick   assert(RequireIntervals);
124709467b48Spatrick   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
124809467b48Spatrick                               LaneBitmask::getAll(),
124909467b48Spatrick       [](const LiveRange &LR, SlotIndex Pos) {
125009467b48Spatrick         return LR.liveAt(Pos);
125109467b48Spatrick       });
125209467b48Spatrick }
125309467b48Spatrick 
getLastUsedLanes(Register RegUnit,SlotIndex Pos) const125473471bf0Spatrick LaneBitmask RegPressureTracker::getLastUsedLanes(Register RegUnit,
125509467b48Spatrick                                                  SlotIndex Pos) const {
125609467b48Spatrick   assert(RequireIntervals);
125709467b48Spatrick   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
125809467b48Spatrick                               Pos.getBaseIndex(), LaneBitmask::getNone(),
125909467b48Spatrick       [](const LiveRange &LR, SlotIndex Pos) {
126009467b48Spatrick         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
126109467b48Spatrick         return S != nullptr && S->end == Pos.getRegSlot();
126209467b48Spatrick       });
126309467b48Spatrick }
126409467b48Spatrick 
getLiveThroughAt(Register RegUnit,SlotIndex Pos) const126573471bf0Spatrick LaneBitmask RegPressureTracker::getLiveThroughAt(Register RegUnit,
126609467b48Spatrick                                                  SlotIndex Pos) const {
126709467b48Spatrick   assert(RequireIntervals);
126809467b48Spatrick   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
126909467b48Spatrick                               LaneBitmask::getNone(),
127009467b48Spatrick       [](const LiveRange &LR, SlotIndex Pos) {
127109467b48Spatrick         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
127209467b48Spatrick         return S != nullptr && S->start < Pos.getRegSlot(true) &&
127309467b48Spatrick                S->end != Pos.getDeadSlot();
127409467b48Spatrick       });
127509467b48Spatrick }
127609467b48Spatrick 
127709467b48Spatrick /// Record the downward impact of a single instruction on current register
127809467b48Spatrick /// pressure. Unlike the advance/recede pressure tracking interface, this does
127909467b48Spatrick /// not discover live in/outs.
128009467b48Spatrick ///
128109467b48Spatrick /// This is intended for speculative queries. It leaves pressure inconsistent
128209467b48Spatrick /// with the current position, so must be restored by the caller.
bumpDownwardPressure(const MachineInstr * MI)128309467b48Spatrick void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
128473471bf0Spatrick   assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
128509467b48Spatrick 
128609467b48Spatrick   SlotIndex SlotIdx;
128709467b48Spatrick   if (RequireIntervals)
128809467b48Spatrick     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
128909467b48Spatrick 
129009467b48Spatrick   // Account for register pressure similar to RegPressureTracker::recede().
129109467b48Spatrick   RegisterOperands RegOpers;
129209467b48Spatrick   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, false);
129309467b48Spatrick   if (TrackLaneMasks)
129409467b48Spatrick     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
129509467b48Spatrick 
129609467b48Spatrick   if (RequireIntervals) {
129709467b48Spatrick     for (const RegisterMaskPair &Use : RegOpers.Uses) {
129873471bf0Spatrick       Register Reg = Use.RegUnit;
129909467b48Spatrick       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
130009467b48Spatrick       if (LastUseMask.none())
130109467b48Spatrick         continue;
130209467b48Spatrick       // The LastUseMask is queried from the liveness information of instruction
130309467b48Spatrick       // which may be further down the schedule. Some lanes may actually not be
130409467b48Spatrick       // last uses for the current position.
130509467b48Spatrick       // FIXME: allow the caller to pass in the list of vreg uses that remain
130609467b48Spatrick       // to be bottom-scheduled to avoid searching uses at each query.
130709467b48Spatrick       SlotIndex CurrIdx = getCurrSlot();
130809467b48Spatrick       LastUseMask
130909467b48Spatrick         = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
131009467b48Spatrick       if (LastUseMask.none())
131109467b48Spatrick         continue;
131209467b48Spatrick 
131309467b48Spatrick       LaneBitmask LiveMask = LiveRegs.contains(Reg);
131409467b48Spatrick       LaneBitmask NewMask = LiveMask & ~LastUseMask;
131509467b48Spatrick       decreaseRegPressure(Reg, LiveMask, NewMask);
131609467b48Spatrick     }
131709467b48Spatrick   }
131809467b48Spatrick 
131909467b48Spatrick   // Generate liveness for defs.
132009467b48Spatrick   for (const RegisterMaskPair &Def : RegOpers.Defs) {
132173471bf0Spatrick     Register Reg = Def.RegUnit;
132209467b48Spatrick     LaneBitmask LiveMask = LiveRegs.contains(Reg);
132309467b48Spatrick     LaneBitmask NewMask = LiveMask | Def.LaneMask;
132409467b48Spatrick     increaseRegPressure(Reg, LiveMask, NewMask);
132509467b48Spatrick   }
132609467b48Spatrick 
132709467b48Spatrick   // Boost pressure for all dead defs together.
132809467b48Spatrick   bumpDeadDefs(RegOpers.DeadDefs);
132909467b48Spatrick }
133009467b48Spatrick 
133109467b48Spatrick /// Consider the pressure increase caused by traversing this instruction
133209467b48Spatrick /// top-down. Find the register class with the most change in its pressure limit
133309467b48Spatrick /// based on the tracker's current pressure, and return the number of excess
133409467b48Spatrick /// register units of that pressure set introduced by this instruction.
133509467b48Spatrick ///
133609467b48Spatrick /// This assumes that the current LiveIn set is sufficient.
133709467b48Spatrick ///
133809467b48Spatrick /// This is expensive for an on-the-fly query because it calls
133909467b48Spatrick /// bumpDownwardPressure to recompute the pressure sets based on current
134009467b48Spatrick /// liveness. We don't yet have a fast version of downward pressure tracking
134109467b48Spatrick /// analogous to getUpwardPressureDelta.
134209467b48Spatrick void RegPressureTracker::
getMaxDownwardPressureDelta(const MachineInstr * MI,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit)134309467b48Spatrick getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
134409467b48Spatrick                             ArrayRef<PressureChange> CriticalPSets,
134509467b48Spatrick                             ArrayRef<unsigned> MaxPressureLimit) {
134609467b48Spatrick   // Snapshot Pressure.
134709467b48Spatrick   std::vector<unsigned> SavedPressure = CurrSetPressure;
134809467b48Spatrick   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
134909467b48Spatrick 
135009467b48Spatrick   bumpDownwardPressure(MI);
135109467b48Spatrick 
135209467b48Spatrick   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
135309467b48Spatrick                              LiveThruPressure);
135409467b48Spatrick   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
135509467b48Spatrick                           MaxPressureLimit, Delta);
135609467b48Spatrick   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
135709467b48Spatrick          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
135809467b48Spatrick 
135909467b48Spatrick   // Restore the tracker's state.
136009467b48Spatrick   P.MaxSetPressure.swap(SavedMaxPressure);
136109467b48Spatrick   CurrSetPressure.swap(SavedPressure);
136209467b48Spatrick }
136309467b48Spatrick 
136409467b48Spatrick /// Get the pressure of each PSet after traversing this instruction bottom-up.
136509467b48Spatrick void RegPressureTracker::
getUpwardPressure(const MachineInstr * MI,std::vector<unsigned> & PressureResult,std::vector<unsigned> & MaxPressureResult)136609467b48Spatrick getUpwardPressure(const MachineInstr *MI,
136709467b48Spatrick                   std::vector<unsigned> &PressureResult,
136809467b48Spatrick                   std::vector<unsigned> &MaxPressureResult) {
136909467b48Spatrick   // Snapshot pressure.
137009467b48Spatrick   PressureResult = CurrSetPressure;
137109467b48Spatrick   MaxPressureResult = P.MaxSetPressure;
137209467b48Spatrick 
137309467b48Spatrick   bumpUpwardPressure(MI);
137409467b48Spatrick 
137509467b48Spatrick   // Current pressure becomes the result. Restore current pressure.
137609467b48Spatrick   P.MaxSetPressure.swap(MaxPressureResult);
137709467b48Spatrick   CurrSetPressure.swap(PressureResult);
137809467b48Spatrick }
137909467b48Spatrick 
138009467b48Spatrick /// Get the pressure of each PSet after traversing this instruction top-down.
138109467b48Spatrick void RegPressureTracker::
getDownwardPressure(const MachineInstr * MI,std::vector<unsigned> & PressureResult,std::vector<unsigned> & MaxPressureResult)138209467b48Spatrick getDownwardPressure(const MachineInstr *MI,
138309467b48Spatrick                     std::vector<unsigned> &PressureResult,
138409467b48Spatrick                     std::vector<unsigned> &MaxPressureResult) {
138509467b48Spatrick   // Snapshot pressure.
138609467b48Spatrick   PressureResult = CurrSetPressure;
138709467b48Spatrick   MaxPressureResult = P.MaxSetPressure;
138809467b48Spatrick 
138909467b48Spatrick   bumpDownwardPressure(MI);
139009467b48Spatrick 
139109467b48Spatrick   // Current pressure becomes the result. Restore current pressure.
139209467b48Spatrick   P.MaxSetPressure.swap(MaxPressureResult);
139309467b48Spatrick   CurrSetPressure.swap(PressureResult);
139409467b48Spatrick }
1395