14dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick//===-- RegisterPressure.cpp - Dynamic Register Pressure ------------------===// 24dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// 34dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// The LLVM Compiler Infrastructure 44dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// 54dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// This file is distributed under the University of Illinois Open Source 64dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// License. See LICENSE.TXT for details. 74dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// 84dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick//===----------------------------------------------------------------------===// 94dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// 104dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// This file implements the RegisterPressure class which can be used to track 114dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// MachineInstr level register pressure. 124dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick// 134dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick//===----------------------------------------------------------------------===// 144dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/RegisterPressure.h" 164dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick#include "llvm/CodeGen/LiveInterval.h" 174dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick#include "llvm/CodeGen/LiveIntervalAnalysis.h" 184dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick#include "llvm/CodeGen/MachineRegisterInfo.h" 191525260b3e50cc578939ef41b60609689eecfdd2Andrew Trick#include "llvm/CodeGen/RegisterClassInfo.h" 205f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick#include "llvm/Support/Debug.h" 215f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick#include "llvm/Support/raw_ostream.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 234dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 244dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickusing namespace llvm; 254dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 26553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick/// Increase pressure for each pressure set provided by TargetRegisterInfo. 274dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickstatic void increaseSetPressure(std::vector<unsigned> &CurrSetPressure, 284dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick std::vector<unsigned> &MaxSetPressure, 29553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick const int *PSet, unsigned Weight) { 30553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick for (; *PSet != -1; ++PSet) { 314dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick CurrSetPressure[*PSet] += Weight; 3255ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (&CurrSetPressure != &MaxSetPressure 3355ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick && CurrSetPressure[*PSet] > MaxSetPressure[*PSet]) { 344dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MaxSetPressure[*PSet] = CurrSetPressure[*PSet]; 3555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 364dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 374dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 384dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 39553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick/// Decrease pressure for each pressure set provided by TargetRegisterInfo. 404dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickstatic void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure, 41553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick const int *PSet, unsigned Weight) { 42553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick for (; *PSet != -1; ++PSet) { 434dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick assert(CurrSetPressure[*PSet] >= Weight && "register pressure underflow"); 444dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick CurrSetPressure[*PSet] -= Weight; 454dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 464dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 474dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 484dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Directly increase pressure only within this RegisterPressure result. 49f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegisterPressure::increase(unsigned Reg, const TargetRegisterInfo *TRI, 50f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const MachineRegisterInfo *MRI) { 51f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Reg)) { 52f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const TargetRegisterClass *RC = MRI->getRegClass(Reg); 53f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseSetPressure(MaxSetPressure, MaxSetPressure, 54f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassPressureSets(RC), 55f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassWeight(RC).RegWeight); 56f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 57f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else { 58f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseSetPressure(MaxSetPressure, MaxSetPressure, 59f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitPressureSets(Reg), 60f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitWeight(Reg)); 61f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 62553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick} 63553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick 64553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick/// Directly decrease pressure only within this RegisterPressure result. 65f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegisterPressure::decrease(unsigned Reg, const TargetRegisterInfo *TRI, 66f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const MachineRegisterInfo *MRI) { 67f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Reg)) { 68f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const TargetRegisterClass *RC = MRI->getRegClass(Reg); 69f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseSetPressure(MaxSetPressure, TRI->getRegClassPressureSets(RC), 70f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassWeight(RC).RegWeight); 71f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 72f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else { 73f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseSetPressure(MaxSetPressure, TRI->getRegUnitPressureSets(Reg), 74f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitWeight(Reg)); 75f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 764dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 774dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 78b720be6a50f4e1b3280d2b029ee38dda14577525Manman Ren#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 7917cf53519905acb69c567173bedd2df1c8e45523Andrew Trickstatic void dumpSetPressure(const std::vector<unsigned> &SetPressure, 8017cf53519905acb69c567173bedd2df1c8e45523Andrew Trick const TargetRegisterInfo *TRI) { 8117cf53519905acb69c567173bedd2df1c8e45523Andrew Trick for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) { 8217cf53519905acb69c567173bedd2df1c8e45523Andrew Trick if (SetPressure[i] != 0) 8317cf53519905acb69c567173bedd2df1c8e45523Andrew Trick dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n'; 8417cf53519905acb69c567173bedd2df1c8e45523Andrew Trick } 8517cf53519905acb69c567173bedd2df1c8e45523Andrew Trick} 8617cf53519905acb69c567173bedd2df1c8e45523Andrew Trick 87881a05b46c28299046bd0dc3d0b8c6677e68a4d7Andrew Trickvoid RegisterPressure::dump(const TargetRegisterInfo *TRI) const { 8817cf53519905acb69c567173bedd2df1c8e45523Andrew Trick dbgs() << "Max Pressure: "; 8917cf53519905acb69c567173bedd2df1c8e45523Andrew Trick dumpSetPressure(MaxSetPressure, TRI); 905f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << "Live In: "; 915f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick for (unsigned i = 0, e = LiveInRegs.size(); i < e; ++i) 925f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << PrintReg(LiveInRegs[i], TRI) << " "; 935f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << '\n'; 945f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << "Live Out: "; 955f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i) 965f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << PrintReg(LiveOutRegs[i], TRI) << " "; 975f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick dbgs() << '\n'; 9817cf53519905acb69c567173bedd2df1c8e45523Andrew Trick} 9917cf53519905acb69c567173bedd2df1c8e45523Andrew Trick 10022af4bc07bb81c22b15d7a63fb566efcab913bd9Andrew Trickvoid RegPressureTracker::dump() const { 10117cf53519905acb69c567173bedd2df1c8e45523Andrew Trick dbgs() << "Curr Pressure: "; 10217cf53519905acb69c567173bedd2df1c8e45523Andrew Trick dumpSetPressure(CurrSetPressure, TRI); 10317cf53519905acb69c567173bedd2df1c8e45523Andrew Trick P.dump(TRI); 1045f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick} 10577e300e8f0b8db8eec448cae9c87d7c5bfad9757Manman Ren#endif 1065f887fab35cd71a1e6fcbfa64ae5cbbf43b39807Andrew Trick 107f54f61538688eff25f392c2062b3a654394333aaAndrew Trick/// Increase the current pressure as impacted by these registers and bump 108553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick/// the high water mark if needed. 109f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegPressureTracker::increaseRegPressure(ArrayRef<unsigned> Regs) { 110553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick for (unsigned I = 0, E = Regs.size(); I != E; ++I) { 111f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Regs[I])) { 112f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]); 113f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseSetPressure(CurrSetPressure, P.MaxSetPressure, 114f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassPressureSets(RC), 115f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassWeight(RC).RegWeight); 116f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 117f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else { 118f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseSetPressure(CurrSetPressure, P.MaxSetPressure, 119f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitPressureSets(Regs[I]), 120f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitWeight(Regs[I])); 121f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 122553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick } 1234dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1244dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 125f54f61538688eff25f392c2062b3a654394333aaAndrew Trick/// Simply decrease the current pressure as impacted by these registers. 126f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegPressureTracker::decreaseRegPressure(ArrayRef<unsigned> Regs) { 127553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick for (unsigned I = 0, E = Regs.size(); I != E; ++I) { 128f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Regs[I])) { 129f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]); 130f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseSetPressure(CurrSetPressure, 131f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassPressureSets(RC), 132f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegClassWeight(RC).RegWeight); 133f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 134f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else { 135f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseSetPressure(CurrSetPressure, TRI->getRegUnitPressureSets(Regs[I]), 136f54f61538688eff25f392c2062b3a654394333aaAndrew Trick TRI->getRegUnitWeight(Regs[I])); 137f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 138553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick } 1394dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1404dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1414dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Clear the result so it can be used for another round of pressure tracking. 1424dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid IntervalPressure::reset() { 1434dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick TopIdx = BottomIdx = SlotIndex(); 1444dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MaxSetPressure.clear(); 1454dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1464dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveOutRegs.clear(); 1474dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1484dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1494dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Clear the result so it can be used for another round of pressure tracking. 1504dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegionPressure::reset() { 1514dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick TopPos = BottomPos = MachineBasicBlock::const_iterator(); 1524dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MaxSetPressure.clear(); 1534dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1544dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveOutRegs.clear(); 1554dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1564dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1574dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// If the current top is not less than or equal to the next index, open it. 1584dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// We happen to need the SlotIndex for the next top for pressure update. 1594dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid IntervalPressure::openTop(SlotIndex NextTop) { 1604dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (TopIdx <= NextTop) 1614dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 1624dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick TopIdx = SlotIndex(); 1634dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1644dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1654dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1664dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// If the current top is the previous instruction (before receding), open it. 1674dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) { 1684dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (TopPos != PrevTop) 1694dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 1704dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick TopPos = MachineBasicBlock::const_iterator(); 1714dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1724dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1734dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1744dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// If the current bottom is not greater than the previous index, open it. 1754dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid IntervalPressure::openBottom(SlotIndex PrevBottom) { 1764dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (BottomIdx > PrevBottom) 1774dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 1784dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick BottomIdx = SlotIndex(); 1794dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1804dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1814dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 1824dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// If the current bottom is the previous instr (before advancing), open it. 1834dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) { 1844dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (BottomPos != PrevBottom) 1854dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 1864dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick BottomPos = MachineBasicBlock::const_iterator(); 1874dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LiveInRegs.clear(); 1884dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 1894dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 190f54f61538688eff25f392c2062b3a654394333aaAndrew Trickconst LiveInterval *RegPressureTracker::getInterval(unsigned Reg) const { 191f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Reg)) 192f54f61538688eff25f392c2062b3a654394333aaAndrew Trick return &LIS->getInterval(Reg); 193f54f61538688eff25f392c2062b3a654394333aaAndrew Trick return LIS->getCachedRegUnit(Reg); 194f54f61538688eff25f392c2062b3a654394333aaAndrew Trick} 195f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 1964dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Setup the RegPressureTracker. 1974dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// 1984dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// TODO: Add support for pressure without LiveIntervals. 1994dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegPressureTracker::init(const MachineFunction *mf, 2004dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick const RegisterClassInfo *rci, 2014dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick const LiveIntervals *lis, 2024dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick const MachineBasicBlock *mbb, 2034dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MachineBasicBlock::const_iterator pos) 2044dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick{ 2054dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MF = mf; 2064dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick TRI = MF->getTarget().getRegisterInfo(); 2074dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick RCI = rci; 2084dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MRI = &MF->getRegInfo(); 2094dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MBB = mbb; 2104dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2114dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) { 2124dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick assert(lis && "IntervalPressure requires LiveIntervals"); 2134dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick LIS = lis; 2144dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 2154dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2164dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick CurrPos = pos; 2174dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0); 2184dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2194dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 2204dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<IntervalPressure&>(P).reset(); 2214dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else 2224dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<RegionPressure&>(P).reset(); 2234dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.MaxSetPressure = CurrSetPressure; 2244dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 225f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.PhysRegs.clear(); 226f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.PhysRegs.setUniverse(TRI->getNumRegs()); 227f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.VirtRegs.clear(); 228f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.VirtRegs.setUniverse(MRI->getNumVirtRegs()); 2294dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 2304dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2314dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Does this pressure result have a valid top position and live ins. 2324dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickbool RegPressureTracker::isTopClosed() const { 2334dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 2344dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return static_cast<IntervalPressure&>(P).TopIdx.isValid(); 2354dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return (static_cast<RegionPressure&>(P).TopPos == 2364dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MachineBasicBlock::const_iterator()); 2374dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 2384dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2394dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Does this pressure result have a valid bottom position and live outs. 2404dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickbool RegPressureTracker::isBottomClosed() const { 2414dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 2424dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return static_cast<IntervalPressure&>(P).BottomIdx.isValid(); 2434dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return (static_cast<RegionPressure&>(P).BottomPos == 2444dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick MachineBasicBlock::const_iterator()); 2454dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 2464dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 247657b75b9946eae763725b413841dfd01ed12a051Andrew Trick 248657b75b9946eae763725b413841dfd01ed12a051Andrew TrickSlotIndex RegPressureTracker::getCurrSlot() const { 249657b75b9946eae763725b413841dfd01ed12a051Andrew Trick MachineBasicBlock::const_iterator IdxPos = CurrPos; 250657b75b9946eae763725b413841dfd01ed12a051Andrew Trick while (IdxPos != MBB->end() && IdxPos->isDebugValue()) 251657b75b9946eae763725b413841dfd01ed12a051Andrew Trick ++IdxPos; 252657b75b9946eae763725b413841dfd01ed12a051Andrew Trick if (IdxPos == MBB->end()) 253657b75b9946eae763725b413841dfd01ed12a051Andrew Trick return LIS->getMBBEndIdx(MBB); 254657b75b9946eae763725b413841dfd01ed12a051Andrew Trick return LIS->getInstructionIndex(IdxPos).getRegSlot(); 255657b75b9946eae763725b413841dfd01ed12a051Andrew Trick} 256657b75b9946eae763725b413841dfd01ed12a051Andrew Trick 2574dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Set the boundary for the top of the region and summarize live ins. 2584dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegPressureTracker::closeTop() { 2594dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 260657b75b9946eae763725b413841dfd01ed12a051Andrew Trick static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot(); 2614dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else 2624dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<RegionPressure&>(P).TopPos = CurrPos; 2634dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2644dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick assert(P.LiveInRegs.empty() && "inconsistent max pressure result"); 265f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size()); 266f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end()); 2674dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick for (SparseSet<unsigned>::const_iterator I = 268f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I) 2694dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveInRegs.push_back(*I); 2704dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick std::sort(P.LiveInRegs.begin(), P.LiveInRegs.end()); 2714dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveInRegs.erase(std::unique(P.LiveInRegs.begin(), P.LiveInRegs.end()), 2724dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveInRegs.end()); 2734dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 2744dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2754dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Set the boundary for the bottom of the region and summarize live outs. 2764dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegPressureTracker::closeBottom() { 2774dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 278657b75b9946eae763725b413841dfd01ed12a051Andrew Trick static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot(); 2794dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else 2804dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<RegionPressure&>(P).BottomPos = CurrPos; 2814dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2824dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick assert(P.LiveOutRegs.empty() && "inconsistent max pressure result"); 283f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size()); 284f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end()); 2854dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick for (SparseSet<unsigned>::const_iterator I = 286f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I) 2874dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveOutRegs.push_back(*I); 2884dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick std::sort(P.LiveOutRegs.begin(), P.LiveOutRegs.end()); 2894dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveOutRegs.erase(std::unique(P.LiveOutRegs.begin(), P.LiveOutRegs.end()), 2904dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveOutRegs.end()); 2914dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 2924dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 2934dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Finalize the region boundaries and record live ins and live outs. 2944dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickvoid RegPressureTracker::closeRegion() { 2954dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (!isTopClosed() && !isBottomClosed()) { 296f54f61538688eff25f392c2062b3a654394333aaAndrew Trick assert(LiveRegs.PhysRegs.empty() && LiveRegs.VirtRegs.empty() && 2974dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick "no region boundary"); 2984dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 2994dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 3004dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (!isBottomClosed()) 3014dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeBottom(); 3024dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else if (!isTopClosed()) 3034dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeTop(); 3044dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // If both top and bottom are closed, do nothing. 3054dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 3064dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 307553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick/// \brief Convenient wrapper for checking membership in RegisterOperands. 308553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trickstatic bool containsReg(ArrayRef<unsigned> Regs, unsigned Reg) { 309553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick return std::find(Regs.begin(), Regs.end(), Reg) != Regs.end(); 3104dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 3114dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3124dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Collect this instruction's unique uses and defs into SmallVectors for 3134dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// processing defs and uses in order. 314553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trickclass RegisterOperands { 315f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const TargetRegisterInfo *TRI; 316f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const MachineRegisterInfo *MRI; 317f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 318553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trickpublic: 3194dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SmallVector<unsigned, 8> Uses; 3204dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SmallVector<unsigned, 8> Defs; 3214dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SmallVector<unsigned, 8> DeadDefs; 3224dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 323f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands(const TargetRegisterInfo *tri, 324f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const MachineRegisterInfo *mri): TRI(tri), MRI(mri) {} 325f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 3264dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick /// Push this operand's register onto the correct vector. 327f54f61538688eff25f392c2062b3a654394333aaAndrew Trick void collect(const MachineOperand &MO) { 328f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (!MO.isReg() || !MO.getReg()) 329f54f61538688eff25f392c2062b3a654394333aaAndrew Trick return; 330553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (MO.readsReg()) 331f54f61538688eff25f392c2062b3a654394333aaAndrew Trick pushRegUnits(MO.getReg(), Uses); 3324dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (MO.isDef()) { 333553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (MO.isDead()) 334f54f61538688eff25f392c2062b3a654394333aaAndrew Trick pushRegUnits(MO.getReg(), DeadDefs); 335553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick else 336f54f61538688eff25f392c2062b3a654394333aaAndrew Trick pushRegUnits(MO.getReg(), Defs); 337553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick } 338553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick } 339553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick 340553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trickprotected: 341f54f61538688eff25f392c2062b3a654394333aaAndrew Trick void pushRegUnits(unsigned Reg, SmallVectorImpl<unsigned> &Regs) { 342f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (TargetRegisterInfo::isVirtualRegister(Reg)) { 343553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (containsReg(Regs, Reg)) 344553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick return; 345553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick Regs.push_back(Reg); 346553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick } 347f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else if (MRI->isAllocatable(Reg)) { 348553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) { 349553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (containsReg(Regs, *Units)) 350553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick continue; 351553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick Regs.push_back(*Units); 3524dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 3534dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 3544dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 3554dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick}; 3564dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3574dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Collect physical and virtual register operands. 3584dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickstatic void collectOperands(const MachineInstr *MI, 359f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands &RegOpers) { 360eb4774a972af4bdd36d8795625c8c5d96ca507d1Benjamin Kramer for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI) 361f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegOpers.collect(*OperI); 3624dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3634dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Remove redundant physreg dead defs. 364eb4774a972af4bdd36d8795625c8c5d96ca507d1Benjamin Kramer SmallVectorImpl<unsigned>::iterator I = 365eb4774a972af4bdd36d8795625c8c5d96ca507d1Benjamin Kramer std::remove_if(RegOpers.DeadDefs.begin(), RegOpers.DeadDefs.end(), 366eb4774a972af4bdd36d8795625c8c5d96ca507d1Benjamin Kramer std::bind1st(std::ptr_fun(containsReg), RegOpers.Defs)); 367eb4774a972af4bdd36d8795625c8c5d96ca507d1Benjamin Kramer RegOpers.DeadDefs.erase(I, RegOpers.DeadDefs.end()); 3684dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 3694dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3707f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trick/// Force liveness of registers. 3717f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trickvoid RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) { 3727f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trick for (unsigned i = 0, e = Regs.size(); i != e; ++i) { 373f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (LiveRegs.insert(Regs[i])) 374f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(Regs[i]); 3757f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trick } 3767f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trick} 3777f8ab785af09e4d6e4db07157a5b5aa449b5c3aeAndrew Trick 378f54f61538688eff25f392c2062b3a654394333aaAndrew Trick/// Add Reg to the live in set and increase max pressure. 379f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegPressureTracker::discoverLiveIn(unsigned Reg) { 380f54f61538688eff25f392c2062b3a654394333aaAndrew Trick assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice"); 381553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (containsReg(P.LiveInRegs, Reg)) 3824dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 3834dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3844dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // At live in discovery, unconditionally increase the high water mark. 3854dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveInRegs.push_back(Reg); 386f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.increase(Reg, TRI, MRI); 3874dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 3884dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 389f54f61538688eff25f392c2062b3a654394333aaAndrew Trick/// Add Reg to the live out set and increase max pressure. 390f54f61538688eff25f392c2062b3a654394333aaAndrew Trickvoid RegPressureTracker::discoverLiveOut(unsigned Reg) { 391f54f61538688eff25f392c2062b3a654394333aaAndrew Trick assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice"); 392553c42cefc9abe1f10ee33d34a12498b8ac12fe6Andrew Trick if (containsReg(P.LiveOutRegs, Reg)) 3934dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return; 3944dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 3954dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // At live out discovery, unconditionally increase the high water mark. 3964dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick P.LiveOutRegs.push_back(Reg); 397f54f61538688eff25f392c2062b3a654394333aaAndrew Trick P.increase(Reg, TRI, MRI); 3984dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 3994dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4004dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Recede across the previous instruction. 4014dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickbool RegPressureTracker::recede() { 4024dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Check for the top of the analyzable region. 4034dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (CurrPos == MBB->begin()) { 4044dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeRegion(); 4054dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return false; 4064dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4074dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (!isBottomClosed()) 4084dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeBottom(); 4094dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4104dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Open the top of the region using block iterators. 4114dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (!RequireIntervals && isTopClosed()) 4124dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<RegionPressure&>(P).openTop(CurrPos); 4134dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4144dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Find the previous instruction. 4152b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer do 4162b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer --CurrPos; 4172b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer while (CurrPos != MBB->begin() && CurrPos->isDebugValue()); 4184dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4194dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (CurrPos->isDebugValue()) { 4204dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeRegion(); 4214dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return false; 4224dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4234dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SlotIndex SlotIdx; 4244dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 4254dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot(); 4264dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4274dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Open the top of the region using slot indexes. 4284dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals && isTopClosed()) 4294dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<IntervalPressure&>(P).openTop(SlotIdx); 4304dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 431f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands RegOpers(TRI, MRI); 432f54f61538688eff25f392c2062b3a654394333aaAndrew Trick collectOperands(CurrPos, RegOpers); 4334dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4344dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Boost pressure for all dead defs together. 435f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(RegOpers.DeadDefs); 436f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(RegOpers.DeadDefs); 4374dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4384dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Kill liveness at live defs. 4394dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // TODO: consider earlyclobbers? 440f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) { 441f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Defs[i]; 442f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (LiveRegs.erase(Reg)) 443f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(Reg); 4444dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else 445f54f61538688eff25f392c2062b3a654394333aaAndrew Trick discoverLiveOut(Reg); 4464dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4474dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4484dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Generate liveness for uses. 449f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) { 450f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Uses[i]; 451f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (!LiveRegs.contains(Reg)) { 4524dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Adjust liveouts if LiveIntervals are available. 4534dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) { 454f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const LiveInterval *LI = getInterval(Reg); 455f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (LI && !LI->killedAt(SlotIdx)) 456f54f61538688eff25f392c2062b3a654394333aaAndrew Trick discoverLiveOut(Reg); 4574dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 458f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(Reg); 459f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.insert(Reg); 4604dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4614dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4624dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return true; 4634dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 4644dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4654dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick/// Advance across the current instruction. 4664dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trickbool RegPressureTracker::advance() { 4674dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Check for the bottom of the analyzable region. 4684dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (CurrPos == MBB->end()) { 4694dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeRegion(); 4704dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return false; 4714dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4724dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (!isTopClosed()) 4734dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick closeTop(); 4744dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4754dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick SlotIndex SlotIdx; 4764dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 477657b75b9946eae763725b413841dfd01ed12a051Andrew Trick SlotIdx = getCurrSlot(); 4784dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 4794dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Open the bottom of the region using slot indexes. 4804dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (isBottomClosed()) { 4814dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) 4824dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<IntervalPressure&>(P).openBottom(SlotIdx); 4834dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick else 4844dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick static_cast<RegionPressure&>(P).openBottom(CurrPos); 4854dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 4864dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 487f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands RegOpers(TRI, MRI); 488f54f61538688eff25f392c2062b3a654394333aaAndrew Trick collectOperands(CurrPos, RegOpers); 4894dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 490f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) { 491f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Uses[i]; 492f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // Discover live-ins. 493f54f61538688eff25f392c2062b3a654394333aaAndrew Trick bool isLive = LiveRegs.contains(Reg); 494f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (!isLive) 495f54f61538688eff25f392c2062b3a654394333aaAndrew Trick discoverLiveIn(Reg); 496f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // Kill liveness at last uses. 497f54f61538688eff25f392c2062b3a654394333aaAndrew Trick bool lastUse = false; 4984dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick if (RequireIntervals) { 499f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const LiveInterval *LI = getInterval(Reg); 500f54f61538688eff25f392c2062b3a654394333aaAndrew Trick lastUse = LI && LI->killedAt(SlotIdx); 5014dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 502f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else { 503f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // Allocatable physregs are always single-use before register rewriting. 504f54f61538688eff25f392c2062b3a654394333aaAndrew Trick lastUse = !TargetRegisterInfo::isVirtualRegister(Reg); 5054dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 506f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (lastUse && isLive) { 507f54f61538688eff25f392c2062b3a654394333aaAndrew Trick LiveRegs.erase(Reg); 508f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(Reg); 509f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 510f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else if (!lastUse && !isLive) 511f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(Reg); 5124dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 5134dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 5144dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Generate liveness for defs. 515f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) { 516f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Defs[i]; 517f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (LiveRegs.insert(Reg)) 518f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(Reg); 5194dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick } 5204dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 5214dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Boost pressure for all dead defs together. 522f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(RegOpers.DeadDefs); 523f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(RegOpers.DeadDefs); 5244dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick 5254dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick // Find the next instruction. 5262b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer do 5272b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer ++CurrPos; 5282b8d0501b169c3ee81a9af1cb715e1be4d6a079eBenjamin Kramer while (CurrPos != MBB->end() && CurrPos->isDebugValue()); 5294dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick return true; 5304dfeef100d940a0c1ca22055dcb29b02a4848f65Andrew Trick} 53155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 53273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// Find the max change in excess pressure across all sets. 53373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trickstatic void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec, 53473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick ArrayRef<unsigned> NewPressureVec, 53573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick RegPressureDelta &Delta, 53673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick const TargetRegisterInfo *TRI) { 53755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick int ExcessUnits = 0; 53873a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick unsigned PSetID = ~0U; 53955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) { 54055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick unsigned POld = OldPressureVec[i]; 54155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick unsigned PNew = NewPressureVec[i]; 54255ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick int PDiff = (int)PNew - (int)POld; 54355ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (!PDiff) // No change in this set in the common case. 54455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick continue; 54555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Only consider change beyond the limit. 54655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick unsigned Limit = TRI->getRegPressureSetLimit(i); 54755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (Limit > POld) { 54855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (Limit > PNew) 54924617213ba8e9d1e0f10af33d88285a92304ab95Andrew Trick PDiff = 0; // Under the limit 55055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick else 55155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick PDiff = PNew - Limit; // Just exceeded limit. 55255ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 55355ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick else if (Limit > PNew) 55424617213ba8e9d1e0f10af33d88285a92304ab95Andrew Trick PDiff = Limit - POld; // Just obeyed limit. 55555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 55655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (std::abs(PDiff) > std::abs(ExcessUnits)) { 55755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick ExcessUnits = PDiff; 55855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick PSetID = i; 55955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 56055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 56173a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.Excess.PSetID = PSetID; 56273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.Excess.UnitIncrease = ExcessUnits; 56373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick} 56473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick 56573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// Find the max change in max pressure that either surpasses a critical PSet 56673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// limit or exceeds the current MaxPressureLimit. 56773a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// 56873a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// FIXME: comparing each element of the old and new MaxPressure vectors here is 56973a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// silly. It's done now to demonstrate the concept but will go away with a 57073a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick/// RegPressureTracker API change to work with pressure differences. 57173a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trickstatic void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec, 57273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick ArrayRef<unsigned> NewMaxPressureVec, 57373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick ArrayRef<PressureElement> CriticalPSets, 57473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick ArrayRef<unsigned> MaxPressureLimit, 57573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick RegPressureDelta &Delta) { 57673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CriticalMax = PressureElement(); 57773a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CurrentMax = PressureElement(); 57873a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick 57973a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick unsigned CritIdx = 0, CritEnd = CriticalPSets.size(); 58073a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) { 58173a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick unsigned POld = OldMaxPressureVec[i]; 58273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick unsigned PNew = NewMaxPressureVec[i]; 58373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick if (PNew == POld) // No change in this set in the common case. 58473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick continue; 58573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick 58673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick while (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID < i) 58773a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick ++CritIdx; 58873a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick 58973a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick if (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID == i) { 59073a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].UnitIncrease; 59173a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick if (PDiff > Delta.CriticalMax.UnitIncrease) { 59273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CriticalMax.PSetID = i; 59373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CriticalMax.UnitIncrease = PDiff; 59473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick } 59573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick } 59673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick 59773a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick // Find the greatest increase above MaxPressureLimit. 59873a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick // (Ignores negative MDiff). 59973a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick int MDiff = (int)PNew - (int)MaxPressureLimit[i]; 60073a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick if (MDiff > Delta.CurrentMax.UnitIncrease) { 60173a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CurrentMax.PSetID = i; 60273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CurrentMax.UnitIncrease = PNew; 60373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick } 60473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick } 60555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick} 60655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 607ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Record the upward impact of a single instruction on current register 608ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// pressure. Unlike the advance/recede pressure tracking interface, this does 609ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// not discover live in/outs. 61055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick/// 611ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// This is intended for speculative queries. It leaves pressure inconsistent 612ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// with the current position, so must be restored by the caller. 613ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) { 614f54f61538688eff25f392c2062b3a654394333aaAndrew Trick assert(!MI->isDebugValue() && "Expect a nondebug instruction."); 615f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 61655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Account for register pressure similar to RegPressureTracker::recede(). 617f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands RegOpers(TRI, MRI); 618f54f61538688eff25f392c2062b3a654394333aaAndrew Trick collectOperands(MI, RegOpers); 61955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 62055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Boost max pressure for all dead defs together. 62155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Since CurrSetPressure and MaxSetPressure 622f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(RegOpers.DeadDefs); 623f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(RegOpers.DeadDefs); 62455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 62555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Kill liveness at live defs. 626f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) { 627f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Defs[i]; 628f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (!containsReg(RegOpers.Uses, Reg)) 629f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(Reg); 630881a05b46c28299046bd0dc3d0b8c6677e68a4d7Andrew Trick } 63155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Generate liveness for uses. 632f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) { 633f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Uses[i]; 634f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (!LiveRegs.contains(Reg)) 635f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(Reg); 63655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 637ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick} 638ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 639ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Consider the pressure increase caused by traversing this instruction 640ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// bottom-up. Find the pressure set with the most change beyond its pressure 641ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// limit based on the tracker's current pressure, and return the change in 642ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// number of register units of that pressure set introduced by this 643ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// instruction. 644ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// 645ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// This assumes that the current LiveOut set is sufficient. 646ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// 647ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// FIXME: This is expensive for an on-the-fly query. We need to cache the 648ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// result per-SUnit with enough information to adjust for the current 649ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// scheduling position. But this works as a proof of concept. 650ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker:: 651ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew TrickgetMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, 652ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick ArrayRef<PressureElement> CriticalPSets, 653ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick ArrayRef<unsigned> MaxPressureLimit) { 654ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Snapshot Pressure. 655ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // FIXME: The snapshot heap space should persist. But I'm planning to 656ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // summarize the pressure effect so we don't need to snapshot at all. 657ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick std::vector<unsigned> SavedPressure = CurrSetPressure; 658ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure; 659ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 660ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick bumpUpwardPressure(MI); 661ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 66273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI); 66373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets, 66473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick MaxPressureLimit, Delta); 66573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick assert(Delta.CriticalMax.UnitIncrease >= 0 && 66673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure"); 66755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 66855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Restore the tracker's state. 66955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick P.MaxSetPressure.swap(SavedMaxPressure); 67055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick CurrSetPressure.swap(SavedPressure); 67155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick} 67255ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 67355ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick/// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx). 67455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trickstatic bool findUseBetween(unsigned Reg, 67555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick SlotIndex PriorUseIdx, SlotIndex NextUseIdx, 67655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick const MachineRegisterInfo *MRI, 67755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick const LiveIntervals *LIS) { 67855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick for (MachineRegisterInfo::use_nodbg_iterator 67955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick UI = MRI->use_nodbg_begin(Reg), UE = MRI->use_nodbg_end(); 68055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick UI != UE; UI.skipInstruction()) { 68155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick const MachineInstr* MI = &*UI; 682f3329c419b1010089e8aaf3d43b811ba12d94c8aAndrew Trick if (MI->isDebugValue()) 683f3329c419b1010089e8aaf3d43b811ba12d94c8aAndrew Trick continue; 68455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick SlotIndex InstSlot = LIS->getInstructionIndex(MI).getRegSlot(); 68555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx) 68655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick return true; 68755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 68855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick return false; 68955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick} 69055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 691ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Record the downward impact of a single instruction on current register 692ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// pressure. Unlike the advance/recede pressure tracking interface, this does 693ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// not discover live in/outs. 69455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick/// 695ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// This is intended for speculative queries. It leaves pressure inconsistent 696ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// with the current position, so must be restored by the caller. 697ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) { 698f54f61538688eff25f392c2062b3a654394333aaAndrew Trick assert(!MI->isDebugValue() && "Expect a nondebug instruction."); 699f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 70055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Account for register pressure similar to RegPressureTracker::recede(). 701f54f61538688eff25f392c2062b3a654394333aaAndrew Trick RegisterOperands RegOpers(TRI, MRI); 702f54f61538688eff25f392c2062b3a654394333aaAndrew Trick collectOperands(MI, RegOpers); 70355ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 70455ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Kill liveness at last uses. Assume allocatable physregs are single-use 70555ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // rather than checking LiveIntervals. 706f54f61538688eff25f392c2062b3a654394333aaAndrew Trick SlotIndex SlotIdx; 707f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (RequireIntervals) 708f54f61538688eff25f392c2062b3a654394333aaAndrew Trick SlotIdx = LIS->getInstructionIndex(MI).getRegSlot(); 709f54f61538688eff25f392c2062b3a654394333aaAndrew Trick 710f54f61538688eff25f392c2062b3a654394333aaAndrew Trick for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) { 711f54f61538688eff25f392c2062b3a654394333aaAndrew Trick unsigned Reg = RegOpers.Uses[i]; 712f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (RequireIntervals) { 713f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // FIXME: allow the caller to pass in the list of vreg uses that remain 714f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // to be bottom-scheduled to avoid searching uses at each query. 715657b75b9946eae763725b413841dfd01ed12a051Andrew Trick SlotIndex CurrIdx = getCurrSlot(); 716f54f61538688eff25f392c2062b3a654394333aaAndrew Trick const LiveInterval *LI = getInterval(Reg); 717f54f61538688eff25f392c2062b3a654394333aaAndrew Trick if (LI && LI->killedAt(SlotIdx) 71855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) { 719f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(Reg); 72055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 72155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 722f54f61538688eff25f392c2062b3a654394333aaAndrew Trick else if (!TargetRegisterInfo::isVirtualRegister(Reg)) { 723f54f61538688eff25f392c2062b3a654394333aaAndrew Trick // Allocatable physregs are always single-use before register rewriting. 724f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(Reg); 725f54f61538688eff25f392c2062b3a654394333aaAndrew Trick } 72655ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick } 72755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 72855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Generate liveness for defs. 729f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(RegOpers.Defs); 73055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 73155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Boost pressure for all dead defs together. 732f54f61538688eff25f392c2062b3a654394333aaAndrew Trick increaseRegPressure(RegOpers.DeadDefs); 733f54f61538688eff25f392c2062b3a654394333aaAndrew Trick decreaseRegPressure(RegOpers.DeadDefs); 734ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick} 735ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 736ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Consider the pressure increase caused by traversing this instruction 737ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// top-down. Find the register class with the most change in its pressure limit 738ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// based on the tracker's current pressure, and return the number of excess 739ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// register units of that pressure set introduced by this instruction. 740ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// 741ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// This assumes that the current LiveIn set is sufficient. 742ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker:: 743ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew TrickgetMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, 744ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick ArrayRef<PressureElement> CriticalPSets, 745ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick ArrayRef<unsigned> MaxPressureLimit) { 746ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Snapshot Pressure. 747ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick std::vector<unsigned> SavedPressure = CurrSetPressure; 748ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure; 749ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 750ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick bumpDownwardPressure(MI); 75155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 75273a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI); 75373a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets, 75473a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick MaxPressureLimit, Delta); 75573a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick assert(Delta.CriticalMax.UnitIncrease >= 0 && 75673a0d8ecf838a9b333c9865d2a4b72c5768fb49fAndrew Trick Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure"); 75755ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick 75855ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick // Restore the tracker's state. 75955ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick P.MaxSetPressure.swap(SavedMaxPressure); 76055ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick CurrSetPressure.swap(SavedPressure); 76155ba5dff3c1a723adf302f1124aafde797dbf31aAndrew Trick} 762ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 763ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Get the pressure of each PSet after traversing this instruction bottom-up. 764ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker:: 765ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew TrickgetUpwardPressure(const MachineInstr *MI, 7660eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick std::vector<unsigned> &PressureResult, 7670eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick std::vector<unsigned> &MaxPressureResult) { 768ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Snapshot pressure. 769ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick PressureResult = CurrSetPressure; 7700eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick MaxPressureResult = P.MaxSetPressure; 771ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 772ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick bumpUpwardPressure(MI); 773ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 774ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Current pressure becomes the result. Restore current pressure. 7750eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick P.MaxSetPressure.swap(MaxPressureResult); 776ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick CurrSetPressure.swap(PressureResult); 777ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick} 778ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 779ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick/// Get the pressure of each PSet after traversing this instruction top-down. 780ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trickvoid RegPressureTracker:: 781ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew TrickgetDownwardPressure(const MachineInstr *MI, 7820eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick std::vector<unsigned> &PressureResult, 7830eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick std::vector<unsigned> &MaxPressureResult) { 784ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Snapshot pressure. 785ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick PressureResult = CurrSetPressure; 7860eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick MaxPressureResult = P.MaxSetPressure; 787ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 788ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick bumpDownwardPressure(MI); 789ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick 790ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick // Current pressure becomes the result. Restore current pressure. 7910eb3a3524e9d68642e574780d19c781386ed4469Andrew Trick P.MaxSetPressure.swap(MaxPressureResult); 792ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick CurrSetPressure.swap(PressureResult); 793ba17293a8827a7e0e390b0a1d6075148a58d9eddAndrew Trick} 794