xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonBlockRanges.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- HexagonBlockRanges.h ---------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker #ifndef HEXAGON_BLOCK_RANGES_H
10*9880d681SAndroid Build Coastguard Worker #define HEXAGON_BLOCK_RANGES_H
11*9880d681SAndroid Build Coastguard Worker 
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"  // For MCPhysReg.
15*9880d681SAndroid Build Coastguard Worker #include <map>
16*9880d681SAndroid Build Coastguard Worker #include <set>
17*9880d681SAndroid Build Coastguard Worker #include <vector>
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker namespace llvm {
20*9880d681SAndroid Build Coastguard Worker   class Function;
21*9880d681SAndroid Build Coastguard Worker   class HexagonSubtarget;
22*9880d681SAndroid Build Coastguard Worker   class MachineBasicBlock;
23*9880d681SAndroid Build Coastguard Worker   class MachineFunction;
24*9880d681SAndroid Build Coastguard Worker   class MachineInstr;
25*9880d681SAndroid Build Coastguard Worker   class MCInstrDesc;
26*9880d681SAndroid Build Coastguard Worker   class raw_ostream;
27*9880d681SAndroid Build Coastguard Worker   class TargetInstrInfo;
28*9880d681SAndroid Build Coastguard Worker   class TargetRegisterClass;
29*9880d681SAndroid Build Coastguard Worker   class TargetRegisterInfo;
30*9880d681SAndroid Build Coastguard Worker   class Type;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker struct HexagonBlockRanges {
33*9880d681SAndroid Build Coastguard Worker   HexagonBlockRanges(MachineFunction &MF);
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker   struct RegisterRef {
36*9880d681SAndroid Build Coastguard Worker     unsigned Reg, Sub;
37*9880d681SAndroid Build Coastguard Worker     bool operator<(RegisterRef R) const {
38*9880d681SAndroid Build Coastguard Worker       return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);
39*9880d681SAndroid Build Coastguard Worker     }
40*9880d681SAndroid Build Coastguard Worker   };
41*9880d681SAndroid Build Coastguard Worker   typedef std::set<RegisterRef> RegisterSet;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker   // This is to represent an "index", which is an abstraction of a position
44*9880d681SAndroid Build Coastguard Worker   // of an instruction within a basic block.
45*9880d681SAndroid Build Coastguard Worker   class IndexType {
46*9880d681SAndroid Build Coastguard Worker   public:
47*9880d681SAndroid Build Coastguard Worker     enum : unsigned {
48*9880d681SAndroid Build Coastguard Worker       None  = 0,
49*9880d681SAndroid Build Coastguard Worker       Entry = 1,
50*9880d681SAndroid Build Coastguard Worker       Exit  = 2,
51*9880d681SAndroid Build Coastguard Worker       First = 11  // 10th + 1st
52*9880d681SAndroid Build Coastguard Worker     };
isInstrHexagonBlockRanges53*9880d681SAndroid Build Coastguard Worker     static bool isInstr(IndexType X) { return X.Index >= First; }
54*9880d681SAndroid Build Coastguard Worker 
IndexTypeHexagonBlockRanges55*9880d681SAndroid Build Coastguard Worker     IndexType() : Index(None) {}
IndexTypeHexagonBlockRanges56*9880d681SAndroid Build Coastguard Worker     IndexType(unsigned Idx) : Index(Idx) {}
57*9880d681SAndroid Build Coastguard Worker     operator unsigned() const;
58*9880d681SAndroid Build Coastguard Worker     bool operator== (unsigned x) const;
59*9880d681SAndroid Build Coastguard Worker     bool operator== (IndexType Idx) const;
60*9880d681SAndroid Build Coastguard Worker     bool operator!= (unsigned x) const;
61*9880d681SAndroid Build Coastguard Worker     bool operator!= (IndexType Idx) const;
62*9880d681SAndroid Build Coastguard Worker     IndexType operator++ ();
63*9880d681SAndroid Build Coastguard Worker     bool operator< (unsigned Idx) const;
64*9880d681SAndroid Build Coastguard Worker     bool operator< (IndexType Idx) const;
65*9880d681SAndroid Build Coastguard Worker     bool operator<= (IndexType Idx) const;
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   private:
68*9880d681SAndroid Build Coastguard Worker     bool operator>  (IndexType Idx) const;
69*9880d681SAndroid Build Coastguard Worker     bool operator>= (IndexType Idx) const;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker     unsigned Index;
72*9880d681SAndroid Build Coastguard Worker   };
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   // A range of indices, essentially a representation of a live range.
75*9880d681SAndroid Build Coastguard Worker   // This is also used to represent "dead ranges", i.e. ranges where a
76*9880d681SAndroid Build Coastguard Worker   // register is dead.
77*9880d681SAndroid Build Coastguard Worker   class IndexRange : public std::pair<IndexType,IndexType> {
78*9880d681SAndroid Build Coastguard Worker   public:
IndexRangeHexagonBlockRanges79*9880d681SAndroid Build Coastguard Worker     IndexRange() : Fixed(false), TiedEnd(false) {}
80*9880d681SAndroid Build Coastguard Worker     IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)
81*9880d681SAndroid Build Coastguard Worker       : std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}
startHexagonBlockRanges82*9880d681SAndroid Build Coastguard Worker     IndexType start() const { return first; }
endHexagonBlockRanges83*9880d681SAndroid Build Coastguard Worker     IndexType end() const   { return second; }
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker     bool operator< (const IndexRange &A) const {
86*9880d681SAndroid Build Coastguard Worker       return start() < A.start();
87*9880d681SAndroid Build Coastguard Worker     }
88*9880d681SAndroid Build Coastguard Worker     bool overlaps(const IndexRange &A) const;
89*9880d681SAndroid Build Coastguard Worker     bool contains(const IndexRange &A) const;
90*9880d681SAndroid Build Coastguard Worker     void merge(const IndexRange &A);
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker     bool Fixed;      // Can be renamed?  "Fixed" means "no".
93*9880d681SAndroid Build Coastguard Worker     bool TiedEnd;    // The end is not a use, but a dead def tied to a use.
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   private:
setStartHexagonBlockRanges96*9880d681SAndroid Build Coastguard Worker     void setStart(const IndexType &S) { first = S; }
setEndHexagonBlockRanges97*9880d681SAndroid Build Coastguard Worker     void setEnd(const IndexType &E)   { second = E; }
98*9880d681SAndroid Build Coastguard Worker   };
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   // A list of index ranges. This represents liveness of a register
101*9880d681SAndroid Build Coastguard Worker   // in a basic block.
102*9880d681SAndroid Build Coastguard Worker   class RangeList : public std::vector<IndexRange> {
103*9880d681SAndroid Build Coastguard Worker   public:
addHexagonBlockRanges104*9880d681SAndroid Build Coastguard Worker     void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {
105*9880d681SAndroid Build Coastguard Worker       push_back(IndexRange(Start, End, Fixed, TiedEnd));
106*9880d681SAndroid Build Coastguard Worker     }
addHexagonBlockRanges107*9880d681SAndroid Build Coastguard Worker     void add(const IndexRange &Range) {
108*9880d681SAndroid Build Coastguard Worker       push_back(Range);
109*9880d681SAndroid Build Coastguard Worker     }
110*9880d681SAndroid Build Coastguard Worker     void include(const RangeList &RL);
111*9880d681SAndroid Build Coastguard Worker     void unionize(bool MergeAdjacent = false);
112*9880d681SAndroid Build Coastguard Worker     void subtract(const IndexRange &Range);
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   private:
115*9880d681SAndroid Build Coastguard Worker     void addsub(const IndexRange &A, const IndexRange &B);
116*9880d681SAndroid Build Coastguard Worker   };
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   class InstrIndexMap {
119*9880d681SAndroid Build Coastguard Worker   public:
120*9880d681SAndroid Build Coastguard Worker     InstrIndexMap(MachineBasicBlock &B);
121*9880d681SAndroid Build Coastguard Worker     MachineInstr *getInstr(IndexType Idx) const;
122*9880d681SAndroid Build Coastguard Worker     IndexType getIndex(MachineInstr *MI) const;
getBlockHexagonBlockRanges123*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &getBlock() const { return Block; }
124*9880d681SAndroid Build Coastguard Worker     IndexType getPrevIndex(IndexType Idx) const;
125*9880d681SAndroid Build Coastguard Worker     IndexType getNextIndex(IndexType Idx) const;
126*9880d681SAndroid Build Coastguard Worker     void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI);
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map);
129*9880d681SAndroid Build Coastguard Worker     IndexType First, Last;
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   private:
132*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &Block;
133*9880d681SAndroid Build Coastguard Worker     std::map<IndexType,MachineInstr*> Map;
134*9880d681SAndroid Build Coastguard Worker   };
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   typedef std::map<RegisterRef,RangeList> RegToRangeMap;
137*9880d681SAndroid Build Coastguard Worker   RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);
138*9880d681SAndroid Build Coastguard Worker   RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);
139*9880d681SAndroid Build Coastguard Worker   static RegisterSet expandToSubRegs(RegisterRef R,
140*9880d681SAndroid Build Coastguard Worker       const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker   struct PrintRangeMap {
PrintRangeMapHexagonBlockRanges::PrintRangeMap143*9880d681SAndroid Build Coastguard Worker     PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I)
144*9880d681SAndroid Build Coastguard Worker         : Map(M), TRI(I) {}
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);
147*9880d681SAndroid Build Coastguard Worker   private:
148*9880d681SAndroid Build Coastguard Worker     const RegToRangeMap &Map;
149*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo &TRI;
150*9880d681SAndroid Build Coastguard Worker   };
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker private:
153*9880d681SAndroid Build Coastguard Worker   RegisterSet getLiveIns(const MachineBasicBlock &B);
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   void computeInitialLiveRanges(InstrIndexMap &IndexMap,
156*9880d681SAndroid Build Coastguard Worker       RegToRangeMap &LiveMap);
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF;
159*9880d681SAndroid Build Coastguard Worker   const HexagonSubtarget &HST;
160*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII;
161*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI;
162*9880d681SAndroid Build Coastguard Worker   BitVector Reserved;
163*9880d681SAndroid Build Coastguard Worker };
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker inline HexagonBlockRanges::IndexType::operator unsigned() const {
167*9880d681SAndroid Build Coastguard Worker   assert(Index >= First);
168*9880d681SAndroid Build Coastguard Worker   return Index;
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {
172*9880d681SAndroid Build Coastguard Worker   return Index == x;
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {
176*9880d681SAndroid Build Coastguard Worker   return Index == Idx.Index;
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const {
180*9880d681SAndroid Build Coastguard Worker   return Index != x;
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const {
184*9880d681SAndroid Build Coastguard Worker   return Index != Idx.Index;
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker inline
188*9880d681SAndroid Build Coastguard Worker HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () {
189*9880d681SAndroid Build Coastguard Worker   assert(Index != None);
190*9880d681SAndroid Build Coastguard Worker   assert(Index != Exit);
191*9880d681SAndroid Build Coastguard Worker   if (Index == Entry)
192*9880d681SAndroid Build Coastguard Worker     Index = First;
193*9880d681SAndroid Build Coastguard Worker   else
194*9880d681SAndroid Build Coastguard Worker     ++Index;
195*9880d681SAndroid Build Coastguard Worker   return *this;
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {
199*9880d681SAndroid Build Coastguard Worker   return operator< (IndexType(Idx));
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker 
202*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const {
203*9880d681SAndroid Build Coastguard Worker   // !(x < x).
204*9880d681SAndroid Build Coastguard Worker   if (Index == Idx.Index)
205*9880d681SAndroid Build Coastguard Worker     return false;
206*9880d681SAndroid Build Coastguard Worker   // !(None < x) for all x.
207*9880d681SAndroid Build Coastguard Worker   // !(x < None) for all x.
208*9880d681SAndroid Build Coastguard Worker   if (Index == None || Idx.Index == None)
209*9880d681SAndroid Build Coastguard Worker     return false;
210*9880d681SAndroid Build Coastguard Worker   // !(Exit < x) for all x.
211*9880d681SAndroid Build Coastguard Worker   // !(x < Entry) for all x.
212*9880d681SAndroid Build Coastguard Worker   if (Index == Exit || Idx.Index == Entry)
213*9880d681SAndroid Build Coastguard Worker     return false;
214*9880d681SAndroid Build Coastguard Worker   // Entry < x for all x != Entry.
215*9880d681SAndroid Build Coastguard Worker   // x < Exit for all x != Exit.
216*9880d681SAndroid Build Coastguard Worker   if (Index == Entry || Idx.Index == Exit)
217*9880d681SAndroid Build Coastguard Worker     return true;
218*9880d681SAndroid Build Coastguard Worker 
219*9880d681SAndroid Build Coastguard Worker   return Index < Idx.Index;
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
223*9880d681SAndroid Build Coastguard Worker   return operator==(Idx) || operator<(Idx);
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
228*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS,
229*9880d681SAndroid Build Coastguard Worker       const HexagonBlockRanges::IndexRange &IR);
230*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS,
231*9880d681SAndroid Build Coastguard Worker       const HexagonBlockRanges::RangeList &RL);
232*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS,
233*9880d681SAndroid Build Coastguard Worker       const HexagonBlockRanges::InstrIndexMap &M);
234*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS,
235*9880d681SAndroid Build Coastguard Worker       const HexagonBlockRanges::PrintRangeMap &P);
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker } // namespace llvm
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker #endif
240