blob: 4d18cf5abe8db869475eb30f7e6683da10cd7b9a [file] [log] [blame]
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +00001//===--- 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
19namespace 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;
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +000031
32struct 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 };
53 static bool isInstr(IndexType X) { return X.Index >= First; }
54
55 IndexType() : Index(None) {}
56 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:
79 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) {}
82 IndexType start() const { return first; }
83 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:
96 void setStart(const IndexType &S) { first = S; }
97 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:
104 void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {
105 push_back(IndexRange(Start, End, Fixed, TiedEnd));
106 }
107 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;
123 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 {
143 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
152private:
Krzysztof Parzyszek5bb417b2016-10-18 19:47:20 +0000153 RegisterSet getLiveIns(const MachineBasicBlock &B,
154 const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000155
156 void computeInitialLiveRanges(InstrIndexMap &IndexMap,
157 RegToRangeMap &LiveMap);
158
159 MachineFunction &MF;
160 const HexagonSubtarget &HST;
161 const TargetInstrInfo &TII;
162 const TargetRegisterInfo &TRI;
163 BitVector Reserved;
164};
165
166
167inline HexagonBlockRanges::IndexType::operator unsigned() const {
168 assert(Index >= First);
169 return Index;
170}
171
172inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {
173 return Index == x;
174}
175
176inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {
177 return Index == Idx.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
189HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () {
190 assert(Index != None);
191 assert(Index != Exit);
192 if (Index == Entry)
193 Index = First;
194 else
195 ++Index;
196 return *this;
197}
198
199inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {
200 return operator< (IndexType(Idx));
201}
202
203inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const {
204 // !(x < x).
205 if (Index == Idx.Index)
206 return false;
207 // !(None < x) for all x.
208 // !(x < None) for all x.
209 if (Index == None || Idx.Index == None)
210 return false;
211 // !(Exit < x) for all x.
212 // !(x < Entry) for all x.
213 if (Index == Exit || Idx.Index == Entry)
214 return false;
215 // Entry < x for all x != Entry.
216 // x < Exit for all x != Exit.
217 if (Index == Entry || Idx.Index == Exit)
218 return true;
219
220 return Index < Idx.Index;
221}
222
223inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
224 return operator==(Idx) || operator<(Idx);
225}
226
227
228raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
229raw_ostream &operator<< (raw_ostream &OS,
230 const HexagonBlockRanges::IndexRange &IR);
231raw_ostream &operator<< (raw_ostream &OS,
232 const HexagonBlockRanges::RangeList &RL);
233raw_ostream &operator<< (raw_ostream &OS,
234 const HexagonBlockRanges::InstrIndexMap &M);
235raw_ostream &operator<< (raw_ostream &OS,
236 const HexagonBlockRanges::PrintRangeMap &P);
237
Benjamin Kramer922efd72016-05-27 10:06:40 +0000238} // namespace llvm
239
Krzysztof Parzyszek7793ddb2016-02-12 22:53:35 +0000240#endif