Target independent Hexagon Packetizer fix.
[oota-llvm.git] / lib / CodeGen / RegisterPressure.h
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/CodeGen/SlotIndexes.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
20 #include "llvm/ADT/SparseSet.h"
21
22 namespace llvm {
23
24 class LiveIntervals;
25 class RegisterClassInfo;
26
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;
31
32   /// List of live in registers.
33   SmallVector<unsigned,8> LiveInRegs;
34   SmallVector<unsigned,8> LiveOutRegs;
35
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);
40
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);
44 };
45
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.
50 ///
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.
57   SlotIndex TopIdx;
58   SlotIndex BottomIdx;
59
60   void reset();
61
62   void openTop(SlotIndex NextTop);
63
64   void openBottom(SlotIndex PrevBottom);
65 };
66
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;
74
75   void reset();
76
77   void openTop(MachineBasicBlock::const_iterator PrevTop);
78
79   void openBottom(MachineBasicBlock::const_iterator PrevBottom);
80 };
81
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.
86 ///
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.
91 ///
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;
104
105   /// We currently only allow pressure tracking within a block.
106   const MachineBasicBlock *MBB;
107
108   /// Track the max pressure within the region traversed so far.
109   RegisterPressure &P;
110
111   /// Run in two modes dependending on whether constructed with IntervalPressure
112   /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
113   bool RequireIntervals;
114
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;
118
119   /// Pressure map indexed by pressure set ID, not class ID.
120   std::vector<unsigned> CurrSetPressure;
121
122   /// List of live registers.
123   SparseSet<unsigned> LivePhysRegs;
124   SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs;
125
126 public:
127   RegPressureTracker(IntervalPressure &rp) :
128     MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true) {}
129
130   RegPressureTracker(RegionPressure &rp) :
131     MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false) {}
132
133   void init(const MachineFunction *mf, const RegisterClassInfo *rci,
134             const LiveIntervals *lis, const MachineBasicBlock *mbb,
135             MachineBasicBlock::const_iterator pos);
136
137   // Get the MI position corresponding to this register pressure.
138   MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
139
140   /// Recede across the previous instruction.
141   bool recede();
142
143   /// Advance across the current instruction.
144   bool advance();
145
146   /// Finalize the region boundaries and recored live ins and live outs.
147   void closeRegion();
148
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; }
153
154 protected:
155   bool isTopClosed() const;
156   bool isBottomClosed() const;
157
158   void closeTop();
159   void closeBottom();
160
161   void increasePhysRegPressure(ArrayRef<unsigned> Regs);
162   void decreasePhysRegPressure(ArrayRef<unsigned> Regs);
163
164   void increaseVirtRegPressure(ArrayRef<unsigned> Regs);
165   void decreaseVirtRegPressure(ArrayRef<unsigned> Regs);
166
167   void discoverPhysLiveIn(unsigned Reg);
168   void discoverPhysLiveOut(unsigned Reg);
169
170   void discoverVirtLiveIn(unsigned Reg);
171   void discoverVirtLiveOut(unsigned Reg);
172 };
173 } // end namespace llvm
174
175 #endif