xref: /aosp_15_r20/external/llvm/lib/CodeGen/RegisterPressure.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- RegisterPressure.cpp - Dynamic Register Pressure ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the RegisterPressure class which can be used to track
11*9880d681SAndroid Build Coastguard Worker // MachineInstr level register pressure.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterPressure.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveInterval.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterClassInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker /// Increase pressure for each pressure set provided by TargetRegisterInfo.
increaseSetPressure(std::vector<unsigned> & CurrSetPressure,const MachineRegisterInfo & MRI,unsigned Reg,LaneBitmask PrevMask,LaneBitmask NewMask)26*9880d681SAndroid Build Coastguard Worker static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
27*9880d681SAndroid Build Coastguard Worker                                 const MachineRegisterInfo &MRI, unsigned Reg,
28*9880d681SAndroid Build Coastguard Worker                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
29*9880d681SAndroid Build Coastguard Worker   assert((PrevMask & ~NewMask) == 0 && "Must not remove bits");
30*9880d681SAndroid Build Coastguard Worker   if (PrevMask != 0 || NewMask == 0)
31*9880d681SAndroid Build Coastguard Worker     return;
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker   PSetIterator PSetI = MRI.getPressureSets(Reg);
34*9880d681SAndroid Build Coastguard Worker   unsigned Weight = PSetI.getWeight();
35*9880d681SAndroid Build Coastguard Worker   for (; PSetI.isValid(); ++PSetI)
36*9880d681SAndroid Build Coastguard Worker     CurrSetPressure[*PSetI] += Weight;
37*9880d681SAndroid Build Coastguard Worker }
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker /// Decrease pressure for each pressure set provided by TargetRegisterInfo.
decreaseSetPressure(std::vector<unsigned> & CurrSetPressure,const MachineRegisterInfo & MRI,unsigned Reg,LaneBitmask PrevMask,LaneBitmask NewMask)40*9880d681SAndroid Build Coastguard Worker static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
41*9880d681SAndroid Build Coastguard Worker                                 const MachineRegisterInfo &MRI, unsigned Reg,
42*9880d681SAndroid Build Coastguard Worker                                 LaneBitmask PrevMask, LaneBitmask NewMask) {
43*9880d681SAndroid Build Coastguard Worker   assert((NewMask & !PrevMask) == 0 && "Must not add bits");
44*9880d681SAndroid Build Coastguard Worker   if (NewMask != 0 || PrevMask == 0)
45*9880d681SAndroid Build Coastguard Worker     return;
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker   PSetIterator PSetI = MRI.getPressureSets(Reg);
48*9880d681SAndroid Build Coastguard Worker   unsigned Weight = PSetI.getWeight();
49*9880d681SAndroid Build Coastguard Worker   for (; PSetI.isValid(); ++PSetI) {
50*9880d681SAndroid Build Coastguard Worker     assert(CurrSetPressure[*PSetI] >= Weight && "register pressure underflow");
51*9880d681SAndroid Build Coastguard Worker     CurrSetPressure[*PSetI] -= Weight;
52*9880d681SAndroid Build Coastguard Worker   }
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD
dumpRegSetPressure(ArrayRef<unsigned> SetPressure,const TargetRegisterInfo * TRI)56*9880d681SAndroid Build Coastguard Worker void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
57*9880d681SAndroid Build Coastguard Worker                               const TargetRegisterInfo *TRI) {
58*9880d681SAndroid Build Coastguard Worker   bool Empty = true;
59*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) {
60*9880d681SAndroid Build Coastguard Worker     if (SetPressure[i] != 0) {
61*9880d681SAndroid Build Coastguard Worker       dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n';
62*9880d681SAndroid Build Coastguard Worker       Empty = false;
63*9880d681SAndroid Build Coastguard Worker     }
64*9880d681SAndroid Build Coastguard Worker   }
65*9880d681SAndroid Build Coastguard Worker   if (Empty)
66*9880d681SAndroid Build Coastguard Worker     dbgs() << "\n";
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD
dump(const TargetRegisterInfo * TRI) const70*9880d681SAndroid Build Coastguard Worker void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
71*9880d681SAndroid Build Coastguard Worker   dbgs() << "Max Pressure: ";
72*9880d681SAndroid Build Coastguard Worker   dumpRegSetPressure(MaxSetPressure, TRI);
73*9880d681SAndroid Build Coastguard Worker   dbgs() << "Live In: ";
74*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : LiveInRegs) {
75*9880d681SAndroid Build Coastguard Worker     dbgs() << PrintVRegOrUnit(P.RegUnit, TRI);
76*9880d681SAndroid Build Coastguard Worker     if (P.LaneMask != ~0u)
77*9880d681SAndroid Build Coastguard Worker       dbgs() << ':' << PrintLaneMask(P.LaneMask);
78*9880d681SAndroid Build Coastguard Worker     dbgs() << ' ';
79*9880d681SAndroid Build Coastguard Worker   }
80*9880d681SAndroid Build Coastguard Worker   dbgs() << '\n';
81*9880d681SAndroid Build Coastguard Worker   dbgs() << "Live Out: ";
82*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : LiveOutRegs) {
83*9880d681SAndroid Build Coastguard Worker     dbgs() << PrintVRegOrUnit(P.RegUnit, TRI);
84*9880d681SAndroid Build Coastguard Worker     if (P.LaneMask != ~0u)
85*9880d681SAndroid Build Coastguard Worker       dbgs() << ':' << PrintLaneMask(P.LaneMask);
86*9880d681SAndroid Build Coastguard Worker     dbgs() << ' ';
87*9880d681SAndroid Build Coastguard Worker   }
88*9880d681SAndroid Build Coastguard Worker   dbgs() << '\n';
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD
dump() const92*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::dump() const {
93*9880d681SAndroid Build Coastguard Worker   if (!isTopClosed() || !isBottomClosed()) {
94*9880d681SAndroid Build Coastguard Worker     dbgs() << "Curr Pressure: ";
95*9880d681SAndroid Build Coastguard Worker     dumpRegSetPressure(CurrSetPressure, TRI);
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker   P.dump(TRI);
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker 
dump(const TargetRegisterInfo & TRI) const100*9880d681SAndroid Build Coastguard Worker void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
101*9880d681SAndroid Build Coastguard Worker   const char *sep = "";
102*9880d681SAndroid Build Coastguard Worker   for (const PressureChange &Change : *this) {
103*9880d681SAndroid Build Coastguard Worker     if (!Change.isValid())
104*9880d681SAndroid Build Coastguard Worker       break;
105*9880d681SAndroid Build Coastguard Worker     dbgs() << sep << TRI.getRegPressureSetName(Change.getPSet())
106*9880d681SAndroid Build Coastguard Worker            << " " << Change.getUnitInc();
107*9880d681SAndroid Build Coastguard Worker     sep = "    ";
108*9880d681SAndroid Build Coastguard Worker   }
109*9880d681SAndroid Build Coastguard Worker   dbgs() << '\n';
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker 
increaseRegPressure(unsigned RegUnit,LaneBitmask PreviousMask,LaneBitmask NewMask)112*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::increaseRegPressure(unsigned RegUnit,
113*9880d681SAndroid Build Coastguard Worker                                              LaneBitmask PreviousMask,
114*9880d681SAndroid Build Coastguard Worker                                              LaneBitmask NewMask) {
115*9880d681SAndroid Build Coastguard Worker   if (PreviousMask != 0 || NewMask == 0)
116*9880d681SAndroid Build Coastguard Worker     return;
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
119*9880d681SAndroid Build Coastguard Worker   unsigned Weight = PSetI.getWeight();
120*9880d681SAndroid Build Coastguard Worker   for (; PSetI.isValid(); ++PSetI) {
121*9880d681SAndroid Build Coastguard Worker     CurrSetPressure[*PSetI] += Weight;
122*9880d681SAndroid Build Coastguard Worker     P.MaxSetPressure[*PSetI] =
123*9880d681SAndroid Build Coastguard Worker         std::max(P.MaxSetPressure[*PSetI], CurrSetPressure[*PSetI]);
124*9880d681SAndroid Build Coastguard Worker   }
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker 
decreaseRegPressure(unsigned RegUnit,LaneBitmask PreviousMask,LaneBitmask NewMask)127*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::decreaseRegPressure(unsigned RegUnit,
128*9880d681SAndroid Build Coastguard Worker                                              LaneBitmask PreviousMask,
129*9880d681SAndroid Build Coastguard Worker                                              LaneBitmask NewMask) {
130*9880d681SAndroid Build Coastguard Worker   decreaseSetPressure(CurrSetPressure, *MRI, RegUnit, PreviousMask, NewMask);
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker /// Clear the result so it can be used for another round of pressure tracking.
reset()134*9880d681SAndroid Build Coastguard Worker void IntervalPressure::reset() {
135*9880d681SAndroid Build Coastguard Worker   TopIdx = BottomIdx = SlotIndex();
136*9880d681SAndroid Build Coastguard Worker   MaxSetPressure.clear();
137*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
138*9880d681SAndroid Build Coastguard Worker   LiveOutRegs.clear();
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker 
141*9880d681SAndroid Build Coastguard Worker /// Clear the result so it can be used for another round of pressure tracking.
reset()142*9880d681SAndroid Build Coastguard Worker void RegionPressure::reset() {
143*9880d681SAndroid Build Coastguard Worker   TopPos = BottomPos = MachineBasicBlock::const_iterator();
144*9880d681SAndroid Build Coastguard Worker   MaxSetPressure.clear();
145*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
146*9880d681SAndroid Build Coastguard Worker   LiveOutRegs.clear();
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker /// If the current top is not less than or equal to the next index, open it.
150*9880d681SAndroid Build Coastguard Worker /// We happen to need the SlotIndex for the next top for pressure update.
openTop(SlotIndex NextTop)151*9880d681SAndroid Build Coastguard Worker void IntervalPressure::openTop(SlotIndex NextTop) {
152*9880d681SAndroid Build Coastguard Worker   if (TopIdx <= NextTop)
153*9880d681SAndroid Build Coastguard Worker     return;
154*9880d681SAndroid Build Coastguard Worker   TopIdx = SlotIndex();
155*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker /// If the current top is the previous instruction (before receding), open it.
openTop(MachineBasicBlock::const_iterator PrevTop)159*9880d681SAndroid Build Coastguard Worker void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
160*9880d681SAndroid Build Coastguard Worker   if (TopPos != PrevTop)
161*9880d681SAndroid Build Coastguard Worker     return;
162*9880d681SAndroid Build Coastguard Worker   TopPos = MachineBasicBlock::const_iterator();
163*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker /// If the current bottom is not greater than the previous index, open it.
openBottom(SlotIndex PrevBottom)167*9880d681SAndroid Build Coastguard Worker void IntervalPressure::openBottom(SlotIndex PrevBottom) {
168*9880d681SAndroid Build Coastguard Worker   if (BottomIdx > PrevBottom)
169*9880d681SAndroid Build Coastguard Worker     return;
170*9880d681SAndroid Build Coastguard Worker   BottomIdx = SlotIndex();
171*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker /// If the current bottom is the previous instr (before advancing), open it.
openBottom(MachineBasicBlock::const_iterator PrevBottom)175*9880d681SAndroid Build Coastguard Worker void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
176*9880d681SAndroid Build Coastguard Worker   if (BottomPos != PrevBottom)
177*9880d681SAndroid Build Coastguard Worker     return;
178*9880d681SAndroid Build Coastguard Worker   BottomPos = MachineBasicBlock::const_iterator();
179*9880d681SAndroid Build Coastguard Worker   LiveInRegs.clear();
180*9880d681SAndroid Build Coastguard Worker }
181*9880d681SAndroid Build Coastguard Worker 
init(const MachineRegisterInfo & MRI)182*9880d681SAndroid Build Coastguard Worker void LiveRegSet::init(const MachineRegisterInfo &MRI) {
183*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
184*9880d681SAndroid Build Coastguard Worker   unsigned NumRegUnits = TRI.getNumRegs();
185*9880d681SAndroid Build Coastguard Worker   unsigned NumVirtRegs = MRI.getNumVirtRegs();
186*9880d681SAndroid Build Coastguard Worker   Regs.setUniverse(NumRegUnits + NumVirtRegs);
187*9880d681SAndroid Build Coastguard Worker   this->NumRegUnits = NumRegUnits;
188*9880d681SAndroid Build Coastguard Worker }
189*9880d681SAndroid Build Coastguard Worker 
clear()190*9880d681SAndroid Build Coastguard Worker void LiveRegSet::clear() {
191*9880d681SAndroid Build Coastguard Worker   Regs.clear();
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker 
getLiveRange(const LiveIntervals & LIS,unsigned Reg)194*9880d681SAndroid Build Coastguard Worker static const LiveRange *getLiveRange(const LiveIntervals &LIS, unsigned Reg) {
195*9880d681SAndroid Build Coastguard Worker   if (TargetRegisterInfo::isVirtualRegister(Reg))
196*9880d681SAndroid Build Coastguard Worker     return &LIS.getInterval(Reg);
197*9880d681SAndroid Build Coastguard Worker   return LIS.getCachedRegUnit(Reg);
198*9880d681SAndroid Build Coastguard Worker }
199*9880d681SAndroid Build Coastguard Worker 
reset()200*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::reset() {
201*9880d681SAndroid Build Coastguard Worker   MBB = nullptr;
202*9880d681SAndroid Build Coastguard Worker   LIS = nullptr;
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.clear();
205*9880d681SAndroid Build Coastguard Worker   LiveThruPressure.clear();
206*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure.clear();
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
209*9880d681SAndroid Build Coastguard Worker     static_cast<IntervalPressure&>(P).reset();
210*9880d681SAndroid Build Coastguard Worker   else
211*9880d681SAndroid Build Coastguard Worker     static_cast<RegionPressure&>(P).reset();
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   LiveRegs.clear();
214*9880d681SAndroid Build Coastguard Worker   UntiedDefs.clear();
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker /// Setup the RegPressureTracker.
218*9880d681SAndroid Build Coastguard Worker ///
219*9880d681SAndroid Build Coastguard Worker /// TODO: Add support for pressure without LiveIntervals.
init(const MachineFunction * mf,const RegisterClassInfo * rci,const LiveIntervals * lis,const MachineBasicBlock * mbb,MachineBasicBlock::const_iterator pos,bool TrackLaneMasks,bool TrackUntiedDefs)220*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::init(const MachineFunction *mf,
221*9880d681SAndroid Build Coastguard Worker                               const RegisterClassInfo *rci,
222*9880d681SAndroid Build Coastguard Worker                               const LiveIntervals *lis,
223*9880d681SAndroid Build Coastguard Worker                               const MachineBasicBlock *mbb,
224*9880d681SAndroid Build Coastguard Worker                               MachineBasicBlock::const_iterator pos,
225*9880d681SAndroid Build Coastguard Worker                               bool TrackLaneMasks, bool TrackUntiedDefs) {
226*9880d681SAndroid Build Coastguard Worker   reset();
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   MF = mf;
229*9880d681SAndroid Build Coastguard Worker   TRI = MF->getSubtarget().getRegisterInfo();
230*9880d681SAndroid Build Coastguard Worker   RCI = rci;
231*9880d681SAndroid Build Coastguard Worker   MRI = &MF->getRegInfo();
232*9880d681SAndroid Build Coastguard Worker   MBB = mbb;
233*9880d681SAndroid Build Coastguard Worker   this->TrackUntiedDefs = TrackUntiedDefs;
234*9880d681SAndroid Build Coastguard Worker   this->TrackLaneMasks = TrackLaneMasks;
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals) {
237*9880d681SAndroid Build Coastguard Worker     assert(lis && "IntervalPressure requires LiveIntervals");
238*9880d681SAndroid Build Coastguard Worker     LIS = lis;
239*9880d681SAndroid Build Coastguard Worker   }
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker   CurrPos = pos;
242*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
243*9880d681SAndroid Build Coastguard Worker 
244*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure = CurrSetPressure;
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker   LiveRegs.init(*MRI);
247*9880d681SAndroid Build Coastguard Worker   if (TrackUntiedDefs)
248*9880d681SAndroid Build Coastguard Worker     UntiedDefs.setUniverse(MRI->getNumVirtRegs());
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker /// Does this pressure result have a valid top position and live ins.
isTopClosed() const252*9880d681SAndroid Build Coastguard Worker bool RegPressureTracker::isTopClosed() const {
253*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
254*9880d681SAndroid Build Coastguard Worker     return static_cast<IntervalPressure&>(P).TopIdx.isValid();
255*9880d681SAndroid Build Coastguard Worker   return (static_cast<RegionPressure&>(P).TopPos ==
256*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock::const_iterator());
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker 
259*9880d681SAndroid Build Coastguard Worker /// Does this pressure result have a valid bottom position and live outs.
isBottomClosed() const260*9880d681SAndroid Build Coastguard Worker bool RegPressureTracker::isBottomClosed() const {
261*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
262*9880d681SAndroid Build Coastguard Worker     return static_cast<IntervalPressure&>(P).BottomIdx.isValid();
263*9880d681SAndroid Build Coastguard Worker   return (static_cast<RegionPressure&>(P).BottomPos ==
264*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock::const_iterator());
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker 
getCurrSlot() const268*9880d681SAndroid Build Coastguard Worker SlotIndex RegPressureTracker::getCurrSlot() const {
269*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator IdxPos = CurrPos;
270*9880d681SAndroid Build Coastguard Worker   while (IdxPos != MBB->end() && IdxPos->isDebugValue())
271*9880d681SAndroid Build Coastguard Worker     ++IdxPos;
272*9880d681SAndroid Build Coastguard Worker   if (IdxPos == MBB->end())
273*9880d681SAndroid Build Coastguard Worker     return LIS->getMBBEndIdx(MBB);
274*9880d681SAndroid Build Coastguard Worker   return LIS->getInstructionIndex(*IdxPos).getRegSlot();
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker 
277*9880d681SAndroid Build Coastguard Worker /// Set the boundary for the top of the region and summarize live ins.
closeTop()278*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::closeTop() {
279*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
280*9880d681SAndroid Build Coastguard Worker     static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot();
281*9880d681SAndroid Build Coastguard Worker   else
282*9880d681SAndroid Build Coastguard Worker     static_cast<RegionPressure&>(P).TopPos = CurrPos;
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker   assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
285*9880d681SAndroid Build Coastguard Worker   P.LiveInRegs.reserve(LiveRegs.size());
286*9880d681SAndroid Build Coastguard Worker   LiveRegs.appendTo(P.LiveInRegs);
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker 
289*9880d681SAndroid Build Coastguard Worker /// Set the boundary for the bottom of the region and summarize live outs.
closeBottom()290*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::closeBottom() {
291*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
292*9880d681SAndroid Build Coastguard Worker     static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot();
293*9880d681SAndroid Build Coastguard Worker   else
294*9880d681SAndroid Build Coastguard Worker     static_cast<RegionPressure&>(P).BottomPos = CurrPos;
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker   assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
297*9880d681SAndroid Build Coastguard Worker   P.LiveOutRegs.reserve(LiveRegs.size());
298*9880d681SAndroid Build Coastguard Worker   LiveRegs.appendTo(P.LiveOutRegs);
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker /// Finalize the region boundaries and record live ins and live outs.
closeRegion()302*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::closeRegion() {
303*9880d681SAndroid Build Coastguard Worker   if (!isTopClosed() && !isBottomClosed()) {
304*9880d681SAndroid Build Coastguard Worker     assert(LiveRegs.size() == 0 && "no region boundary");
305*9880d681SAndroid Build Coastguard Worker     return;
306*9880d681SAndroid Build Coastguard Worker   }
307*9880d681SAndroid Build Coastguard Worker   if (!isBottomClosed())
308*9880d681SAndroid Build Coastguard Worker     closeBottom();
309*9880d681SAndroid Build Coastguard Worker   else if (!isTopClosed())
310*9880d681SAndroid Build Coastguard Worker     closeTop();
311*9880d681SAndroid Build Coastguard Worker   // If both top and bottom are closed, do nothing.
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker 
314*9880d681SAndroid Build Coastguard Worker /// The register tracker is unaware of global liveness so ignores normal
315*9880d681SAndroid Build Coastguard Worker /// live-thru ranges. However, two-address or coalesced chains can also lead
316*9880d681SAndroid Build Coastguard Worker /// to live ranges with no holes. Count these to inform heuristics that we
317*9880d681SAndroid Build Coastguard Worker /// can never drop below this pressure.
initLiveThru(const RegPressureTracker & RPTracker)318*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
319*9880d681SAndroid Build Coastguard Worker   LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
320*9880d681SAndroid Build Coastguard Worker   assert(isBottomClosed() && "need bottom-up tracking to intialize.");
321*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Pair : P.LiveOutRegs) {
322*9880d681SAndroid Build Coastguard Worker     unsigned RegUnit = Pair.RegUnit;
323*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(RegUnit)
324*9880d681SAndroid Build Coastguard Worker         && !RPTracker.hasUntiedDef(RegUnit))
325*9880d681SAndroid Build Coastguard Worker       increaseSetPressure(LiveThruPressure, *MRI, RegUnit, 0, Pair.LaneMask);
326*9880d681SAndroid Build Coastguard Worker   }
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker 
getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,unsigned RegUnit)329*9880d681SAndroid Build Coastguard Worker static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
330*9880d681SAndroid Build Coastguard Worker                                unsigned RegUnit) {
331*9880d681SAndroid Build Coastguard Worker   auto I = std::find_if(RegUnits.begin(), RegUnits.end(),
332*9880d681SAndroid Build Coastguard Worker                         [RegUnit](const RegisterMaskPair Other) {
333*9880d681SAndroid Build Coastguard Worker                         return Other.RegUnit == RegUnit;
334*9880d681SAndroid Build Coastguard Worker                         });
335*9880d681SAndroid Build Coastguard Worker   if (I == RegUnits.end())
336*9880d681SAndroid Build Coastguard Worker     return 0;
337*9880d681SAndroid Build Coastguard Worker   return I->LaneMask;
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker 
addRegLanes(SmallVectorImpl<RegisterMaskPair> & RegUnits,RegisterMaskPair Pair)340*9880d681SAndroid Build Coastguard Worker static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
341*9880d681SAndroid Build Coastguard Worker                         RegisterMaskPair Pair) {
342*9880d681SAndroid Build Coastguard Worker   unsigned RegUnit = Pair.RegUnit;
343*9880d681SAndroid Build Coastguard Worker   assert(Pair.LaneMask != 0);
344*9880d681SAndroid Build Coastguard Worker   auto I = std::find_if(RegUnits.begin(), RegUnits.end(),
345*9880d681SAndroid Build Coastguard Worker                         [RegUnit](const RegisterMaskPair Other) {
346*9880d681SAndroid Build Coastguard Worker                           return Other.RegUnit == RegUnit;
347*9880d681SAndroid Build Coastguard Worker                         });
348*9880d681SAndroid Build Coastguard Worker   if (I == RegUnits.end()) {
349*9880d681SAndroid Build Coastguard Worker     RegUnits.push_back(Pair);
350*9880d681SAndroid Build Coastguard Worker   } else {
351*9880d681SAndroid Build Coastguard Worker     I->LaneMask |= Pair.LaneMask;
352*9880d681SAndroid Build Coastguard Worker   }
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker 
setRegZero(SmallVectorImpl<RegisterMaskPair> & RegUnits,unsigned RegUnit)355*9880d681SAndroid Build Coastguard Worker static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
356*9880d681SAndroid Build Coastguard Worker                        unsigned RegUnit) {
357*9880d681SAndroid Build Coastguard Worker   auto I = std::find_if(RegUnits.begin(), RegUnits.end(),
358*9880d681SAndroid Build Coastguard Worker                         [RegUnit](const RegisterMaskPair Other) {
359*9880d681SAndroid Build Coastguard Worker                           return Other.RegUnit == RegUnit;
360*9880d681SAndroid Build Coastguard Worker                         });
361*9880d681SAndroid Build Coastguard Worker   if (I == RegUnits.end()) {
362*9880d681SAndroid Build Coastguard Worker     RegUnits.push_back(RegisterMaskPair(RegUnit, 0));
363*9880d681SAndroid Build Coastguard Worker   } else {
364*9880d681SAndroid Build Coastguard Worker     I->LaneMask = 0;
365*9880d681SAndroid Build Coastguard Worker   }
366*9880d681SAndroid Build Coastguard Worker }
367*9880d681SAndroid Build Coastguard Worker 
removeRegLanes(SmallVectorImpl<RegisterMaskPair> & RegUnits,RegisterMaskPair Pair)368*9880d681SAndroid Build Coastguard Worker static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
369*9880d681SAndroid Build Coastguard Worker                            RegisterMaskPair Pair) {
370*9880d681SAndroid Build Coastguard Worker   unsigned RegUnit = Pair.RegUnit;
371*9880d681SAndroid Build Coastguard Worker   assert(Pair.LaneMask != 0);
372*9880d681SAndroid Build Coastguard Worker   auto I = std::find_if(RegUnits.begin(), RegUnits.end(),
373*9880d681SAndroid Build Coastguard Worker                         [RegUnit](const RegisterMaskPair Other) {
374*9880d681SAndroid Build Coastguard Worker                           return Other.RegUnit == RegUnit;
375*9880d681SAndroid Build Coastguard Worker                         });
376*9880d681SAndroid Build Coastguard Worker   if (I != RegUnits.end()) {
377*9880d681SAndroid Build Coastguard Worker     I->LaneMask &= ~Pair.LaneMask;
378*9880d681SAndroid Build Coastguard Worker     if (I->LaneMask == 0)
379*9880d681SAndroid Build Coastguard Worker       RegUnits.erase(I);
380*9880d681SAndroid Build Coastguard Worker   }
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker 
getLanesWithProperty(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,bool TrackLaneMasks,unsigned RegUnit,SlotIndex Pos,LaneBitmask SafeDefault,bool (* Property)(const LiveRange & LR,SlotIndex Pos))383*9880d681SAndroid Build Coastguard Worker static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
384*9880d681SAndroid Build Coastguard Worker     const MachineRegisterInfo &MRI, bool TrackLaneMasks, unsigned RegUnit,
385*9880d681SAndroid Build Coastguard Worker     SlotIndex Pos, LaneBitmask SafeDefault,
386*9880d681SAndroid Build Coastguard Worker     bool(*Property)(const LiveRange &LR, SlotIndex Pos)) {
387*9880d681SAndroid Build Coastguard Worker   if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
388*9880d681SAndroid Build Coastguard Worker     const LiveInterval &LI = LIS.getInterval(RegUnit);
389*9880d681SAndroid Build Coastguard Worker     LaneBitmask Result = 0;
390*9880d681SAndroid Build Coastguard Worker     if (TrackLaneMasks && LI.hasSubRanges()) {
391*9880d681SAndroid Build Coastguard Worker         for (const LiveInterval::SubRange &SR : LI.subranges()) {
392*9880d681SAndroid Build Coastguard Worker           if (Property(SR, Pos))
393*9880d681SAndroid Build Coastguard Worker             Result |= SR.LaneMask;
394*9880d681SAndroid Build Coastguard Worker         }
395*9880d681SAndroid Build Coastguard Worker     } else if (Property(LI, Pos)) {
396*9880d681SAndroid Build Coastguard Worker       Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit) : ~0u;
397*9880d681SAndroid Build Coastguard Worker     }
398*9880d681SAndroid Build Coastguard Worker 
399*9880d681SAndroid Build Coastguard Worker     return Result;
400*9880d681SAndroid Build Coastguard Worker   } else {
401*9880d681SAndroid Build Coastguard Worker     const LiveRange *LR = LIS.getCachedRegUnit(RegUnit);
402*9880d681SAndroid Build Coastguard Worker     // Be prepared for missing liveranges: We usually do not compute liveranges
403*9880d681SAndroid Build Coastguard Worker     // for physical registers on targets with many registers (GPUs).
404*9880d681SAndroid Build Coastguard Worker     if (LR == nullptr)
405*9880d681SAndroid Build Coastguard Worker       return SafeDefault;
406*9880d681SAndroid Build Coastguard Worker     return Property(*LR, Pos) ? ~0u : 0;
407*9880d681SAndroid Build Coastguard Worker   }
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker 
getLiveLanesAt(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,bool TrackLaneMasks,unsigned RegUnit,SlotIndex Pos)410*9880d681SAndroid Build Coastguard Worker static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
411*9880d681SAndroid Build Coastguard Worker                                   const MachineRegisterInfo &MRI,
412*9880d681SAndroid Build Coastguard Worker                                   bool TrackLaneMasks, unsigned RegUnit,
413*9880d681SAndroid Build Coastguard Worker                                   SlotIndex Pos) {
414*9880d681SAndroid Build Coastguard Worker   return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
415*9880d681SAndroid Build Coastguard Worker                               [](const LiveRange &LR, SlotIndex Pos) {
416*9880d681SAndroid Build Coastguard Worker                                 return LR.liveAt(Pos);
417*9880d681SAndroid Build Coastguard Worker                               });
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker 
420*9880d681SAndroid Build Coastguard Worker 
421*9880d681SAndroid Build Coastguard Worker namespace {
422*9880d681SAndroid Build Coastguard Worker 
423*9880d681SAndroid Build Coastguard Worker /// Collect this instruction's unique uses and defs into SmallVectors for
424*9880d681SAndroid Build Coastguard Worker /// processing defs and uses in order.
425*9880d681SAndroid Build Coastguard Worker ///
426*9880d681SAndroid Build Coastguard Worker /// FIXME: always ignore tied opers
427*9880d681SAndroid Build Coastguard Worker class RegisterOperandsCollector {
428*9880d681SAndroid Build Coastguard Worker   RegisterOperands &RegOpers;
429*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI;
430*9880d681SAndroid Build Coastguard Worker   const MachineRegisterInfo &MRI;
431*9880d681SAndroid Build Coastguard Worker   bool IgnoreDead;
432*9880d681SAndroid Build Coastguard Worker 
RegisterOperandsCollector(RegisterOperands & RegOpers,const TargetRegisterInfo & TRI,const MachineRegisterInfo & MRI,bool IgnoreDead)433*9880d681SAndroid Build Coastguard Worker   RegisterOperandsCollector(RegisterOperands &RegOpers,
434*9880d681SAndroid Build Coastguard Worker                             const TargetRegisterInfo &TRI,
435*9880d681SAndroid Build Coastguard Worker                             const MachineRegisterInfo &MRI, bool IgnoreDead)
436*9880d681SAndroid Build Coastguard Worker     : RegOpers(RegOpers), TRI(TRI), MRI(MRI), IgnoreDead(IgnoreDead) {}
437*9880d681SAndroid Build Coastguard Worker 
collectInstr(const MachineInstr & MI) const438*9880d681SAndroid Build Coastguard Worker   void collectInstr(const MachineInstr &MI) const {
439*9880d681SAndroid Build Coastguard Worker     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
440*9880d681SAndroid Build Coastguard Worker       collectOperand(*OperI);
441*9880d681SAndroid Build Coastguard Worker 
442*9880d681SAndroid Build Coastguard Worker     // Remove redundant physreg dead defs.
443*9880d681SAndroid Build Coastguard Worker     for (const RegisterMaskPair &P : RegOpers.Defs)
444*9880d681SAndroid Build Coastguard Worker       removeRegLanes(RegOpers.DeadDefs, P);
445*9880d681SAndroid Build Coastguard Worker   }
446*9880d681SAndroid Build Coastguard Worker 
collectInstrLanes(const MachineInstr & MI) const447*9880d681SAndroid Build Coastguard Worker   void collectInstrLanes(const MachineInstr &MI) const {
448*9880d681SAndroid Build Coastguard Worker     for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
449*9880d681SAndroid Build Coastguard Worker       collectOperandLanes(*OperI);
450*9880d681SAndroid Build Coastguard Worker 
451*9880d681SAndroid Build Coastguard Worker     // Remove redundant physreg dead defs.
452*9880d681SAndroid Build Coastguard Worker     for (const RegisterMaskPair &P : RegOpers.Defs)
453*9880d681SAndroid Build Coastguard Worker       removeRegLanes(RegOpers.DeadDefs, P);
454*9880d681SAndroid Build Coastguard Worker   }
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   /// Push this operand's register onto the correct vectors.
collectOperand(const MachineOperand & MO) const457*9880d681SAndroid Build Coastguard Worker   void collectOperand(const MachineOperand &MO) const {
458*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || !MO.getReg())
459*9880d681SAndroid Build Coastguard Worker       return;
460*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
461*9880d681SAndroid Build Coastguard Worker     if (MO.isUse()) {
462*9880d681SAndroid Build Coastguard Worker       if (!MO.isUndef() && !MO.isInternalRead())
463*9880d681SAndroid Build Coastguard Worker         pushReg(Reg, RegOpers.Uses);
464*9880d681SAndroid Build Coastguard Worker     } else {
465*9880d681SAndroid Build Coastguard Worker       assert(MO.isDef());
466*9880d681SAndroid Build Coastguard Worker       // Subregister definitions may imply a register read.
467*9880d681SAndroid Build Coastguard Worker       if (MO.readsReg())
468*9880d681SAndroid Build Coastguard Worker         pushReg(Reg, RegOpers.Uses);
469*9880d681SAndroid Build Coastguard Worker 
470*9880d681SAndroid Build Coastguard Worker       if (MO.isDead()) {
471*9880d681SAndroid Build Coastguard Worker         if (!IgnoreDead)
472*9880d681SAndroid Build Coastguard Worker           pushReg(Reg, RegOpers.DeadDefs);
473*9880d681SAndroid Build Coastguard Worker       } else
474*9880d681SAndroid Build Coastguard Worker         pushReg(Reg, RegOpers.Defs);
475*9880d681SAndroid Build Coastguard Worker     }
476*9880d681SAndroid Build Coastguard Worker   }
477*9880d681SAndroid Build Coastguard Worker 
pushReg(unsigned Reg,SmallVectorImpl<RegisterMaskPair> & RegUnits) const478*9880d681SAndroid Build Coastguard Worker   void pushReg(unsigned Reg,
479*9880d681SAndroid Build Coastguard Worker                SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
480*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
481*9880d681SAndroid Build Coastguard Worker       addRegLanes(RegUnits, RegisterMaskPair(Reg, ~0u));
482*9880d681SAndroid Build Coastguard Worker     } else if (MRI.isAllocatable(Reg)) {
483*9880d681SAndroid Build Coastguard Worker       for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
484*9880d681SAndroid Build Coastguard Worker         addRegLanes(RegUnits, RegisterMaskPair(*Units, ~0u));
485*9880d681SAndroid Build Coastguard Worker     }
486*9880d681SAndroid Build Coastguard Worker   }
487*9880d681SAndroid Build Coastguard Worker 
collectOperandLanes(const MachineOperand & MO) const488*9880d681SAndroid Build Coastguard Worker   void collectOperandLanes(const MachineOperand &MO) const {
489*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || !MO.getReg())
490*9880d681SAndroid Build Coastguard Worker       return;
491*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
492*9880d681SAndroid Build Coastguard Worker     unsigned SubRegIdx = MO.getSubReg();
493*9880d681SAndroid Build Coastguard Worker     if (MO.isUse()) {
494*9880d681SAndroid Build Coastguard Worker       if (!MO.isUndef() && !MO.isInternalRead())
495*9880d681SAndroid Build Coastguard Worker         pushRegLanes(Reg, SubRegIdx, RegOpers.Uses);
496*9880d681SAndroid Build Coastguard Worker     } else {
497*9880d681SAndroid Build Coastguard Worker       assert(MO.isDef());
498*9880d681SAndroid Build Coastguard Worker       // Treat read-undef subreg defs as definitions of the whole register.
499*9880d681SAndroid Build Coastguard Worker       if (MO.isUndef())
500*9880d681SAndroid Build Coastguard Worker         SubRegIdx = 0;
501*9880d681SAndroid Build Coastguard Worker 
502*9880d681SAndroid Build Coastguard Worker       if (MO.isDead()) {
503*9880d681SAndroid Build Coastguard Worker         if (!IgnoreDead)
504*9880d681SAndroid Build Coastguard Worker           pushRegLanes(Reg, SubRegIdx, RegOpers.DeadDefs);
505*9880d681SAndroid Build Coastguard Worker       } else
506*9880d681SAndroid Build Coastguard Worker         pushRegLanes(Reg, SubRegIdx, RegOpers.Defs);
507*9880d681SAndroid Build Coastguard Worker     }
508*9880d681SAndroid Build Coastguard Worker   }
509*9880d681SAndroid Build Coastguard Worker 
pushRegLanes(unsigned Reg,unsigned SubRegIdx,SmallVectorImpl<RegisterMaskPair> & RegUnits) const510*9880d681SAndroid Build Coastguard Worker   void pushRegLanes(unsigned Reg, unsigned SubRegIdx,
511*9880d681SAndroid Build Coastguard Worker                     SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
512*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
513*9880d681SAndroid Build Coastguard Worker       LaneBitmask LaneMask = SubRegIdx != 0
514*9880d681SAndroid Build Coastguard Worker                              ? TRI.getSubRegIndexLaneMask(SubRegIdx)
515*9880d681SAndroid Build Coastguard Worker                              : MRI.getMaxLaneMaskForVReg(Reg);
516*9880d681SAndroid Build Coastguard Worker       addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneMask));
517*9880d681SAndroid Build Coastguard Worker     } else if (MRI.isAllocatable(Reg)) {
518*9880d681SAndroid Build Coastguard Worker       for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
519*9880d681SAndroid Build Coastguard Worker         addRegLanes(RegUnits, RegisterMaskPair(*Units, ~0u));
520*9880d681SAndroid Build Coastguard Worker     }
521*9880d681SAndroid Build Coastguard Worker   }
522*9880d681SAndroid Build Coastguard Worker 
523*9880d681SAndroid Build Coastguard Worker   friend class llvm::RegisterOperands;
524*9880d681SAndroid Build Coastguard Worker };
525*9880d681SAndroid Build Coastguard Worker 
526*9880d681SAndroid Build Coastguard Worker } // namespace
527*9880d681SAndroid Build Coastguard Worker 
collect(const MachineInstr & MI,const TargetRegisterInfo & TRI,const MachineRegisterInfo & MRI,bool TrackLaneMasks,bool IgnoreDead)528*9880d681SAndroid Build Coastguard Worker void RegisterOperands::collect(const MachineInstr &MI,
529*9880d681SAndroid Build Coastguard Worker                                const TargetRegisterInfo &TRI,
530*9880d681SAndroid Build Coastguard Worker                                const MachineRegisterInfo &MRI,
531*9880d681SAndroid Build Coastguard Worker                                bool TrackLaneMasks, bool IgnoreDead) {
532*9880d681SAndroid Build Coastguard Worker   RegisterOperandsCollector Collector(*this, TRI, MRI, IgnoreDead);
533*9880d681SAndroid Build Coastguard Worker   if (TrackLaneMasks)
534*9880d681SAndroid Build Coastguard Worker     Collector.collectInstrLanes(MI);
535*9880d681SAndroid Build Coastguard Worker   else
536*9880d681SAndroid Build Coastguard Worker     Collector.collectInstr(MI);
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker 
detectDeadDefs(const MachineInstr & MI,const LiveIntervals & LIS)539*9880d681SAndroid Build Coastguard Worker void RegisterOperands::detectDeadDefs(const MachineInstr &MI,
540*9880d681SAndroid Build Coastguard Worker                                       const LiveIntervals &LIS) {
541*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx = LIS.getInstructionIndex(MI);
542*9880d681SAndroid Build Coastguard Worker   for (auto RI = Defs.begin(); RI != Defs.end(); /*empty*/) {
543*9880d681SAndroid Build Coastguard Worker     unsigned Reg = RI->RegUnit;
544*9880d681SAndroid Build Coastguard Worker     const LiveRange *LR = getLiveRange(LIS, Reg);
545*9880d681SAndroid Build Coastguard Worker     if (LR != nullptr) {
546*9880d681SAndroid Build Coastguard Worker       LiveQueryResult LRQ = LR->Query(SlotIdx);
547*9880d681SAndroid Build Coastguard Worker       if (LRQ.isDeadDef()) {
548*9880d681SAndroid Build Coastguard Worker         // LiveIntervals knows this is a dead even though it's MachineOperand is
549*9880d681SAndroid Build Coastguard Worker         // not flagged as such.
550*9880d681SAndroid Build Coastguard Worker         DeadDefs.push_back(*RI);
551*9880d681SAndroid Build Coastguard Worker         RI = Defs.erase(RI);
552*9880d681SAndroid Build Coastguard Worker         continue;
553*9880d681SAndroid Build Coastguard Worker       }
554*9880d681SAndroid Build Coastguard Worker     }
555*9880d681SAndroid Build Coastguard Worker     ++RI;
556*9880d681SAndroid Build Coastguard Worker   }
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker 
adjustLaneLiveness(const LiveIntervals & LIS,const MachineRegisterInfo & MRI,SlotIndex Pos,MachineInstr * AddFlagsMI)559*9880d681SAndroid Build Coastguard Worker void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
560*9880d681SAndroid Build Coastguard Worker                                           const MachineRegisterInfo &MRI,
561*9880d681SAndroid Build Coastguard Worker                                           SlotIndex Pos,
562*9880d681SAndroid Build Coastguard Worker                                           MachineInstr *AddFlagsMI) {
563*9880d681SAndroid Build Coastguard Worker   for (auto I = Defs.begin(); I != Defs.end(); ) {
564*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
565*9880d681SAndroid Build Coastguard Worker                                            Pos.getDeadSlot());
566*9880d681SAndroid Build Coastguard Worker     // If the the def is all that is live after the instruction, then in case
567*9880d681SAndroid Build Coastguard Worker     // of a subregister def we need a read-undef flag.
568*9880d681SAndroid Build Coastguard Worker     unsigned RegUnit = I->RegUnit;
569*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(RegUnit) &&
570*9880d681SAndroid Build Coastguard Worker         AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask) == 0)
571*9880d681SAndroid Build Coastguard Worker       AddFlagsMI->setRegisterDefReadUndef(RegUnit);
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker     LaneBitmask ActualDef = I->LaneMask & LiveAfter;
574*9880d681SAndroid Build Coastguard Worker     if (ActualDef == 0) {
575*9880d681SAndroid Build Coastguard Worker       I = Defs.erase(I);
576*9880d681SAndroid Build Coastguard Worker     } else {
577*9880d681SAndroid Build Coastguard Worker       I->LaneMask = ActualDef;
578*9880d681SAndroid Build Coastguard Worker       ++I;
579*9880d681SAndroid Build Coastguard Worker     }
580*9880d681SAndroid Build Coastguard Worker   }
581*9880d681SAndroid Build Coastguard Worker   for (auto I = Uses.begin(); I != Uses.end(); ) {
582*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveBefore = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
583*9880d681SAndroid Build Coastguard Worker                                             Pos.getBaseIndex());
584*9880d681SAndroid Build Coastguard Worker     LaneBitmask LaneMask = I->LaneMask & LiveBefore;
585*9880d681SAndroid Build Coastguard Worker     if (LaneMask == 0) {
586*9880d681SAndroid Build Coastguard Worker       I = Uses.erase(I);
587*9880d681SAndroid Build Coastguard Worker     } else {
588*9880d681SAndroid Build Coastguard Worker       I->LaneMask = LaneMask;
589*9880d681SAndroid Build Coastguard Worker       ++I;
590*9880d681SAndroid Build Coastguard Worker     }
591*9880d681SAndroid Build Coastguard Worker   }
592*9880d681SAndroid Build Coastguard Worker   if (AddFlagsMI != nullptr) {
593*9880d681SAndroid Build Coastguard Worker     for (const RegisterMaskPair &P : DeadDefs) {
594*9880d681SAndroid Build Coastguard Worker       unsigned RegUnit = P.RegUnit;
595*9880d681SAndroid Build Coastguard Worker       if (!TargetRegisterInfo::isVirtualRegister(RegUnit))
596*9880d681SAndroid Build Coastguard Worker         continue;
597*9880d681SAndroid Build Coastguard Worker       LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
598*9880d681SAndroid Build Coastguard Worker                                              Pos.getDeadSlot());
599*9880d681SAndroid Build Coastguard Worker       if (LiveAfter == 0)
600*9880d681SAndroid Build Coastguard Worker         AddFlagsMI->setRegisterDefReadUndef(RegUnit);
601*9880d681SAndroid Build Coastguard Worker     }
602*9880d681SAndroid Build Coastguard Worker   }
603*9880d681SAndroid Build Coastguard Worker }
604*9880d681SAndroid Build Coastguard Worker 
605*9880d681SAndroid Build Coastguard Worker /// Initialize an array of N PressureDiffs.
init(unsigned N)606*9880d681SAndroid Build Coastguard Worker void PressureDiffs::init(unsigned N) {
607*9880d681SAndroid Build Coastguard Worker   Size = N;
608*9880d681SAndroid Build Coastguard Worker   if (N <= Max) {
609*9880d681SAndroid Build Coastguard Worker     memset(PDiffArray, 0, N * sizeof(PressureDiff));
610*9880d681SAndroid Build Coastguard Worker     return;
611*9880d681SAndroid Build Coastguard Worker   }
612*9880d681SAndroid Build Coastguard Worker   Max = Size;
613*9880d681SAndroid Build Coastguard Worker   free(PDiffArray);
614*9880d681SAndroid Build Coastguard Worker   PDiffArray = reinterpret_cast<PressureDiff*>(calloc(N, sizeof(PressureDiff)));
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker 
addInstruction(unsigned Idx,const RegisterOperands & RegOpers,const MachineRegisterInfo & MRI)617*9880d681SAndroid Build Coastguard Worker void PressureDiffs::addInstruction(unsigned Idx,
618*9880d681SAndroid Build Coastguard Worker                                    const RegisterOperands &RegOpers,
619*9880d681SAndroid Build Coastguard Worker                                    const MachineRegisterInfo &MRI) {
620*9880d681SAndroid Build Coastguard Worker   PressureDiff &PDiff = (*this)[Idx];
621*9880d681SAndroid Build Coastguard Worker   assert(!PDiff.begin()->isValid() && "stale PDiff");
622*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : RegOpers.Defs)
623*9880d681SAndroid Build Coastguard Worker     PDiff.addPressureChange(P.RegUnit, true, &MRI);
624*9880d681SAndroid Build Coastguard Worker 
625*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : RegOpers.Uses)
626*9880d681SAndroid Build Coastguard Worker     PDiff.addPressureChange(P.RegUnit, false, &MRI);
627*9880d681SAndroid Build Coastguard Worker }
628*9880d681SAndroid Build Coastguard Worker 
629*9880d681SAndroid Build Coastguard Worker /// Add a change in pressure to the pressure diff of a given instruction.
addPressureChange(unsigned RegUnit,bool IsDec,const MachineRegisterInfo * MRI)630*9880d681SAndroid Build Coastguard Worker void PressureDiff::addPressureChange(unsigned RegUnit, bool IsDec,
631*9880d681SAndroid Build Coastguard Worker                                      const MachineRegisterInfo *MRI) {
632*9880d681SAndroid Build Coastguard Worker   PSetIterator PSetI = MRI->getPressureSets(RegUnit);
633*9880d681SAndroid Build Coastguard Worker   int Weight = IsDec ? -PSetI.getWeight() : PSetI.getWeight();
634*9880d681SAndroid Build Coastguard Worker   for (; PSetI.isValid(); ++PSetI) {
635*9880d681SAndroid Build Coastguard Worker     // Find an existing entry in the pressure diff for this PSet.
636*9880d681SAndroid Build Coastguard Worker     PressureDiff::iterator I = nonconst_begin(), E = nonconst_end();
637*9880d681SAndroid Build Coastguard Worker     for (; I != E && I->isValid(); ++I) {
638*9880d681SAndroid Build Coastguard Worker       if (I->getPSet() >= *PSetI)
639*9880d681SAndroid Build Coastguard Worker         break;
640*9880d681SAndroid Build Coastguard Worker     }
641*9880d681SAndroid Build Coastguard Worker     // If all pressure sets are more constrained, skip the remaining PSets.
642*9880d681SAndroid Build Coastguard Worker     if (I == E)
643*9880d681SAndroid Build Coastguard Worker       break;
644*9880d681SAndroid Build Coastguard Worker     // Insert this PressureChange.
645*9880d681SAndroid Build Coastguard Worker     if (!I->isValid() || I->getPSet() != *PSetI) {
646*9880d681SAndroid Build Coastguard Worker       PressureChange PTmp = PressureChange(*PSetI);
647*9880d681SAndroid Build Coastguard Worker       for (PressureDiff::iterator J = I; J != E && PTmp.isValid(); ++J)
648*9880d681SAndroid Build Coastguard Worker         std::swap(*J, PTmp);
649*9880d681SAndroid Build Coastguard Worker     }
650*9880d681SAndroid Build Coastguard Worker     // Update the units for this pressure set.
651*9880d681SAndroid Build Coastguard Worker     unsigned NewUnitInc = I->getUnitInc() + Weight;
652*9880d681SAndroid Build Coastguard Worker     if (NewUnitInc != 0) {
653*9880d681SAndroid Build Coastguard Worker       I->setUnitInc(NewUnitInc);
654*9880d681SAndroid Build Coastguard Worker     } else {
655*9880d681SAndroid Build Coastguard Worker       // Remove entry
656*9880d681SAndroid Build Coastguard Worker       PressureDiff::iterator J;
657*9880d681SAndroid Build Coastguard Worker       for (J = std::next(I); J != E && J->isValid(); ++J, ++I)
658*9880d681SAndroid Build Coastguard Worker         *I = *J;
659*9880d681SAndroid Build Coastguard Worker       if (J != E)
660*9880d681SAndroid Build Coastguard Worker         *I = *J;
661*9880d681SAndroid Build Coastguard Worker     }
662*9880d681SAndroid Build Coastguard Worker   }
663*9880d681SAndroid Build Coastguard Worker }
664*9880d681SAndroid Build Coastguard Worker 
665*9880d681SAndroid Build Coastguard Worker /// Force liveness of registers.
addLiveRegs(ArrayRef<RegisterMaskPair> Regs)666*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::addLiveRegs(ArrayRef<RegisterMaskPair> Regs) {
667*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : Regs) {
668*9880d681SAndroid Build Coastguard Worker     LaneBitmask PrevMask = LiveRegs.insert(P);
669*9880d681SAndroid Build Coastguard Worker     LaneBitmask NewMask = PrevMask | P.LaneMask;
670*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(P.RegUnit, PrevMask, NewMask);
671*9880d681SAndroid Build Coastguard Worker   }
672*9880d681SAndroid Build Coastguard Worker }
673*9880d681SAndroid Build Coastguard Worker 
discoverLiveInOrOut(RegisterMaskPair Pair,SmallVectorImpl<RegisterMaskPair> & LiveInOrOut)674*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
675*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<RegisterMaskPair> &LiveInOrOut) {
676*9880d681SAndroid Build Coastguard Worker   assert(Pair.LaneMask != 0);
677*9880d681SAndroid Build Coastguard Worker 
678*9880d681SAndroid Build Coastguard Worker   unsigned RegUnit = Pair.RegUnit;
679*9880d681SAndroid Build Coastguard Worker   auto I = std::find_if(LiveInOrOut.begin(), LiveInOrOut.end(),
680*9880d681SAndroid Build Coastguard Worker                         [RegUnit](const RegisterMaskPair &Other) {
681*9880d681SAndroid Build Coastguard Worker                           return Other.RegUnit == RegUnit;
682*9880d681SAndroid Build Coastguard Worker                         });
683*9880d681SAndroid Build Coastguard Worker   LaneBitmask PrevMask;
684*9880d681SAndroid Build Coastguard Worker   LaneBitmask NewMask;
685*9880d681SAndroid Build Coastguard Worker   if (I == LiveInOrOut.end()) {
686*9880d681SAndroid Build Coastguard Worker     PrevMask = 0;
687*9880d681SAndroid Build Coastguard Worker     NewMask = Pair.LaneMask;
688*9880d681SAndroid Build Coastguard Worker     LiveInOrOut.push_back(Pair);
689*9880d681SAndroid Build Coastguard Worker   } else {
690*9880d681SAndroid Build Coastguard Worker     PrevMask = I->LaneMask;
691*9880d681SAndroid Build Coastguard Worker     NewMask = PrevMask | Pair.LaneMask;
692*9880d681SAndroid Build Coastguard Worker     I->LaneMask = NewMask;
693*9880d681SAndroid Build Coastguard Worker   }
694*9880d681SAndroid Build Coastguard Worker   increaseSetPressure(P.MaxSetPressure, *MRI, RegUnit, PrevMask, NewMask);
695*9880d681SAndroid Build Coastguard Worker }
696*9880d681SAndroid Build Coastguard Worker 
discoverLiveIn(RegisterMaskPair Pair)697*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::discoverLiveIn(RegisterMaskPair Pair) {
698*9880d681SAndroid Build Coastguard Worker   discoverLiveInOrOut(Pair, P.LiveInRegs);
699*9880d681SAndroid Build Coastguard Worker }
700*9880d681SAndroid Build Coastguard Worker 
discoverLiveOut(RegisterMaskPair Pair)701*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::discoverLiveOut(RegisterMaskPair Pair) {
702*9880d681SAndroid Build Coastguard Worker   discoverLiveInOrOut(Pair, P.LiveOutRegs);
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker 
bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs)705*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs) {
706*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : DeadDefs) {
707*9880d681SAndroid Build Coastguard Worker     unsigned Reg = P.RegUnit;
708*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveMask = LiveRegs.contains(Reg);
709*9880d681SAndroid Build Coastguard Worker     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
710*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(Reg, LiveMask, BumpedMask);
711*9880d681SAndroid Build Coastguard Worker   }
712*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : DeadDefs) {
713*9880d681SAndroid Build Coastguard Worker     unsigned Reg = P.RegUnit;
714*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveMask = LiveRegs.contains(Reg);
715*9880d681SAndroid Build Coastguard Worker     LaneBitmask BumpedMask = LiveMask | P.LaneMask;
716*9880d681SAndroid Build Coastguard Worker     decreaseRegPressure(Reg, BumpedMask, LiveMask);
717*9880d681SAndroid Build Coastguard Worker   }
718*9880d681SAndroid Build Coastguard Worker }
719*9880d681SAndroid Build Coastguard Worker 
720*9880d681SAndroid Build Coastguard Worker /// Recede across the previous instruction. If LiveUses is provided, record any
721*9880d681SAndroid Build Coastguard Worker /// RegUnits that are made live by the current instruction's uses. This includes
722*9880d681SAndroid Build Coastguard Worker /// registers that are both defined and used by the instruction.  If a pressure
723*9880d681SAndroid Build Coastguard Worker /// difference pointer is provided record the changes is pressure caused by this
724*9880d681SAndroid Build Coastguard Worker /// instruction independent of liveness.
recede(const RegisterOperands & RegOpers,SmallVectorImpl<RegisterMaskPair> * LiveUses)725*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::recede(const RegisterOperands &RegOpers,
726*9880d681SAndroid Build Coastguard Worker                                 SmallVectorImpl<RegisterMaskPair> *LiveUses) {
727*9880d681SAndroid Build Coastguard Worker   assert(!CurrPos->isDebugValue());
728*9880d681SAndroid Build Coastguard Worker 
729*9880d681SAndroid Build Coastguard Worker   // Boost pressure for all dead defs together.
730*9880d681SAndroid Build Coastguard Worker   bumpDeadDefs(RegOpers.DeadDefs);
731*9880d681SAndroid Build Coastguard Worker 
732*9880d681SAndroid Build Coastguard Worker   // Kill liveness at live defs.
733*9880d681SAndroid Build Coastguard Worker   // TODO: consider earlyclobbers?
734*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Def : RegOpers.Defs) {
735*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Def.RegUnit;
736*9880d681SAndroid Build Coastguard Worker 
737*9880d681SAndroid Build Coastguard Worker     LaneBitmask PreviousMask = LiveRegs.erase(Def);
738*9880d681SAndroid Build Coastguard Worker     LaneBitmask NewMask = PreviousMask & ~Def.LaneMask;
739*9880d681SAndroid Build Coastguard Worker 
740*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveOut = Def.LaneMask & ~PreviousMask;
741*9880d681SAndroid Build Coastguard Worker     if (LiveOut != 0) {
742*9880d681SAndroid Build Coastguard Worker       discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
743*9880d681SAndroid Build Coastguard Worker       // Retroactively model effects on pressure of the live out lanes.
744*9880d681SAndroid Build Coastguard Worker       increaseSetPressure(CurrSetPressure, *MRI, Reg, 0, LiveOut);
745*9880d681SAndroid Build Coastguard Worker       PreviousMask = LiveOut;
746*9880d681SAndroid Build Coastguard Worker     }
747*9880d681SAndroid Build Coastguard Worker 
748*9880d681SAndroid Build Coastguard Worker     if (NewMask == 0) {
749*9880d681SAndroid Build Coastguard Worker       // Add a 0 entry to LiveUses as a marker that the complete vreg has become
750*9880d681SAndroid Build Coastguard Worker       // dead.
751*9880d681SAndroid Build Coastguard Worker       if (TrackLaneMasks && LiveUses != nullptr)
752*9880d681SAndroid Build Coastguard Worker         setRegZero(*LiveUses, Reg);
753*9880d681SAndroid Build Coastguard Worker     }
754*9880d681SAndroid Build Coastguard Worker 
755*9880d681SAndroid Build Coastguard Worker     decreaseRegPressure(Reg, PreviousMask, NewMask);
756*9880d681SAndroid Build Coastguard Worker   }
757*9880d681SAndroid Build Coastguard Worker 
758*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx;
759*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
760*9880d681SAndroid Build Coastguard Worker     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
761*9880d681SAndroid Build Coastguard Worker 
762*9880d681SAndroid Build Coastguard Worker   // Generate liveness for uses.
763*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Use : RegOpers.Uses) {
764*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Use.RegUnit;
765*9880d681SAndroid Build Coastguard Worker     assert(Use.LaneMask != 0);
766*9880d681SAndroid Build Coastguard Worker     LaneBitmask PreviousMask = LiveRegs.insert(Use);
767*9880d681SAndroid Build Coastguard Worker     LaneBitmask NewMask = PreviousMask | Use.LaneMask;
768*9880d681SAndroid Build Coastguard Worker     if (NewMask == PreviousMask)
769*9880d681SAndroid Build Coastguard Worker       continue;
770*9880d681SAndroid Build Coastguard Worker 
771*9880d681SAndroid Build Coastguard Worker     // Did the register just become live?
772*9880d681SAndroid Build Coastguard Worker     if (PreviousMask == 0) {
773*9880d681SAndroid Build Coastguard Worker       if (LiveUses != nullptr) {
774*9880d681SAndroid Build Coastguard Worker         if (!TrackLaneMasks) {
775*9880d681SAndroid Build Coastguard Worker           addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
776*9880d681SAndroid Build Coastguard Worker         } else {
777*9880d681SAndroid Build Coastguard Worker           auto I = std::find_if(LiveUses->begin(), LiveUses->end(),
778*9880d681SAndroid Build Coastguard Worker                                 [Reg](const RegisterMaskPair Other) {
779*9880d681SAndroid Build Coastguard Worker                                 return Other.RegUnit == Reg;
780*9880d681SAndroid Build Coastguard Worker                                 });
781*9880d681SAndroid Build Coastguard Worker           bool IsRedef = I != LiveUses->end();
782*9880d681SAndroid Build Coastguard Worker           if (IsRedef) {
783*9880d681SAndroid Build Coastguard Worker             // ignore re-defs here...
784*9880d681SAndroid Build Coastguard Worker             assert(I->LaneMask == 0);
785*9880d681SAndroid Build Coastguard Worker             removeRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
786*9880d681SAndroid Build Coastguard Worker           } else {
787*9880d681SAndroid Build Coastguard Worker             addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
788*9880d681SAndroid Build Coastguard Worker           }
789*9880d681SAndroid Build Coastguard Worker         }
790*9880d681SAndroid Build Coastguard Worker       }
791*9880d681SAndroid Build Coastguard Worker 
792*9880d681SAndroid Build Coastguard Worker       // Discover live outs if this may be the first occurance of this register.
793*9880d681SAndroid Build Coastguard Worker       if (RequireIntervals) {
794*9880d681SAndroid Build Coastguard Worker         LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
795*9880d681SAndroid Build Coastguard Worker         if (LiveOut != 0)
796*9880d681SAndroid Build Coastguard Worker           discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
797*9880d681SAndroid Build Coastguard Worker       }
798*9880d681SAndroid Build Coastguard Worker     }
799*9880d681SAndroid Build Coastguard Worker 
800*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(Reg, PreviousMask, NewMask);
801*9880d681SAndroid Build Coastguard Worker   }
802*9880d681SAndroid Build Coastguard Worker   if (TrackUntiedDefs) {
803*9880d681SAndroid Build Coastguard Worker     for (const RegisterMaskPair &Def : RegOpers.Defs) {
804*9880d681SAndroid Build Coastguard Worker       unsigned RegUnit = Def.RegUnit;
805*9880d681SAndroid Build Coastguard Worker       if (TargetRegisterInfo::isVirtualRegister(RegUnit) &&
806*9880d681SAndroid Build Coastguard Worker           (LiveRegs.contains(RegUnit) & Def.LaneMask) == 0)
807*9880d681SAndroid Build Coastguard Worker         UntiedDefs.insert(RegUnit);
808*9880d681SAndroid Build Coastguard Worker     }
809*9880d681SAndroid Build Coastguard Worker   }
810*9880d681SAndroid Build Coastguard Worker }
811*9880d681SAndroid Build Coastguard Worker 
recedeSkipDebugValues()812*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::recedeSkipDebugValues() {
813*9880d681SAndroid Build Coastguard Worker   assert(CurrPos != MBB->begin());
814*9880d681SAndroid Build Coastguard Worker   if (!isBottomClosed())
815*9880d681SAndroid Build Coastguard Worker     closeBottom();
816*9880d681SAndroid Build Coastguard Worker 
817*9880d681SAndroid Build Coastguard Worker   // Open the top of the region using block iterators.
818*9880d681SAndroid Build Coastguard Worker   if (!RequireIntervals && isTopClosed())
819*9880d681SAndroid Build Coastguard Worker     static_cast<RegionPressure&>(P).openTop(CurrPos);
820*9880d681SAndroid Build Coastguard Worker 
821*9880d681SAndroid Build Coastguard Worker   // Find the previous instruction.
822*9880d681SAndroid Build Coastguard Worker   do
823*9880d681SAndroid Build Coastguard Worker     --CurrPos;
824*9880d681SAndroid Build Coastguard Worker   while (CurrPos != MBB->begin() && CurrPos->isDebugValue());
825*9880d681SAndroid Build Coastguard Worker 
826*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx;
827*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
828*9880d681SAndroid Build Coastguard Worker     SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
829*9880d681SAndroid Build Coastguard Worker 
830*9880d681SAndroid Build Coastguard Worker   // Open the top of the region using slot indexes.
831*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals && isTopClosed())
832*9880d681SAndroid Build Coastguard Worker     static_cast<IntervalPressure&>(P).openTop(SlotIdx);
833*9880d681SAndroid Build Coastguard Worker }
834*9880d681SAndroid Build Coastguard Worker 
recede(SmallVectorImpl<RegisterMaskPair> * LiveUses)835*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::recede(SmallVectorImpl<RegisterMaskPair> *LiveUses) {
836*9880d681SAndroid Build Coastguard Worker   recedeSkipDebugValues();
837*9880d681SAndroid Build Coastguard Worker 
838*9880d681SAndroid Build Coastguard Worker   const MachineInstr &MI = *CurrPos;
839*9880d681SAndroid Build Coastguard Worker   RegisterOperands RegOpers;
840*9880d681SAndroid Build Coastguard Worker   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
841*9880d681SAndroid Build Coastguard Worker   if (TrackLaneMasks) {
842*9880d681SAndroid Build Coastguard Worker     SlotIndex SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
843*9880d681SAndroid Build Coastguard Worker     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
844*9880d681SAndroid Build Coastguard Worker   } else if (RequireIntervals) {
845*9880d681SAndroid Build Coastguard Worker     RegOpers.detectDeadDefs(MI, *LIS);
846*9880d681SAndroid Build Coastguard Worker   }
847*9880d681SAndroid Build Coastguard Worker 
848*9880d681SAndroid Build Coastguard Worker   recede(RegOpers, LiveUses);
849*9880d681SAndroid Build Coastguard Worker }
850*9880d681SAndroid Build Coastguard Worker 
851*9880d681SAndroid Build Coastguard Worker /// Advance across the current instruction.
advance(const RegisterOperands & RegOpers)852*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
853*9880d681SAndroid Build Coastguard Worker   assert(!TrackUntiedDefs && "unsupported mode");
854*9880d681SAndroid Build Coastguard Worker   assert(CurrPos != MBB->end());
855*9880d681SAndroid Build Coastguard Worker   if (!isTopClosed())
856*9880d681SAndroid Build Coastguard Worker     closeTop();
857*9880d681SAndroid Build Coastguard Worker 
858*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx;
859*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
860*9880d681SAndroid Build Coastguard Worker     SlotIdx = getCurrSlot();
861*9880d681SAndroid Build Coastguard Worker 
862*9880d681SAndroid Build Coastguard Worker   // Open the bottom of the region using slot indexes.
863*9880d681SAndroid Build Coastguard Worker   if (isBottomClosed()) {
864*9880d681SAndroid Build Coastguard Worker     if (RequireIntervals)
865*9880d681SAndroid Build Coastguard Worker       static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
866*9880d681SAndroid Build Coastguard Worker     else
867*9880d681SAndroid Build Coastguard Worker       static_cast<RegionPressure&>(P).openBottom(CurrPos);
868*9880d681SAndroid Build Coastguard Worker   }
869*9880d681SAndroid Build Coastguard Worker 
870*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Use : RegOpers.Uses) {
871*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Use.RegUnit;
872*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveMask = LiveRegs.contains(Reg);
873*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
874*9880d681SAndroid Build Coastguard Worker     if (LiveIn != 0) {
875*9880d681SAndroid Build Coastguard Worker       discoverLiveIn(RegisterMaskPair(Reg, LiveIn));
876*9880d681SAndroid Build Coastguard Worker       increaseRegPressure(Reg, LiveMask, LiveMask | LiveIn);
877*9880d681SAndroid Build Coastguard Worker       LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
878*9880d681SAndroid Build Coastguard Worker     }
879*9880d681SAndroid Build Coastguard Worker     // Kill liveness at last uses.
880*9880d681SAndroid Build Coastguard Worker     if (RequireIntervals) {
881*9880d681SAndroid Build Coastguard Worker       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
882*9880d681SAndroid Build Coastguard Worker       if (LastUseMask != 0) {
883*9880d681SAndroid Build Coastguard Worker         LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
884*9880d681SAndroid Build Coastguard Worker         decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
885*9880d681SAndroid Build Coastguard Worker       }
886*9880d681SAndroid Build Coastguard Worker     }
887*9880d681SAndroid Build Coastguard Worker   }
888*9880d681SAndroid Build Coastguard Worker 
889*9880d681SAndroid Build Coastguard Worker   // Generate liveness for defs.
890*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Def : RegOpers.Defs) {
891*9880d681SAndroid Build Coastguard Worker     LaneBitmask PreviousMask = LiveRegs.insert(Def);
892*9880d681SAndroid Build Coastguard Worker     LaneBitmask NewMask = PreviousMask | Def.LaneMask;
893*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(Def.RegUnit, PreviousMask, NewMask);
894*9880d681SAndroid Build Coastguard Worker   }
895*9880d681SAndroid Build Coastguard Worker 
896*9880d681SAndroid Build Coastguard Worker   // Boost pressure for all dead defs together.
897*9880d681SAndroid Build Coastguard Worker   bumpDeadDefs(RegOpers.DeadDefs);
898*9880d681SAndroid Build Coastguard Worker 
899*9880d681SAndroid Build Coastguard Worker   // Find the next instruction.
900*9880d681SAndroid Build Coastguard Worker   do
901*9880d681SAndroid Build Coastguard Worker     ++CurrPos;
902*9880d681SAndroid Build Coastguard Worker   while (CurrPos != MBB->end() && CurrPos->isDebugValue());
903*9880d681SAndroid Build Coastguard Worker }
904*9880d681SAndroid Build Coastguard Worker 
advance()905*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::advance() {
906*9880d681SAndroid Build Coastguard Worker   const MachineInstr &MI = *CurrPos;
907*9880d681SAndroid Build Coastguard Worker   RegisterOperands RegOpers;
908*9880d681SAndroid Build Coastguard Worker   RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
909*9880d681SAndroid Build Coastguard Worker   if (TrackLaneMasks) {
910*9880d681SAndroid Build Coastguard Worker     SlotIndex SlotIdx = getCurrSlot();
911*9880d681SAndroid Build Coastguard Worker     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
912*9880d681SAndroid Build Coastguard Worker   }
913*9880d681SAndroid Build Coastguard Worker   advance(RegOpers);
914*9880d681SAndroid Build Coastguard Worker }
915*9880d681SAndroid Build Coastguard Worker 
916*9880d681SAndroid Build Coastguard Worker /// Find the max change in excess pressure across all sets.
computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,ArrayRef<unsigned> NewPressureVec,RegPressureDelta & Delta,const RegisterClassInfo * RCI,ArrayRef<unsigned> LiveThruPressureVec)917*9880d681SAndroid Build Coastguard Worker static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
918*9880d681SAndroid Build Coastguard Worker                                        ArrayRef<unsigned> NewPressureVec,
919*9880d681SAndroid Build Coastguard Worker                                        RegPressureDelta &Delta,
920*9880d681SAndroid Build Coastguard Worker                                        const RegisterClassInfo *RCI,
921*9880d681SAndroid Build Coastguard Worker                                        ArrayRef<unsigned> LiveThruPressureVec) {
922*9880d681SAndroid Build Coastguard Worker   Delta.Excess = PressureChange();
923*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
924*9880d681SAndroid Build Coastguard Worker     unsigned POld = OldPressureVec[i];
925*9880d681SAndroid Build Coastguard Worker     unsigned PNew = NewPressureVec[i];
926*9880d681SAndroid Build Coastguard Worker     int PDiff = (int)PNew - (int)POld;
927*9880d681SAndroid Build Coastguard Worker     if (!PDiff) // No change in this set in the common case.
928*9880d681SAndroid Build Coastguard Worker       continue;
929*9880d681SAndroid Build Coastguard Worker     // Only consider change beyond the limit.
930*9880d681SAndroid Build Coastguard Worker     unsigned Limit = RCI->getRegPressureSetLimit(i);
931*9880d681SAndroid Build Coastguard Worker     if (!LiveThruPressureVec.empty())
932*9880d681SAndroid Build Coastguard Worker       Limit += LiveThruPressureVec[i];
933*9880d681SAndroid Build Coastguard Worker 
934*9880d681SAndroid Build Coastguard Worker     if (Limit > POld) {
935*9880d681SAndroid Build Coastguard Worker       if (Limit > PNew)
936*9880d681SAndroid Build Coastguard Worker         PDiff = 0;            // Under the limit
937*9880d681SAndroid Build Coastguard Worker       else
938*9880d681SAndroid Build Coastguard Worker         PDiff = PNew - Limit; // Just exceeded limit.
939*9880d681SAndroid Build Coastguard Worker     } else if (Limit > PNew)
940*9880d681SAndroid Build Coastguard Worker       PDiff = Limit - POld;   // Just obeyed limit.
941*9880d681SAndroid Build Coastguard Worker 
942*9880d681SAndroid Build Coastguard Worker     if (PDiff) {
943*9880d681SAndroid Build Coastguard Worker       Delta.Excess = PressureChange(i);
944*9880d681SAndroid Build Coastguard Worker       Delta.Excess.setUnitInc(PDiff);
945*9880d681SAndroid Build Coastguard Worker       break;
946*9880d681SAndroid Build Coastguard Worker     }
947*9880d681SAndroid Build Coastguard Worker   }
948*9880d681SAndroid Build Coastguard Worker }
949*9880d681SAndroid Build Coastguard Worker 
950*9880d681SAndroid Build Coastguard Worker /// Find the max change in max pressure that either surpasses a critical PSet
951*9880d681SAndroid Build Coastguard Worker /// limit or exceeds the current MaxPressureLimit.
952*9880d681SAndroid Build Coastguard Worker ///
953*9880d681SAndroid Build Coastguard Worker /// FIXME: comparing each element of the old and new MaxPressure vectors here is
954*9880d681SAndroid Build Coastguard Worker /// silly. It's done now to demonstrate the concept but will go away with a
955*9880d681SAndroid Build Coastguard Worker /// RegPressureTracker API change to work with pressure differences.
computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,ArrayRef<unsigned> NewMaxPressureVec,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit,RegPressureDelta & Delta)956*9880d681SAndroid Build Coastguard Worker static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
957*9880d681SAndroid Build Coastguard Worker                                     ArrayRef<unsigned> NewMaxPressureVec,
958*9880d681SAndroid Build Coastguard Worker                                     ArrayRef<PressureChange> CriticalPSets,
959*9880d681SAndroid Build Coastguard Worker                                     ArrayRef<unsigned> MaxPressureLimit,
960*9880d681SAndroid Build Coastguard Worker                                     RegPressureDelta &Delta) {
961*9880d681SAndroid Build Coastguard Worker   Delta.CriticalMax = PressureChange();
962*9880d681SAndroid Build Coastguard Worker   Delta.CurrentMax = PressureChange();
963*9880d681SAndroid Build Coastguard Worker 
964*9880d681SAndroid Build Coastguard Worker   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
965*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
966*9880d681SAndroid Build Coastguard Worker     unsigned POld = OldMaxPressureVec[i];
967*9880d681SAndroid Build Coastguard Worker     unsigned PNew = NewMaxPressureVec[i];
968*9880d681SAndroid Build Coastguard Worker     if (PNew == POld) // No change in this set in the common case.
969*9880d681SAndroid Build Coastguard Worker       continue;
970*9880d681SAndroid Build Coastguard Worker 
971*9880d681SAndroid Build Coastguard Worker     if (!Delta.CriticalMax.isValid()) {
972*9880d681SAndroid Build Coastguard Worker       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < i)
973*9880d681SAndroid Build Coastguard Worker         ++CritIdx;
974*9880d681SAndroid Build Coastguard Worker 
975*9880d681SAndroid Build Coastguard Worker       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == i) {
976*9880d681SAndroid Build Coastguard Worker         int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].getUnitInc();
977*9880d681SAndroid Build Coastguard Worker         if (PDiff > 0) {
978*9880d681SAndroid Build Coastguard Worker           Delta.CriticalMax = PressureChange(i);
979*9880d681SAndroid Build Coastguard Worker           Delta.CriticalMax.setUnitInc(PDiff);
980*9880d681SAndroid Build Coastguard Worker         }
981*9880d681SAndroid Build Coastguard Worker       }
982*9880d681SAndroid Build Coastguard Worker     }
983*9880d681SAndroid Build Coastguard Worker     // Find the first increase above MaxPressureLimit.
984*9880d681SAndroid Build Coastguard Worker     // (Ignores negative MDiff).
985*9880d681SAndroid Build Coastguard Worker     if (!Delta.CurrentMax.isValid() && PNew > MaxPressureLimit[i]) {
986*9880d681SAndroid Build Coastguard Worker       Delta.CurrentMax = PressureChange(i);
987*9880d681SAndroid Build Coastguard Worker       Delta.CurrentMax.setUnitInc(PNew - POld);
988*9880d681SAndroid Build Coastguard Worker       if (CritIdx == CritEnd || Delta.CriticalMax.isValid())
989*9880d681SAndroid Build Coastguard Worker         break;
990*9880d681SAndroid Build Coastguard Worker     }
991*9880d681SAndroid Build Coastguard Worker   }
992*9880d681SAndroid Build Coastguard Worker }
993*9880d681SAndroid Build Coastguard Worker 
994*9880d681SAndroid Build Coastguard Worker /// Record the upward impact of a single instruction on current register
995*9880d681SAndroid Build Coastguard Worker /// pressure. Unlike the advance/recede pressure tracking interface, this does
996*9880d681SAndroid Build Coastguard Worker /// not discover live in/outs.
997*9880d681SAndroid Build Coastguard Worker ///
998*9880d681SAndroid Build Coastguard Worker /// This is intended for speculative queries. It leaves pressure inconsistent
999*9880d681SAndroid Build Coastguard Worker /// with the current position, so must be restored by the caller.
bumpUpwardPressure(const MachineInstr * MI)1000*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
1001*9880d681SAndroid Build Coastguard Worker   assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
1002*9880d681SAndroid Build Coastguard Worker 
1003*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx;
1004*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
1005*9880d681SAndroid Build Coastguard Worker     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
1006*9880d681SAndroid Build Coastguard Worker 
1007*9880d681SAndroid Build Coastguard Worker   // Account for register pressure similar to RegPressureTracker::recede().
1008*9880d681SAndroid Build Coastguard Worker   RegisterOperands RegOpers;
1009*9880d681SAndroid Build Coastguard Worker   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/true);
1010*9880d681SAndroid Build Coastguard Worker   assert(RegOpers.DeadDefs.size() == 0);
1011*9880d681SAndroid Build Coastguard Worker   if (TrackLaneMasks)
1012*9880d681SAndroid Build Coastguard Worker     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
1013*9880d681SAndroid Build Coastguard Worker   else if (RequireIntervals)
1014*9880d681SAndroid Build Coastguard Worker     RegOpers.detectDeadDefs(*MI, *LIS);
1015*9880d681SAndroid Build Coastguard Worker 
1016*9880d681SAndroid Build Coastguard Worker   // Boost max pressure for all dead defs together.
1017*9880d681SAndroid Build Coastguard Worker   // Since CurrSetPressure and MaxSetPressure
1018*9880d681SAndroid Build Coastguard Worker   bumpDeadDefs(RegOpers.DeadDefs);
1019*9880d681SAndroid Build Coastguard Worker 
1020*9880d681SAndroid Build Coastguard Worker   // Kill liveness at live defs.
1021*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : RegOpers.Defs) {
1022*9880d681SAndroid Build Coastguard Worker     unsigned Reg = P.RegUnit;
1023*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveLanes = LiveRegs.contains(Reg);
1024*9880d681SAndroid Build Coastguard Worker     LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg);
1025*9880d681SAndroid Build Coastguard Worker     LaneBitmask DefLanes = P.LaneMask;
1026*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveAfter = (LiveLanes & ~DefLanes) | UseLanes;
1027*9880d681SAndroid Build Coastguard Worker     decreaseRegPressure(Reg, LiveLanes, LiveAfter);
1028*9880d681SAndroid Build Coastguard Worker   }
1029*9880d681SAndroid Build Coastguard Worker   // Generate liveness for uses.
1030*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &P : RegOpers.Uses) {
1031*9880d681SAndroid Build Coastguard Worker     unsigned Reg = P.RegUnit;
1032*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveLanes = LiveRegs.contains(Reg);
1033*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveAfter = LiveLanes | P.LaneMask;
1034*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(Reg, LiveLanes, LiveAfter);
1035*9880d681SAndroid Build Coastguard Worker   }
1036*9880d681SAndroid Build Coastguard Worker }
1037*9880d681SAndroid Build Coastguard Worker 
1038*9880d681SAndroid Build Coastguard Worker /// Consider the pressure increase caused by traversing this instruction
1039*9880d681SAndroid Build Coastguard Worker /// bottom-up. Find the pressure set with the most change beyond its pressure
1040*9880d681SAndroid Build Coastguard Worker /// limit based on the tracker's current pressure, and return the change in
1041*9880d681SAndroid Build Coastguard Worker /// number of register units of that pressure set introduced by this
1042*9880d681SAndroid Build Coastguard Worker /// instruction.
1043*9880d681SAndroid Build Coastguard Worker ///
1044*9880d681SAndroid Build Coastguard Worker /// This assumes that the current LiveOut set is sufficient.
1045*9880d681SAndroid Build Coastguard Worker ///
1046*9880d681SAndroid Build Coastguard Worker /// This is expensive for an on-the-fly query because it calls
1047*9880d681SAndroid Build Coastguard Worker /// bumpUpwardPressure to recompute the pressure sets based on current
1048*9880d681SAndroid Build Coastguard Worker /// liveness. This mainly exists to verify correctness, e.g. with
1049*9880d681SAndroid Build Coastguard Worker /// -verify-misched. getUpwardPressureDelta is the fast version of this query
1050*9880d681SAndroid Build Coastguard Worker /// that uses the per-SUnit cache of the PressureDiff.
1051*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::
getMaxUpwardPressureDelta(const MachineInstr * MI,PressureDiff * PDiff,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit)1052*9880d681SAndroid Build Coastguard Worker getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
1053*9880d681SAndroid Build Coastguard Worker                           RegPressureDelta &Delta,
1054*9880d681SAndroid Build Coastguard Worker                           ArrayRef<PressureChange> CriticalPSets,
1055*9880d681SAndroid Build Coastguard Worker                           ArrayRef<unsigned> MaxPressureLimit) {
1056*9880d681SAndroid Build Coastguard Worker   // Snapshot Pressure.
1057*9880d681SAndroid Build Coastguard Worker   // FIXME: The snapshot heap space should persist. But I'm planning to
1058*9880d681SAndroid Build Coastguard Worker   // summarize the pressure effect so we don't need to snapshot at all.
1059*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> SavedPressure = CurrSetPressure;
1060*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
1061*9880d681SAndroid Build Coastguard Worker 
1062*9880d681SAndroid Build Coastguard Worker   bumpUpwardPressure(MI);
1063*9880d681SAndroid Build Coastguard Worker 
1064*9880d681SAndroid Build Coastguard Worker   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
1065*9880d681SAndroid Build Coastguard Worker                              LiveThruPressure);
1066*9880d681SAndroid Build Coastguard Worker   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
1067*9880d681SAndroid Build Coastguard Worker                           MaxPressureLimit, Delta);
1068*9880d681SAndroid Build Coastguard Worker   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
1069*9880d681SAndroid Build Coastguard Worker          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
1070*9880d681SAndroid Build Coastguard Worker 
1071*9880d681SAndroid Build Coastguard Worker   // Restore the tracker's state.
1072*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure.swap(SavedMaxPressure);
1073*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.swap(SavedPressure);
1074*9880d681SAndroid Build Coastguard Worker 
1075*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
1076*9880d681SAndroid Build Coastguard Worker   if (!PDiff)
1077*9880d681SAndroid Build Coastguard Worker     return;
1078*9880d681SAndroid Build Coastguard Worker 
1079*9880d681SAndroid Build Coastguard Worker   // Check if the alternate algorithm yields the same result.
1080*9880d681SAndroid Build Coastguard Worker   RegPressureDelta Delta2;
1081*9880d681SAndroid Build Coastguard Worker   getUpwardPressureDelta(MI, *PDiff, Delta2, CriticalPSets, MaxPressureLimit);
1082*9880d681SAndroid Build Coastguard Worker   if (Delta != Delta2) {
1083*9880d681SAndroid Build Coastguard Worker     dbgs() << "PDiff: ";
1084*9880d681SAndroid Build Coastguard Worker     PDiff->dump(*TRI);
1085*9880d681SAndroid Build Coastguard Worker     dbgs() << "DELTA: " << *MI;
1086*9880d681SAndroid Build Coastguard Worker     if (Delta.Excess.isValid())
1087*9880d681SAndroid Build Coastguard Worker       dbgs() << "Excess1 " << TRI->getRegPressureSetName(Delta.Excess.getPSet())
1088*9880d681SAndroid Build Coastguard Worker              << " " << Delta.Excess.getUnitInc() << "\n";
1089*9880d681SAndroid Build Coastguard Worker     if (Delta.CriticalMax.isValid())
1090*9880d681SAndroid Build Coastguard Worker       dbgs() << "Critic1 " << TRI->getRegPressureSetName(Delta.CriticalMax.getPSet())
1091*9880d681SAndroid Build Coastguard Worker              << " " << Delta.CriticalMax.getUnitInc() << "\n";
1092*9880d681SAndroid Build Coastguard Worker     if (Delta.CurrentMax.isValid())
1093*9880d681SAndroid Build Coastguard Worker       dbgs() << "CurrMx1 " << TRI->getRegPressureSetName(Delta.CurrentMax.getPSet())
1094*9880d681SAndroid Build Coastguard Worker              << " " << Delta.CurrentMax.getUnitInc() << "\n";
1095*9880d681SAndroid Build Coastguard Worker     if (Delta2.Excess.isValid())
1096*9880d681SAndroid Build Coastguard Worker       dbgs() << "Excess2 " << TRI->getRegPressureSetName(Delta2.Excess.getPSet())
1097*9880d681SAndroid Build Coastguard Worker              << " " << Delta2.Excess.getUnitInc() << "\n";
1098*9880d681SAndroid Build Coastguard Worker     if (Delta2.CriticalMax.isValid())
1099*9880d681SAndroid Build Coastguard Worker       dbgs() << "Critic2 " << TRI->getRegPressureSetName(Delta2.CriticalMax.getPSet())
1100*9880d681SAndroid Build Coastguard Worker              << " " << Delta2.CriticalMax.getUnitInc() << "\n";
1101*9880d681SAndroid Build Coastguard Worker     if (Delta2.CurrentMax.isValid())
1102*9880d681SAndroid Build Coastguard Worker       dbgs() << "CurrMx2 " << TRI->getRegPressureSetName(Delta2.CurrentMax.getPSet())
1103*9880d681SAndroid Build Coastguard Worker              << " " << Delta2.CurrentMax.getUnitInc() << "\n";
1104*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("RegP Delta Mismatch");
1105*9880d681SAndroid Build Coastguard Worker   }
1106*9880d681SAndroid Build Coastguard Worker #endif
1107*9880d681SAndroid Build Coastguard Worker }
1108*9880d681SAndroid Build Coastguard Worker 
1109*9880d681SAndroid Build Coastguard Worker /// This is the fast version of querying register pressure that does not
1110*9880d681SAndroid Build Coastguard Worker /// directly depend on current liveness.
1111*9880d681SAndroid Build Coastguard Worker ///
1112*9880d681SAndroid Build Coastguard Worker /// @param Delta captures information needed for heuristics.
1113*9880d681SAndroid Build Coastguard Worker ///
1114*9880d681SAndroid Build Coastguard Worker /// @param CriticalPSets Are the pressure sets that are known to exceed some
1115*9880d681SAndroid Build Coastguard Worker /// limit within the region, not necessarily at the current position.
1116*9880d681SAndroid Build Coastguard Worker ///
1117*9880d681SAndroid Build Coastguard Worker /// @param MaxPressureLimit Is the max pressure within the region, not
1118*9880d681SAndroid Build Coastguard Worker /// necessarily at the current position.
1119*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::
getUpwardPressureDelta(const MachineInstr * MI,PressureDiff & PDiff,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit) const1120*9880d681SAndroid Build Coastguard Worker getUpwardPressureDelta(const MachineInstr *MI, /*const*/ PressureDiff &PDiff,
1121*9880d681SAndroid Build Coastguard Worker                        RegPressureDelta &Delta,
1122*9880d681SAndroid Build Coastguard Worker                        ArrayRef<PressureChange> CriticalPSets,
1123*9880d681SAndroid Build Coastguard Worker                        ArrayRef<unsigned> MaxPressureLimit) const {
1124*9880d681SAndroid Build Coastguard Worker   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
1125*9880d681SAndroid Build Coastguard Worker   for (PressureDiff::const_iterator
1126*9880d681SAndroid Build Coastguard Worker          PDiffI = PDiff.begin(), PDiffE = PDiff.end();
1127*9880d681SAndroid Build Coastguard Worker        PDiffI != PDiffE && PDiffI->isValid(); ++PDiffI) {
1128*9880d681SAndroid Build Coastguard Worker 
1129*9880d681SAndroid Build Coastguard Worker     unsigned PSetID = PDiffI->getPSet();
1130*9880d681SAndroid Build Coastguard Worker     unsigned Limit = RCI->getRegPressureSetLimit(PSetID);
1131*9880d681SAndroid Build Coastguard Worker     if (!LiveThruPressure.empty())
1132*9880d681SAndroid Build Coastguard Worker       Limit += LiveThruPressure[PSetID];
1133*9880d681SAndroid Build Coastguard Worker 
1134*9880d681SAndroid Build Coastguard Worker     unsigned POld = CurrSetPressure[PSetID];
1135*9880d681SAndroid Build Coastguard Worker     unsigned MOld = P.MaxSetPressure[PSetID];
1136*9880d681SAndroid Build Coastguard Worker     unsigned MNew = MOld;
1137*9880d681SAndroid Build Coastguard Worker     // Ignore DeadDefs here because they aren't captured by PressureChange.
1138*9880d681SAndroid Build Coastguard Worker     unsigned PNew = POld + PDiffI->getUnitInc();
1139*9880d681SAndroid Build Coastguard Worker     assert((PDiffI->getUnitInc() >= 0) == (PNew >= POld)
1140*9880d681SAndroid Build Coastguard Worker            && "PSet overflow/underflow");
1141*9880d681SAndroid Build Coastguard Worker     if (PNew > MOld)
1142*9880d681SAndroid Build Coastguard Worker       MNew = PNew;
1143*9880d681SAndroid Build Coastguard Worker     // Check if current pressure has exceeded the limit.
1144*9880d681SAndroid Build Coastguard Worker     if (!Delta.Excess.isValid()) {
1145*9880d681SAndroid Build Coastguard Worker       unsigned ExcessInc = 0;
1146*9880d681SAndroid Build Coastguard Worker       if (PNew > Limit)
1147*9880d681SAndroid Build Coastguard Worker         ExcessInc = POld > Limit ? PNew - POld : PNew - Limit;
1148*9880d681SAndroid Build Coastguard Worker       else if (POld > Limit)
1149*9880d681SAndroid Build Coastguard Worker         ExcessInc = Limit - POld;
1150*9880d681SAndroid Build Coastguard Worker       if (ExcessInc) {
1151*9880d681SAndroid Build Coastguard Worker         Delta.Excess = PressureChange(PSetID);
1152*9880d681SAndroid Build Coastguard Worker         Delta.Excess.setUnitInc(ExcessInc);
1153*9880d681SAndroid Build Coastguard Worker       }
1154*9880d681SAndroid Build Coastguard Worker     }
1155*9880d681SAndroid Build Coastguard Worker     // Check if max pressure has exceeded a critical pressure set max.
1156*9880d681SAndroid Build Coastguard Worker     if (MNew == MOld)
1157*9880d681SAndroid Build Coastguard Worker       continue;
1158*9880d681SAndroid Build Coastguard Worker     if (!Delta.CriticalMax.isValid()) {
1159*9880d681SAndroid Build Coastguard Worker       while (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() < PSetID)
1160*9880d681SAndroid Build Coastguard Worker         ++CritIdx;
1161*9880d681SAndroid Build Coastguard Worker 
1162*9880d681SAndroid Build Coastguard Worker       if (CritIdx != CritEnd && CriticalPSets[CritIdx].getPSet() == PSetID) {
1163*9880d681SAndroid Build Coastguard Worker         int CritInc = (int)MNew - (int)CriticalPSets[CritIdx].getUnitInc();
1164*9880d681SAndroid Build Coastguard Worker         if (CritInc > 0 && CritInc <= INT16_MAX) {
1165*9880d681SAndroid Build Coastguard Worker           Delta.CriticalMax = PressureChange(PSetID);
1166*9880d681SAndroid Build Coastguard Worker           Delta.CriticalMax.setUnitInc(CritInc);
1167*9880d681SAndroid Build Coastguard Worker         }
1168*9880d681SAndroid Build Coastguard Worker       }
1169*9880d681SAndroid Build Coastguard Worker     }
1170*9880d681SAndroid Build Coastguard Worker     // Check if max pressure has exceeded the current max.
1171*9880d681SAndroid Build Coastguard Worker     if (!Delta.CurrentMax.isValid() && MNew > MaxPressureLimit[PSetID]) {
1172*9880d681SAndroid Build Coastguard Worker       Delta.CurrentMax = PressureChange(PSetID);
1173*9880d681SAndroid Build Coastguard Worker       Delta.CurrentMax.setUnitInc(MNew - MOld);
1174*9880d681SAndroid Build Coastguard Worker     }
1175*9880d681SAndroid Build Coastguard Worker   }
1176*9880d681SAndroid Build Coastguard Worker }
1177*9880d681SAndroid Build Coastguard Worker 
1178*9880d681SAndroid Build Coastguard Worker /// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
1179*9880d681SAndroid Build Coastguard Worker /// The query starts with a lane bitmask which gets lanes/bits removed for every
1180*9880d681SAndroid Build Coastguard Worker /// use we find.
findUseBetween(unsigned Reg,LaneBitmask LastUseMask,SlotIndex PriorUseIdx,SlotIndex NextUseIdx,const MachineRegisterInfo & MRI,const LiveIntervals * LIS)1181*9880d681SAndroid Build Coastguard Worker static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
1182*9880d681SAndroid Build Coastguard Worker                                   SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
1183*9880d681SAndroid Build Coastguard Worker                                   const MachineRegisterInfo &MRI,
1184*9880d681SAndroid Build Coastguard Worker                                   const LiveIntervals *LIS) {
1185*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
1186*9880d681SAndroid Build Coastguard Worker   for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
1187*9880d681SAndroid Build Coastguard Worker     if (MO.isUndef())
1188*9880d681SAndroid Build Coastguard Worker       continue;
1189*9880d681SAndroid Build Coastguard Worker     const MachineInstr *MI = MO.getParent();
1190*9880d681SAndroid Build Coastguard Worker     SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
1191*9880d681SAndroid Build Coastguard Worker     if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx) {
1192*9880d681SAndroid Build Coastguard Worker       unsigned SubRegIdx = MO.getSubReg();
1193*9880d681SAndroid Build Coastguard Worker       LaneBitmask UseMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
1194*9880d681SAndroid Build Coastguard Worker       LastUseMask &= ~UseMask;
1195*9880d681SAndroid Build Coastguard Worker       if (LastUseMask == 0)
1196*9880d681SAndroid Build Coastguard Worker         return 0;
1197*9880d681SAndroid Build Coastguard Worker     }
1198*9880d681SAndroid Build Coastguard Worker   }
1199*9880d681SAndroid Build Coastguard Worker   return LastUseMask;
1200*9880d681SAndroid Build Coastguard Worker }
1201*9880d681SAndroid Build Coastguard Worker 
getLiveLanesAt(unsigned RegUnit,SlotIndex Pos) const1202*9880d681SAndroid Build Coastguard Worker LaneBitmask RegPressureTracker::getLiveLanesAt(unsigned RegUnit,
1203*9880d681SAndroid Build Coastguard Worker                                                SlotIndex Pos) const {
1204*9880d681SAndroid Build Coastguard Worker   assert(RequireIntervals);
1205*9880d681SAndroid Build Coastguard Worker   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
1206*9880d681SAndroid Build Coastguard Worker       [](const LiveRange &LR, SlotIndex Pos) {
1207*9880d681SAndroid Build Coastguard Worker         return LR.liveAt(Pos);
1208*9880d681SAndroid Build Coastguard Worker       });
1209*9880d681SAndroid Build Coastguard Worker }
1210*9880d681SAndroid Build Coastguard Worker 
getLastUsedLanes(unsigned RegUnit,SlotIndex Pos) const1211*9880d681SAndroid Build Coastguard Worker LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
1212*9880d681SAndroid Build Coastguard Worker                                                  SlotIndex Pos) const {
1213*9880d681SAndroid Build Coastguard Worker   assert(RequireIntervals);
1214*9880d681SAndroid Build Coastguard Worker   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
1215*9880d681SAndroid Build Coastguard Worker                               Pos.getBaseIndex(), 0,
1216*9880d681SAndroid Build Coastguard Worker       [](const LiveRange &LR, SlotIndex Pos) {
1217*9880d681SAndroid Build Coastguard Worker         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
1218*9880d681SAndroid Build Coastguard Worker         return S != nullptr && S->end == Pos.getRegSlot();
1219*9880d681SAndroid Build Coastguard Worker       });
1220*9880d681SAndroid Build Coastguard Worker }
1221*9880d681SAndroid Build Coastguard Worker 
getLiveThroughAt(unsigned RegUnit,SlotIndex Pos) const1222*9880d681SAndroid Build Coastguard Worker LaneBitmask RegPressureTracker::getLiveThroughAt(unsigned RegUnit,
1223*9880d681SAndroid Build Coastguard Worker                                                  SlotIndex Pos) const {
1224*9880d681SAndroid Build Coastguard Worker   assert(RequireIntervals);
1225*9880d681SAndroid Build Coastguard Worker   return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, 0u,
1226*9880d681SAndroid Build Coastguard Worker       [](const LiveRange &LR, SlotIndex Pos) {
1227*9880d681SAndroid Build Coastguard Worker         const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
1228*9880d681SAndroid Build Coastguard Worker         return S != nullptr && S->start < Pos.getRegSlot(true) &&
1229*9880d681SAndroid Build Coastguard Worker                S->end != Pos.getDeadSlot();
1230*9880d681SAndroid Build Coastguard Worker       });
1231*9880d681SAndroid Build Coastguard Worker }
1232*9880d681SAndroid Build Coastguard Worker 
1233*9880d681SAndroid Build Coastguard Worker /// Record the downward impact of a single instruction on current register
1234*9880d681SAndroid Build Coastguard Worker /// pressure. Unlike the advance/recede pressure tracking interface, this does
1235*9880d681SAndroid Build Coastguard Worker /// not discover live in/outs.
1236*9880d681SAndroid Build Coastguard Worker ///
1237*9880d681SAndroid Build Coastguard Worker /// This is intended for speculative queries. It leaves pressure inconsistent
1238*9880d681SAndroid Build Coastguard Worker /// with the current position, so must be restored by the caller.
bumpDownwardPressure(const MachineInstr * MI)1239*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
1240*9880d681SAndroid Build Coastguard Worker   assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
1241*9880d681SAndroid Build Coastguard Worker 
1242*9880d681SAndroid Build Coastguard Worker   SlotIndex SlotIdx;
1243*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals)
1244*9880d681SAndroid Build Coastguard Worker     SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();
1245*9880d681SAndroid Build Coastguard Worker 
1246*9880d681SAndroid Build Coastguard Worker   // Account for register pressure similar to RegPressureTracker::recede().
1247*9880d681SAndroid Build Coastguard Worker   RegisterOperands RegOpers;
1248*9880d681SAndroid Build Coastguard Worker   RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, false);
1249*9880d681SAndroid Build Coastguard Worker   if (TrackLaneMasks)
1250*9880d681SAndroid Build Coastguard Worker     RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
1251*9880d681SAndroid Build Coastguard Worker 
1252*9880d681SAndroid Build Coastguard Worker   if (RequireIntervals) {
1253*9880d681SAndroid Build Coastguard Worker     for (const RegisterMaskPair &Use : RegOpers.Uses) {
1254*9880d681SAndroid Build Coastguard Worker       unsigned Reg = Use.RegUnit;
1255*9880d681SAndroid Build Coastguard Worker       LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
1256*9880d681SAndroid Build Coastguard Worker       if (LastUseMask == 0)
1257*9880d681SAndroid Build Coastguard Worker         continue;
1258*9880d681SAndroid Build Coastguard Worker       // The LastUseMask is queried from the liveness information of instruction
1259*9880d681SAndroid Build Coastguard Worker       // which may be further down the schedule. Some lanes may actually not be
1260*9880d681SAndroid Build Coastguard Worker       // last uses for the current position.
1261*9880d681SAndroid Build Coastguard Worker       // FIXME: allow the caller to pass in the list of vreg uses that remain
1262*9880d681SAndroid Build Coastguard Worker       // to be bottom-scheduled to avoid searching uses at each query.
1263*9880d681SAndroid Build Coastguard Worker       SlotIndex CurrIdx = getCurrSlot();
1264*9880d681SAndroid Build Coastguard Worker       LastUseMask
1265*9880d681SAndroid Build Coastguard Worker         = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
1266*9880d681SAndroid Build Coastguard Worker       if (LastUseMask == 0)
1267*9880d681SAndroid Build Coastguard Worker         continue;
1268*9880d681SAndroid Build Coastguard Worker 
1269*9880d681SAndroid Build Coastguard Worker       LaneBitmask LiveMask = LiveRegs.contains(Reg);
1270*9880d681SAndroid Build Coastguard Worker       LaneBitmask NewMask = LiveMask & ~LastUseMask;
1271*9880d681SAndroid Build Coastguard Worker       decreaseRegPressure(Reg, LiveMask, NewMask);
1272*9880d681SAndroid Build Coastguard Worker     }
1273*9880d681SAndroid Build Coastguard Worker   }
1274*9880d681SAndroid Build Coastguard Worker 
1275*9880d681SAndroid Build Coastguard Worker   // Generate liveness for defs.
1276*9880d681SAndroid Build Coastguard Worker   for (const RegisterMaskPair &Def : RegOpers.Defs) {
1277*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Def.RegUnit;
1278*9880d681SAndroid Build Coastguard Worker     LaneBitmask LiveMask = LiveRegs.contains(Reg);
1279*9880d681SAndroid Build Coastguard Worker     LaneBitmask NewMask = LiveMask | Def.LaneMask;
1280*9880d681SAndroid Build Coastguard Worker     increaseRegPressure(Reg, LiveMask, NewMask);
1281*9880d681SAndroid Build Coastguard Worker   }
1282*9880d681SAndroid Build Coastguard Worker 
1283*9880d681SAndroid Build Coastguard Worker   // Boost pressure for all dead defs together.
1284*9880d681SAndroid Build Coastguard Worker   bumpDeadDefs(RegOpers.DeadDefs);
1285*9880d681SAndroid Build Coastguard Worker }
1286*9880d681SAndroid Build Coastguard Worker 
1287*9880d681SAndroid Build Coastguard Worker /// Consider the pressure increase caused by traversing this instruction
1288*9880d681SAndroid Build Coastguard Worker /// top-down. Find the register class with the most change in its pressure limit
1289*9880d681SAndroid Build Coastguard Worker /// based on the tracker's current pressure, and return the number of excess
1290*9880d681SAndroid Build Coastguard Worker /// register units of that pressure set introduced by this instruction.
1291*9880d681SAndroid Build Coastguard Worker ///
1292*9880d681SAndroid Build Coastguard Worker /// This assumes that the current LiveIn set is sufficient.
1293*9880d681SAndroid Build Coastguard Worker ///
1294*9880d681SAndroid Build Coastguard Worker /// This is expensive for an on-the-fly query because it calls
1295*9880d681SAndroid Build Coastguard Worker /// bumpDownwardPressure to recompute the pressure sets based on current
1296*9880d681SAndroid Build Coastguard Worker /// liveness. We don't yet have a fast version of downward pressure tracking
1297*9880d681SAndroid Build Coastguard Worker /// analogous to getUpwardPressureDelta.
1298*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::
getMaxDownwardPressureDelta(const MachineInstr * MI,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit)1299*9880d681SAndroid Build Coastguard Worker getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
1300*9880d681SAndroid Build Coastguard Worker                             ArrayRef<PressureChange> CriticalPSets,
1301*9880d681SAndroid Build Coastguard Worker                             ArrayRef<unsigned> MaxPressureLimit) {
1302*9880d681SAndroid Build Coastguard Worker   // Snapshot Pressure.
1303*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> SavedPressure = CurrSetPressure;
1304*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
1305*9880d681SAndroid Build Coastguard Worker 
1306*9880d681SAndroid Build Coastguard Worker   bumpDownwardPressure(MI);
1307*9880d681SAndroid Build Coastguard Worker 
1308*9880d681SAndroid Build Coastguard Worker   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
1309*9880d681SAndroid Build Coastguard Worker                              LiveThruPressure);
1310*9880d681SAndroid Build Coastguard Worker   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
1311*9880d681SAndroid Build Coastguard Worker                           MaxPressureLimit, Delta);
1312*9880d681SAndroid Build Coastguard Worker   assert(Delta.CriticalMax.getUnitInc() >= 0 &&
1313*9880d681SAndroid Build Coastguard Worker          Delta.CurrentMax.getUnitInc() >= 0 && "cannot decrease max pressure");
1314*9880d681SAndroid Build Coastguard Worker 
1315*9880d681SAndroid Build Coastguard Worker   // Restore the tracker's state.
1316*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure.swap(SavedMaxPressure);
1317*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.swap(SavedPressure);
1318*9880d681SAndroid Build Coastguard Worker }
1319*9880d681SAndroid Build Coastguard Worker 
1320*9880d681SAndroid Build Coastguard Worker /// Get the pressure of each PSet after traversing this instruction bottom-up.
1321*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::
getUpwardPressure(const MachineInstr * MI,std::vector<unsigned> & PressureResult,std::vector<unsigned> & MaxPressureResult)1322*9880d681SAndroid Build Coastguard Worker getUpwardPressure(const MachineInstr *MI,
1323*9880d681SAndroid Build Coastguard Worker                   std::vector<unsigned> &PressureResult,
1324*9880d681SAndroid Build Coastguard Worker                   std::vector<unsigned> &MaxPressureResult) {
1325*9880d681SAndroid Build Coastguard Worker   // Snapshot pressure.
1326*9880d681SAndroid Build Coastguard Worker   PressureResult = CurrSetPressure;
1327*9880d681SAndroid Build Coastguard Worker   MaxPressureResult = P.MaxSetPressure;
1328*9880d681SAndroid Build Coastguard Worker 
1329*9880d681SAndroid Build Coastguard Worker   bumpUpwardPressure(MI);
1330*9880d681SAndroid Build Coastguard Worker 
1331*9880d681SAndroid Build Coastguard Worker   // Current pressure becomes the result. Restore current pressure.
1332*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure.swap(MaxPressureResult);
1333*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.swap(PressureResult);
1334*9880d681SAndroid Build Coastguard Worker }
1335*9880d681SAndroid Build Coastguard Worker 
1336*9880d681SAndroid Build Coastguard Worker /// Get the pressure of each PSet after traversing this instruction top-down.
1337*9880d681SAndroid Build Coastguard Worker void RegPressureTracker::
getDownwardPressure(const MachineInstr * MI,std::vector<unsigned> & PressureResult,std::vector<unsigned> & MaxPressureResult)1338*9880d681SAndroid Build Coastguard Worker getDownwardPressure(const MachineInstr *MI,
1339*9880d681SAndroid Build Coastguard Worker                     std::vector<unsigned> &PressureResult,
1340*9880d681SAndroid Build Coastguard Worker                     std::vector<unsigned> &MaxPressureResult) {
1341*9880d681SAndroid Build Coastguard Worker   // Snapshot pressure.
1342*9880d681SAndroid Build Coastguard Worker   PressureResult = CurrSetPressure;
1343*9880d681SAndroid Build Coastguard Worker   MaxPressureResult = P.MaxSetPressure;
1344*9880d681SAndroid Build Coastguard Worker 
1345*9880d681SAndroid Build Coastguard Worker   bumpDownwardPressure(MI);
1346*9880d681SAndroid Build Coastguard Worker 
1347*9880d681SAndroid Build Coastguard Worker   // Current pressure becomes the result. Restore current pressure.
1348*9880d681SAndroid Build Coastguard Worker   P.MaxSetPressure.swap(MaxPressureResult);
1349*9880d681SAndroid Build Coastguard Worker   CurrSetPressure.swap(PressureResult);
1350*9880d681SAndroid Build Coastguard Worker }
1351