X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLiveIntervalAnalysis.h;h=f7f4569cb3518b05f08268bd8311d03642bf8014;hb=151c80be8180a7a0aa1594848699aa6b678b3998;hp=a78aed186f48cf5a5b92ba7b34c885f12cc1ea78;hpb=fe1630b43ef3e9506fde9780108c2af0431393e9;p=oota-llvm.git diff --git a/lib/CodeGen/LiveIntervalAnalysis.h b/lib/CodeGen/LiveIntervalAnalysis.h index a78aed186f4..f7f4569cb35 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.h +++ b/lib/CodeGen/LiveIntervalAnalysis.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ----*- C++ -*-===// +//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,194 +17,182 @@ // //===----------------------------------------------------------------------===// -#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 +#include "LiveInterval.h" namespace llvm { - class LiveVariables; - class MRegisterInfo; - class VirtRegMap; + class LiveVariables; + class MRegisterInfo; + class TargetInstrInfo; + class VirtRegMap; - struct LiveInterval { - typedef std::pair Range; - typedef std::vector 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 + class LiveIntervals : public MachineFunctionPass { + MachineFunction* mf_; + const TargetMachine* tm_; + const MRegisterInfo* mri_; + const TargetInstrInfo* tii_; + LiveVariables* lv_; - explicit LiveInterval(unsigned r); + typedef std::map Mi2IndexMap; + Mi2IndexMap mi2iMap_; - bool empty() const { return ranges.empty(); } + typedef std::vector Index2MiMap; + Index2MiMap i2miMap_; - bool spilled() const; + typedef std::map Reg2IntervalMap; + Reg2IntervalMap r2iMap_; - unsigned start() const { - assert(!empty() && "empty interval for register"); - return ranges.front().first; - } + typedef DenseMap Reg2RegMap; + Reg2RegMap r2rMap_; - unsigned end() const { - assert(!empty() && "empty interval for register"); - return ranges.back().second; - } + std::vector allocatableRegs_; - bool expiredAt(unsigned index) const { - return end() <= (index + 1); - } - - bool liveAt(unsigned index) const; - - bool overlaps(const LiveInterval& other) const; - - void addRange(unsigned start, unsigned end); - - void join(const LiveInterval& other); - - 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 Intervals; - - private: - MachineFunction* mf_; - const TargetMachine* tm_; - const MRegisterInfo* mri_; - MachineBasicBlock* currentMbb_; - MachineBasicBlock::iterator currentInstr_; - LiveVariables* lv_; - - typedef std::map Mi2IndexMap; - Mi2IndexMap mi2iMap_; - - typedef std::vector Index2MiMap; - Index2MiMap i2miMap_; - - typedef std::map Reg2IntervalMap; - Reg2IntervalMap r2iMap_; - - typedef std::map 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 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 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. If the defining instruction is a move instruction, SrcReg will be + /// the input register, and DestReg will be the result. Note that Interval + /// may not match DestReg (it might be an alias instead). + /// + void handlePhysicalRegisterDef(MachineBasicBlock* mbb, + MachineBasicBlock::iterator mi, + LiveInterval& interval, + unsigned SrcReg, unsigned DestReg); + + /// 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