1 //===-- RegisterPressure.h - Dynamic Register Pressure -*- C++ -*-------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the RegisterPressure class which can be used to track
11 // MachineInstr level register pressure.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
16 #define LLVM_CODEGEN_REGISTERPRESSURE_H
18 #include "llvm/CodeGen/SlotIndexes.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
20 #include "llvm/ADT/SparseSet.h"
25 class RegisterClassInfo;
27 /// Base class for register pressure results.
28 struct RegisterPressure {
29 /// Map of max reg pressure indexed by pressure set ID, not class ID.
30 std::vector<unsigned> MaxSetPressure;
32 /// List of live in registers.
33 SmallVector<unsigned,8> LiveInRegs;
34 SmallVector<unsigned,8> LiveOutRegs;
36 /// Increase register pressure for each pressure set impacted by this register
37 /// class. Normally called by RegPressureTracker, but may be called manually
38 /// to account for live through (global liveness).
39 void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
41 /// Decrease register pressure for each pressure set impacted by this register
42 /// class. This is only useful to account for spilling or rematerialization.
43 void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI);
46 /// RegisterPressure computed within a region of instructions delimited by
47 /// TopIdx and BottomIdx. During pressure computation, the maximum pressure per
48 /// register pressure set is increased. Once pressure within a region is fully
49 /// computed, the live-in and live-out sets are recorded.
51 /// This is preferable to RegionPressure when LiveIntervals are available,
52 /// because delimiting regions by SlotIndex is more robust and convenient than
53 /// holding block iterators. The block contents can change without invalidating
54 /// the pressure result.
55 struct IntervalPressure : RegisterPressure {
56 /// Record the boundary of the region being tracked.
62 void openTop(SlotIndex NextTop);
64 void openBottom(SlotIndex PrevBottom);
67 /// RegisterPressure computed within a region of instructions delimited by
68 /// TopPos and BottomPos. This is a less precise version of IntervalPressure for
69 /// use when LiveIntervals are unavailable.
70 struct RegionPressure : RegisterPressure {
71 /// Record the boundary of the region being tracked.
72 MachineBasicBlock::const_iterator TopPos;
73 MachineBasicBlock::const_iterator BottomPos;
77 void openTop(MachineBasicBlock::const_iterator PrevTop);
79 void openBottom(MachineBasicBlock::const_iterator PrevBottom);
82 /// Track the current register pressure at some position in the instruction
83 /// stream, and remember the high water mark within the region traversed. This
84 /// does not automatically consider live-through ranges. The client may
85 /// independently adjust for global liveness.
87 /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
88 /// be tracked across a larger region by storing a RegisterPressure result at
89 /// each block boundary and explicitly adjusting pressure to account for block
90 /// live-in and live-out register sets.
92 /// RegPressureTracker holds a reference to a RegisterPressure result that it
93 /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
94 /// is invalid until it reaches the end of the block or closeRegion() is
95 /// explicitly called. Similarly, P.TopIdx is invalid during upward
96 /// tracking. Changing direction has the side effect of closing region, and
97 /// traversing past TopIdx or BottomIdx reopens it.
98 class RegPressureTracker {
99 const MachineFunction *MF;
100 const TargetRegisterInfo *TRI;
101 const RegisterClassInfo *RCI;
102 const MachineRegisterInfo *MRI;
103 const LiveIntervals *LIS;
105 /// We currently only allow pressure tracking within a block.
106 const MachineBasicBlock *MBB;
108 /// Track the max pressure within the region traversed so far.
111 /// Run in two modes dependending on whether constructed with IntervalPressure
112 /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
113 bool RequireIntervals;
115 /// Register pressure corresponds to liveness before this instruction
116 /// iterator. It may point to the end of the block rather than an instruction.
117 MachineBasicBlock::const_iterator CurrPos;
119 /// Pressure map indexed by pressure set ID, not class ID.
120 std::vector<unsigned> CurrSetPressure;
122 /// List of live registers.
123 SparseSet<unsigned> LivePhysRegs;
124 SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs;
127 RegPressureTracker(IntervalPressure &rp) :
128 MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true) {}
130 RegPressureTracker(RegionPressure &rp) :
131 MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false) {}
133 void init(const MachineFunction *mf, const RegisterClassInfo *rci,
134 const LiveIntervals *lis, const MachineBasicBlock *mbb,
135 MachineBasicBlock::const_iterator pos);
137 // Get the MI position corresponding to this register pressure.
138 MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
140 /// Recede across the previous instruction.
143 /// Advance across the current instruction.
146 /// Finalize the region boundaries and recored live ins and live outs.
149 /// Get the resulting register pressure over the traversed region.
150 /// This result is complete if either advance() or recede() has returned true,
151 /// or if closeRegion() was explicitly invoked.
152 RegisterPressure &getPressure() { return P; }
155 bool isTopClosed() const;
156 bool isBottomClosed() const;
161 void increasePhysRegPressure(ArrayRef<unsigned> Regs);
162 void decreasePhysRegPressure(ArrayRef<unsigned> Regs);
164 void increaseVirtRegPressure(ArrayRef<unsigned> Regs);
165 void decreaseVirtRegPressure(ArrayRef<unsigned> Regs);
167 void discoverPhysLiveIn(unsigned Reg);
168 void discoverPhysLiveOut(unsigned Reg);
170 void discoverVirtLiveIn(unsigned Reg);
171 void discoverVirtLiveOut(unsigned Reg);
173 } // end namespace llvm