X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineRegisterInfo.h;h=b851fdf66da9496d27bb402c6330b276d9afbc1a;hb=5eca075b74d62c621b160aa216b4cd50829a2cc7;hp=14d601f0bd4ef551052cd9301f88a086f9e00897;hpb=6c5757e4e85bb190097be13c1630bb107a1fbcfe;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 14d601f0bd4..b851fdf66da 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -14,19 +14,20 @@ #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" +#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. + /// 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. @@ -54,7 +55,7 @@ class MachineRegisterInfo { MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT public: - MachineRegisterInfo(const MRegisterInfo &MRI); + explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); ~MachineRegisterInfo(); //===--------------------------------------------------------------------===// @@ -64,38 +65,83 @@ public: /// 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. - class reg_iterator; + 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 < MRegisterInfo::FirstVirtualRegister) + if (RegNo < TargetRegisterInfo::FirstVirtualRegister) return PhysRegUseDefLists[RegNo]; - RegNo -= MRegisterInfo::FirstVirtualRegister; + RegNo -= TargetRegisterInfo::FirstVirtualRegister; return VRegInfo[RegNo].second; } MachineOperand *getRegUseDefListHead(unsigned RegNo) const { - if (RegNo < MRegisterInfo::FirstVirtualRegister) + if (RegNo < TargetRegisterInfo::FirstVirtualRegister) return PhysRegUseDefLists[RegNo]; - RegNo -= MRegisterInfo::FirstVirtualRegister; + 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].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. @@ -103,10 +149,10 @@ public: unsigned createVirtualRegister(const TargetRegisterClass *RegClass) { assert(RegClass && "Cannot create register without RegClass!"); // Add a reg, but keep track of whether the vector reallocated or not. - void *ArrayBase = &VRegInfo[0]; + void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0]; VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0)); - if (&VRegInfo[0] == ArrayBase) + if (&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1) return getLastVirtReg(); // Otherwise, the vector reallocated, handle this now. @@ -117,9 +163,10 @@ public: /// 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 //===--------------------------------------------------------------------===// @@ -159,29 +206,48 @@ 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: - /// reg_iterator - This class provides iterator support for machine - /// operands in the function that use or define a specific register. - class reg_iterator : public forward_iterator { - typedef forward_iterator super; - + /// 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; - reg_iterator(MachineOperand *op) : Op(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 super::reference reference; - typedef super::pointer pointer; + typedef forward_iterator::reference reference; + typedef forward_iterator::pointer pointer; - reg_iterator(const reg_iterator &I) : Op(I.Op) {} - reg_iterator() : Op(0) {} + defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {} + defusechain_iterator() : Op(0) {} - bool operator==(const reg_iterator &x) const { + bool operator==(const defusechain_iterator &x) const { return Op == x.Op; } - bool operator!=(const reg_iterator &x) const { + bool operator!=(const defusechain_iterator &x) const { return !operator==(x); } @@ -189,22 +255,43 @@ public: bool atEnd() const { return Op == 0; } // Iterator traversal: forward iteration only - reg_iterator &operator++() { // Preincrement + 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; } - reg_iterator operator++(int) { // Postincrement - reg_iterator tmp = *this; ++*this; return tmp; + defusechain_iterator operator++(int) { // Postincrement + defusechain_iterator tmp = *this; ++*this; return tmp; } - // Retrieve a reference to the current operand. - MachineOperand &operator*() const { + MachineOperand &getOperand() const { assert(Op && "Cannot dereference end iterator!"); return *Op; } - MachineOperand *operator->() const { 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(); + } }; };