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