LLVM API Documentation
00001 //===-- RegisterPressure.h - Dynamic Register Pressure -*- C++ -*-------===// 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 defines the RegisterPressure class which can be used to track 00011 // MachineInstr level register pressure. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H 00016 #define LLVM_CODEGEN_REGISTERPRESSURE_H 00017 00018 #include "llvm/ADT/SparseSet.h" 00019 #include "llvm/CodeGen/SlotIndexes.h" 00020 #include "llvm/Target/TargetRegisterInfo.h" 00021 00022 namespace llvm { 00023 00024 class LiveIntervals; 00025 class LiveInterval; 00026 class RegisterClassInfo; 00027 class MachineInstr; 00028 00029 /// Base class for register pressure results. 00030 struct RegisterPressure { 00031 /// Map of max reg pressure indexed by pressure set ID, not class ID. 00032 std::vector<unsigned> MaxSetPressure; 00033 00034 /// List of live in virtual registers or physical register units. 00035 SmallVector<unsigned,8> LiveInRegs; 00036 SmallVector<unsigned,8> LiveOutRegs; 00037 00038 /// Increase register pressure for each pressure set impacted by this register 00039 /// class. Normally called by RegPressureTracker, but may be called manually 00040 /// to account for live through (global liveness). 00041 /// 00042 /// \param Reg is either a virtual register number or register unit number. 00043 void increase(unsigned Reg, const TargetRegisterInfo *TRI, 00044 const MachineRegisterInfo *MRI); 00045 00046 /// Decrease register pressure for each pressure set impacted by this register 00047 /// class. This is only useful to account for spilling or rematerialization. 00048 /// 00049 /// \param Reg is either a virtual register number or register unit number. 00050 void decrease(unsigned Reg, const TargetRegisterInfo *TRI, 00051 const MachineRegisterInfo *MRI); 00052 00053 void dump(const TargetRegisterInfo *TRI) const; 00054 }; 00055 00056 /// RegisterPressure computed within a region of instructions delimited by 00057 /// TopIdx and BottomIdx. During pressure computation, the maximum pressure per 00058 /// register pressure set is increased. Once pressure within a region is fully 00059 /// computed, the live-in and live-out sets are recorded. 00060 /// 00061 /// This is preferable to RegionPressure when LiveIntervals are available, 00062 /// because delimiting regions by SlotIndex is more robust and convenient than 00063 /// holding block iterators. The block contents can change without invalidating 00064 /// the pressure result. 00065 struct IntervalPressure : RegisterPressure { 00066 /// Record the boundary of the region being tracked. 00067 SlotIndex TopIdx; 00068 SlotIndex BottomIdx; 00069 00070 void reset(); 00071 00072 void openTop(SlotIndex NextTop); 00073 00074 void openBottom(SlotIndex PrevBottom); 00075 }; 00076 00077 /// RegisterPressure computed within a region of instructions delimited by 00078 /// TopPos and BottomPos. This is a less precise version of IntervalPressure for 00079 /// use when LiveIntervals are unavailable. 00080 struct RegionPressure : RegisterPressure { 00081 /// Record the boundary of the region being tracked. 00082 MachineBasicBlock::const_iterator TopPos; 00083 MachineBasicBlock::const_iterator BottomPos; 00084 00085 void reset(); 00086 00087 void openTop(MachineBasicBlock::const_iterator PrevTop); 00088 00089 void openBottom(MachineBasicBlock::const_iterator PrevBottom); 00090 }; 00091 00092 /// An element of pressure difference that identifies the pressure set and 00093 /// amount of increase or decrease in units of pressure. 00094 struct PressureElement { 00095 unsigned PSetID; 00096 int UnitIncrease; 00097 00098 PressureElement(): PSetID(~0U), UnitIncrease(0) {} 00099 PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc) {} 00100 00101 bool isValid() const { return PSetID != ~0U; } 00102 }; 00103 00104 /// Store the effects of a change in pressure on things that MI scheduler cares 00105 /// about. 00106 /// 00107 /// Excess records the value of the largest difference in register units beyond 00108 /// the target's pressure limits across the affected pressure sets, where 00109 /// largest is defined as the absolute value of the difference. Negative 00110 /// ExcessUnits indicates a reduction in pressure that had already exceeded the 00111 /// target's limits. 00112 /// 00113 /// CriticalMax records the largest increase in the tracker's max pressure that 00114 /// exceeds the critical limit for some pressure set determined by the client. 00115 /// 00116 /// CurrentMax records the largest increase in the tracker's max pressure that 00117 /// exceeds the current limit for some pressure set determined by the client. 00118 struct RegPressureDelta { 00119 PressureElement Excess; 00120 PressureElement CriticalMax; 00121 PressureElement CurrentMax; 00122 00123 RegPressureDelta() {} 00124 }; 00125 00126 /// \brief A set of live virtual registers and physical register units. 00127 /// 00128 /// Virtual and physical register numbers require separate sparse sets, but most 00129 /// of the RegisterPressureTracker handles them uniformly. 00130 struct LiveRegSet { 00131 SparseSet<unsigned> PhysRegs; 00132 SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs; 00133 00134 bool contains(unsigned Reg) { 00135 if (TargetRegisterInfo::isVirtualRegister(Reg)) 00136 return VirtRegs.count(Reg); 00137 return PhysRegs.count(Reg); 00138 } 00139 00140 bool insert(unsigned Reg) { 00141 if (TargetRegisterInfo::isVirtualRegister(Reg)) 00142 return VirtRegs.insert(Reg).second; 00143 return PhysRegs.insert(Reg).second; 00144 } 00145 00146 bool erase(unsigned Reg) { 00147 if (TargetRegisterInfo::isVirtualRegister(Reg)) 00148 return VirtRegs.erase(Reg); 00149 return PhysRegs.erase(Reg); 00150 } 00151 }; 00152 00153 /// Track the current register pressure at some position in the instruction 00154 /// stream, and remember the high water mark within the region traversed. This 00155 /// does not automatically consider live-through ranges. The client may 00156 /// independently adjust for global liveness. 00157 /// 00158 /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can 00159 /// be tracked across a larger region by storing a RegisterPressure result at 00160 /// each block boundary and explicitly adjusting pressure to account for block 00161 /// live-in and live-out register sets. 00162 /// 00163 /// RegPressureTracker holds a reference to a RegisterPressure result that it 00164 /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos 00165 /// is invalid until it reaches the end of the block or closeRegion() is 00166 /// explicitly called. Similarly, P.TopIdx is invalid during upward 00167 /// tracking. Changing direction has the side effect of closing region, and 00168 /// traversing past TopIdx or BottomIdx reopens it. 00169 class RegPressureTracker { 00170 const MachineFunction *MF; 00171 const TargetRegisterInfo *TRI; 00172 const RegisterClassInfo *RCI; 00173 const MachineRegisterInfo *MRI; 00174 const LiveIntervals *LIS; 00175 00176 /// We currently only allow pressure tracking within a block. 00177 const MachineBasicBlock *MBB; 00178 00179 /// Track the max pressure within the region traversed so far. 00180 RegisterPressure &P; 00181 00182 /// Run in two modes dependending on whether constructed with IntervalPressure 00183 /// or RegisterPressure. If requireIntervals is false, LIS are ignored. 00184 bool RequireIntervals; 00185 00186 /// Register pressure corresponds to liveness before this instruction 00187 /// iterator. It may point to the end of the block or a DebugValue rather than 00188 /// an instruction. 00189 MachineBasicBlock::const_iterator CurrPos; 00190 00191 /// Pressure map indexed by pressure set ID, not class ID. 00192 std::vector<unsigned> CurrSetPressure; 00193 00194 /// Set of live registers. 00195 LiveRegSet LiveRegs; 00196 00197 public: 00198 RegPressureTracker(IntervalPressure &rp) : 00199 MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true) {} 00200 00201 RegPressureTracker(RegionPressure &rp) : 00202 MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false) {} 00203 00204 void init(const MachineFunction *mf, const RegisterClassInfo *rci, 00205 const LiveIntervals *lis, const MachineBasicBlock *mbb, 00206 MachineBasicBlock::const_iterator pos); 00207 00208 /// Force liveness of virtual registers or physical register 00209 /// units. Particularly useful to initialize the livein/out state of the 00210 /// tracker before the first call to advance/recede. 00211 void addLiveRegs(ArrayRef<unsigned> Regs); 00212 00213 /// Get the MI position corresponding to this register pressure. 00214 MachineBasicBlock::const_iterator getPos() const { return CurrPos; } 00215 00216 // Reset the MI position corresponding to the register pressure. This allows 00217 // schedulers to move instructions above the RegPressureTracker's 00218 // CurrPos. Since the pressure is computed before CurrPos, the iterator 00219 // position changes while pressure does not. 00220 void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } 00221 00222 /// \brief Get the SlotIndex for the first nondebug instruction including or 00223 /// after the current position. 00224 SlotIndex getCurrSlot() const; 00225 00226 /// Recede across the previous instruction. 00227 bool recede(); 00228 00229 /// Advance across the current instruction. 00230 bool advance(); 00231 00232 /// Finalize the region boundaries and recored live ins and live outs. 00233 void closeRegion(); 00234 00235 /// Get the resulting register pressure over the traversed region. 00236 /// This result is complete if either advance() or recede() has returned true, 00237 /// or if closeRegion() was explicitly invoked. 00238 RegisterPressure &getPressure() { return P; } 00239 const RegisterPressure &getPressure() const { return P; } 00240 00241 /// Get the register set pressure at the current position, which may be less 00242 /// than the pressure across the traversed region. 00243 std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } 00244 00245 void discoverLiveOut(unsigned Reg); 00246 void discoverLiveIn(unsigned Reg); 00247 00248 bool isTopClosed() const; 00249 bool isBottomClosed() const; 00250 00251 void closeTop(); 00252 void closeBottom(); 00253 00254 /// Consider the pressure increase caused by traversing this instruction 00255 /// bottom-up. Find the pressure set with the most change beyond its pressure 00256 /// limit based on the tracker's current pressure, and record the number of 00257 /// excess register units of that pressure set introduced by this instruction. 00258 void getMaxUpwardPressureDelta(const MachineInstr *MI, 00259 RegPressureDelta &Delta, 00260 ArrayRef<PressureElement> CriticalPSets, 00261 ArrayRef<unsigned> MaxPressureLimit); 00262 00263 /// Consider the pressure increase caused by traversing this instruction 00264 /// top-down. Find the pressure set with the most change beyond its pressure 00265 /// limit based on the tracker's current pressure, and record the number of 00266 /// excess register units of that pressure set introduced by this instruction. 00267 void getMaxDownwardPressureDelta(const MachineInstr *MI, 00268 RegPressureDelta &Delta, 00269 ArrayRef<PressureElement> CriticalPSets, 00270 ArrayRef<unsigned> MaxPressureLimit); 00271 00272 /// Find the pressure set with the most change beyond its pressure limit after 00273 /// traversing this instruction either upward or downward depending on the 00274 /// closed end of the current region. 00275 void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, 00276 ArrayRef<PressureElement> CriticalPSets, 00277 ArrayRef<unsigned> MaxPressureLimit) { 00278 if (isTopClosed()) 00279 return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets, 00280 MaxPressureLimit); 00281 00282 assert(isBottomClosed() && "Uninitialized pressure tracker"); 00283 return getMaxUpwardPressureDelta(MI, Delta, CriticalPSets, 00284 MaxPressureLimit); 00285 } 00286 00287 /// Get the pressure of each PSet after traversing this instruction bottom-up. 00288 void getUpwardPressure(const MachineInstr *MI, 00289 std::vector<unsigned> &PressureResult, 00290 std::vector<unsigned> &MaxPressureResult); 00291 00292 /// Get the pressure of each PSet after traversing this instruction top-down. 00293 void getDownwardPressure(const MachineInstr *MI, 00294 std::vector<unsigned> &PressureResult, 00295 std::vector<unsigned> &MaxPressureResult); 00296 00297 void getPressureAfterInst(const MachineInstr *MI, 00298 std::vector<unsigned> &PressureResult, 00299 std::vector<unsigned> &MaxPressureResult) { 00300 if (isTopClosed()) 00301 return getUpwardPressure(MI, PressureResult, MaxPressureResult); 00302 00303 assert(isBottomClosed() && "Uninitialized pressure tracker"); 00304 return getDownwardPressure(MI, PressureResult, MaxPressureResult); 00305 } 00306 00307 void dump() const; 00308 00309 protected: 00310 const LiveInterval *getInterval(unsigned Reg) const; 00311 00312 void increaseRegPressure(ArrayRef<unsigned> Regs); 00313 void decreaseRegPressure(ArrayRef<unsigned> Regs); 00314 00315 void bumpUpwardPressure(const MachineInstr *MI); 00316 void bumpDownwardPressure(const MachineInstr *MI); 00317 }; 00318 } // end namespace llvm 00319 00320 #endif