-//===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ----*- C++ -*-===//
+//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_LIVEINTERVALS_H
-#define LLVM_CODEGEN_LIVEINTERVALS_H
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include <list>
+#include "LiveInterval.h"
namespace llvm {
- class LiveVariables;
- class MRegisterInfo;
- class VirtRegMap;
-
- /// LiveRange structure - This represents a simple register range in the
- /// program, with an inclusive start point and an exclusive end point.
- /// These ranges are rendered as [start,end).
- struct LiveRange {
- unsigned start; // Start point of the interval (inclusive)
- unsigned end; // End point of the interval (exclusive)
- LiveRange(unsigned S, unsigned E) : start(S), end(E) {
- assert(S < E && "Cannot create empty or backwards range");
- }
-
- bool operator<(const LiveRange &LR) const {
- return start < LR.start || (start == LR.start && end < LR.end);
- }
- bool operator==(const LiveRange &LR) const {
- return start == LR.start && end == LR.end;
- }
- private:
- LiveRange(); // DO NOT IMPLEMENT
- };
- std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
-
- struct LiveInterval {
- typedef std::vector<LiveRange> Ranges;
- unsigned reg; // the register of this interval
- float weight; // weight of this interval:
- // (number of uses *10^loopDepth)
- Ranges ranges; // the ranges in which this register is live
- bool isDefinedOnce; // True if there is one def of this register
-
- explicit LiveInterval(unsigned r);
-
- bool empty() const { return ranges.empty(); }
-
- bool spilled() const;
-
- /// start - Return the lowest numbered slot covered by interval.
- unsigned start() const {
- assert(!empty() && "empty interval for register");
- return ranges.front().start;
- }
+ class LiveVariables;
+ class MRegisterInfo;
+ class VirtRegMap;
- /// end - return the maximum point of the interval of the whole,
- /// exclusive.
- unsigned end() const {
- assert(!empty() && "empty interval for register");
- return ranges.back().end;
- }
+ class LiveIntervals : public MachineFunctionPass {
+ MachineFunction* mf_;
+ const TargetMachine* tm_;
+ const MRegisterInfo* mri_;
+ LiveVariables* lv_;
- bool expiredAt(unsigned index) const {
- return end() <= (index + 1);
- }
+ typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
+ Mi2IndexMap mi2iMap_;
- bool liveAt(unsigned index) const;
+ typedef std::vector<MachineInstr*> Index2MiMap;
+ Index2MiMap i2miMap_;
- bool overlaps(const LiveInterval& other) const;
+ typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
+ Reg2IntervalMap r2iMap_;
- void addRange(LiveRange R);
+ typedef DenseMap<unsigned> Reg2RegMap;
+ Reg2RegMap r2rMap_;
- void join(const LiveInterval& other);
+ std::vector<bool> allocatableRegs_;
- bool operator<(const LiveInterval& other) const {
- return start() < other.start();
- }
-
- bool operator==(const LiveInterval& other) const {
- return reg == other.reg;
- }
-
- private:
- Ranges::iterator mergeRangesForward(Ranges::iterator it);
- Ranges::iterator mergeRangesBackward(Ranges::iterator it);
- };
-
- std::ostream& operator<<(std::ostream& os, const LiveInterval& li);
-
- class LiveIntervals : public MachineFunctionPass
+ public:
+ struct InstrSlots
{
- public:
- typedef std::list<LiveInterval> Intervals;
-
- private:
- MachineFunction* mf_;
- const TargetMachine* tm_;
- const MRegisterInfo* mri_;
- MachineBasicBlock* currentMbb_;
- MachineBasicBlock::iterator currentInstr_;
- LiveVariables* lv_;
-
- typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
- Mi2IndexMap mi2iMap_;
-
- typedef std::vector<MachineInstr*> Index2MiMap;
- Index2MiMap i2miMap_;
-
- typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
- Reg2IntervalMap r2iMap_;
-
- typedef std::map<unsigned, unsigned> Reg2RegMap;
- Reg2RegMap r2rMap_;
-
- Intervals intervals_;
-
- public:
- struct InstrSlots
- {
- enum {
- LOAD = 0,
- USE = 1,
- DEF = 2,
- STORE = 3,
- NUM = 4,
- };
- };
-
- static unsigned getBaseIndex(unsigned index) {
- return index - (index % InstrSlots::NUM);
- }
- static unsigned getBoundaryIndex(unsigned index) {
- return getBaseIndex(index + InstrSlots::NUM - 1);
- }
- static unsigned getLoadIndex(unsigned index) {
- return getBaseIndex(index) + InstrSlots::LOAD;
- }
- static unsigned getUseIndex(unsigned index) {
- return getBaseIndex(index) + InstrSlots::USE;
- }
- static unsigned getDefIndex(unsigned index) {
- return getBaseIndex(index) + InstrSlots::DEF;
- }
- static unsigned getStoreIndex(unsigned index) {
- return getBaseIndex(index) + InstrSlots::STORE;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
-
- /// runOnMachineFunction - pass entry point
- virtual bool runOnMachineFunction(MachineFunction&);
-
- LiveInterval& getInterval(unsigned reg) {
- assert(r2iMap_.count(reg)&& "Interval does not exist for register");
- return *r2iMap_.find(reg)->second;
- }
-
- /// getInstructionIndex - returns the base index of instr
- unsigned getInstructionIndex(MachineInstr* instr) const;
-
- /// getInstructionFromIndex - given an index in any slot of an
- /// instruction return a pointer the instruction
- MachineInstr* getInstructionFromIndex(unsigned index) const;
-
- Intervals& getIntervals() { return intervals_; }
-
- std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
- VirtRegMap& vrm,
- int slot);
-
- private:
- /// computeIntervals - compute live intervals
- void computeIntervals();
-
- /// joinIntervals - join compatible live intervals
- void joinIntervals();
-
- /// joinIntervalsInMachineBB - Join intervals based on move
- /// instructions in the specified basic block.
- void joinIntervalsInMachineBB(MachineBasicBlock *MBB);
-
- /// handleRegisterDef - update intervals for a register def
- /// (calls handlePhysicalRegisterDef and
- /// handleVirtualRegisterDef)
- void handleRegisterDef(MachineBasicBlock* mbb,
- MachineBasicBlock::iterator mi,
- unsigned reg);
-
- /// handleVirtualRegisterDef - update intervals for a virtual
- /// register def
- void handleVirtualRegisterDef(MachineBasicBlock* mbb,
- MachineBasicBlock::iterator mi,
- LiveInterval& interval);
-
- /// handlePhysicalRegisterDef - update intervals for a
- /// physical register def
- void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
- MachineBasicBlock::iterator mi,
- LiveInterval& interval);
-
- bool overlapsAliases(const LiveInterval& lhs,
- const LiveInterval& rhs) const;
-
-
- LiveInterval& getOrCreateInterval(unsigned reg);
-
- /// rep - returns the representative of this register
- unsigned rep(unsigned reg);
-
- void printRegName(unsigned reg) const;
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4,
+ };
};
+ static unsigned getBaseIndex(unsigned index) {
+ return index - (index % InstrSlots::NUM);
+ }
+ static unsigned getBoundaryIndex(unsigned index) {
+ return getBaseIndex(index + InstrSlots::NUM - 1);
+ }
+ static unsigned getLoadIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::LOAD;
+ }
+ static unsigned getUseIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::USE;
+ }
+ static unsigned getDefIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::DEF;
+ }
+ static unsigned getStoreIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::STORE;
+ }
+
+ typedef Reg2IntervalMap::iterator iterator;
+ typedef Reg2IntervalMap::const_iterator const_iterator;
+ const_iterator begin() const { return r2iMap_.begin(); }
+ const_iterator end() const { return r2iMap_.end(); }
+ iterator begin() { return r2iMap_.begin(); }
+ iterator end() { return r2iMap_.end(); }
+ unsigned getNumIntervals() const { return r2iMap_.size(); }
+
+ LiveInterval &getInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ const LiveInterval &getInterval(unsigned reg) const {
+ Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ /// getInstructionIndex - returns the base index of instr
+ unsigned getInstructionIndex(MachineInstr* instr) const {
+ Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
+ assert(it != mi2iMap_.end() && "Invalid instruction!");
+ return it->second;
+ }
+
+ /// getInstructionFromIndex - given an index in any slot of an
+ /// instruction return a pointer the instruction
+ MachineInstr* getInstructionFromIndex(unsigned index) const {
+ index /= InstrSlots::NUM; // convert index to vector index
+ assert(index < i2miMap_.size() &&
+ "index does not correspond to an instruction");
+ return i2miMap_[index];
+ }
+
+ std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
+ VirtRegMap& vrm,
+ int slot);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(std::ostream &O, const Module* = 0) const;
+
+ private:
+ /// computeIntervals - compute live intervals
+ void computeIntervals();
+
+ /// joinIntervals - join compatible live intervals
+ void joinIntervals();
+
+ /// joinIntervalsInMachineBB - Join intervals based on move
+ /// instructions in the specified basic block.
+ void joinIntervalsInMachineBB(MachineBasicBlock *MBB);
+
+ /// handleRegisterDef - update intervals for a register def
+ /// (calls handlePhysicalRegisterDef and
+ /// handleVirtualRegisterDef)
+ void handleRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ unsigned reg);
+
+ /// handleVirtualRegisterDef - update intervals for a virtual
+ /// register def
+ void handleVirtualRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ LiveInterval& interval);
+
+ /// handlePhysicalRegisterDef - update intervals for a
+ /// physical register def
+ void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ LiveInterval& interval);
+
+ /// Return true if the two specified registers belong to different
+ /// register classes. The registers may be either phys or virt regs.
+ bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
+
+ bool overlapsAliases(const LiveInterval *lhs,
+ const LiveInterval *rhs) const;
+
+ static LiveInterval createInterval(unsigned Reg);
+
+ LiveInterval &getOrCreateInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ if (I == r2iMap_.end())
+ I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
+ return I->second;
+ }
+
+ /// rep - returns the representative of this register
+ unsigned rep(unsigned Reg) {
+ unsigned Rep = r2rMap_[Reg];
+ if (Rep)
+ return r2rMap_[Reg] = rep(Rep);
+ return Reg;
+ }
+
+ void printRegName(unsigned reg) const;
+ };
+
} // End llvm namespace
#endif