X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineRegisterInfo.h;h=b851fdf66da9496d27bb402c6330b276d9afbc1a;hb=5eca075b74d62c621b160aa216b4cd50829a2cc7;hp=2919d92b93b10680574a3ec99b13ee19892805a8;hpb=84bc5427d6883f73cfeae3da640acd011d35c006;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 2919d92b93b..b851fdf66da 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -14,19 +14,28 @@ #ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H #define LLVM_CODEGEN_MACHINEREGISTERINFO_H -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/iterator.h" #include namespace llvm { -/// MachineRegisterInfo - Keep track of information for each virtual register, -/// including its register class. +/// MachineRegisterInfo - Keep track of information for virtual and physical +/// registers, including vreg register classes, use/def chains for registers, +/// etc. class MachineRegisterInfo { /// VRegInfo - Information we keep for each virtual register. The entries in /// this vector are actually converted to vreg numbers by adding the - /// MRegisterInfo::FirstVirtualRegister delta to their index. - std::vector VRegInfo; + /// TargetRegisterInfo::FirstVirtualRegister delta to their index. + /// + /// Each element in this list contains the register class of the vreg and the + /// start of the use/def list for the register. + std::vector > VRegInfo; + + /// PhysRegUseDefLists - This is an array of the head of the use/def list for + /// physical registers. + MachineOperand **PhysRegUseDefLists; /// UsedPhysRegs - This is a bit vector that is computed and set by the /// register allocator, and must be kept up to date by passes that run after @@ -42,36 +51,122 @@ class MachineRegisterInfo { /// stored in the second element. std::vector > LiveIns; std::vector LiveOuts; + + MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT + void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT public: - MachineRegisterInfo(const MRegisterInfo &MRI); + explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); + ~MachineRegisterInfo(); + //===--------------------------------------------------------------------===// + // Register Info + //===--------------------------------------------------------------------===// + + /// reg_begin/reg_end - Provide iteration support to walk over all definitions + /// and uses of a register within the MachineFunction that corresponds to this + /// MachineRegisterInfo object. + template + class defusechain_iterator; + + /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified + /// register. + typedef defusechain_iterator reg_iterator; + reg_iterator reg_begin(unsigned RegNo) const { + return reg_iterator(getRegUseDefListHead(RegNo)); + } + static reg_iterator reg_end() { return reg_iterator(0); } + + /// def_iterator/def_begin/def_end - Walk all defs of the specified register. + typedef defusechain_iterator def_iterator; + def_iterator def_begin(unsigned RegNo) const { + return def_iterator(getRegUseDefListHead(RegNo)); + } + static def_iterator def_end() { return def_iterator(0); } + + /// use_iterator/use_begin/use_end - Walk all uses of the specified register. + typedef defusechain_iterator use_iterator; + use_iterator use_begin(unsigned RegNo) const { + return use_iterator(getRegUseDefListHead(RegNo)); + } + static use_iterator use_end() { return use_iterator(0); } + + /// use_empty - Return true if there are no instructions using the specified + /// register. + bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); } + + + /// replaceRegWith - Replace all instances of FromReg with ToReg in the + /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), + /// except that it also changes any definitions of the register as well. + void replaceRegWith(unsigned FromReg, unsigned ToReg); + + /// getRegUseDefListHead - Return the head pointer for the register use/def + /// list for the specified virtual or physical register. + MachineOperand *&getRegUseDefListHead(unsigned RegNo) { + if (RegNo < TargetRegisterInfo::FirstVirtualRegister) + return PhysRegUseDefLists[RegNo]; + RegNo -= TargetRegisterInfo::FirstVirtualRegister; + return VRegInfo[RegNo].second; + } + + MachineOperand *getRegUseDefListHead(unsigned RegNo) const { + if (RegNo < TargetRegisterInfo::FirstVirtualRegister) + return PhysRegUseDefLists[RegNo]; + RegNo -= TargetRegisterInfo::FirstVirtualRegister; + return VRegInfo[RegNo].second; + } + + /// getVRegDef - Return the machine instr that defines the specified virtual + /// register or null if none is found. This assumes that the code is in SSA + /// form, so there should only be one definition. + MachineInstr *getVRegDef(unsigned Reg) const; + +#ifndef NDEBUG + void dumpUses(unsigned RegNo) const; +#endif //===--------------------------------------------------------------------===// // Virtual Register Info //===--------------------------------------------------------------------===// /// getRegClass - Return the register class of the specified virtual register. - const TargetRegisterClass *getRegClass(unsigned Reg) { - Reg -= MRegisterInfo::FirstVirtualRegister; + const TargetRegisterClass *getRegClass(unsigned Reg) const { + Reg -= TargetRegisterInfo::FirstVirtualRegister; assert(Reg < VRegInfo.size() && "Invalid vreg!"); - return VRegInfo[Reg]; + return VRegInfo[Reg].first; } + /// setRegClass - Set the register class of the specified virtual register. + void setRegClass(unsigned Reg, const TargetRegisterClass *RC) { + Reg -= TargetRegisterInfo::FirstVirtualRegister; + assert(Reg < VRegInfo.size() && "Invalid vreg!"); + VRegInfo[Reg].first = RC; + } + /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// unsigned createVirtualRegister(const TargetRegisterClass *RegClass) { assert(RegClass && "Cannot create register without RegClass!"); - VRegInfo.push_back(RegClass); + // Add a reg, but keep track of whether the vector reallocated or not. + void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0]; + VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0)); + + if (&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1) + return getLastVirtReg(); + + // Otherwise, the vector reallocated, handle this now. + HandleVRegListReallocation(); return getLastVirtReg(); } /// getLastVirtReg - Return the highest currently assigned virtual register. /// unsigned getLastVirtReg() const { - return VRegInfo.size()+MRegisterInfo::FirstVirtualRegister-1; + return (unsigned)VRegInfo.size()+TargetRegisterInfo::FirstVirtualRegister-1; } + //===--------------------------------------------------------------------===// // Physical Register Use Info //===--------------------------------------------------------------------===// @@ -111,6 +206,94 @@ public: liveout_iterator liveout_begin() const { return LiveOuts.begin(); } liveout_iterator liveout_end() const { return LiveOuts.end(); } bool liveout_empty() const { return LiveOuts.empty(); } + + bool isLiveIn(unsigned Reg) const { + for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) + if (I->first == Reg || I->second == Reg) + return true; + return false; + } + +private: + void HandleVRegListReallocation(); + +public: + /// defusechain_iterator - This class provides iterator support for machine + /// operands in the function that use or define a specific register. If + /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it + /// returns defs. If neither are true then you are silly and it always + /// returns end(). + template + class defusechain_iterator + : public forward_iterator { + MachineOperand *Op; + explicit defusechain_iterator(MachineOperand *op) : Op(op) { + // If the first node isn't one we're interested in, advance to one that + // we are interested in. + if (op) { + if ((!ReturnUses && op->isUse()) || + (!ReturnDefs && op->isDef())) + ++*this; + } + } + friend class MachineRegisterInfo; + public: + typedef forward_iterator::reference reference; + typedef forward_iterator::pointer pointer; + + defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {} + defusechain_iterator() : Op(0) {} + + bool operator==(const defusechain_iterator &x) const { + return Op == x.Op; + } + bool operator!=(const defusechain_iterator &x) const { + return !operator==(x); + } + + /// atEnd - return true if this iterator is equal to reg_end() on the value. + bool atEnd() const { return Op == 0; } + + // Iterator traversal: forward iteration only + defusechain_iterator &operator++() { // Preincrement + assert(Op && "Cannot increment end iterator!"); + Op = Op->getNextOperandForReg(); + + // If this is an operand we don't care about, skip it. + while (Op && ((!ReturnUses && Op->isUse()) || + (!ReturnDefs && Op->isDef()))) + Op = Op->getNextOperandForReg(); + + return *this; + } + defusechain_iterator operator++(int) { // Postincrement + defusechain_iterator tmp = *this; ++*this; return tmp; + } + + MachineOperand &getOperand() const { + assert(Op && "Cannot dereference end iterator!"); + return *Op; + } + + /// getOperandNo - Return the operand # of this MachineOperand in its + /// MachineInstr. + unsigned getOperandNo() const { + assert(Op && "Cannot dereference end iterator!"); + return Op - &Op->getParent()->getOperand(0); + } + + // Retrieve a reference to the current operand. + MachineInstr &operator*() const { + assert(Op && "Cannot dereference end iterator!"); + return *Op->getParent(); + } + + MachineInstr *operator->() const { + assert(Op && "Cannot dereference end iterator!"); + return Op->getParent(); + } + }; + }; } // End llvm namespace