LLVM API Documentation

RegisterPressure.cpp
Go to the documentation of this file.
00001 //===-- RegisterPressure.cpp - Dynamic Register Pressure ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the RegisterPressure class which can be used to track
00011 // MachineInstr level register pressure.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/CodeGen/RegisterPressure.h"
00016 #include "llvm/CodeGen/LiveInterval.h"
00017 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
00018 #include "llvm/CodeGen/MachineRegisterInfo.h"
00019 #include "llvm/CodeGen/RegisterClassInfo.h"
00020 #include "llvm/Support/Debug.h"
00021 #include "llvm/Support/raw_ostream.h"
00022 #include "llvm/Target/TargetMachine.h"
00023 
00024 using namespace llvm;
00025 
00026 /// Increase pressure for each pressure set provided by TargetRegisterInfo.
00027 static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
00028                                 std::vector<unsigned> &MaxSetPressure,
00029                                 const int *PSet, unsigned Weight) {
00030   for (; *PSet != -1; ++PSet) {
00031     CurrSetPressure[*PSet] += Weight;
00032     if (&CurrSetPressure != &MaxSetPressure
00033         && CurrSetPressure[*PSet] > MaxSetPressure[*PSet]) {
00034       MaxSetPressure[*PSet] = CurrSetPressure[*PSet];
00035     }
00036   }
00037 }
00038 
00039 /// Decrease pressure for each pressure set provided by TargetRegisterInfo.
00040 static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
00041                                 const int *PSet, unsigned Weight) {
00042   for (; *PSet != -1; ++PSet) {
00043     assert(CurrSetPressure[*PSet] >= Weight && "register pressure underflow");
00044     CurrSetPressure[*PSet] -= Weight;
00045   }
00046 }
00047 
00048 /// Directly increase pressure only within this RegisterPressure result.
00049 void RegisterPressure::increase(unsigned Reg, const TargetRegisterInfo *TRI,
00050                                 const MachineRegisterInfo *MRI) {
00051   if (TargetRegisterInfo::isVirtualRegister(Reg)) {
00052     const TargetRegisterClass *RC = MRI->getRegClass(Reg);
00053     increaseSetPressure(MaxSetPressure, MaxSetPressure,
00054                         TRI->getRegClassPressureSets(RC),
00055                         TRI->getRegClassWeight(RC).RegWeight);
00056   }
00057   else {
00058     increaseSetPressure(MaxSetPressure, MaxSetPressure,
00059                         TRI->getRegUnitPressureSets(Reg),
00060                         TRI->getRegUnitWeight(Reg));
00061   }
00062 }
00063 
00064 /// Directly decrease pressure only within this RegisterPressure result.
00065 void RegisterPressure::decrease(unsigned Reg, const TargetRegisterInfo *TRI,
00066                                 const MachineRegisterInfo *MRI) {
00067   if (TargetRegisterInfo::isVirtualRegister(Reg)) {
00068     const TargetRegisterClass *RC = MRI->getRegClass(Reg);
00069     decreaseSetPressure(MaxSetPressure, TRI->getRegClassPressureSets(RC),
00070                         TRI->getRegClassWeight(RC).RegWeight);
00071   }
00072   else {
00073     decreaseSetPressure(MaxSetPressure, TRI->getRegUnitPressureSets(Reg),
00074                         TRI->getRegUnitWeight(Reg));
00075   }
00076 }
00077 
00078 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
00079 static void dumpSetPressure(const std::vector<unsigned> &SetPressure,
00080                             const TargetRegisterInfo *TRI) {
00081   for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) {
00082     if (SetPressure[i] != 0)
00083       dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n';
00084   }
00085 }
00086 
00087 void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
00088   dbgs() << "Max Pressure: ";
00089   dumpSetPressure(MaxSetPressure, TRI);
00090   dbgs() << "Live In: ";
00091   for (unsigned i = 0, e = LiveInRegs.size(); i < e; ++i)
00092     dbgs() << PrintReg(LiveInRegs[i], TRI) << " ";
00093   dbgs() << '\n';
00094   dbgs() << "Live Out: ";
00095   for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i)
00096     dbgs() << PrintReg(LiveOutRegs[i], TRI) << " ";
00097   dbgs() << '\n';
00098 }
00099 
00100 void RegPressureTracker::dump() const {
00101   dbgs() << "Curr Pressure: ";
00102   dumpSetPressure(CurrSetPressure, TRI);
00103   P.dump(TRI);
00104 }
00105 #endif
00106 
00107 /// Increase the current pressure as impacted by these registers and bump
00108 /// the high water mark if needed.
00109 void RegPressureTracker::increaseRegPressure(ArrayRef<unsigned> Regs) {
00110   for (unsigned I = 0, E = Regs.size(); I != E; ++I) {
00111     if (TargetRegisterInfo::isVirtualRegister(Regs[I])) {
00112       const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]);
00113       increaseSetPressure(CurrSetPressure, P.MaxSetPressure,
00114                           TRI->getRegClassPressureSets(RC),
00115                           TRI->getRegClassWeight(RC).RegWeight);
00116     }
00117     else {
00118       increaseSetPressure(CurrSetPressure, P.MaxSetPressure,
00119                           TRI->getRegUnitPressureSets(Regs[I]),
00120                           TRI->getRegUnitWeight(Regs[I]));
00121     }
00122   }
00123 }
00124 
00125 /// Simply decrease the current pressure as impacted by these registers.
00126 void RegPressureTracker::decreaseRegPressure(ArrayRef<unsigned> Regs) {
00127   for (unsigned I = 0, E = Regs.size(); I != E; ++I) {
00128     if (TargetRegisterInfo::isVirtualRegister(Regs[I])) {
00129       const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]);
00130       decreaseSetPressure(CurrSetPressure,
00131                           TRI->getRegClassPressureSets(RC),
00132                           TRI->getRegClassWeight(RC).RegWeight);
00133     }
00134     else {
00135       decreaseSetPressure(CurrSetPressure, TRI->getRegUnitPressureSets(Regs[I]),
00136                           TRI->getRegUnitWeight(Regs[I]));
00137     }
00138   }
00139 }
00140 
00141 /// Clear the result so it can be used for another round of pressure tracking.
00142 void IntervalPressure::reset() {
00143   TopIdx = BottomIdx = SlotIndex();
00144   MaxSetPressure.clear();
00145   LiveInRegs.clear();
00146   LiveOutRegs.clear();
00147 }
00148 
00149 /// Clear the result so it can be used for another round of pressure tracking.
00150 void RegionPressure::reset() {
00151   TopPos = BottomPos = MachineBasicBlock::const_iterator();
00152   MaxSetPressure.clear();
00153   LiveInRegs.clear();
00154   LiveOutRegs.clear();
00155 }
00156 
00157 /// If the current top is not less than or equal to the next index, open it.
00158 /// We happen to need the SlotIndex for the next top for pressure update.
00159 void IntervalPressure::openTop(SlotIndex NextTop) {
00160   if (TopIdx <= NextTop)
00161     return;
00162   TopIdx = SlotIndex();
00163   LiveInRegs.clear();
00164 }
00165 
00166 /// If the current top is the previous instruction (before receding), open it.
00167 void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
00168   if (TopPos != PrevTop)
00169     return;
00170   TopPos = MachineBasicBlock::const_iterator();
00171   LiveInRegs.clear();
00172 }
00173 
00174 /// If the current bottom is not greater than the previous index, open it.
00175 void IntervalPressure::openBottom(SlotIndex PrevBottom) {
00176   if (BottomIdx > PrevBottom)
00177     return;
00178   BottomIdx = SlotIndex();
00179   LiveInRegs.clear();
00180 }
00181 
00182 /// If the current bottom is the previous instr (before advancing), open it.
00183 void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
00184   if (BottomPos != PrevBottom)
00185     return;
00186   BottomPos = MachineBasicBlock::const_iterator();
00187   LiveInRegs.clear();
00188 }
00189 
00190 const LiveInterval *RegPressureTracker::getInterval(unsigned Reg) const {
00191   if (TargetRegisterInfo::isVirtualRegister(Reg))
00192     return &LIS->getInterval(Reg);
00193   return LIS->getCachedRegUnit(Reg);
00194 }
00195 
00196 /// Setup the RegPressureTracker.
00197 ///
00198 /// TODO: Add support for pressure without LiveIntervals.
00199 void RegPressureTracker::init(const MachineFunction *mf,
00200                               const RegisterClassInfo *rci,
00201                               const LiveIntervals *lis,
00202                               const MachineBasicBlock *mbb,
00203                               MachineBasicBlock::const_iterator pos)
00204 {
00205   MF = mf;
00206   TRI = MF->getTarget().getRegisterInfo();
00207   RCI = rci;
00208   MRI = &MF->getRegInfo();
00209   MBB = mbb;
00210 
00211   if (RequireIntervals) {
00212     assert(lis && "IntervalPressure requires LiveIntervals");
00213     LIS = lis;
00214   }
00215 
00216   CurrPos = pos;
00217   CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
00218 
00219   if (RequireIntervals)
00220     static_cast<IntervalPressure&>(P).reset();
00221   else
00222     static_cast<RegionPressure&>(P).reset();
00223   P.MaxSetPressure = CurrSetPressure;
00224 
00225   LiveRegs.PhysRegs.clear();
00226   LiveRegs.PhysRegs.setUniverse(TRI->getNumRegs());
00227   LiveRegs.VirtRegs.clear();
00228   LiveRegs.VirtRegs.setUniverse(MRI->getNumVirtRegs());
00229 }
00230 
00231 /// Does this pressure result have a valid top position and live ins.
00232 bool RegPressureTracker::isTopClosed() const {
00233   if (RequireIntervals)
00234     return static_cast<IntervalPressure&>(P).TopIdx.isValid();
00235   return (static_cast<RegionPressure&>(P).TopPos ==
00236           MachineBasicBlock::const_iterator());
00237 }
00238 
00239 /// Does this pressure result have a valid bottom position and live outs.
00240 bool RegPressureTracker::isBottomClosed() const {
00241   if (RequireIntervals)
00242     return static_cast<IntervalPressure&>(P).BottomIdx.isValid();
00243   return (static_cast<RegionPressure&>(P).BottomPos ==
00244           MachineBasicBlock::const_iterator());
00245 }
00246 
00247 
00248 SlotIndex RegPressureTracker::getCurrSlot() const {
00249   MachineBasicBlock::const_iterator IdxPos = CurrPos;
00250   while (IdxPos != MBB->end() && IdxPos->isDebugValue())
00251     ++IdxPos;
00252   if (IdxPos == MBB->end())
00253     return LIS->getMBBEndIdx(MBB);
00254   return LIS->getInstructionIndex(IdxPos).getRegSlot();
00255 }
00256 
00257 /// Set the boundary for the top of the region and summarize live ins.
00258 void RegPressureTracker::closeTop() {
00259   if (RequireIntervals)
00260     static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot();
00261   else
00262     static_cast<RegionPressure&>(P).TopPos = CurrPos;
00263 
00264   assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
00265   P.LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
00266   P.LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
00267   for (SparseSet<unsigned>::const_iterator I =
00268          LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
00269     P.LiveInRegs.push_back(*I);
00270   std::sort(P.LiveInRegs.begin(), P.LiveInRegs.end());
00271   P.LiveInRegs.erase(std::unique(P.LiveInRegs.begin(), P.LiveInRegs.end()),
00272                      P.LiveInRegs.end());
00273 }
00274 
00275 /// Set the boundary for the bottom of the region and summarize live outs.
00276 void RegPressureTracker::closeBottom() {
00277   if (RequireIntervals)
00278     static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot();
00279   else
00280     static_cast<RegionPressure&>(P).BottomPos = CurrPos;
00281 
00282   assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
00283   P.LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
00284   P.LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
00285   for (SparseSet<unsigned>::const_iterator I =
00286          LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
00287     P.LiveOutRegs.push_back(*I);
00288   std::sort(P.LiveOutRegs.begin(), P.LiveOutRegs.end());
00289   P.LiveOutRegs.erase(std::unique(P.LiveOutRegs.begin(), P.LiveOutRegs.end()),
00290                       P.LiveOutRegs.end());
00291 }
00292 
00293 /// Finalize the region boundaries and record live ins and live outs.
00294 void RegPressureTracker::closeRegion() {
00295   if (!isTopClosed() && !isBottomClosed()) {
00296     assert(LiveRegs.PhysRegs.empty() && LiveRegs.VirtRegs.empty() &&
00297            "no region boundary");
00298     return;
00299   }
00300   if (!isBottomClosed())
00301     closeBottom();
00302   else if (!isTopClosed())
00303     closeTop();
00304   // If both top and bottom are closed, do nothing.
00305 }
00306 
00307 /// \brief Convenient wrapper for checking membership in RegisterOperands.
00308 static bool containsReg(ArrayRef<unsigned> Regs, unsigned Reg) {
00309   return std::find(Regs.begin(), Regs.end(), Reg) != Regs.end();
00310 }
00311 
00312 /// Collect this instruction's unique uses and defs into SmallVectors for
00313 /// processing defs and uses in order.
00314 class RegisterOperands {
00315   const TargetRegisterInfo *TRI;
00316   const MachineRegisterInfo *MRI;
00317 
00318 public:
00319   SmallVector<unsigned, 8> Uses;
00320   SmallVector<unsigned, 8> Defs;
00321   SmallVector<unsigned, 8> DeadDefs;
00322 
00323   RegisterOperands(const TargetRegisterInfo *tri,
00324                    const MachineRegisterInfo *mri): TRI(tri), MRI(mri) {}
00325 
00326   /// Push this operand's register onto the correct vector.
00327   void collect(const MachineOperand &MO) {
00328     if (!MO.isReg() || !MO.getReg())
00329       return;
00330     if (MO.readsReg())
00331       pushRegUnits(MO.getReg(), Uses);
00332     if (MO.isDef()) {
00333       if (MO.isDead())
00334         pushRegUnits(MO.getReg(), DeadDefs);
00335       else
00336         pushRegUnits(MO.getReg(), Defs);
00337     }
00338   }
00339 
00340 protected:
00341   void pushRegUnits(unsigned Reg, SmallVectorImpl<unsigned> &Regs) {
00342     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
00343       if (containsReg(Regs, Reg))
00344         return;
00345       Regs.push_back(Reg);
00346     }
00347     else if (MRI->isAllocatable(Reg)) {
00348       for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
00349         if (containsReg(Regs, *Units))
00350           continue;
00351         Regs.push_back(*Units);
00352       }
00353     }
00354   }
00355 };
00356 
00357 /// Collect physical and virtual register operands.
00358 static void collectOperands(const MachineInstr *MI,
00359                             RegisterOperands &RegOpers) {
00360   for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
00361     RegOpers.collect(*OperI);
00362 
00363   // Remove redundant physreg dead defs.
00364   SmallVectorImpl<unsigned>::iterator I =
00365     std::remove_if(RegOpers.DeadDefs.begin(), RegOpers.DeadDefs.end(),
00366                    std::bind1st(std::ptr_fun(containsReg), RegOpers.Defs));
00367   RegOpers.DeadDefs.erase(I, RegOpers.DeadDefs.end());
00368 }
00369 
00370 /// Force liveness of registers.
00371 void RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) {
00372   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
00373     if (LiveRegs.insert(Regs[i]))
00374       increaseRegPressure(Regs[i]);
00375   }
00376 }
00377 
00378 /// Add Reg to the live in set and increase max pressure.
00379 void RegPressureTracker::discoverLiveIn(unsigned Reg) {
00380   assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
00381   if (containsReg(P.LiveInRegs, Reg))
00382     return;
00383 
00384   // At live in discovery, unconditionally increase the high water mark.
00385   P.LiveInRegs.push_back(Reg);
00386   P.increase(Reg, TRI, MRI);
00387 }
00388 
00389 /// Add Reg to the live out set and increase max pressure.
00390 void RegPressureTracker::discoverLiveOut(unsigned Reg) {
00391   assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
00392   if (containsReg(P.LiveOutRegs, Reg))
00393     return;
00394 
00395   // At live out discovery, unconditionally increase the high water mark.
00396   P.LiveOutRegs.push_back(Reg);
00397   P.increase(Reg, TRI, MRI);
00398 }
00399 
00400 /// Recede across the previous instruction.
00401 bool RegPressureTracker::recede() {
00402   // Check for the top of the analyzable region.
00403   if (CurrPos == MBB->begin()) {
00404     closeRegion();
00405     return false;
00406   }
00407   if (!isBottomClosed())
00408     closeBottom();
00409 
00410   // Open the top of the region using block iterators.
00411   if (!RequireIntervals && isTopClosed())
00412     static_cast<RegionPressure&>(P).openTop(CurrPos);
00413 
00414   // Find the previous instruction.
00415   do
00416     --CurrPos;
00417   while (CurrPos != MBB->begin() && CurrPos->isDebugValue());
00418 
00419   if (CurrPos->isDebugValue()) {
00420     closeRegion();
00421     return false;
00422   }
00423   SlotIndex SlotIdx;
00424   if (RequireIntervals)
00425     SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
00426 
00427   // Open the top of the region using slot indexes.
00428   if (RequireIntervals && isTopClosed())
00429     static_cast<IntervalPressure&>(P).openTop(SlotIdx);
00430 
00431   RegisterOperands RegOpers(TRI, MRI);
00432   collectOperands(CurrPos, RegOpers);
00433 
00434   // Boost pressure for all dead defs together.
00435   increaseRegPressure(RegOpers.DeadDefs);
00436   decreaseRegPressure(RegOpers.DeadDefs);
00437 
00438   // Kill liveness at live defs.
00439   // TODO: consider earlyclobbers?
00440   for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
00441     unsigned Reg = RegOpers.Defs[i];
00442     if (LiveRegs.erase(Reg))
00443       decreaseRegPressure(Reg);
00444     else
00445       discoverLiveOut(Reg);
00446   }
00447 
00448   // Generate liveness for uses.
00449   for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
00450     unsigned Reg = RegOpers.Uses[i];
00451     if (!LiveRegs.contains(Reg)) {
00452       // Adjust liveouts if LiveIntervals are available.
00453       if (RequireIntervals) {
00454         const LiveInterval *LI = getInterval(Reg);
00455         if (LI && !LI->killedAt(SlotIdx))
00456           discoverLiveOut(Reg);
00457       }
00458       increaseRegPressure(Reg);
00459       LiveRegs.insert(Reg);
00460     }
00461   }
00462   return true;
00463 }
00464 
00465 /// Advance across the current instruction.
00466 bool RegPressureTracker::advance() {
00467   // Check for the bottom of the analyzable region.
00468   if (CurrPos == MBB->end()) {
00469     closeRegion();
00470     return false;
00471   }
00472   if (!isTopClosed())
00473     closeTop();
00474 
00475   SlotIndex SlotIdx;
00476   if (RequireIntervals)
00477     SlotIdx = getCurrSlot();
00478 
00479   // Open the bottom of the region using slot indexes.
00480   if (isBottomClosed()) {
00481     if (RequireIntervals)
00482       static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
00483     else
00484       static_cast<RegionPressure&>(P).openBottom(CurrPos);
00485   }
00486 
00487   RegisterOperands RegOpers(TRI, MRI);
00488   collectOperands(CurrPos, RegOpers);
00489 
00490   for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
00491     unsigned Reg = RegOpers.Uses[i];
00492     // Discover live-ins.
00493     bool isLive = LiveRegs.contains(Reg);
00494     if (!isLive)
00495       discoverLiveIn(Reg);
00496     // Kill liveness at last uses.
00497     bool lastUse = false;
00498     if (RequireIntervals) {
00499       const LiveInterval *LI = getInterval(Reg);
00500       lastUse = LI && LI->killedAt(SlotIdx);
00501     }
00502     else {
00503       // Allocatable physregs are always single-use before register rewriting.
00504       lastUse = !TargetRegisterInfo::isVirtualRegister(Reg);
00505     }
00506     if (lastUse && isLive) {
00507       LiveRegs.erase(Reg);
00508       decreaseRegPressure(Reg);
00509     }
00510     else if (!lastUse && !isLive)
00511       increaseRegPressure(Reg);
00512   }
00513 
00514   // Generate liveness for defs.
00515   for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
00516     unsigned Reg = RegOpers.Defs[i];
00517     if (LiveRegs.insert(Reg))
00518       increaseRegPressure(Reg);
00519   }
00520 
00521   // Boost pressure for all dead defs together.
00522   increaseRegPressure(RegOpers.DeadDefs);
00523   decreaseRegPressure(RegOpers.DeadDefs);
00524 
00525   // Find the next instruction.
00526   do
00527     ++CurrPos;
00528   while (CurrPos != MBB->end() && CurrPos->isDebugValue());
00529   return true;
00530 }
00531 
00532 /// Find the max change in excess pressure across all sets.
00533 static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
00534                                        ArrayRef<unsigned> NewPressureVec,
00535                                        RegPressureDelta &Delta,
00536                                        const TargetRegisterInfo *TRI) {
00537   int ExcessUnits = 0;
00538   unsigned PSetID = ~0U;
00539   for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
00540     unsigned POld = OldPressureVec[i];
00541     unsigned PNew = NewPressureVec[i];
00542     int PDiff = (int)PNew - (int)POld;
00543     if (!PDiff) // No change in this set in the common case.
00544       continue;
00545     // Only consider change beyond the limit.
00546     unsigned Limit = TRI->getRegPressureSetLimit(i);
00547     if (Limit > POld) {
00548       if (Limit > PNew)
00549         PDiff = 0;            // Under the limit
00550       else
00551         PDiff = PNew - Limit; // Just exceeded limit.
00552     }
00553     else if (Limit > PNew)
00554       PDiff = Limit - POld;   // Just obeyed limit.
00555 
00556     if (std::abs(PDiff) > std::abs(ExcessUnits)) {
00557       ExcessUnits = PDiff;
00558       PSetID = i;
00559     }
00560   }
00561   Delta.Excess.PSetID = PSetID;
00562   Delta.Excess.UnitIncrease = ExcessUnits;
00563 }
00564 
00565 /// Find the max change in max pressure that either surpasses a critical PSet
00566 /// limit or exceeds the current MaxPressureLimit.
00567 ///
00568 /// FIXME: comparing each element of the old and new MaxPressure vectors here is
00569 /// silly. It's done now to demonstrate the concept but will go away with a
00570 /// RegPressureTracker API change to work with pressure differences.
00571 static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
00572                                     ArrayRef<unsigned> NewMaxPressureVec,
00573                                     ArrayRef<PressureElement> CriticalPSets,
00574                                     ArrayRef<unsigned> MaxPressureLimit,
00575                                     RegPressureDelta &Delta) {
00576   Delta.CriticalMax = PressureElement();
00577   Delta.CurrentMax = PressureElement();
00578 
00579   unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
00580   for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
00581     unsigned POld = OldMaxPressureVec[i];
00582     unsigned PNew = NewMaxPressureVec[i];
00583     if (PNew == POld) // No change in this set in the common case.
00584       continue;
00585 
00586     while (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID < i)
00587       ++CritIdx;
00588 
00589     if (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID == i) {
00590       int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].UnitIncrease;
00591       if (PDiff > Delta.CriticalMax.UnitIncrease) {
00592         Delta.CriticalMax.PSetID = i;
00593         Delta.CriticalMax.UnitIncrease = PDiff;
00594       }
00595     }
00596 
00597     // Find the greatest increase above MaxPressureLimit.
00598     // (Ignores negative MDiff).
00599     int MDiff = (int)PNew - (int)MaxPressureLimit[i];
00600     if (MDiff > Delta.CurrentMax.UnitIncrease) {
00601       Delta.CurrentMax.PSetID = i;
00602       Delta.CurrentMax.UnitIncrease = PNew;
00603     }
00604   }
00605 }
00606 
00607 /// Record the upward impact of a single instruction on current register
00608 /// pressure. Unlike the advance/recede pressure tracking interface, this does
00609 /// not discover live in/outs.
00610 ///
00611 /// This is intended for speculative queries. It leaves pressure inconsistent
00612 /// with the current position, so must be restored by the caller.
00613 void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
00614   assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
00615 
00616   // Account for register pressure similar to RegPressureTracker::recede().
00617   RegisterOperands RegOpers(TRI, MRI);
00618   collectOperands(MI, RegOpers);
00619 
00620   // Boost max pressure for all dead defs together.
00621   // Since CurrSetPressure and MaxSetPressure
00622   increaseRegPressure(RegOpers.DeadDefs);
00623   decreaseRegPressure(RegOpers.DeadDefs);
00624 
00625   // Kill liveness at live defs.
00626   for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
00627     unsigned Reg = RegOpers.Defs[i];
00628     if (!containsReg(RegOpers.Uses, Reg))
00629       decreaseRegPressure(Reg);
00630   }
00631   // Generate liveness for uses.
00632   for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
00633     unsigned Reg = RegOpers.Uses[i];
00634     if (!LiveRegs.contains(Reg))
00635       increaseRegPressure(Reg);
00636   }
00637 }
00638 
00639 /// Consider the pressure increase caused by traversing this instruction
00640 /// bottom-up. Find the pressure set with the most change beyond its pressure
00641 /// limit based on the tracker's current pressure, and return the change in
00642 /// number of register units of that pressure set introduced by this
00643 /// instruction.
00644 ///
00645 /// This assumes that the current LiveOut set is sufficient.
00646 ///
00647 /// FIXME: This is expensive for an on-the-fly query. We need to cache the
00648 /// result per-SUnit with enough information to adjust for the current
00649 /// scheduling position. But this works as a proof of concept.
00650 void RegPressureTracker::
00651 getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
00652                           ArrayRef<PressureElement> CriticalPSets,
00653                           ArrayRef<unsigned> MaxPressureLimit) {
00654   // Snapshot Pressure.
00655   // FIXME: The snapshot heap space should persist. But I'm planning to
00656   // summarize the pressure effect so we don't need to snapshot at all.
00657   std::vector<unsigned> SavedPressure = CurrSetPressure;
00658   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
00659 
00660   bumpUpwardPressure(MI);
00661 
00662   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI);
00663   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
00664                           MaxPressureLimit, Delta);
00665   assert(Delta.CriticalMax.UnitIncrease >= 0 &&
00666          Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
00667 
00668   // Restore the tracker's state.
00669   P.MaxSetPressure.swap(SavedMaxPressure);
00670   CurrSetPressure.swap(SavedPressure);
00671 }
00672 
00673 /// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
00674 static bool findUseBetween(unsigned Reg,
00675                            SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
00676                            const MachineRegisterInfo *MRI,
00677                            const LiveIntervals *LIS) {
00678   for (MachineRegisterInfo::use_nodbg_iterator
00679          UI = MRI->use_nodbg_begin(Reg), UE = MRI->use_nodbg_end();
00680          UI != UE; UI.skipInstruction()) {
00681       const MachineInstr* MI = &*UI;
00682       if (MI->isDebugValue())
00683         continue;
00684       SlotIndex InstSlot = LIS->getInstructionIndex(MI).getRegSlot();
00685       if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx)
00686         return true;
00687   }
00688   return false;
00689 }
00690 
00691 /// Record the downward impact of a single instruction on current register
00692 /// pressure. Unlike the advance/recede pressure tracking interface, this does
00693 /// not discover live in/outs.
00694 ///
00695 /// This is intended for speculative queries. It leaves pressure inconsistent
00696 /// with the current position, so must be restored by the caller.
00697 void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
00698   assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
00699 
00700   // Account for register pressure similar to RegPressureTracker::recede().
00701   RegisterOperands RegOpers(TRI, MRI);
00702   collectOperands(MI, RegOpers);
00703 
00704   // Kill liveness at last uses. Assume allocatable physregs are single-use
00705   // rather than checking LiveIntervals.
00706   SlotIndex SlotIdx;
00707   if (RequireIntervals)
00708     SlotIdx = LIS->getInstructionIndex(MI).getRegSlot();
00709 
00710   for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
00711     unsigned Reg = RegOpers.Uses[i];
00712     if (RequireIntervals) {
00713       // FIXME: allow the caller to pass in the list of vreg uses that remain
00714       // to be bottom-scheduled to avoid searching uses at each query.
00715       SlotIndex CurrIdx = getCurrSlot();
00716       const LiveInterval *LI = getInterval(Reg);
00717       if (LI && LI->killedAt(SlotIdx)
00718           && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) {
00719         decreaseRegPressure(Reg);
00720       }
00721     }
00722     else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
00723       // Allocatable physregs are always single-use before register rewriting.
00724       decreaseRegPressure(Reg);
00725     }
00726   }
00727 
00728   // Generate liveness for defs.
00729   increaseRegPressure(RegOpers.Defs);
00730 
00731   // Boost pressure for all dead defs together.
00732   increaseRegPressure(RegOpers.DeadDefs);
00733   decreaseRegPressure(RegOpers.DeadDefs);
00734 }
00735 
00736 /// Consider the pressure increase caused by traversing this instruction
00737 /// top-down. Find the register class with the most change in its pressure limit
00738 /// based on the tracker's current pressure, and return the number of excess
00739 /// register units of that pressure set introduced by this instruction.
00740 ///
00741 /// This assumes that the current LiveIn set is sufficient.
00742 void RegPressureTracker::
00743 getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
00744                             ArrayRef<PressureElement> CriticalPSets,
00745                             ArrayRef<unsigned> MaxPressureLimit) {
00746   // Snapshot Pressure.
00747   std::vector<unsigned> SavedPressure = CurrSetPressure;
00748   std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
00749 
00750   bumpDownwardPressure(MI);
00751 
00752   computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI);
00753   computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
00754                           MaxPressureLimit, Delta);
00755   assert(Delta.CriticalMax.UnitIncrease >= 0 &&
00756          Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
00757 
00758   // Restore the tracker's state.
00759   P.MaxSetPressure.swap(SavedMaxPressure);
00760   CurrSetPressure.swap(SavedPressure);
00761 }
00762 
00763 /// Get the pressure of each PSet after traversing this instruction bottom-up.
00764 void RegPressureTracker::
00765 getUpwardPressure(const MachineInstr *MI,
00766                   std::vector<unsigned> &PressureResult,
00767                   std::vector<unsigned> &MaxPressureResult) {
00768   // Snapshot pressure.
00769   PressureResult = CurrSetPressure;
00770   MaxPressureResult = P.MaxSetPressure;
00771 
00772   bumpUpwardPressure(MI);
00773 
00774   // Current pressure becomes the result. Restore current pressure.
00775   P.MaxSetPressure.swap(MaxPressureResult);
00776   CurrSetPressure.swap(PressureResult);
00777 }
00778 
00779 /// Get the pressure of each PSet after traversing this instruction top-down.
00780 void RegPressureTracker::
00781 getDownwardPressure(const MachineInstr *MI,
00782                     std::vector<unsigned> &PressureResult,
00783                     std::vector<unsigned> &MaxPressureResult) {
00784   // Snapshot pressure.
00785   PressureResult = CurrSetPressure;
00786   MaxPressureResult = P.MaxSetPressure;
00787 
00788   bumpDownwardPressure(MI);
00789 
00790   // Current pressure becomes the result. Restore current pressure.
00791   P.MaxSetPressure.swap(MaxPressureResult);
00792   CurrSetPressure.swap(PressureResult);
00793 }