blob: 4da5a970a65976f3f5266fcf5f8093a2359304bf [file] [log] [blame]
Eugene Zelenko3b873362017-09-28 22:27:31 +00001//===- HexagonBlockRanges.h -------------------------------------*- C++ -*-===//
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +00002//
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//===----------------------------------------------------------------------===//
Eugene Zelenko3b873362017-09-28 22:27:31 +00009
10#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
11#define LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000012
13#include "llvm/ADT/BitVector.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000014#include <cassert>
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000015#include <map>
16#include <set>
Eugene Zelenko82085922016-12-13 22:13:50 +000017#include <utility>
Chandler Carruth6bda14b2017-06-06 11:49:48 +000018#include <vector>
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000019
20namespace llvm {
Eugene Zelenko82085922016-12-13 22:13:50 +000021
22class HexagonSubtarget;
23class MachineBasicBlock;
24class MachineFunction;
25class MachineInstr;
Eugene Zelenko3b873362017-09-28 22:27:31 +000026class MachineRegisterInfo;
Eugene Zelenko82085922016-12-13 22:13:50 +000027class raw_ostream;
28class TargetInstrInfo;
29class TargetRegisterInfo;
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000030
31struct HexagonBlockRanges {
32 HexagonBlockRanges(MachineFunction &MF);
33
34 struct RegisterRef {
35 unsigned Reg, Sub;
Eugene Zelenko3b873362017-09-28 22:27:31 +000036
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000037 bool operator<(RegisterRef R) const {
38 return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);
39 }
40 };
Eugene Zelenko3b873362017-09-28 22:27:31 +000041 using RegisterSet = std::set<RegisterRef>;
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000042
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 };
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000053
Eugene Zelenko3b873362017-09-28 22:27:31 +000054 IndexType() {}
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000055 IndexType(unsigned Idx) : Index(Idx) {}
Eugene Zelenko82085922016-12-13 22:13:50 +000056
57 static bool isInstr(IndexType X) { return X.Index >= First; }
58
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000059 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
Eugene Zelenko3b873362017-09-28 22:27:31 +000073 unsigned Index = None;
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000074 };
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.
Eugene Zelenkoefd3d582017-07-26 23:45:28 +000079 class IndexRange : public std::pair<IndexType,IndexType> {
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000080 public:
Eugene Zelenko82085922016-12-13 22:13:50 +000081 IndexRange() = default;
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000082 IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)
83 : std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}
Eugene Zelenko82085922016-12-13 22:13:50 +000084
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000085 IndexType start() const { return first; }
86 IndexType end() const { return second; }
87
88 bool operator< (const IndexRange &A) const {
89 return start() < A.start();
90 }
Eugene Zelenko82085922016-12-13 22:13:50 +000091
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000092 bool overlaps(const IndexRange &A) const;
93 bool contains(const IndexRange &A) const;
94 void merge(const IndexRange &A);
95
Eugene Zelenko82085922016-12-13 22:13:50 +000096 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.
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000098
99 private:
100 void setStart(const IndexType &S) { first = S; }
101 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:
108 void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {
109 push_back(IndexRange(Start, End, Fixed, TiedEnd));
110 }
111 void add(const IndexRange &Range) {
112 push_back(Range);
113 }
Eugene Zelenko82085922016-12-13 22:13:50 +0000114
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000115 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);
Eugene Zelenko82085922016-12-13 22:13:50 +0000126
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000127 MachineInstr *getInstr(IndexType Idx) const;
128 IndexType getIndex(MachineInstr *MI) const;
129 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);
Eugene Zelenko82085922016-12-13 22:13:50 +0000135
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000136 IndexType First, Last;
137
138 private:
139 MachineBasicBlock &Block;
140 std::map<IndexType,MachineInstr*> Map;
141 };
142
Eugene Zelenko3b873362017-09-28 22:27:31 +0000143 using RegToRangeMap = std::map<RegisterRef, RangeList>;
144
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000145 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 {
151 PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I)
152 : Map(M), TRI(I) {}
153
154 friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);
Eugene Zelenko82085922016-12-13 22:13:50 +0000155
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000156 private:
157 const RegToRangeMap &Map;
158 const TargetRegisterInfo &TRI;
159 };
160
161private:
Krzysztof Parzyszek5bb417b2016-10-18 19:47:20 +0000162 RegisterSet getLiveIns(const MachineBasicBlock &B,
163 const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000164
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
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000175inline HexagonBlockRanges::IndexType::operator unsigned() const {
176 assert(Index >= First);
177 return Index;
178}
179
180inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {
181 return Index == x;
182}
183
184inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {
185 return Index == Idx.Index;
186}
187
188inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const {
189 return Index != x;
190}
191
192inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const {
193 return Index != Idx.Index;
194}
195
196inline
197HexagonBlockRanges::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
207inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {
208 return operator< (IndexType(Idx));
209}
210
211inline 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
231inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
232 return operator==(Idx) || operator<(Idx);
233}
234
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000235raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
236raw_ostream &operator<< (raw_ostream &OS,
237 const HexagonBlockRanges::IndexRange &IR);
238raw_ostream &operator<< (raw_ostream &OS,
239 const HexagonBlockRanges::RangeList &RL);
240raw_ostream &operator<< (raw_ostream &OS,
241 const HexagonBlockRanges::InstrIndexMap &M);
242raw_ostream &operator<< (raw_ostream &OS,
243 const HexagonBlockRanges::PrintRangeMap &P);
244
Eugene Zelenko82085922016-12-13 22:13:50 +0000245} // end namespace llvm
Benjamin Kramer922efd72016-05-27 10:06:40 +0000246
Eugene Zelenko3b873362017-09-28 22:27:31 +0000247#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H