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