Home | History | Annotate | Download | only in CodeGen
      1 //===-- RegisterPressure.h - Dynamic Register Pressure -*- C++ -*-------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the RegisterPressure class which can be used to track
     11 // MachineInstr level register pressure.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
     16 #define LLVM_CODEGEN_REGISTERPRESSURE_H
     17 
     18 #include "llvm/ADT/SparseSet.h"
     19 #include "llvm/CodeGen/SlotIndexes.h"
     20 #include "llvm/Target/TargetRegisterInfo.h"
     21 
     22 namespace llvm {
     23 
     24 class LiveIntervals;
     25 class LiveInterval;
     26 class RegisterClassInfo;
     27 class MachineInstr;
     28 
     29 /// Base class for register pressure results.
     30 struct RegisterPressure {
     31   /// Map of max reg pressure indexed by pressure set ID, not class ID.
     32   std::vector<unsigned> MaxSetPressure;
     33 
     34   /// List of live in virtual registers or physical register units.
     35   SmallVector<unsigned,8> LiveInRegs;
     36   SmallVector<unsigned,8> LiveOutRegs;
     37 
     38   /// Increase register pressure for each pressure set impacted by this register
     39   /// class. Normally called by RegPressureTracker, but may be called manually
     40   /// to account for live through (global liveness).
     41   ///
     42   /// \param Reg is either a virtual register number or register unit number.
     43   void increase(unsigned Reg, const TargetRegisterInfo *TRI,
     44                 const MachineRegisterInfo *MRI);
     45 
     46   /// Decrease register pressure for each pressure set impacted by this register
     47   /// class. This is only useful to account for spilling or rematerialization.
     48   ///
     49   /// \param Reg is either a virtual register number or register unit number.
     50   void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
     51                 const MachineRegisterInfo *MRI);
     52 
     53   void dump(const TargetRegisterInfo *TRI) const;
     54 };
     55 
     56 /// RegisterPressure computed within a region of instructions delimited by
     57 /// TopIdx and BottomIdx.  During pressure computation, the maximum pressure per
     58 /// register pressure set is increased. Once pressure within a region is fully
     59 /// computed, the live-in and live-out sets are recorded.
     60 ///
     61 /// This is preferable to RegionPressure when LiveIntervals are available,
     62 /// because delimiting regions by SlotIndex is more robust and convenient than
     63 /// holding block iterators. The block contents can change without invalidating
     64 /// the pressure result.
     65 struct IntervalPressure : RegisterPressure {
     66   /// Record the boundary of the region being tracked.
     67   SlotIndex TopIdx;
     68   SlotIndex BottomIdx;
     69 
     70   void reset();
     71 
     72   void openTop(SlotIndex NextTop);
     73 
     74   void openBottom(SlotIndex PrevBottom);
     75 };
     76 
     77 /// RegisterPressure computed within a region of instructions delimited by
     78 /// TopPos and BottomPos. This is a less precise version of IntervalPressure for
     79 /// use when LiveIntervals are unavailable.
     80 struct RegionPressure : RegisterPressure {
     81   /// Record the boundary of the region being tracked.
     82   MachineBasicBlock::const_iterator TopPos;
     83   MachineBasicBlock::const_iterator BottomPos;
     84 
     85   void reset();
     86 
     87   void openTop(MachineBasicBlock::const_iterator PrevTop);
     88 
     89   void openBottom(MachineBasicBlock::const_iterator PrevBottom);
     90 };
     91 
     92 /// An element of pressure difference that identifies the pressure set and
     93 /// amount of increase or decrease in units of pressure.
     94 struct PressureElement {
     95   unsigned PSetID;
     96   int UnitIncrease;
     97 
     98   PressureElement(): PSetID(~0U), UnitIncrease(0) {}
     99   PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc) {}
    100 
    101   bool isValid() const { return PSetID != ~0U; }
    102 
    103   // If signed PSetID is negative, it is invalid; convert it to INT_MAX to give
    104   // it lowest priority.
    105   int PSetRank() const { return PSetID & INT_MAX; }
    106 };
    107 
    108 /// Store the effects of a change in pressure on things that MI scheduler cares
    109 /// about.
    110 ///
    111 /// Excess records the value of the largest difference in register units beyond
    112 /// the target's pressure limits across the affected pressure sets, where
    113 /// largest is defined as the absolute value of the difference. Negative
    114 /// ExcessUnits indicates a reduction in pressure that had already exceeded the
    115 /// target's limits.
    116 ///
    117 /// CriticalMax records the largest increase in the tracker's max pressure that
    118 /// exceeds the critical limit for some pressure set determined by the client.
    119 ///
    120 /// CurrentMax records the largest increase in the tracker's max pressure that
    121 /// exceeds the current limit for some pressure set determined by the client.
    122 struct RegPressureDelta {
    123   PressureElement Excess;
    124   PressureElement CriticalMax;
    125   PressureElement CurrentMax;
    126 
    127   RegPressureDelta() {}
    128 };
    129 
    130 /// \brief A set of live virtual registers and physical register units.
    131 ///
    132 /// Virtual and physical register numbers require separate sparse sets, but most
    133 /// of the RegisterPressureTracker handles them uniformly.
    134 struct LiveRegSet {
    135   SparseSet<unsigned> PhysRegs;
    136   SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs;
    137 
    138   bool contains(unsigned Reg) {
    139     if (TargetRegisterInfo::isVirtualRegister(Reg))
    140       return VirtRegs.count(Reg);
    141     return PhysRegs.count(Reg);
    142   }
    143 
    144   bool insert(unsigned Reg) {
    145     if (TargetRegisterInfo::isVirtualRegister(Reg))
    146       return VirtRegs.insert(Reg).second;
    147     return PhysRegs.insert(Reg).second;
    148   }
    149 
    150   bool erase(unsigned Reg) {
    151     if (TargetRegisterInfo::isVirtualRegister(Reg))
    152       return VirtRegs.erase(Reg);
    153     return PhysRegs.erase(Reg);
    154   }
    155 };
    156 
    157 /// Track the current register pressure at some position in the instruction
    158 /// stream, and remember the high water mark within the region traversed. This
    159 /// does not automatically consider live-through ranges. The client may
    160 /// independently adjust for global liveness.
    161 ///
    162 /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
    163 /// be tracked across a larger region by storing a RegisterPressure result at
    164 /// each block boundary and explicitly adjusting pressure to account for block
    165 /// live-in and live-out register sets.
    166 ///
    167 /// RegPressureTracker holds a reference to a RegisterPressure result that it
    168 /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
    169 /// is invalid until it reaches the end of the block or closeRegion() is
    170 /// explicitly called. Similarly, P.TopIdx is invalid during upward
    171 /// tracking. Changing direction has the side effect of closing region, and
    172 /// traversing past TopIdx or BottomIdx reopens it.
    173 class RegPressureTracker {
    174   const MachineFunction     *MF;
    175   const TargetRegisterInfo  *TRI;
    176   const RegisterClassInfo   *RCI;
    177   const MachineRegisterInfo *MRI;
    178   const LiveIntervals       *LIS;
    179 
    180   /// We currently only allow pressure tracking within a block.
    181   const MachineBasicBlock *MBB;
    182 
    183   /// Track the max pressure within the region traversed so far.
    184   RegisterPressure &P;
    185 
    186   /// Run in two modes dependending on whether constructed with IntervalPressure
    187   /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
    188   bool RequireIntervals;
    189 
    190   /// True if UntiedDefs will be populated.
    191   bool TrackUntiedDefs;
    192 
    193   /// Register pressure corresponds to liveness before this instruction
    194   /// iterator. It may point to the end of the block or a DebugValue rather than
    195   /// an instruction.
    196   MachineBasicBlock::const_iterator CurrPos;
    197 
    198   /// Pressure map indexed by pressure set ID, not class ID.
    199   std::vector<unsigned> CurrSetPressure;
    200 
    201   /// Set of live registers.
    202   LiveRegSet LiveRegs;
    203 
    204   /// Set of vreg defs that start a live range.
    205   SparseSet<unsigned, VirtReg2IndexFunctor> UntiedDefs;
    206   /// Live-through pressure.
    207   std::vector<unsigned> LiveThruPressure;
    208 
    209 public:
    210   RegPressureTracker(IntervalPressure &rp) :
    211     MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true),
    212     TrackUntiedDefs(false) {}
    213 
    214   RegPressureTracker(RegionPressure &rp) :
    215     MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false),
    216     TrackUntiedDefs(false) {}
    217 
    218   void init(const MachineFunction *mf, const RegisterClassInfo *rci,
    219             const LiveIntervals *lis, const MachineBasicBlock *mbb,
    220             MachineBasicBlock::const_iterator pos,
    221             bool ShouldTrackUntiedDefs = false);
    222 
    223   /// Force liveness of virtual registers or physical register
    224   /// units. Particularly useful to initialize the livein/out state of the
    225   /// tracker before the first call to advance/recede.
    226   void addLiveRegs(ArrayRef<unsigned> Regs);
    227 
    228   /// Get the MI position corresponding to this register pressure.
    229   MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
    230 
    231   // Reset the MI position corresponding to the register pressure. This allows
    232   // schedulers to move instructions above the RegPressureTracker's
    233   // CurrPos. Since the pressure is computed before CurrPos, the iterator
    234   // position changes while pressure does not.
    235   void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
    236 
    237   /// \brief Get the SlotIndex for the first nondebug instruction including or
    238   /// after the current position.
    239   SlotIndex getCurrSlot() const;
    240 
    241   /// Recede across the previous instruction.
    242   bool recede();
    243 
    244   /// Advance across the current instruction.
    245   bool advance();
    246 
    247   /// Finalize the region boundaries and recored live ins and live outs.
    248   void closeRegion();
    249 
    250   /// Initialize the LiveThru pressure set based on the untied defs found in
    251   /// RPTracker.
    252   void initLiveThru(const RegPressureTracker &RPTracker);
    253 
    254   /// Copy an existing live thru pressure result.
    255   void initLiveThru(ArrayRef<unsigned> PressureSet) {
    256     LiveThruPressure.assign(PressureSet.begin(), PressureSet.end());
    257   }
    258 
    259   ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
    260 
    261   /// Get the resulting register pressure over the traversed region.
    262   /// This result is complete if either advance() or recede() has returned true,
    263   /// or if closeRegion() was explicitly invoked.
    264   RegisterPressure &getPressure() { return P; }
    265   const RegisterPressure &getPressure() const { return P; }
    266 
    267   /// Get the register set pressure at the current position, which may be less
    268   /// than the pressure across the traversed region.
    269   std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
    270 
    271   void discoverLiveOut(unsigned Reg);
    272   void discoverLiveIn(unsigned Reg);
    273 
    274   bool isTopClosed() const;
    275   bool isBottomClosed() const;
    276 
    277   void closeTop();
    278   void closeBottom();
    279 
    280   /// Consider the pressure increase caused by traversing this instruction
    281   /// bottom-up. Find the pressure set with the most change beyond its pressure
    282   /// limit based on the tracker's current pressure, and record the number of
    283   /// excess register units of that pressure set introduced by this instruction.
    284   void getMaxUpwardPressureDelta(const MachineInstr *MI,
    285                                  RegPressureDelta &Delta,
    286                                  ArrayRef<PressureElement> CriticalPSets,
    287                                  ArrayRef<unsigned> MaxPressureLimit);
    288 
    289   /// Consider the pressure increase caused by traversing this instruction
    290   /// top-down. Find the pressure set with the most change beyond its pressure
    291   /// limit based on the tracker's current pressure, and record the number of
    292   /// excess register units of that pressure set introduced by this instruction.
    293   void getMaxDownwardPressureDelta(const MachineInstr *MI,
    294                                    RegPressureDelta &Delta,
    295                                    ArrayRef<PressureElement> CriticalPSets,
    296                                    ArrayRef<unsigned> MaxPressureLimit);
    297 
    298   /// Find the pressure set with the most change beyond its pressure limit after
    299   /// traversing this instruction either upward or downward depending on the
    300   /// closed end of the current region.
    301   void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
    302                            ArrayRef<PressureElement> CriticalPSets,
    303                            ArrayRef<unsigned> MaxPressureLimit) {
    304     if (isTopClosed())
    305       return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
    306                                          MaxPressureLimit);
    307 
    308     assert(isBottomClosed() && "Uninitialized pressure tracker");
    309     return getMaxUpwardPressureDelta(MI, Delta, CriticalPSets,
    310                                      MaxPressureLimit);
    311   }
    312 
    313   /// Get the pressure of each PSet after traversing this instruction bottom-up.
    314   void getUpwardPressure(const MachineInstr *MI,
    315                          std::vector<unsigned> &PressureResult,
    316                          std::vector<unsigned> &MaxPressureResult);
    317 
    318   /// Get the pressure of each PSet after traversing this instruction top-down.
    319   void getDownwardPressure(const MachineInstr *MI,
    320                            std::vector<unsigned> &PressureResult,
    321                            std::vector<unsigned> &MaxPressureResult);
    322 
    323   void getPressureAfterInst(const MachineInstr *MI,
    324                             std::vector<unsigned> &PressureResult,
    325                             std::vector<unsigned> &MaxPressureResult) {
    326     if (isTopClosed())
    327       return getUpwardPressure(MI, PressureResult, MaxPressureResult);
    328 
    329     assert(isBottomClosed() && "Uninitialized pressure tracker");
    330     return getDownwardPressure(MI, PressureResult, MaxPressureResult);
    331   }
    332 
    333   bool hasUntiedDef(unsigned VirtReg) const {
    334     return UntiedDefs.count(VirtReg);
    335   }
    336 
    337   void dump() const;
    338 
    339 protected:
    340   const LiveInterval *getInterval(unsigned Reg) const;
    341 
    342   void increaseRegPressure(ArrayRef<unsigned> Regs);
    343   void decreaseRegPressure(ArrayRef<unsigned> Regs);
    344 
    345   void bumpUpwardPressure(const MachineInstr *MI);
    346   void bumpDownwardPressure(const MachineInstr *MI);
    347 };
    348 
    349 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    350 void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
    351                         const TargetRegisterInfo *TRI);
    352 #endif
    353 } // end namespace llvm
    354 
    355 #endif
    356