LiveIntervalAnalysis.h revision 5f37502bfbadfa65de087627bd67fd58bb03725c
1//===-- 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
12// depth-first order) an interval [i, j) is said to be a live interval
13// 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
16// have holes, i.e. an interval might look like [1,20), [50,65),
17// [1000,1001)
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_CODEGEN_LIVEINTERVALS_H
22#define LLVM_CODEGEN_LIVEINTERVALS_H
23
24#include "llvm/CodeGen/MachineFunctionPass.h"
25#include <list>
26
27namespace llvm {
28
29    class LiveVariables;
30    class MRegisterInfo;
31    class VirtRegMap;
32
33    class LiveIntervals : public MachineFunctionPass
34    {
35    public:
36        struct Interval {
37            typedef std::pair<unsigned, unsigned> Range;
38            typedef std::vector<Range> Ranges;
39            unsigned reg;   // the register of this interval
40            float weight;   // weight of this interval (number of uses
41                            // * 10^loopDepth)
42            Ranges ranges;  // the ranges in which this register is live
43
44            Interval(unsigned r);
45
46            bool empty() const { return ranges.empty(); }
47
48            bool spilled() const;
49
50            unsigned start() const {
51                assert(!empty() && "empty interval for register");
52                return ranges.front().first;
53            }
54
55            unsigned end() const {
56                assert(!empty() && "empty interval for register");
57                return ranges.back().second;
58            }
59
60            bool expiredAt(unsigned index) const {
61                return end() <= (index + 1);
62            }
63
64            bool liveAt(unsigned index) const;
65
66            bool overlaps(const Interval& other) const;
67
68            void addRange(unsigned start, unsigned end);
69
70            void join(const Interval& other);
71
72        private:
73            Ranges::iterator mergeRangesForward(Ranges::iterator it);
74
75            Ranges::iterator mergeRangesBackward(Ranges::iterator it);
76        };
77
78        struct StartPointComp {
79            bool operator()(const Interval& lhs, const Interval& rhs) {
80                return lhs.ranges.front().first < rhs.ranges.front().first;
81            }
82        };
83
84        struct EndPointComp {
85            bool operator()(const Interval& lhs, const Interval& rhs) {
86                return lhs.ranges.back().second < rhs.ranges.back().second;
87            }
88        };
89
90        typedef std::list<Interval> Intervals;
91
92    private:
93        MachineFunction* mf_;
94        const TargetMachine* tm_;
95        const MRegisterInfo* mri_;
96        MachineBasicBlock* currentMbb_;
97        MachineBasicBlock::iterator currentInstr_;
98        LiveVariables* lv_;
99
100        typedef std::map<unsigned, MachineBasicBlock*> MbbIndex2MbbMap;
101        MbbIndex2MbbMap mbbi2mbbMap_;
102
103        typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
104        Mi2IndexMap mi2iMap_;
105
106        typedef std::vector<MachineInstr*> Index2MiMap;
107        Index2MiMap i2miMap_;
108
109        typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
110        Reg2IntervalMap r2iMap_;
111
112        typedef std::map<unsigned, unsigned> Reg2RegMap;
113        Reg2RegMap r2rMap_;
114
115        Intervals intervals_;
116
117    public:
118        struct InstrSlots
119        {
120            enum {
121                LOAD  = 0,
122                USE   = 1,
123                DEF   = 2,
124                STORE = 3,
125                NUM   = 4,
126            };
127        };
128
129        static unsigned getBaseIndex(unsigned index) {
130            return index - (index % InstrSlots::NUM);
131        }
132        static unsigned getBoundaryIndex(unsigned index) {
133            return getBaseIndex(index + InstrSlots::NUM - 1);
134        }
135        static unsigned getLoadIndex(unsigned index) {
136            return getBaseIndex(index) + InstrSlots::LOAD;
137        }
138        static unsigned getUseIndex(unsigned index) {
139            return getBaseIndex(index) + InstrSlots::USE;
140        }
141        static unsigned getDefIndex(unsigned index) {
142            return getBaseIndex(index) + InstrSlots::DEF;
143        }
144        static unsigned getStoreIndex(unsigned index) {
145            return getBaseIndex(index) + InstrSlots::STORE;
146        }
147
148        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
149        virtual void releaseMemory();
150
151        /// runOnMachineFunction - pass entry point
152        virtual bool runOnMachineFunction(MachineFunction&);
153
154        Interval& getInterval(unsigned reg) {
155            assert(r2iMap_.count(reg)&& "Interval does not exist for register");
156            return *r2iMap_.find(reg)->second;
157        }
158
159        /// getInstructionIndex - returns the base index of instr
160        unsigned getInstructionIndex(MachineInstr* instr) const;
161
162        /// getInstructionFromIndex - given an index in any slot of an
163        /// instruction return a pointer the instruction
164        MachineInstr* getInstructionFromIndex(unsigned index) const;
165
166        Intervals& getIntervals() { return intervals_; }
167
168        void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
169
170    private:
171        /// computeIntervals - compute live intervals
172        void computeIntervals();
173
174        /// joinIntervals - join compatible live intervals
175        void joinIntervals();
176
177        /// handleRegisterDef - update intervals for a register def
178        /// (calls handlePhysicalRegisterDef and
179        /// handleVirtualRegisterDef)
180        void handleRegisterDef(MachineBasicBlock* mbb,
181                               MachineBasicBlock::iterator mi,
182                               unsigned reg);
183
184        /// handleVirtualRegisterDef - update intervals for a virtual
185        /// register def
186        void handleVirtualRegisterDef(MachineBasicBlock* mbb,
187                                      MachineBasicBlock::iterator mi,
188                                      unsigned reg);
189
190        /// handlePhysicalRegisterDef - update intervals for a
191        /// physical register def
192        void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
193                                       MachineBasicBlock::iterator mi,
194                                       unsigned reg);
195
196        bool overlapsAliases(const Interval& lhs, const Interval& rhs) const;
197
198        /// rep - returns the representative of this register
199        unsigned rep(unsigned reg);
200
201        void printRegName(unsigned reg) const;
202    };
203
204    inline bool operator==(const LiveIntervals::Interval& lhs,
205                           const LiveIntervals::Interval& rhs) {
206        return lhs.reg == rhs.reg;
207    }
208
209    std::ostream& operator<<(std::ostream& os,
210                             const LiveIntervals::Interval& li);
211
212} // End llvm namespace
213
214#endif
215