blob: 7587e4f6f89f62e834cb8102e7376c50dfc369d6 [file] [log] [blame]
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +00001//===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the LiveInterval analysis pass. Given some
11// numbering of each the machine instructions (in this implemention
Alkis Evlogimenos08cec002004-01-31 19:59:32 +000012// depth-first order) an interval [i, j) is said to be a live interval
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000013// for register v if there is no instruction with number j' > j such
14// that v is live at j' abd there is no instruction with number i' < i
15// such that v is live at i'. In this implementation intervals can
Alkis Evlogimenos08cec002004-01-31 19:59:32 +000016// have holes, i.e. an interval might look like [1,20), [50,65),
17// [1000,1001)
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000018//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_CODEGEN_LIVEINTERVALS_H
22#define LLVM_CODEGEN_LIVEINTERVALS_H
23
24#include "llvm/CodeGen/MachineFunctionPass.h"
Alkis Evlogimenosf5f16892004-01-16 16:06:59 +000025#include <list>
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000026
27namespace llvm {
28
29 class LiveVariables;
30 class MRegisterInfo;
Alkis Evlogimenos5f375022004-03-01 20:05:10 +000031 class VirtRegMap;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000032
33 class LiveIntervals : public MachineFunctionPass
34 {
35 public:
36 struct Interval {
37 typedef std::pair<unsigned, unsigned> Range;
38 typedef std::vector<Range> Ranges;
Alkis Evlogimenos9a8b4902004-04-09 18:07:57 +000039 typedef std::vector<unsigned> Defs;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000040 unsigned reg; // the register of this interval
Alkis Evlogimenos6b4edba2003-12-21 20:19:10 +000041 float weight; // weight of this interval (number of uses
42 // * 10^loopDepth)
Alkis Evlogimenose88280a2004-01-22 23:08:45 +000043 Ranges ranges; // the ranges in which this register is live
Alkis Evlogimenos9a8b4902004-04-09 18:07:57 +000044 Defs defs;
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +000045 Interval(unsigned r);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000046
Alkis Evlogimenos7093d372004-02-17 05:14:37 +000047 bool empty() const { return ranges.empty(); }
48
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +000049 bool spilled() const;
50
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000051 unsigned start() const {
Alkis Evlogimenos7093d372004-02-17 05:14:37 +000052 assert(!empty() && "empty interval for register");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000053 return ranges.front().first;
54 }
55
56 unsigned end() const {
Alkis Evlogimenos7093d372004-02-17 05:14:37 +000057 assert(!empty() && "empty interval for register");
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000058 return ranges.back().second;
59 }
60
Alkis Evlogimenos485ec3c2003-12-18 08:56:11 +000061 bool expiredAt(unsigned index) const {
Alkis Evlogimenos3b02cbe2004-01-16 20:17:05 +000062 return end() <= (index + 1);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000063 }
64
Alkis Evlogimenos169cfd02003-12-21 05:43:40 +000065 bool liveAt(unsigned index) const;
66
67 bool overlaps(const Interval& other) const;
68
Alkis Evlogimenosdd2cc652003-12-18 08:48:48 +000069 void addRange(unsigned start, unsigned end);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000070
Alkis Evlogimenose88280a2004-01-22 23:08:45 +000071 void join(const Interval& other);
Alkis Evlogimenosdd2cc652003-12-18 08:48:48 +000072
Alkis Evlogimenose88280a2004-01-22 23:08:45 +000073 private:
74 Ranges::iterator mergeRangesForward(Ranges::iterator it);
75
76 Ranges::iterator mergeRangesBackward(Ranges::iterator it);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000077 };
78
79 struct StartPointComp {
80 bool operator()(const Interval& lhs, const Interval& rhs) {
81 return lhs.ranges.front().first < rhs.ranges.front().first;
82 }
83 };
84
85 struct EndPointComp {
86 bool operator()(const Interval& lhs, const Interval& rhs) {
87 return lhs.ranges.back().second < rhs.ranges.back().second;
88 }
89 };
90
Alkis Evlogimenosf5f16892004-01-16 16:06:59 +000091 typedef std::list<Interval> Intervals;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +000092
93 private:
94 MachineFunction* mf_;
95 const TargetMachine* tm_;
96 const MRegisterInfo* mri_;
97 MachineBasicBlock* currentMbb_;
98 MachineBasicBlock::iterator currentInstr_;
99 LiveVariables* lv_;
100
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000101 typedef std::map<unsigned, MachineBasicBlock*> MbbIndex2MbbMap;
102 MbbIndex2MbbMap mbbi2mbbMap_;
103
104 typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
105 Mi2IndexMap mi2iMap_;
106
Alkis Evlogimenos843b1602004-02-15 10:24:21 +0000107 typedef std::vector<MachineInstr*> Index2MiMap;
108 Index2MiMap i2miMap_;
109
Alkis Evlogimenosf5f16892004-01-16 16:06:59 +0000110 typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000111 Reg2IntervalMap r2iMap_;
112
Alkis Evlogimenos52f8f562004-02-18 23:14:52 +0000113 typedef std::map<unsigned, unsigned> Reg2RegMap;
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000114 Reg2RegMap r2rMap_;
115
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000116 Intervals intervals_;
117
118 public:
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +0000119 struct InstrSlots
120 {
121 enum {
122 LOAD = 0,
123 USE = 1,
124 DEF = 2,
125 STORE = 3,
126 NUM = 4,
127 };
128 };
129
130 static unsigned getBaseIndex(unsigned index) {
Alkis Evlogimenos7200c6b2004-02-22 04:05:13 +0000131 return index - (index % InstrSlots::NUM);
132 }
133 static unsigned getBoundaryIndex(unsigned index) {
134 return getBaseIndex(index + InstrSlots::NUM - 1);
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +0000135 }
136 static unsigned getLoadIndex(unsigned index) {
137 return getBaseIndex(index) + InstrSlots::LOAD;
138 }
139 static unsigned getUseIndex(unsigned index) {
140 return getBaseIndex(index) + InstrSlots::USE;
141 }
142 static unsigned getDefIndex(unsigned index) {
143 return getBaseIndex(index) + InstrSlots::DEF;
144 }
145 static unsigned getStoreIndex(unsigned index) {
146 return getBaseIndex(index) + InstrSlots::STORE;
147 }
148
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000149 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
Alkis Evlogimenos08cec002004-01-31 19:59:32 +0000150 virtual void releaseMemory();
151
152 /// runOnMachineFunction - pass entry point
153 virtual bool runOnMachineFunction(MachineFunction&);
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000154
Alkis Evlogimenos52f8f562004-02-18 23:14:52 +0000155 Interval& getInterval(unsigned reg) {
156 assert(r2iMap_.count(reg)&& "Interval does not exist for register");
157 return *r2iMap_.find(reg)->second;
158 }
159
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +0000160 /// getInstructionIndex - returns the base index of instr
Alkis Evlogimenos843b1602004-02-15 10:24:21 +0000161 unsigned getInstructionIndex(MachineInstr* instr) const;
162
Alkis Evlogimenos39a0d5c2004-02-20 06:15:40 +0000163 /// getInstructionFromIndex - given an index in any slot of an
164 /// instruction return a pointer the instruction
Alkis Evlogimenos843b1602004-02-15 10:24:21 +0000165 MachineInstr* getInstructionFromIndex(unsigned index) const;
166
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000167 Intervals& getIntervals() { return intervals_; }
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000168
Alkis Evlogimenos5f375022004-03-01 20:05:10 +0000169 void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000170
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000171 private:
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000172 /// computeIntervals - compute live intervals
173 void computeIntervals();
174
Alkis Evlogimenose88280a2004-01-22 23:08:45 +0000175 /// joinIntervals - join compatible live intervals
176 void joinIntervals();
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000177
178 /// handleRegisterDef - update intervals for a register def
179 /// (calls handlePhysicalRegisterDef and
180 /// handleVirtualRegisterDef)
181 void handleRegisterDef(MachineBasicBlock* mbb,
182 MachineBasicBlock::iterator mi,
183 unsigned reg);
184
185 /// handleVirtualRegisterDef - update intervals for a virtual
186 /// register def
187 void handleVirtualRegisterDef(MachineBasicBlock* mbb,
188 MachineBasicBlock::iterator mi,
Alkis Evlogimenos9a8b4902004-04-09 18:07:57 +0000189 Interval& interval);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000190
191 /// handlePhysicalRegisterDef - update intervals for a
192 /// physical register def
193 void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
194 MachineBasicBlock::iterator mi,
Alkis Evlogimenos9a8b4902004-04-09 18:07:57 +0000195 Interval& interval);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000196
Alkis Evlogimenos79b0c3f2004-01-23 13:37:51 +0000197 bool overlapsAliases(const Interval& lhs, const Interval& rhs) const;
198
Alkis Evlogimenos9a8b4902004-04-09 18:07:57 +0000199
200 Interval& getOrCreateInterval(unsigned reg);
201
Alkis Evlogimenos843b1602004-02-15 10:24:21 +0000202 /// rep - returns the representative of this register
203 unsigned rep(unsigned reg);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000204
205 void printRegName(unsigned reg) const;
206 };
207
208 inline bool operator==(const LiveIntervals::Interval& lhs,
209 const LiveIntervals::Interval& rhs) {
210 return lhs.reg == rhs.reg;
211 }
212
Alkis Evlogimenosb27ef242003-12-05 10:38:28 +0000213 std::ostream& operator<<(std::ostream& os,
214 const LiveIntervals::Interval& li);
Alkis Evlogimenosff0cbe12003-11-20 03:32:25 +0000215
216} // End llvm namespace
217
218#endif