xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegisterPressure.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- RegisterPressure.cpp - Dynamic Register Pressure -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the RegisterPressure class which can be used to track
100b57cec5SDimitry Andric // MachineInstr level register pressure.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterPressure.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
300b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
310b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h"
320b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
330b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
340b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
370b57cec5SDimitry Andric #include <algorithm>
380b57cec5SDimitry Andric #include <cassert>
390b57cec5SDimitry Andric #include <cstdint>
400b57cec5SDimitry Andric #include <cstdlib>
410b57cec5SDimitry Andric #include <cstring>
420b57cec5SDimitry Andric #include <iterator>
430b57cec5SDimitry Andric #include <limits>
440b57cec5SDimitry Andric #include <utility>
450b57cec5SDimitry Andric #include <vector>
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric using namespace llvm;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric /// Increase pressure for each pressure set provided by TargetRegisterInfo.
500b57cec5SDimitry Andric static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
510b57cec5SDimitry Andric                                 const MachineRegisterInfo &MRI, unsigned Reg,
520b57cec5SDimitry Andric                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
530b57cec5SDimitry Andric   assert((PrevMask & ~NewMask).none() && "Must not remove bits");
540b57cec5SDimitry Andric   if (PrevMask.any() || NewMask.none())
550b57cec5SDimitry Andric     return;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   PSetIterator PSetI = MRI.getPressureSets(Reg);
580b57cec5SDimitry Andric   unsigned Weight = PSetI.getWeight();
590b57cec5SDimitry Andric   for (; PSetI.isValid(); ++PSetI)
600b57cec5SDimitry Andric     CurrSetPressure[*PSetI] += Weight;
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric /// Decrease pressure for each pressure set provided by TargetRegisterInfo.
640b57cec5SDimitry Andric static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
65e8d8bef9SDimitry Andric                                 const MachineRegisterInfo &MRI, Register Reg,
660b57cec5SDimitry Andric                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
67*0fca6ea1SDimitry Andric   assert((NewMask & ~PrevMask).none() && "Must not add bits");
680b57cec5SDimitry Andric   if (NewMask.any() || PrevMask.none())
690b57cec5SDimitry Andric     return;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   PSetIterator PSetI = MRI.getPressureSets(Reg);
720b57cec5SDimitry Andric   unsigned Weight = PSetI.getWeight();
730b57cec5SDimitry Andric   for (; PSetI.isValid(); ++PSetI) {
740b57cec5SDimitry Andric     assert(CurrSetPressure[*PSetI] >= Weight && "register pressure underflow");
750b57cec5SDimitry Andric     CurrSetPressure[*PSetI] -= Weight;
760b57cec5SDimitry Andric   }
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
800b57cec5SDimitry Andric LLVM_DUMP_METHOD
810b57cec5SDimitry Andric void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
820b57cec5SDimitry Andric                               const TargetRegisterInfo *TRI) {
830b57cec5SDimitry Andric   bool Empty = true;
840b57cec5SDimitry Andric   for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) {
850b57cec5SDimitry Andric     if (SetPressure[i] != 0) {
860b57cec5SDimitry Andric       dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n';
870b57cec5SDimitry Andric       Empty = false;
880b57cec5SDimitry Andric     }
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric   if (Empty)
910b57cec5SDimitry Andric     dbgs() << "\n";
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric LLVM_DUMP_METHOD
950b57cec5SDimitry Andric void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
960b57cec5SDimitry Andric   dbgs() << "Max Pressure: ";
970b57cec5SDimitry Andric   dumpRegSetPressure(MaxSetPressure, TRI);
980b57cec5SDimitry Andric   dbgs() << "Live In: ";
990b57cec5SDimitry Andric   for (const RegisterMaskPair &P : LiveInRegs) {
1000b57cec5SDimitry Andric     dbgs() << printVRegOrUnit(P.RegUnit, TRI);
1010b57cec5SDimitry Andric     if (!P.LaneMask.all())
1020b57cec5SDimitry Andric       dbgs() << ':' << PrintLaneMask(P.LaneMask);
1030b57cec5SDimitry Andric     dbgs() << ' ';
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   dbgs() << '\n';
1060b57cec5SDimitry Andric   dbgs() << "Live Out: ";
1070b57cec5SDimitry Andric   for (const RegisterMaskPair &P : LiveOutRegs) {
1080b57cec5SDimitry Andric     dbgs() << printVRegOrUnit(P.RegUnit, TRI);
1090b57cec5SDimitry Andric     if (!P.LaneMask.all())
1100b57cec5SDimitry Andric       dbgs() << ':' << PrintLaneMask(P.LaneMask);
1110b57cec5SDimitry Andric     dbgs() << ' ';
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric   dbgs() << '\n';
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric LLVM_DUMP_METHOD
1170b57cec5SDimitry Andric void RegPressureTracker::dump() const {
1180b57cec5SDimitry Andric   if (!isTopClosed() || !isBottomClosed()) {
1190b57cec5SDimitry Andric     dbgs() << "Curr Pressure: ";
1200b57cec5SDimitry Andric     dumpRegSetPressure(CurrSetPressure, TRI);
1210b57cec5SDimitry Andric   }
1220b57cec5SDimitry Andric   P.dump(TRI);
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric LLVM_DUMP_METHOD
1260b57cec5SDimitry Andric void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
1270b57cec5SDimitry Andric   const char *sep = "";
1280b57cec5SDimitry Andric   for (const PressureChange &Change : *this) {
1290b57cec5SDimitry Andric     if (!Change.isValid())
1300b57cec5SDimitry Andric       break;
1310b57cec5SDimitry Andric     dbgs() << sep << TRI.getRegPressureSetName(Change.getPSet())
1320b57cec5SDimitry Andric            << " " << Change.getUnitInc();
1330b57cec5SDimitry Andric     sep = "    ";
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric   dbgs() << '\n';
1360b57cec5SDimitry Andric }
1378bcb0991SDimitry Andric 
1388bcb0991SDimitry Andric LLVM_DUMP_METHOD
1398bcb0991SDimitry Andric void PressureChange::dump() const {
1408bcb0991SDimitry Andric   dbgs() << "[" << getPSetOrMax() << ", " << getUnitInc() << "]\n";
1418bcb0991SDimitry Andric }
1428bcb0991SDimitry Andric 
1438bcb0991SDimitry Andric void RegPressureDelta::dump() const {
1448bcb0991SDimitry Andric   dbgs() << "[Excess=";
1458bcb0991SDimitry Andric   Excess.dump();
1468bcb0991SDimitry Andric   dbgs() << ", CriticalMax=";
1478bcb0991SDimitry Andric   CriticalMax.dump();
1488bcb0991SDimitry Andric   dbgs() << ", CurrentMax=";
1498bcb0991SDimitry Andric   CurrentMax.dump();
1508bcb0991SDimitry Andric   dbgs() << "]\n";
1518bcb0991SDimitry Andric }
1528bcb0991SDimitry Andric 
1530b57cec5SDimitry Andric #endif
1540b57cec5SDimitry Andric 
155e8d8bef9SDimitry Andric void RegPressureTracker::increaseRegPressure(Register RegUnit,
1560b57cec5SDimitry Andric                                              LaneBitmask PreviousMask,
1570b57cec5SDimitry Andric                                              LaneBitmask NewMask) {
1580b57cec5SDimitry Andric   if (PreviousMask.any() || NewMask.none())
1590b57cec5SDimitry Andric     return;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
1620b57cec5SDimitry Andric   unsigned Weight = PSetI.getWeight();
1630b57cec5SDimitry Andric   for (; PSetI.isValid(); ++PSetI) {
1640b57cec5SDimitry Andric     CurrSetPressure[*PSetI] += Weight;
1650b57cec5SDimitry Andric     P.MaxSetPressure[*PSetI] =
1660b57cec5SDimitry Andric         std::max(P.MaxSetPressure[*PSetI], CurrSetPressure[*PSetI]);
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
170e8d8bef9SDimitry Andric void RegPressureTracker::decreaseRegPressure(Register RegUnit,
1710b57cec5SDimitry Andric                                              LaneBitmask PreviousMask,
1720b57cec5SDimitry Andric                                              LaneBitmask NewMask) {
1730b57cec5SDimitry Andric   decreaseSetPressure(CurrSetPressure, *MRI, RegUnit, PreviousMask, NewMask);
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric /// Clear the result so it can be used for another round of pressure tracking.
1770b57cec5SDimitry Andric void IntervalPressure::reset() {
1780b57cec5SDimitry Andric   TopIdx = BottomIdx = SlotIndex();
1790b57cec5SDimitry Andric   MaxSetPressure.clear();
1800b57cec5SDimitry Andric   LiveInRegs.clear();
1810b57cec5SDimitry Andric   LiveOutRegs.clear();
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric /// Clear the result so it can be used for another round of pressure tracking.
1850b57cec5SDimitry Andric void RegionPressure::reset() {
1860b57cec5SDimitry Andric   TopPos = BottomPos = MachineBasicBlock::const_iterator();
1870b57cec5SDimitry Andric   MaxSetPressure.clear();
1880b57cec5SDimitry Andric   LiveInRegs.clear();
1890b57cec5SDimitry Andric   LiveOutRegs.clear();
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric /// If the current top is not less than or equal to the next index, open it.
1930b57cec5SDimitry Andric /// We happen to need the SlotIndex for the next top for pressure update.
1940b57cec5SDimitry Andric void IntervalPressure::openTop(SlotIndex NextTop) {
1950b57cec5SDimitry Andric   if (TopIdx <= NextTop)
1960b57cec5SDimitry Andric     return;
1970b57cec5SDimitry Andric   TopIdx = SlotIndex();
1980b57cec5SDimitry Andric   LiveInRegs.clear();
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric /// If the current top is the previous instruction (before receding), open it.
2020b57cec5SDimitry Andric void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
2030b57cec5SDimitry Andric   if (TopPos != PrevTop)
2040b57cec5SDimitry Andric     return;
2050b57cec5SDimitry Andric   TopPos = MachineBasicBlock::const_iterator();
2060b57cec5SDimitry Andric   LiveInRegs.clear();
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric /// If the current bottom is not greater than the previous index, open it.
2100b57cec5SDimitry Andric void IntervalPressure::openBottom(SlotIndex PrevBottom) {
2110b57cec5SDimitry Andric   if (BottomIdx > PrevBottom)
2120b57cec5SDimitry Andric     return;
2130b57cec5SDimitry Andric   BottomIdx = SlotIndex();
2140b57cec5SDimitry Andric   LiveInRegs.clear();
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric /// If the current bottom is the previous instr (before advancing), open it.
2180b57cec5SDimitry Andric void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
2190b57cec5SDimitry Andric   if (BottomPos != PrevBottom)
2200b57cec5SDimitry Andric     return;
2210b57cec5SDimitry Andric   BottomPos = MachineBasicBlock::const_iterator();
2220b57cec5SDimitry Andric   LiveInRegs.clear();
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric void LiveRegSet::init(const MachineRegisterInfo &MRI) {
2260b57cec5SDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
2270b57cec5SDimitry Andric   unsigned NumRegUnits = TRI.getNumRegs();
2280b57cec5SDimitry Andric   unsigned NumVirtRegs = MRI.getNumVirtRegs();
2290b57cec5SDimitry Andric   Regs.setUniverse(NumRegUnits + NumVirtRegs);
2300b57cec5SDimitry Andric   this->NumRegUnits = NumRegUnits;
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric void LiveRegSet::clear() {
2340b57cec5SDimitry Andric   Regs.clear();
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric static const LiveRange *getLiveRange(const LiveIntervals &LIS, unsigned Reg) {
2388bcb0991SDimitry Andric   if (Register::isVirtualRegister(Reg))
2390b57cec5SDimitry Andric     return &LIS.getInterval(Reg);
2400b57cec5SDimitry Andric   return LIS.getCachedRegUnit(Reg);
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric void RegPressureTracker::reset() {
2440b57cec5SDimitry Andric   MBB = nullptr;
2450b57cec5SDimitry Andric   LIS = nullptr;
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   CurrSetPressure.clear();
2480b57cec5SDimitry Andric   LiveThruPressure.clear();
2490b57cec5SDimitry Andric   P.MaxSetPressure.clear();
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   if (RequireIntervals)
2520b57cec5SDimitry Andric     static_cast<IntervalPressure&>(P).reset();
2530b57cec5SDimitry Andric   else
2540b57cec5SDimitry Andric     static_cast<RegionPressure&>(P).reset();
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   LiveRegs.clear();
2570b57cec5SDimitry Andric   UntiedDefs.clear();
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric /// Setup the RegPressureTracker.
2610b57cec5SDimitry Andric ///
2620b57cec5SDimitry Andric /// TODO: Add support for pressure without LiveIntervals.
2630b57cec5SDimitry Andric void RegPressureTracker::init(const MachineFunction *mf,
2640b57cec5SDimitry Andric                               const RegisterClassInfo *rci,
2650b57cec5SDimitry Andric                               const LiveIntervals *lis,
2660b57cec5SDimitry Andric                               const MachineBasicBlock *mbb,
2670b57cec5SDimitry Andric                               MachineBasicBlock::const_iterator pos,
2680b57cec5SDimitry Andric                               bool TrackLaneMasks, bool TrackUntiedDefs) {
2690b57cec5SDimitry Andric   reset();
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric   MF = mf;
2720b57cec5SDimitry Andric   TRI = MF->getSubtarget().getRegisterInfo();
2730b57cec5SDimitry Andric   RCI = rci;
2740b57cec5SDimitry Andric   MRI = &MF->getRegInfo();
2750b57cec5SDimitry Andric   MBB = mbb;
2760b57cec5SDimitry Andric   this->TrackUntiedDefs = TrackUntiedDefs;
2770b57cec5SDimitry Andric   this->TrackLaneMasks = TrackLaneMasks;
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   if (RequireIntervals) {
2800b57cec5SDimitry Andric     assert(lis && "IntervalPressure requires LiveIntervals");
2810b57cec5SDimitry Andric     LIS = lis;
2820b57cec5SDimitry Andric   }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   CurrPos = pos;
2850b57cec5SDimitry Andric   CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   P.MaxSetPressure = CurrSetPressure;
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   LiveRegs.init(*MRI);
2900b57cec5SDimitry Andric   if (TrackUntiedDefs)
2910b57cec5SDimitry Andric     UntiedDefs.setUniverse(MRI->getNumVirtRegs());
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric /// Does this pressure result have a valid top position and live ins.
2950b57cec5SDimitry Andric bool RegPressureTracker::isTopClosed() const {
2960b57cec5SDimitry Andric   if (RequireIntervals)
2970b57cec5SDimitry Andric     return static_cast<IntervalPressure&>(P).TopIdx.isValid();
2980b57cec5SDimitry Andric   return (static_cast<RegionPressure&>(P).TopPos ==
2990b57cec5SDimitry Andric           MachineBasicBlock::const_iterator());
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric /// Does this pressure result have a valid bottom position and live outs.
3030b57cec5SDimitry Andric bool RegPressureTracker::isBottomClosed() const {
3040b57cec5SDimitry Andric   if (RequireIntervals)
3050b57cec5SDimitry Andric     return static_cast<IntervalPressure&>(P).BottomIdx.isValid();
3060b57cec5SDimitry Andric   return (static_cast<RegionPressure&>(P).BottomPos ==
3070b57cec5SDimitry Andric           MachineBasicBlock::const_iterator());
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric SlotIndex RegPressureTracker::getCurrSlot() const {
3110b57cec5SDimitry Andric   MachineBasicBlock::const_iterator IdxPos =
3120b57cec5SDimitry Andric     skipDebugInstructionsForward(CurrPos, MBB->end());
3130b57cec5SDimitry Andric   if (IdxPos == MBB->end())
3140b57cec5SDimitry Andric     return LIS->getMBBEndIdx(MBB);
3150b57cec5SDimitry Andric   return LIS->getInstructionIndex(*IdxPos).getRegSlot();
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric /// Set the boundary for the top of the region and summarize live ins.
3190b57cec5SDimitry Andric void RegPressureTracker::closeTop() {
3200b57cec5SDimitry Andric   if (RequireIntervals)
3210b57cec5SDimitry Andric     static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot();
3220b57cec5SDimitry Andric   else
3230b57cec5SDimitry Andric     static_cast<RegionPressure&>(P).TopPos = CurrPos;
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
3260b57cec5SDimitry Andric   P.LiveInRegs.reserve(LiveRegs.size());
3270b57cec5SDimitry Andric   LiveRegs.appendTo(P.LiveInRegs);
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric /// Set the boundary for the bottom of the region and summarize live outs.
3310b57cec5SDimitry Andric void RegPressureTracker::closeBottom() {
3320b57cec5SDimitry Andric   if (RequireIntervals)
3330b57cec5SDimitry Andric     static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot();
3340b57cec5SDimitry Andric   else
3350b57cec5SDimitry Andric     static_cast<RegionPressure&>(P).BottomPos = CurrPos;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
3380b57cec5SDimitry Andric   P.LiveOutRegs.reserve(LiveRegs.size());
3390b57cec5SDimitry Andric   LiveRegs.appendTo(P.LiveOutRegs);
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric /// Finalize the region boundaries and record live ins and live outs.
3430b57cec5SDimitry Andric void RegPressureTracker::closeRegion() {
3440b57cec5SDimitry Andric   if (!isTopClosed() && !isBottomClosed()) {
3450b57cec5SDimitry Andric     assert(LiveRegs.size() == 0 && "no region boundary");
3460b57cec5SDimitry Andric     return;
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric   if (!isBottomClosed())
3490b57cec5SDimitry Andric     closeBottom();
3500b57cec5SDimitry Andric   else if (!isTopClosed())
3510b57cec5SDimitry Andric     closeTop();
3520b57cec5SDimitry Andric   // If both top and bottom are closed, do nothing.
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric /// The register tracker is unaware of global liveness so ignores normal
3560b57cec5SDimitry Andric /// live-thru ranges. However, two-address or coalesced chains can also lead
3570b57cec5SDimitry Andric /// to live ranges with no holes. Count these to inform heuristics that we
3580b57cec5SDimitry Andric /// can never drop below this pressure.
3590b57cec5SDimitry Andric void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
3600b57cec5SDimitry Andric   LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
3610b57cec5SDimitry Andric   assert(isBottomClosed() && "need bottom-up tracking to intialize.");
3620b57cec5SDimitry Andric   for (const RegisterMaskPair &Pair : P.LiveOutRegs) {
363e8d8bef9SDimitry Andric     Register RegUnit = Pair.RegUnit;
364bdd1243dSDimitry Andric     if (RegUnit.isVirtual() && !RPTracker.hasUntiedDef(RegUnit))
3650b57cec5SDimitry Andric       increaseSetPressure(LiveThruPressure, *MRI, RegUnit,
3660b57cec5SDimitry Andric                           LaneBitmask::getNone(), Pair.LaneMask);
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
371e8d8bef9SDimitry Andric                                Register RegUnit) {
3720b57cec5SDimitry Andric   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
3730b57cec5SDimitry Andric     return Other.RegUnit == RegUnit;
3740b57cec5SDimitry Andric   });
3750b57cec5SDimitry Andric   if (I == RegUnits.end())
3760b57cec5SDimitry Andric     return LaneBitmask::getNone();
3770b57cec5SDimitry Andric   return I->LaneMask;
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
3810b57cec5SDimitry Andric                         RegisterMaskPair Pair) {
382e8d8bef9SDimitry Andric   Register RegUnit = Pair.RegUnit;
3830b57cec5SDimitry Andric   assert(Pair.LaneMask.any());
3840b57cec5SDimitry Andric   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
3850b57cec5SDimitry Andric     return Other.RegUnit == RegUnit;
3860b57cec5SDimitry Andric   });
3870b57cec5SDimitry Andric   if (I == RegUnits.end()) {
3880b57cec5SDimitry Andric     RegUnits.push_back(Pair);
3890b57cec5SDimitry Andric   } else {
3900b57cec5SDimitry Andric     I->LaneMask |= Pair.LaneMask;
3910b57cec5SDimitry Andric   }
3920b57cec5SDimitry Andric }
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
395e8d8bef9SDimitry Andric                        Register RegUnit) {
3960b57cec5SDimitry Andric   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
3970b57cec5SDimitry Andric     return Other.RegUnit == RegUnit;
3980b57cec5SDimitry Andric   });
3990b57cec5SDimitry Andric   if (I == RegUnits.end()) {
4000b57cec5SDimitry Andric     RegUnits.push_back(RegisterMaskPair(RegUnit, LaneBitmask::getNone()));
4010b57cec5SDimitry Andric   } else {
4020b57cec5SDimitry Andric     I->LaneMask = LaneBitmask::getNone();
4030b57cec5SDimitry Andric   }
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
4070b57cec5SDimitry Andric                            RegisterMaskPair Pair) {
408e8d8bef9SDimitry Andric   Register RegUnit = Pair.RegUnit;
4090b57cec5SDimitry Andric   assert(Pair.LaneMask.any());
4100b57cec5SDimitry Andric   auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
4110b57cec5SDimitry Andric     return Other.RegUnit == RegUnit;
4120b57cec5SDimitry Andric   });
4130b57cec5SDimitry Andric   if (I != RegUnits.end()) {
4140b57cec5SDimitry Andric     I->LaneMask &= ~Pair.LaneMask;
4150b57cec5SDimitry Andric     if (I->LaneMask.none())
4160b57cec5SDimitry Andric       RegUnits.erase(I);
4170b57cec5SDimitry Andric   }
4180b57cec5SDimitry Andric }
4190b57cec5SDimitry Andric 
420e8d8bef9SDimitry Andric static LaneBitmask
421e8d8bef9SDimitry Andric getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
422e8d8bef9SDimitry Andric                      bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
423e8d8bef9SDimitry Andric                      LaneBitmask SafeDefault,
4240b57cec5SDimitry Andric                      bool (*Property)(const LiveRange &LR, SlotIndex Pos)) {
425e8d8bef9SDimitry Andric   if (RegUnit.isVirtual()) {
4260b57cec5SDimitry Andric     const LiveInterval &LI = LIS.getInterval(RegUnit);
4270b57cec5SDimitry Andric     LaneBitmask Result;
4280b57cec5SDimitry Andric     if (TrackLaneMasks && LI.hasSubRanges()) {
4290b57cec5SDimitry Andric         for (const LiveInterval::SubRange &SR : LI.subranges()) {
4300b57cec5SDimitry Andric           if (Property(SR, Pos))
4310b57cec5SDimitry Andric             Result |= SR.LaneMask;
4320b57cec5SDimitry Andric         }
4330b57cec5SDimitry Andric     } else if (Property(LI, Pos)) {
4340b57cec5SDimitry Andric       Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit)
4350b57cec5SDimitry Andric                               : LaneBitmask::getAll();
4360b57cec5SDimitry Andric     }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric     return Result;
4390b57cec5SDimitry Andric   } else {
4400b57cec5SDimitry Andric     const LiveRange *LR = LIS.getCachedRegUnit(RegUnit);
4410b57cec5SDimitry Andric     // Be prepared for missing liveranges: We usually do not compute liveranges
4420b57cec5SDimitry Andric     // for physical registers on targets with many registers (GPUs).
4430b57cec5SDimitry Andric     if (LR == nullptr)
4440b57cec5SDimitry Andric       return SafeDefault;
4450b57cec5SDimitry Andric     return Property(*LR, Pos) ? LaneBitmask::getAll() : LaneBitmask::getNone();
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
4500b57cec5SDimitry Andric                                   const MachineRegisterInfo &MRI,
451e8d8bef9SDimitry Andric                                   bool TrackLaneMasks, Register RegUnit,
4520b57cec5SDimitry Andric                                   SlotIndex Pos) {
4530b57cec5SDimitry Andric   return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos,
4540b57cec5SDimitry Andric                               LaneBitmask::getAll(),
4550b57cec5SDimitry Andric                               [](const LiveRange &LR, SlotIndex Pos) {
4560b57cec5SDimitry Andric                                 return LR.liveAt(Pos);
4570b57cec5SDimitry Andric                               });
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric namespace {
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric /// Collect this instruction's unique uses and defs into SmallVectors for
4630b57cec5SDimitry Andric /// processing defs and uses in order.
4640b57cec5SDimitry Andric ///
4650b57cec5SDimitry Andric /// FIXME: always ignore tied opers
4660b57cec5SDimitry Andric class RegisterOperandsCollector {
4670b57cec5SDimitry Andric   friend class llvm::RegisterOperands;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   RegisterOperands &RegOpers;
4700b57cec5SDimitry Andric   const TargetRegisterInfo &TRI;
4710b57cec5SDimitry Andric   const MachineRegisterInfo &MRI;
4720b57cec5SDimitry Andric   bool IgnoreDead;
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   RegisterOperandsCollector(RegisterOperands &RegOpers,
4750b57cec5SDimitry Andric                             const TargetRegisterInfo &TRI,
4760b57cec5SDimitry Andric                             const MachineRegisterInfo &MRI, bool IgnoreDead)
4770b57cec5SDimitry Andric     : RegOpers(RegOpers), TRI(TRI), MRI(MRI), IgnoreDead(IgnoreDead) {}
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   void collectInstr(const MachineInstr &MI) const {
4800b57cec5SDimitry Andric     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
4810b57cec5SDimitry Andric       collectOperand(*OperI);
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric     // Remove redundant physreg dead defs.
4840b57cec5SDimitry Andric     for (const RegisterMaskPair &P : RegOpers.Defs)
4850b57cec5SDimitry Andric       removeRegLanes(RegOpers.DeadDefs, P);
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   void collectInstrLanes(const MachineInstr &MI) const {
4890b57cec5SDimitry Andric     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
4900b57cec5SDimitry Andric       collectOperandLanes(*OperI);
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric     // Remove redundant physreg dead defs.
4930b57cec5SDimitry Andric     for (const RegisterMaskPair &P : RegOpers.Defs)
4940b57cec5SDimitry Andric       removeRegLanes(RegOpers.DeadDefs, P);
4950b57cec5SDimitry Andric   }
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   /// Push this operand's register onto the correct vectors.
4980b57cec5SDimitry Andric   void collectOperand(const MachineOperand &MO) const {
4990b57cec5SDimitry Andric     if (!MO.isReg() || !MO.getReg())
5000b57cec5SDimitry Andric       return;
5018bcb0991SDimitry Andric     Register Reg = MO.getReg();
5020b57cec5SDimitry Andric     if (MO.isUse()) {
5030b57cec5SDimitry Andric       if (!MO.isUndef() && !MO.isInternalRead())
5040b57cec5SDimitry Andric         pushReg(Reg, RegOpers.Uses);
5050b57cec5SDimitry Andric     } else {
5060b57cec5SDimitry Andric       assert(MO.isDef());
5070b57cec5SDimitry Andric       // Subregister definitions may imply a register read.
5080b57cec5SDimitry Andric       if (MO.readsReg())
5090b57cec5SDimitry Andric         pushReg(Reg, RegOpers.Uses);
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric       if (MO.isDead()) {
5120b57cec5SDimitry Andric         if (!IgnoreDead)
5130b57cec5SDimitry Andric           pushReg(Reg, RegOpers.DeadDefs);
5140b57cec5SDimitry Andric       } else
5150b57cec5SDimitry Andric         pushReg(Reg, RegOpers.Defs);
5160b57cec5SDimitry Andric     }
5170b57cec5SDimitry Andric   }
5180b57cec5SDimitry Andric 
519e8d8bef9SDimitry Andric   void pushReg(Register Reg,
5200b57cec5SDimitry Andric                SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
521e8d8bef9SDimitry Andric     if (Reg.isVirtual()) {
5220b57cec5SDimitry Andric       addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneBitmask::getAll()));
5230b57cec5SDimitry Andric     } else if (MRI.isAllocatable(Reg)) {
52406c3fb27SDimitry Andric       for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
52506c3fb27SDimitry Andric         addRegLanes(RegUnits, RegisterMaskPair(Unit, LaneBitmask::getAll()));
5260b57cec5SDimitry Andric     }
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   void collectOperandLanes(const MachineOperand &MO) const {
5300b57cec5SDimitry Andric     if (!MO.isReg() || !MO.getReg())
5310b57cec5SDimitry Andric       return;
5328bcb0991SDimitry Andric     Register Reg = MO.getReg();
5330b57cec5SDimitry Andric     unsigned SubRegIdx = MO.getSubReg();
5340b57cec5SDimitry Andric     if (MO.isUse()) {
5350b57cec5SDimitry Andric       if (!MO.isUndef() && !MO.isInternalRead())
5360b57cec5SDimitry Andric         pushRegLanes(Reg, SubRegIdx, RegOpers.Uses);
5370b57cec5SDimitry Andric     } else {
5380b57cec5SDimitry Andric       assert(MO.isDef());
5390b57cec5SDimitry Andric       // Treat read-undef subreg defs as definitions of the whole register.
5400b57cec5SDimitry Andric       if (MO.isUndef())
5410b57cec5SDimitry Andric         SubRegIdx = 0;
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric       if (MO.isDead()) {
5440b57cec5SDimitry Andric         if (!IgnoreDead)
5450b57cec5SDimitry Andric           pushRegLanes(Reg, SubRegIdx, RegOpers.DeadDefs);
5460b57cec5SDimitry Andric       } else
5470b57cec5SDimitry Andric         pushRegLanes(Reg, SubRegIdx, RegOpers.Defs);
5480b57cec5SDimitry Andric     }
5490b57cec5SDimitry Andric   }
5500b57cec5SDimitry Andric 
551e8d8bef9SDimitry Andric   void pushRegLanes(Register Reg, unsigned SubRegIdx,
5520b57cec5SDimitry Andric                     SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
553e8d8bef9SDimitry Andric     if (Reg.isVirtual()) {
5540b57cec5SDimitry Andric       LaneBitmask LaneMask = SubRegIdx != 0
5550b57cec5SDimitry Andric                              ? TRI.getSubRegIndexLaneMask(SubRegIdx)
5560b57cec5SDimitry Andric                              : MRI.getMaxLaneMaskForVReg(Reg);
5570b57cec5SDimitry Andric       addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneMask));
5580b57cec5SDimitry Andric     } else if (MRI.isAllocatable(Reg)) {
55906c3fb27SDimitry Andric       for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
56006c3fb27SDimitry Andric         addRegLanes(RegUnits, RegisterMaskPair(Unit, LaneBitmask::getAll()));
5610b57cec5SDimitry Andric     }
5620b57cec5SDimitry Andric   }
5630b57cec5SDimitry Andric };
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric } // end anonymous namespace
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric void RegisterOperands::collect(const MachineInstr &MI,
5680b57cec5SDimitry Andric                                const TargetRegisterInfo &TRI,
5690b57cec5SDimitry Andric                                const MachineRegisterInfo &MRI,
5700b57cec5SDimitry Andric                                bool TrackLaneMasks, bool IgnoreDead) {
5710b57cec5SDimitry Andric   RegisterOperandsCollector Collector(*this, TRI, MRI, IgnoreDead);
5720b57cec5SDimitry Andric   if (TrackLaneMasks)
5730b57cec5SDimitry Andric     Collector.collectInstrLanes(MI);
5740b57cec5SDimitry Andric   else
5750b57cec5SDimitry Andric     Collector.collectInstr(MI);
5760b57cec5SDimitry Andric }
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric void RegisterOperands::detectDeadDefs(const MachineInstr &MI,
5790b57cec5SDimitry Andric                                       const LiveIntervals &LIS) {
5800b57cec5SDimitry Andric   SlotIndex SlotIdx = LIS.getInstructionIndex(MI);
581fcaf7f86SDimitry Andric   for (auto *RI = Defs.begin(); RI != Defs.end(); /*empty*/) {
582e8d8bef9SDimitry Andric     Register Reg = RI->RegUnit;
5830b57cec5SDimitry Andric     const LiveRange *LR = getLiveRange(LIS, Reg);
5840b57cec5SDimitry Andric     if (LR != nullptr) {
5850b57cec5SDimitry Andric       LiveQueryResult LRQ = LR->Query(SlotIdx);
5860b57cec5SDimitry Andric       if (LRQ.isDeadDef()) {
5870b57cec5SDimitry Andric         // LiveIntervals knows this is a dead even though it's MachineOperand is
5880b57cec5SDimitry Andric         // not flagged as such.
5890b57cec5SDimitry Andric         DeadDefs.push_back(*RI);
5900b57cec5SDimitry Andric         RI = Defs.erase(RI);
5910b57cec5SDimitry Andric         continue;
5920b57cec5SDimitry Andric       }
5930b57cec5SDimitry Andric     }
5940b57cec5SDimitry Andric     ++RI;
5950b57cec5SDimitry Andric   }
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
5990b57cec5SDimitry Andric                                           const MachineRegisterInfo &MRI,
6000b57cec5SDimitry Andric                                           SlotIndex Pos,
6010b57cec5SDimitry Andric                                           MachineInstr *AddFlagsMI) {
602fcaf7f86SDimitry Andric   for (auto *I = Defs.begin(); I != Defs.end();) {
6030b57cec5SDimitry Andric     LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
6040b57cec5SDimitry Andric                                            Pos.getDeadSlot());
6050b57cec5SDimitry Andric     // If the def is all that is live after the instruction, then in case
6060b57cec5SDimitry Andric     // of a subregister def we need a read-undef flag.
607e8d8bef9SDimitry Andric     Register RegUnit = I->RegUnit;
608bdd1243dSDimitry Andric     if (RegUnit.isVirtual() && AddFlagsMI != nullptr &&
609bdd1243dSDimitry Andric         (LiveAfter & ~I->LaneMask).none())
6100b57cec5SDimitry Andric       AddFlagsMI->setRegisterDefReadUndef(RegUnit);
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric     LaneBitmask ActualDef = I->LaneMask & LiveAfter;
6130b57cec5SDimitry Andric     if (ActualDef.none()) {
6140b57cec5SDimitry Andric       I = Defs.erase(I);
6150b57cec5SDimitry Andric     } else {
6160b57cec5SDimitry Andric       I->LaneMask = ActualDef;
6170b57cec5SDimitry Andric       ++I;
6180b57cec5SDimitry Andric     }
6190b57cec5SDimitry Andric   }
620*0fca6ea1SDimitry Andric 
621*0fca6ea1SDimitry Andric   // For uses just copy the information from LIS.
622*0fca6ea1SDimitry Andric   for (auto &[RegUnit, LaneMask] : Uses)
623*0fca6ea1SDimitry Andric     LaneMask = getLiveLanesAt(LIS, MRI, true, RegUnit, Pos.getBaseIndex());
624*0fca6ea1SDimitry Andric 
6250b57cec5SDimitry Andric   if (AddFlagsMI != nullptr) {
6260b57cec5SDimitry Andric     for (const RegisterMaskPair &P : DeadDefs) {
627e8d8bef9SDimitry Andric       Register RegUnit = P.RegUnit;
628bdd1243dSDimitry Andric       if (!RegUnit.isVirtual())
6290b57cec5SDimitry Andric         continue;
6300b57cec5SDimitry Andric       LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
6310b57cec5SDimitry Andric                                              Pos.getDeadSlot());
6320b57cec5SDimitry Andric       if (LiveAfter.none())
6330b57cec5SDimitry Andric         AddFlagsMI->setRegisterDefReadUndef(RegUnit);
6340b57cec5SDimitry Andric     }
6350b57cec5SDimitry Andric   }
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric /// Initialize an array of N PressureDiffs.
6390b57cec5SDimitry Andric void PressureDiffs::init(unsigned N) {
6400b57cec5SDimitry Andric   Size = N;
6410b57cec5SDimitry Andric   if (N <= Max) {
6420b57cec5SDimitry Andric     memset(PDiffArray, 0, N * sizeof(PressureDiff));
6430b57cec5SDimitry Andric     return;
6440b57cec5SDimitry Andric   }
6450b57cec5SDimitry Andric   Max = Size;
6460b57cec5SDimitry Andric   free(PDiffArray);
6470b57cec5SDimitry Andric   PDiffArray = static_cast<PressureDiff*>(safe_calloc(N, sizeof(PressureDiff)));
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric void PressureDiffs::addInstruction(unsigned Idx,
6510b57cec5SDimitry Andric                                    const RegisterOperands &RegOpers,
6520b57cec5SDimitry Andric                                    const MachineRegisterInfo &MRI) {
6530b57cec5SDimitry Andric   PressureDiff &PDiff = (*this)[Idx];
6540b57cec5SDimitry Andric   assert(!PDiff.begin()->isValid() && "stale PDiff");
6550b57cec5SDimitry Andric   for (const RegisterMaskPair &P : RegOpers.Defs)
6560b57cec5SDimitry Andric     PDiff.addPressureChange(P.RegUnit, true, &MRI);
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   for (const RegisterMaskPair &P : RegOpers.Uses)
6590b57cec5SDimitry Andric     PDiff.addPressureChange(P.RegUnit, false, &MRI);
6600b57cec5SDimitry Andric }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric /// Add a change in pressure to the pressure diff of a given instruction.
663e8d8bef9SDimitry Andric void PressureDiff::addPressureChange(Register RegUnit, bool IsDec,
6640b57cec5SDimitry Andric                                      const MachineRegisterInfo *MRI) {
6650b57cec5SDimitry Andric   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
6660b57cec5SDimitry Andric   int Weight = IsDec ? -PSetI.getWeight() : PSetI.getWeight();
6670b57cec5SDimitry Andric   for (; PSetI.isValid(); ++PSetI) {
6680b57cec5SDimitry Andric     // Find an existing entry in the pressure diff for this PSet.
6690b57cec5SDimitry Andric     PressureDiff::iterator I = nonconst_begin(), E = nonconst_end();
6700b57cec5SDimitry Andric     for (; I != E && I->isValid(); ++I) {
6710b57cec5SDimitry Andric       if (I->getPSet() >= *PSetI)
6720b57cec5SDimitry Andric         break;
6730b57cec5SDimitry Andric     }
6740b57cec5SDimitry Andric     // If all pressure sets are more constrained, skip the remaining PSets.
6750b57cec5SDimitry Andric     if (I == E)
6760b57cec5SDimitry Andric       break;
6770b57cec5SDimitry Andric     // Insert this PressureChange.
6780b57cec5SDimitry Andric     if (!I->isValid() || I->getPSet() != *PSetI) {
6790b57cec5SDimitry Andric       PressureChange PTmp = PressureChange(*PSetI);
6800b57cec5SDimitry Andric       for (PressureDiff::iterator J = I; J != E && PTmp.isValid(); ++J)
6810b57cec5SDimitry Andric         std::swap(*J, PTmp);
6820b57cec5SDimitry Andric     }
6830b57cec5SDimitry Andric     // Update the units for this pressure set.
6840b57cec5SDimitry Andric     unsigned NewUnitInc = I->getUnitInc() + Weight;
6850b57cec5SDimitry Andric     if (NewUnitInc != 0) {
6860b57cec5SDimitry Andric       I->setUnitInc(NewUnitInc);
6870b57cec5SDimitry Andric     } else {
6880b57cec5SDimitry Andric       // Remove entry
6890b57cec5SDimitry Andric       PressureDiff::iterator J;
6900b57cec5SDimitry Andric       for (J = std::next(I); J != E && J->isValid(); ++J, ++I)
6910b57cec5SDimitry Andric         *I = *J;
6920b57cec5SDimitry Andric       *I = PressureChange();
6930b57cec5SDimitry Andric     }
6940b57cec5SDimitry Andric   }
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric /// Force liveness of registers.
6980b57cec5SDimitry Andric void RegPressureTracker::addLiveRegs(ArrayRef<RegisterMaskPair> Regs) {
6990b57cec5SDimitry Andric   for (const RegisterMaskPair &P : Regs) {
7000b57cec5SDimitry Andric     LaneBitmask PrevMask = LiveRegs.insert(P);
7010b57cec5SDimitry Andric     LaneBitmask NewMask = PrevMask | P.LaneMask;
7020b57cec5SDimitry Andric     increaseRegPressure(P.RegUnit, PrevMask, NewMask);
7030b57cec5SDimitry Andric   }
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
7070b57cec5SDimitry Andric     SmallVectorImpl<RegisterMaskPair> &LiveInOrOut) {
7080b57cec5SDimitry Andric   assert(Pair.LaneMask.any());
7090b57cec5SDimitry Andric 
710e8d8bef9SDimitry Andric   Register RegUnit = Pair.RegUnit;
7110b57cec5SDimitry Andric   auto I = llvm::find_if(LiveInOrOut, [RegUnit](const RegisterMaskPair &Other) {
7120b57cec5SDimitry Andric     return Other.RegUnit == RegUnit;
7130b57cec5SDimitry Andric   });
7140b57cec5SDimitry Andric   LaneBitmask PrevMask;
7150b57cec5SDimitry Andric   LaneBitmask NewMask;
7160b57cec5SDimitry Andric   if (I == LiveInOrOut.end()) {
7170b57cec5SDimitry Andric     PrevMask = LaneBitmask::getNone();
7180b57cec5SDimitry Andric     NewMask = Pair.LaneMask;
7190b57cec5SDimitry Andric     LiveInOrOut.push_back(Pair);
7200b57cec5SDimitry Andric   } else {
7210b57cec5SDimitry Andric     PrevMask = I->LaneMask;
7220b57cec5SDimitry Andric     NewMask = PrevMask | Pair.LaneMask;
7230b57cec5SDimitry Andric     I->LaneMask = NewMask;
7240b57cec5SDimitry Andric   }
7250b57cec5SDimitry Andric   increaseSetPressure(P.MaxSetPressure, *MRI, RegUnit, PrevMask, NewMask);
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric void RegPressureTracker::discoverLiveIn(RegisterMaskPair Pair) {
7290b57cec5SDimitry Andric   discoverLiveInOrOut(Pair, P.LiveInRegs);
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric void RegPressureTracker::discoverLiveOut(RegisterMaskPair Pair) {
7330b57cec5SDimitry Andric   discoverLiveInOrOut(Pair, P.LiveOutRegs);
7340b57cec5SDimitry Andric }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric void RegPressureTracker::bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs) {
7370b57cec5SDimitry Andric   for (const RegisterMaskPair &P : DeadDefs) {
738e8d8bef9SDimitry Andric     Register Reg = P.RegUnit;
7390b57cec5SDimitry Andric     LaneBitmask LiveMask = LiveRegs.contains(Reg);
7400b57cec5SDimitry Andric     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
7410b57cec5SDimitry Andric     increaseRegPressure(Reg, LiveMask, BumpedMask);
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric   for (const RegisterMaskPair &P : DeadDefs) {
744e8d8bef9SDimitry Andric     Register Reg = P.RegUnit;
7450b57cec5SDimitry Andric     LaneBitmask LiveMask = LiveRegs.contains(Reg);
7460b57cec5SDimitry Andric     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
7470b57cec5SDimitry Andric     decreaseRegPressure(Reg, BumpedMask, LiveMask);
7480b57cec5SDimitry Andric   }
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric /// Recede across the previous instruction. If LiveUses is provided, record any
7520b57cec5SDimitry Andric /// RegUnits that are made live by the current instruction's uses. This includes
7530b57cec5SDimitry Andric /// registers that are both defined and used by the instruction.  If a pressure
7540b57cec5SDimitry Andric /// difference pointer is provided record the changes is pressure caused by this
7550b57cec5SDimitry Andric /// instruction independent of liveness.
7560b57cec5SDimitry Andric void RegPressureTracker::recede(const RegisterOperands &RegOpers,
7570b57cec5SDimitry Andric                                 SmallVectorImpl<RegisterMaskPair> *LiveUses) {
758fe6060f1SDimitry Andric   assert(!CurrPos->isDebugOrPseudoInstr());
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   // Boost pressure for all dead defs together.
7610b57cec5SDimitry Andric   bumpDeadDefs(RegOpers.DeadDefs);
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric   // Kill liveness at live defs.
7640b57cec5SDimitry Andric   // TODO: consider earlyclobbers?
7650b57cec5SDimitry Andric   for (const RegisterMaskPair &Def : RegOpers.Defs) {
766e8d8bef9SDimitry Andric     Register Reg = Def.RegUnit;
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric     LaneBitmask PreviousMask = LiveRegs.erase(Def);
7690b57cec5SDimitry Andric     LaneBitmask NewMask = PreviousMask & ~Def.LaneMask;
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric     LaneBitmask LiveOut = Def.LaneMask & ~PreviousMask;
7720b57cec5SDimitry Andric     if (LiveOut.any()) {
7730b57cec5SDimitry Andric       discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
7740b57cec5SDimitry Andric       // Retroactively model effects on pressure of the live out lanes.
7750b57cec5SDimitry Andric       increaseSetPressure(CurrSetPressure, *MRI, Reg, LaneBitmask::getNone(),
7760b57cec5SDimitry Andric                           LiveOut);
7770b57cec5SDimitry Andric       PreviousMask = LiveOut;
7780b57cec5SDimitry Andric     }
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric     if (NewMask.none()) {
7810b57cec5SDimitry Andric       // Add a 0 entry to LiveUses as a marker that the complete vreg has become
7820b57cec5SDimitry Andric       // dead.
7830b57cec5SDimitry Andric       if (TrackLaneMasks && LiveUses != nullptr)
7840b57cec5SDimitry Andric         setRegZero(*LiveUses, Reg);
7850b57cec5SDimitry Andric     }
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric     decreaseRegPressure(Reg, PreviousMask, NewMask);
7880b57cec5SDimitry Andric   }
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric   SlotIndex SlotIdx;
7910b57cec5SDimitry Andric   if (RequireIntervals)
7920b57cec5SDimitry Andric     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   // Generate liveness for uses.
7950b57cec5SDimitry Andric   for (const RegisterMaskPair &Use : RegOpers.Uses) {
796e8d8bef9SDimitry Andric     Register Reg = Use.RegUnit;
7970b57cec5SDimitry Andric     assert(Use.LaneMask.any());
7980b57cec5SDimitry Andric     LaneBitmask PreviousMask = LiveRegs.insert(Use);
7990b57cec5SDimitry Andric     LaneBitmask NewMask = PreviousMask | Use.LaneMask;
8000b57cec5SDimitry Andric     if (NewMask == PreviousMask)
8010b57cec5SDimitry Andric       continue;
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric     // Did the register just become live?
8040b57cec5SDimitry Andric     if (PreviousMask.none()) {
8050b57cec5SDimitry Andric       if (LiveUses != nullptr) {
8060b57cec5SDimitry Andric         if (!TrackLaneMasks) {
8070b57cec5SDimitry Andric           addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
8080b57cec5SDimitry Andric         } else {
8090b57cec5SDimitry Andric           auto I =
8100b57cec5SDimitry Andric               llvm::find_if(*LiveUses, [Reg](const RegisterMaskPair Other) {
8110b57cec5SDimitry Andric                 return Other.RegUnit == Reg;
8120b57cec5SDimitry Andric               });
8130b57cec5SDimitry Andric           bool IsRedef = I != LiveUses->end();
8140b57cec5SDimitry Andric           if (IsRedef) {
8150b57cec5SDimitry Andric             // ignore re-defs here...
8160b57cec5SDimitry Andric             assert(I->LaneMask.none());
8170b57cec5SDimitry Andric             removeRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
8180b57cec5SDimitry Andric           } else {
8190b57cec5SDimitry Andric             addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
8200b57cec5SDimitry Andric           }
8210b57cec5SDimitry Andric         }
8220b57cec5SDimitry Andric       }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric       // Discover live outs if this may be the first occurance of this register.
8250b57cec5SDimitry Andric       if (RequireIntervals) {
8260b57cec5SDimitry Andric         LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
8270b57cec5SDimitry Andric         if (LiveOut.any())
8280b57cec5SDimitry Andric           discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
8290b57cec5SDimitry Andric       }
8300b57cec5SDimitry Andric     }
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric     increaseRegPressure(Reg, PreviousMask, NewMask);
8330b57cec5SDimitry Andric   }
8340b57cec5SDimitry Andric   if (TrackUntiedDefs) {
8350b57cec5SDimitry Andric     for (const RegisterMaskPair &Def : RegOpers.Defs) {
836e8d8bef9SDimitry Andric       Register RegUnit = Def.RegUnit;
837bdd1243dSDimitry Andric       if (RegUnit.isVirtual() &&
8380b57cec5SDimitry Andric           (LiveRegs.contains(RegUnit) & Def.LaneMask).none())
8390b57cec5SDimitry Andric         UntiedDefs.insert(RegUnit);
8400b57cec5SDimitry Andric     }
8410b57cec5SDimitry Andric   }
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric void RegPressureTracker::recedeSkipDebugValues() {
8450b57cec5SDimitry Andric   assert(CurrPos != MBB->begin());
8460b57cec5SDimitry Andric   if (!isBottomClosed())
8470b57cec5SDimitry Andric     closeBottom();
8480b57cec5SDimitry Andric 
8490b57cec5SDimitry Andric   // Open the top of the region using block iterators.
8500b57cec5SDimitry Andric   if (!RequireIntervals && isTopClosed())
8510b57cec5SDimitry Andric     static_cast<RegionPressure&>(P).openTop(CurrPos);
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   // Find the previous instruction.
8545ffd83dbSDimitry Andric   CurrPos = prev_nodbg(CurrPos, MBB->begin());
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric   SlotIndex SlotIdx;
857fe6060f1SDimitry Andric   if (RequireIntervals && !CurrPos->isDebugOrPseudoInstr())
8580b57cec5SDimitry Andric     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric   // Open the top of the region using slot indexes.
8610b57cec5SDimitry Andric   if (RequireIntervals && isTopClosed())
8620b57cec5SDimitry Andric     static_cast<IntervalPressure&>(P).openTop(SlotIdx);
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric void RegPressureTracker::recede(SmallVectorImpl<RegisterMaskPair> *LiveUses) {
8660b57cec5SDimitry Andric   recedeSkipDebugValues();
867fe6060f1SDimitry Andric   if (CurrPos->isDebugInstr() || CurrPos->isPseudoProbe()) {
868fe6060f1SDimitry Andric     // It's possible to only have debug_value and pseudo probe instructions and
869fe6060f1SDimitry Andric     // hit the start of the block.
8700b57cec5SDimitry Andric     assert(CurrPos == MBB->begin());
8710b57cec5SDimitry Andric     return;
8720b57cec5SDimitry Andric   }
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric   const MachineInstr &MI = *CurrPos;
8750b57cec5SDimitry Andric   RegisterOperands RegOpers;
876*0fca6ea1SDimitry Andric   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/false);
8770b57cec5SDimitry Andric   if (TrackLaneMasks) {
8780b57cec5SDimitry Andric     SlotIndex SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
8790b57cec5SDimitry Andric     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
8800b57cec5SDimitry Andric   } else if (RequireIntervals) {
8810b57cec5SDimitry Andric     RegOpers.detectDeadDefs(MI, *LIS);
8820b57cec5SDimitry Andric   }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric   recede(RegOpers, LiveUses);
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric /// Advance across the current instruction.
8880b57cec5SDimitry Andric void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
8890b57cec5SDimitry Andric   assert(!TrackUntiedDefs && "unsupported mode");
8900b57cec5SDimitry Andric   assert(CurrPos != MBB->end());
8910b57cec5SDimitry Andric   if (!isTopClosed())
8920b57cec5SDimitry Andric     closeTop();
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric   SlotIndex SlotIdx;
8950b57cec5SDimitry Andric   if (RequireIntervals)
8960b57cec5SDimitry Andric     SlotIdx = getCurrSlot();
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   // Open the bottom of the region using slot indexes.
8990b57cec5SDimitry Andric   if (isBottomClosed()) {
9000b57cec5SDimitry Andric     if (RequireIntervals)
9010b57cec5SDimitry Andric       static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
9020b57cec5SDimitry Andric     else
9030b57cec5SDimitry Andric       static_cast<RegionPressure&>(P).openBottom(CurrPos);
9040b57cec5SDimitry Andric   }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   for (const RegisterMaskPair &Use : RegOpers.Uses) {
907e8d8bef9SDimitry Andric     Register Reg = Use.RegUnit;
9080b57cec5SDimitry Andric     LaneBitmask LiveMask = LiveRegs.contains(Reg);
9090b57cec5SDimitry Andric     LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
9100b57cec5SDimitry Andric     if (LiveIn.any()) {
9110b57cec5SDimitry Andric       discoverLiveIn(RegisterMaskPair(Reg, LiveIn));
9120b57cec5SDimitry Andric       increaseRegPressure(Reg, LiveMask, LiveMask | LiveIn);
9130b57cec5SDimitry Andric       LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
9140b57cec5SDimitry Andric     }
9150b57cec5SDimitry Andric     // Kill liveness at last uses.
9160b57cec5SDimitry Andric     if (RequireIntervals) {
9170b57cec5SDimitry Andric       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
9180b57cec5SDimitry Andric       if (LastUseMask.any()) {
9190b57cec5SDimitry Andric         LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
9200b57cec5SDimitry Andric         decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
9210b57cec5SDimitry Andric       }
9220b57cec5SDimitry Andric     }
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   // Generate liveness for defs.
9260b57cec5SDimitry Andric   for (const RegisterMaskPair &Def : RegOpers.Defs) {
9270b57cec5SDimitry Andric     LaneBitmask PreviousMask = LiveRegs.insert(Def);
9280b57cec5SDimitry Andric     LaneBitmask NewMask = PreviousMask | Def.LaneMask;
9290b57cec5SDimitry Andric     increaseRegPressure(Def.RegUnit, PreviousMask, NewMask);
9300b57cec5SDimitry Andric   }
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   // Boost pressure for all dead defs together.
9330b57cec5SDimitry Andric   bumpDeadDefs(RegOpers.DeadDefs);
9340b57cec5SDimitry Andric 
9350b57cec5SDimitry Andric   // Find the next instruction.
9365ffd83dbSDimitry Andric   CurrPos = next_nodbg(CurrPos, MBB->end());
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric void RegPressureTracker::advance() {
9400b57cec5SDimitry Andric   const MachineInstr &MI = *CurrPos;
9410b57cec5SDimitry Andric   RegisterOperands RegOpers;
9420b57cec5SDimitry Andric   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
9430b57cec5SDimitry Andric   if (TrackLaneMasks) {
9440b57cec5SDimitry Andric     SlotIndex SlotIdx = getCurrSlot();
9450b57cec5SDimitry Andric     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric   advance(RegOpers);
9480b57cec5SDimitry Andric }
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric /// Find the max change in excess pressure across all sets.
9510b57cec5SDimitry Andric static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
9520b57cec5SDimitry Andric                                        ArrayRef<unsigned> NewPressureVec,
9530b57cec5SDimitry Andric                                        RegPressureDelta &Delta,
9540b57cec5SDimitry Andric                                        const RegisterClassInfo *RCI,
9550b57cec5SDimitry Andric                                        ArrayRef<unsigned> LiveThruPressureVec) {
9560b57cec5SDimitry Andric   Delta.Excess = PressureChange();
9570b57cec5SDimitry Andric   for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
9580b57cec5SDimitry Andric     unsigned POld = OldPressureVec[i];
9590b57cec5SDimitry Andric     unsigned PNew = NewPressureVec[i];
9600b57cec5SDimitry Andric     int PDiff = (int)PNew - (int)POld;
9610b57cec5SDimitry Andric     if (!PDiff) // No change in this set in the common case.
9620b57cec5SDimitry Andric       continue;
9630b57cec5SDimitry Andric     // Only consider change beyond the limit.
9640b57cec5SDimitry Andric     unsigned Limit = RCI->getRegPressureSetLimit(i);
9650b57cec5SDimitry Andric     if (!LiveThruPressureVec.empty())
9660b57cec5SDimitry Andric       Limit += LiveThruPressureVec[i];
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric     if (Limit > POld) {
9690b57cec5SDimitry Andric       if (Limit > PNew)
9700b57cec5SDimitry Andric         PDiff = 0;            // Under the limit
9710b57cec5SDimitry Andric       else
9720b57cec5SDimitry Andric         PDiff = PNew - Limit; // Just exceeded limit.
9730b57cec5SDimitry Andric     } else if (Limit > PNew)
9740b57cec5SDimitry Andric       PDiff = Limit - POld;   // Just obeyed limit.
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric     if (PDiff) {
9770b57cec5SDimitry Andric       Delta.Excess = PressureChange(i);
9780b57cec5SDimitry Andric       Delta.Excess.setUnitInc(PDiff);
9790b57cec5SDimitry Andric       break;
9800b57cec5SDimitry Andric     }
9810b57cec5SDimitry Andric   }
9820b57cec5SDimitry Andric }
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric /// Find the max change in max pressure that either surpasses a critical PSet
9850b57cec5SDimitry Andric /// limit or exceeds the current MaxPressureLimit.
9860b57cec5SDimitry Andric ///
9870b57cec5SDimitry Andric /// FIXME: comparing each element of the old and new MaxPressure vectors here is
9880b57cec5SDimitry Andric /// silly. It's done now to demonstrate the concept but will go away with a
9890b57cec5SDimitry Andric /// RegPressureTracker API change to work with pressure differences.
9900b57cec5SDimitry Andric static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
9910b57cec5SDimitry Andric                                     ArrayRef<unsigned> NewMaxPressureVec,
9920b57cec5SDimitry Andric                                     ArrayRef<PressureChange> CriticalPSets,
9930b57cec5SDimitry Andric                                     ArrayRef<unsigned> MaxPressureLimit,
9940b57cec5SDimitry Andric                                     RegPressureDelta &Delta) {
9950b57cec5SDimitry Andric   Delta.CriticalMax = PressureChange();
9960b57cec5SDimitry Andric   Delta.CurrentMax = PressureChange();
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
9990b57cec5SDimitry Andric   for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
10000b57cec5SDimitry Andric     unsigned POld = OldMaxPressureVec[i];
10010b57cec5SDimitry Andric     unsigned PNew = NewMaxPressureVec[i];
10020b57cec5SDimitry Andric     if (PNew == POld) // No change in this set in the common case.
10030b57cec5SDimitry Andric       continue;
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric     if (!Delta.CriticalMax.isValid()) {
10060b57cec5SDimitry Andric       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < i)
10070b57cec5SDimitry Andric         ++CritIdx;
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == i) {
10100b57cec5SDimitry Andric         int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].getUnitInc();
10110b57cec5SDimitry Andric         if (PDiff > 0) {
10120b57cec5SDimitry Andric           Delta.CriticalMax = PressureChange(i);
10130b57cec5SDimitry Andric           Delta.CriticalMax.setUnitInc(PDiff);
10140b57cec5SDimitry Andric         }
10150b57cec5SDimitry Andric       }
10160b57cec5SDimitry Andric     }
10170b57cec5SDimitry Andric     // Find the first increase above MaxPressureLimit.
10180b57cec5SDimitry Andric     // (Ignores negative MDiff).
10190b57cec5SDimitry Andric     if (!Delta.CurrentMax.isValid() && PNew > MaxPressureLimit[i]) {
10200b57cec5SDimitry Andric       Delta.CurrentMax = PressureChange(i);
10210b57cec5SDimitry Andric       Delta.CurrentMax.setUnitInc(PNew - POld);
10220b57cec5SDimitry Andric       if (CritIdx == CritEnd || Delta.CriticalMax.isValid())
10230b57cec5SDimitry Andric         break;
10240b57cec5SDimitry Andric     }
10250b57cec5SDimitry Andric   }
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric /// Record the upward impact of a single instruction on current register
10290b57cec5SDimitry Andric /// pressure. Unlike the advance/recede pressure tracking interface, this does
10300b57cec5SDimitry Andric /// not discover live in/outs.
10310b57cec5SDimitry Andric ///
10320b57cec5SDimitry Andric /// This is intended for speculative queries. It leaves pressure inconsistent
10330b57cec5SDimitry Andric /// with the current position, so must be restored by the caller.
10340b57cec5SDimitry Andric void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
1035fe6060f1SDimitry Andric   assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   SlotIndex SlotIdx;
10380b57cec5SDimitry Andric   if (RequireIntervals)
10390b57cec5SDimitry Andric     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   // Account for register pressure similar to RegPressureTracker::recede().
10420b57cec5SDimitry Andric   RegisterOperands RegOpers;
10430b57cec5SDimitry Andric   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/true);
1044*0fca6ea1SDimitry Andric   assert(RegOpers.DeadDefs.empty());
10450b57cec5SDimitry Andric   if (TrackLaneMasks)
10460b57cec5SDimitry Andric     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
10470b57cec5SDimitry Andric   else if (RequireIntervals)
10480b57cec5SDimitry Andric     RegOpers.detectDeadDefs(*MI, *LIS);
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // Boost max pressure for all dead defs together.
10510b57cec5SDimitry Andric   // Since CurrSetPressure and MaxSetPressure
10520b57cec5SDimitry Andric   bumpDeadDefs(RegOpers.DeadDefs);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   // Kill liveness at live defs.
10550b57cec5SDimitry Andric   for (const RegisterMaskPair &P : RegOpers.Defs) {
1056e8d8bef9SDimitry Andric     Register Reg = P.RegUnit;
1057*0fca6ea1SDimitry Andric     LaneBitmask LiveAfter = LiveRegs.contains(Reg);
10580b57cec5SDimitry Andric     LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg);
10590b57cec5SDimitry Andric     LaneBitmask DefLanes = P.LaneMask;
1060*0fca6ea1SDimitry Andric     LaneBitmask LiveBefore = (LiveAfter & ~DefLanes) | UseLanes;
1061*0fca6ea1SDimitry Andric 
1062*0fca6ea1SDimitry Andric     // There may be parts of the register that were dead before the
1063*0fca6ea1SDimitry Andric     // instruction, but became live afterwards. Similarly, some parts
1064*0fca6ea1SDimitry Andric     // may have been killed in this instruction.
1065*0fca6ea1SDimitry Andric     decreaseRegPressure(Reg, LiveAfter, LiveAfter & LiveBefore);
1066*0fca6ea1SDimitry Andric     increaseRegPressure(Reg, LiveAfter, ~LiveAfter & LiveBefore);
10670b57cec5SDimitry Andric   }
10680b57cec5SDimitry Andric   // Generate liveness for uses.
10690b57cec5SDimitry Andric   for (const RegisterMaskPair &P : RegOpers.Uses) {
1070e8d8bef9SDimitry Andric     Register Reg = P.RegUnit;
1071*0fca6ea1SDimitry Andric     // If this register was also in a def operand, we've handled it
1072*0fca6ea1SDimitry Andric     // with defs.
1073*0fca6ea1SDimitry Andric     if (getRegLanes(RegOpers.Defs, Reg).any())
1074*0fca6ea1SDimitry Andric       continue;
1075*0fca6ea1SDimitry Andric     LaneBitmask LiveAfter = LiveRegs.contains(Reg);
1076*0fca6ea1SDimitry Andric     LaneBitmask LiveBefore = LiveAfter | P.LaneMask;
1077*0fca6ea1SDimitry Andric     increaseRegPressure(Reg, LiveAfter, LiveBefore);
10780b57cec5SDimitry Andric   }
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric /// Consider the pressure increase caused by traversing this instruction
10820b57cec5SDimitry Andric /// bottom-up. Find the pressure set with the most change beyond its pressure
10830b57cec5SDimitry Andric /// limit based on the tracker's current pressure, and return the change in
10840b57cec5SDimitry Andric /// number of register units of that pressure set introduced by this
10850b57cec5SDimitry Andric /// instruction.
10860b57cec5SDimitry Andric ///
10870b57cec5SDimitry Andric /// This assumes that the current LiveOut set is sufficient.
10880b57cec5SDimitry Andric ///
10890b57cec5SDimitry Andric /// This is expensive for an on-the-fly query because it calls
10900b57cec5SDimitry Andric /// bumpUpwardPressure to recompute the pressure sets based on current
10910b57cec5SDimitry Andric /// liveness. This mainly exists to verify correctness, e.g. with
10920b57cec5SDimitry Andric /// -verify-misched. getUpwardPressureDelta is the fast version of this query
10930b57cec5SDimitry Andric /// that uses the per-SUnit cache of the PressureDiff.
10940b57cec5SDimitry Andric void RegPressureTracker::
10950b57cec5SDimitry Andric getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
10960b57cec5SDimitry Andric                           RegPressureDelta &Delta,
10970b57cec5SDimitry Andric                           ArrayRef<PressureChange> CriticalPSets,
10980b57cec5SDimitry Andric                           ArrayRef<unsigned> MaxPressureLimit) {
10990b57cec5SDimitry Andric   // Snapshot Pressure.
11000b57cec5SDimitry Andric   // FIXME: The snapshot heap space should persist. But I'm planning to
11010b57cec5SDimitry Andric   // summarize the pressure effect so we don't need to snapshot at all.
11020b57cec5SDimitry Andric   std::vector<unsigned> SavedPressure = CurrSetPressure;
11030b57cec5SDimitry Andric   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   bumpUpwardPressure(MI);
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
11080b57cec5SDimitry Andric                              LiveThruPressure);
11090b57cec5SDimitry Andric   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
11100b57cec5SDimitry Andric                           MaxPressureLimit, Delta);
11110b57cec5SDimitry Andric   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
11120b57cec5SDimitry Andric          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric   // Restore the tracker's state.
11150b57cec5SDimitry Andric   P.MaxSetPressure.swap(SavedMaxPressure);
11160b57cec5SDimitry Andric   CurrSetPressure.swap(SavedPressure);
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric #ifndef NDEBUG
11190b57cec5SDimitry Andric   if (!PDiff)
11200b57cec5SDimitry Andric     return;
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   // Check if the alternate algorithm yields the same result.
11230b57cec5SDimitry Andric   RegPressureDelta Delta2;
11240b57cec5SDimitry Andric   getUpwardPressureDelta(MI, *PDiff, Delta2, CriticalPSets, MaxPressureLimit);
11250b57cec5SDimitry Andric   if (Delta != Delta2) {
11260b57cec5SDimitry Andric     dbgs() << "PDiff: ";
11270b57cec5SDimitry Andric     PDiff->dump(*TRI);
11280b57cec5SDimitry Andric     dbgs() << "DELTA: " << *MI;
11290b57cec5SDimitry Andric     if (Delta.Excess.isValid())
11300b57cec5SDimitry Andric       dbgs() << "Excess1 " << TRI->getRegPressureSetName(Delta.Excess.getPSet())
11310b57cec5SDimitry Andric              << " " << Delta.Excess.getUnitInc() << "\n";
11320b57cec5SDimitry Andric     if (Delta.CriticalMax.isValid())
11330b57cec5SDimitry Andric       dbgs() << "Critic1 " << TRI->getRegPressureSetName(Delta.CriticalMax.getPSet())
11340b57cec5SDimitry Andric              << " " << Delta.CriticalMax.getUnitInc() << "\n";
11350b57cec5SDimitry Andric     if (Delta.CurrentMax.isValid())
11360b57cec5SDimitry Andric       dbgs() << "CurrMx1 " << TRI->getRegPressureSetName(Delta.CurrentMax.getPSet())
11370b57cec5SDimitry Andric              << " " << Delta.CurrentMax.getUnitInc() << "\n";
11380b57cec5SDimitry Andric     if (Delta2.Excess.isValid())
11390b57cec5SDimitry Andric       dbgs() << "Excess2 " << TRI->getRegPressureSetName(Delta2.Excess.getPSet())
11400b57cec5SDimitry Andric              << " " << Delta2.Excess.getUnitInc() << "\n";
11410b57cec5SDimitry Andric     if (Delta2.CriticalMax.isValid())
11420b57cec5SDimitry Andric       dbgs() << "Critic2 " << TRI->getRegPressureSetName(Delta2.CriticalMax.getPSet())
11430b57cec5SDimitry Andric              << " " << Delta2.CriticalMax.getUnitInc() << "\n";
11440b57cec5SDimitry Andric     if (Delta2.CurrentMax.isValid())
11450b57cec5SDimitry Andric       dbgs() << "CurrMx2 " << TRI->getRegPressureSetName(Delta2.CurrentMax.getPSet())
11460b57cec5SDimitry Andric              << " " << Delta2.CurrentMax.getUnitInc() << "\n";
11470b57cec5SDimitry Andric     llvm_unreachable("RegP Delta Mismatch");
11480b57cec5SDimitry Andric   }
11490b57cec5SDimitry Andric #endif
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric /// This is the fast version of querying register pressure that does not
11530b57cec5SDimitry Andric /// directly depend on current liveness.
11540b57cec5SDimitry Andric ///
11550b57cec5SDimitry Andric /// @param Delta captures information needed for heuristics.
11560b57cec5SDimitry Andric ///
11570b57cec5SDimitry Andric /// @param CriticalPSets Are the pressure sets that are known to exceed some
11580b57cec5SDimitry Andric /// limit within the region, not necessarily at the current position.
11590b57cec5SDimitry Andric ///
11600b57cec5SDimitry Andric /// @param MaxPressureLimit Is the max pressure within the region, not
11610b57cec5SDimitry Andric /// necessarily at the current position.
11620b57cec5SDimitry Andric void RegPressureTracker::
11630b57cec5SDimitry Andric getUpwardPressureDelta(const MachineInstr *MI, /*const*/ PressureDiff &PDiff,
11640b57cec5SDimitry Andric                        RegPressureDelta &Delta,
11650b57cec5SDimitry Andric                        ArrayRef<PressureChange> CriticalPSets,
11660b57cec5SDimitry Andric                        ArrayRef<unsigned> MaxPressureLimit) const {
11670b57cec5SDimitry Andric   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
11680b57cec5SDimitry Andric   for (PressureDiff::const_iterator
11690b57cec5SDimitry Andric          PDiffI = PDiff.begin(), PDiffE = PDiff.end();
11700b57cec5SDimitry Andric        PDiffI != PDiffE && PDiffI->isValid(); ++PDiffI) {
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric     unsigned PSetID = PDiffI->getPSet();
11730b57cec5SDimitry Andric     unsigned Limit = RCI->getRegPressureSetLimit(PSetID);
11740b57cec5SDimitry Andric     if (!LiveThruPressure.empty())
11750b57cec5SDimitry Andric       Limit += LiveThruPressure[PSetID];
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric     unsigned POld = CurrSetPressure[PSetID];
11780b57cec5SDimitry Andric     unsigned MOld = P.MaxSetPressure[PSetID];
11790b57cec5SDimitry Andric     unsigned MNew = MOld;
11800b57cec5SDimitry Andric     // Ignore DeadDefs here because they aren't captured by PressureChange.
11810b57cec5SDimitry Andric     unsigned PNew = POld + PDiffI->getUnitInc();
11820b57cec5SDimitry Andric     assert((PDiffI->getUnitInc() >= 0) == (PNew >= POld)
11830b57cec5SDimitry Andric            && "PSet overflow/underflow");
11840b57cec5SDimitry Andric     if (PNew > MOld)
11850b57cec5SDimitry Andric       MNew = PNew;
11860b57cec5SDimitry Andric     // Check if current pressure has exceeded the limit.
11870b57cec5SDimitry Andric     if (!Delta.Excess.isValid()) {
11880b57cec5SDimitry Andric       unsigned ExcessInc = 0;
11890b57cec5SDimitry Andric       if (PNew > Limit)
11900b57cec5SDimitry Andric         ExcessInc = POld > Limit ? PNew - POld : PNew - Limit;
11910b57cec5SDimitry Andric       else if (POld > Limit)
11920b57cec5SDimitry Andric         ExcessInc = Limit - POld;
11930b57cec5SDimitry Andric       if (ExcessInc) {
11940b57cec5SDimitry Andric         Delta.Excess = PressureChange(PSetID);
11950b57cec5SDimitry Andric         Delta.Excess.setUnitInc(ExcessInc);
11960b57cec5SDimitry Andric       }
11970b57cec5SDimitry Andric     }
11980b57cec5SDimitry Andric     // Check if max pressure has exceeded a critical pressure set max.
11990b57cec5SDimitry Andric     if (MNew == MOld)
12000b57cec5SDimitry Andric       continue;
12010b57cec5SDimitry Andric     if (!Delta.CriticalMax.isValid()) {
12020b57cec5SDimitry Andric       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < PSetID)
12030b57cec5SDimitry Andric         ++CritIdx;
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == PSetID) {
12060b57cec5SDimitry Andric         int CritInc = (int)MNew - (int)CriticalPSets[CritIdx].getUnitInc();
12070b57cec5SDimitry Andric         if (CritInc > 0 && CritInc <= std::numeric_limits<int16_t>::max()) {
12080b57cec5SDimitry Andric           Delta.CriticalMax = PressureChange(PSetID);
12090b57cec5SDimitry Andric           Delta.CriticalMax.setUnitInc(CritInc);
12100b57cec5SDimitry Andric         }
12110b57cec5SDimitry Andric       }
12120b57cec5SDimitry Andric     }
12130b57cec5SDimitry Andric     // Check if max pressure has exceeded the current max.
12140b57cec5SDimitry Andric     if (!Delta.CurrentMax.isValid() && MNew > MaxPressureLimit[PSetID]) {
12150b57cec5SDimitry Andric       Delta.CurrentMax = PressureChange(PSetID);
12160b57cec5SDimitry Andric       Delta.CurrentMax.setUnitInc(MNew - MOld);
12170b57cec5SDimitry Andric     }
12180b57cec5SDimitry Andric   }
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric /// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
12220b57cec5SDimitry Andric /// The query starts with a lane bitmask which gets lanes/bits removed for every
12230b57cec5SDimitry Andric /// use we find.
12240b57cec5SDimitry Andric static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
12250b57cec5SDimitry Andric                                   SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
12260b57cec5SDimitry Andric                                   const MachineRegisterInfo &MRI,
12270b57cec5SDimitry Andric                                   const LiveIntervals *LIS) {
12280b57cec5SDimitry Andric   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
12290b57cec5SDimitry Andric   for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
12300b57cec5SDimitry Andric     if (MO.isUndef())
12310b57cec5SDimitry Andric       continue;
12320b57cec5SDimitry Andric     const MachineInstr *MI = MO.getParent();
12330b57cec5SDimitry Andric     SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
12340b57cec5SDimitry Andric     if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx) {
12350b57cec5SDimitry Andric       unsigned SubRegIdx = MO.getSubReg();
12360b57cec5SDimitry Andric       LaneBitmask UseMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
12370b57cec5SDimitry Andric       LastUseMask &= ~UseMask;
12380b57cec5SDimitry Andric       if (LastUseMask.none())
12390b57cec5SDimitry Andric         return LaneBitmask::getNone();
12400b57cec5SDimitry Andric     }
12410b57cec5SDimitry Andric   }
12420b57cec5SDimitry Andric   return LastUseMask;
12430b57cec5SDimitry Andric }
12440b57cec5SDimitry Andric 
1245e8d8bef9SDimitry Andric LaneBitmask RegPressureTracker::getLiveLanesAt(Register RegUnit,
12460b57cec5SDimitry Andric                                                SlotIndex Pos) const {
12470b57cec5SDimitry Andric   assert(RequireIntervals);
12480b57cec5SDimitry Andric   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
12490b57cec5SDimitry Andric                               LaneBitmask::getAll(),
12500b57cec5SDimitry Andric       [](const LiveRange &LR, SlotIndex Pos) {
12510b57cec5SDimitry Andric         return LR.liveAt(Pos);
12520b57cec5SDimitry Andric       });
12530b57cec5SDimitry Andric }
12540b57cec5SDimitry Andric 
1255e8d8bef9SDimitry Andric LaneBitmask RegPressureTracker::getLastUsedLanes(Register RegUnit,
12560b57cec5SDimitry Andric                                                  SlotIndex Pos) const {
12570b57cec5SDimitry Andric   assert(RequireIntervals);
12580b57cec5SDimitry Andric   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
12590b57cec5SDimitry Andric                               Pos.getBaseIndex(), LaneBitmask::getNone(),
12600b57cec5SDimitry Andric       [](const LiveRange &LR, SlotIndex Pos) {
12610b57cec5SDimitry Andric         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
12620b57cec5SDimitry Andric         return S != nullptr && S->end == Pos.getRegSlot();
12630b57cec5SDimitry Andric       });
12640b57cec5SDimitry Andric }
12650b57cec5SDimitry Andric 
1266e8d8bef9SDimitry Andric LaneBitmask RegPressureTracker::getLiveThroughAt(Register RegUnit,
12670b57cec5SDimitry Andric                                                  SlotIndex Pos) const {
12680b57cec5SDimitry Andric   assert(RequireIntervals);
12690b57cec5SDimitry Andric   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
12700b57cec5SDimitry Andric                               LaneBitmask::getNone(),
12710b57cec5SDimitry Andric       [](const LiveRange &LR, SlotIndex Pos) {
12720b57cec5SDimitry Andric         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
12730b57cec5SDimitry Andric         return S != nullptr && S->start < Pos.getRegSlot(true) &&
12740b57cec5SDimitry Andric                S->end != Pos.getDeadSlot();
12750b57cec5SDimitry Andric       });
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric /// Record the downward impact of a single instruction on current register
12790b57cec5SDimitry Andric /// pressure. Unlike the advance/recede pressure tracking interface, this does
12800b57cec5SDimitry Andric /// not discover live in/outs.
12810b57cec5SDimitry Andric ///
12820b57cec5SDimitry Andric /// This is intended for speculative queries. It leaves pressure inconsistent
12830b57cec5SDimitry Andric /// with the current position, so must be restored by the caller.
12840b57cec5SDimitry Andric void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
1285fe6060f1SDimitry Andric   assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric   SlotIndex SlotIdx;
12880b57cec5SDimitry Andric   if (RequireIntervals)
12890b57cec5SDimitry Andric     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
12900b57cec5SDimitry Andric 
1291*0fca6ea1SDimitry Andric   // Account for register pressure similar to RegPressureTracker::advance().
12920b57cec5SDimitry Andric   RegisterOperands RegOpers;
1293*0fca6ea1SDimitry Andric   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/false);
12940b57cec5SDimitry Andric   if (TrackLaneMasks)
12950b57cec5SDimitry Andric     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric   if (RequireIntervals) {
12980b57cec5SDimitry Andric     for (const RegisterMaskPair &Use : RegOpers.Uses) {
1299e8d8bef9SDimitry Andric       Register Reg = Use.RegUnit;
13000b57cec5SDimitry Andric       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
13010b57cec5SDimitry Andric       if (LastUseMask.none())
13020b57cec5SDimitry Andric         continue;
13030b57cec5SDimitry Andric       // The LastUseMask is queried from the liveness information of instruction
13040b57cec5SDimitry Andric       // which may be further down the schedule. Some lanes may actually not be
13050b57cec5SDimitry Andric       // last uses for the current position.
13060b57cec5SDimitry Andric       // FIXME: allow the caller to pass in the list of vreg uses that remain
13070b57cec5SDimitry Andric       // to be bottom-scheduled to avoid searching uses at each query.
13080b57cec5SDimitry Andric       SlotIndex CurrIdx = getCurrSlot();
13090b57cec5SDimitry Andric       LastUseMask
13100b57cec5SDimitry Andric         = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
13110b57cec5SDimitry Andric       if (LastUseMask.none())
13120b57cec5SDimitry Andric         continue;
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric       LaneBitmask LiveMask = LiveRegs.contains(Reg);
13150b57cec5SDimitry Andric       LaneBitmask NewMask = LiveMask & ~LastUseMask;
13160b57cec5SDimitry Andric       decreaseRegPressure(Reg, LiveMask, NewMask);
13170b57cec5SDimitry Andric     }
13180b57cec5SDimitry Andric   }
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric   // Generate liveness for defs.
13210b57cec5SDimitry Andric   for (const RegisterMaskPair &Def : RegOpers.Defs) {
1322e8d8bef9SDimitry Andric     Register Reg = Def.RegUnit;
13230b57cec5SDimitry Andric     LaneBitmask LiveMask = LiveRegs.contains(Reg);
13240b57cec5SDimitry Andric     LaneBitmask NewMask = LiveMask | Def.LaneMask;
13250b57cec5SDimitry Andric     increaseRegPressure(Reg, LiveMask, NewMask);
13260b57cec5SDimitry Andric   }
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric   // Boost pressure for all dead defs together.
13290b57cec5SDimitry Andric   bumpDeadDefs(RegOpers.DeadDefs);
13300b57cec5SDimitry Andric }
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric /// Consider the pressure increase caused by traversing this instruction
13330b57cec5SDimitry Andric /// top-down. Find the register class with the most change in its pressure limit
13340b57cec5SDimitry Andric /// based on the tracker's current pressure, and return the number of excess
13350b57cec5SDimitry Andric /// register units of that pressure set introduced by this instruction.
13360b57cec5SDimitry Andric ///
13370b57cec5SDimitry Andric /// This assumes that the current LiveIn set is sufficient.
13380b57cec5SDimitry Andric ///
13390b57cec5SDimitry Andric /// This is expensive for an on-the-fly query because it calls
13400b57cec5SDimitry Andric /// bumpDownwardPressure to recompute the pressure sets based on current
13410b57cec5SDimitry Andric /// liveness. We don't yet have a fast version of downward pressure tracking
13420b57cec5SDimitry Andric /// analogous to getUpwardPressureDelta.
13430b57cec5SDimitry Andric void RegPressureTracker::
13440b57cec5SDimitry Andric getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
13450b57cec5SDimitry Andric                             ArrayRef<PressureChange> CriticalPSets,
13460b57cec5SDimitry Andric                             ArrayRef<unsigned> MaxPressureLimit) {
13470b57cec5SDimitry Andric   // Snapshot Pressure.
13480b57cec5SDimitry Andric   std::vector<unsigned> SavedPressure = CurrSetPressure;
13490b57cec5SDimitry Andric   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   bumpDownwardPressure(MI);
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
13540b57cec5SDimitry Andric                              LiveThruPressure);
13550b57cec5SDimitry Andric   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
13560b57cec5SDimitry Andric                           MaxPressureLimit, Delta);
13570b57cec5SDimitry Andric   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
13580b57cec5SDimitry Andric          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric   // Restore the tracker's state.
13610b57cec5SDimitry Andric   P.MaxSetPressure.swap(SavedMaxPressure);
13620b57cec5SDimitry Andric   CurrSetPressure.swap(SavedPressure);
13630b57cec5SDimitry Andric }
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric /// Get the pressure of each PSet after traversing this instruction bottom-up.
13660b57cec5SDimitry Andric void RegPressureTracker::
13670b57cec5SDimitry Andric getUpwardPressure(const MachineInstr *MI,
13680b57cec5SDimitry Andric                   std::vector<unsigned> &PressureResult,
13690b57cec5SDimitry Andric                   std::vector<unsigned> &MaxPressureResult) {
13700b57cec5SDimitry Andric   // Snapshot pressure.
13710b57cec5SDimitry Andric   PressureResult = CurrSetPressure;
13720b57cec5SDimitry Andric   MaxPressureResult = P.MaxSetPressure;
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric   bumpUpwardPressure(MI);
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric   // Current pressure becomes the result. Restore current pressure.
13770b57cec5SDimitry Andric   P.MaxSetPressure.swap(MaxPressureResult);
13780b57cec5SDimitry Andric   CurrSetPressure.swap(PressureResult);
13790b57cec5SDimitry Andric }
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric /// Get the pressure of each PSet after traversing this instruction top-down.
13820b57cec5SDimitry Andric void RegPressureTracker::
13830b57cec5SDimitry Andric getDownwardPressure(const MachineInstr *MI,
13840b57cec5SDimitry Andric                     std::vector<unsigned> &PressureResult,
13850b57cec5SDimitry Andric                     std::vector<unsigned> &MaxPressureResult) {
13860b57cec5SDimitry Andric   // Snapshot pressure.
13870b57cec5SDimitry Andric   PressureResult = CurrSetPressure;
13880b57cec5SDimitry Andric   MaxPressureResult = P.MaxSetPressure;
13890b57cec5SDimitry Andric 
13900b57cec5SDimitry Andric   bumpDownwardPressure(MI);
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric   // Current pressure becomes the result. Restore current pressure.
13930b57cec5SDimitry Andric   P.MaxSetPressure.swap(MaxPressureResult);
13940b57cec5SDimitry Andric   CurrSetPressure.swap(PressureResult);
13950b57cec5SDimitry Andric }
1396