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