LLVM API Documentation
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 }