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